import { Router } from 'express'; import { query } from '../db'; import { z } from 'zod'; const router = Router(); // Validation schema const waitlistSchema = z.object({ email: z.string().email('Invalid email address'), source: z.string().optional().default('landing_page'), referrer: z.string().optional(), }); // POST /api/waitlist - Add email to waitlist router.post('/', async (req, res) => { try { const data = waitlistSchema.parse(req.body); // Check if email already exists const existing = await query( 'SELECT id FROM waitlist_leads WHERE email = $1', [data.email.toLowerCase()] ); if (existing.rows.length > 0) { // Already on waitlist - return success anyway (don't reveal they're already signed up) const countResult = await query('SELECT COUNT(*) FROM waitlist_leads'); const position = parseInt(countResult.rows[0].count, 10); res.json({ success: true, message: 'You\'re on the list!', position, alreadySignedUp: true, }); return; } // Insert new lead await query( 'INSERT INTO waitlist_leads (email, source, referrer) VALUES ($1, $2, $3)', [data.email.toLowerCase(), data.source, data.referrer || null] ); // Get current position (total count) const countResult = await query('SELECT COUNT(*) FROM waitlist_leads'); const position = parseInt(countResult.rows[0].count, 10); console.log(`✅ Waitlist signup: ${data.email} (Position #${position})`); res.json({ success: true, message: 'You\'re on the list!', position, }); } catch (error) { if (error instanceof z.ZodError) { res.status(400).json({ success: false, error: 'validation_error', message: error.errors[0].message, }); return; } console.error('Waitlist signup error:', error); res.status(500).json({ success: false, error: 'server_error', message: 'Failed to join waitlist. Please try again.', }); } }); // GET /api/waitlist/count - Get current waitlist count (public) router.get('/count', async (_req, res) => { try { const result = await query('SELECT COUNT(*) FROM waitlist_leads'); const count = parseInt(result.rows[0].count, 10); // Add a base number to make it look more impressive at launch const displayCount = count + 430; // Starting with "430+ waiting" res.json({ success: true, count: displayCount, }); } catch (error) { console.error('Waitlist count error:', error); res.status(500).json({ success: false, count: 430, // Fallback to base number }); } }); // GET /api/waitlist/admin - Get waitlist leads (Admin only) router.get('/admin', async (req, res) => { try { const adminPassword = process.env.ADMIN_PASSWORD; const providedPassword = req.headers['x-admin-password']; if (!adminPassword || providedPassword !== adminPassword) { res.status(401).json({ success: false, message: 'Unauthorized', }); return; } // Get stats const countResult = await query('SELECT COUNT(*) FROM waitlist_leads'); const total = parseInt(countResult.rows[0].count, 10); // Get leads const leadsResult = await query( 'SELECT * FROM waitlist_leads ORDER BY created_at DESC LIMIT 100' ); res.json({ success: true, total, leads: leadsResult.rows, }); } catch (error) { console.error('Waitlist admin error:', error); res.status(500).json({ success: false, message: 'Server error', }); } }); export default router;