website-monitor/backend/src/routes/waitlist.ts

96 lines
2.7 KiB
TypeScript

import { Router } from 'express';
import { pool } 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 pool.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 pool.query('SELECT COUNT(*) FROM waitlist_leads');
const position = parseInt(countResult.rows[0].count, 10);
return res.json({
success: true,
message: 'You\'re on the list!',
position,
alreadySignedUp: true,
});
}
// Insert new lead
await pool.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 pool.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) {
return res.status(400).json({
success: false,
error: 'validation_error',
message: error.errors[0].message,
});
}
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 pool.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
});
}
});
export default router;