// Waitlist API endpoint using PostgreSQL // Simple interest signups with email confirmation via Resend const { Pool } = require('pg'); const { Resend } = require('resend'); // Initialize PostgreSQL connection pool const pool = new Pool({ connectionString: process.env.DATABASE_URL, ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false }); // Initialize Resend const resend = new Resend(process.env.RESEND_API_KEY); const welcomeEmail = (signup) => ({ subject: 'Welcome to Valley of the Commons', html: `

Welcome to the Valley!

Dear ${signup.name},

Thank you for your interest in Valley of the Commons - a four-week pop-up village in the Austrian Alps (August 24 - September 20, 2026).

You've been added to our community list. We'll keep you updated on:

${signup.involvement ? `
Your interests:

${signup.involvement}

` : ''}

Apply Now

See you in the valley,
The Valley of the Commons Team


You received this email because you signed up at votc.jeffemmett.com.
Unsubscribe

` }); async function logEmail(recipientEmail, recipientName, emailType, subject, resendId, metadata = {}) { try { await pool.query( `INSERT INTO email_log (recipient_email, recipient_name, email_type, subject, resend_id, metadata) VALUES ($1, $2, $3, $4, $5, $6)`, [recipientEmail, recipientName, emailType, subject, resendId, JSON.stringify(metadata)] ); } catch (error) { console.error('Failed to log email:', error); } } module.exports = async function handler(req, res) { // CORS headers res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); if (req.method === 'OPTIONS') { return res.status(200).end(); } if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } try { const { email, name, involvement } = req.body; // Validate email if (!email || !email.includes('@')) { return res.status(400).json({ error: 'Valid email is required' }); } // Validate name if (!name || name.trim() === '') { return res.status(400).json({ error: 'Name is required' }); } // Validate involvement if (!involvement || involvement.trim() === '') { return res.status(400).json({ error: 'Please describe your desired involvement' }); } const emailLower = email.toLowerCase().trim(); const nameTrimmed = name.trim(); const involvementTrimmed = involvement.trim(); // Check if email already exists const existing = await pool.query( 'SELECT id FROM waitlist WHERE email = $1', [emailLower] ); if (existing.rows.length > 0) { // Update existing entry await pool.query( 'UPDATE waitlist SET name = $1, involvement = $2 WHERE email = $3', [nameTrimmed, involvementTrimmed, emailLower] ); return res.status(200).json({ success: true, message: 'Your information has been updated!' }); } // Insert new signup const result = await pool.query( `INSERT INTO waitlist (email, name, involvement) VALUES ($1, $2, $3) RETURNING id`, [emailLower, nameTrimmed, involvementTrimmed] ); const signup = { id: result.rows[0].id, email: emailLower, name: nameTrimmed, involvement: involvementTrimmed }; // Send welcome email if (process.env.RESEND_API_KEY) { try { const email = welcomeEmail(signup); const { data: emailData } = await resend.emails.send({ from: process.env.EMAIL_FROM || 'Valley of the Commons ', to: signup.email, subject: email.subject, html: email.html }); await logEmail(signup.email, signup.name, 'waitlist_welcome', email.subject, emailData?.id); } catch (emailError) { console.error('Failed to send welcome email:', emailError); // Don't fail the request if email fails } } return res.status(200).json({ success: true, message: 'Successfully joined the waitlist!' }); } catch (error) { console.error('Waitlist error:', error); return res.status(500).json({ error: 'Failed to join waitlist. Please try again later.' }); } };