feat: add booking details (ticket, weeks, price) to confirmation email

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-23 20:58:48 -08:00
parent 8b1d45485c
commit 6ab2a8ff3b
1 changed files with 42 additions and 5 deletions

View File

@ -4,7 +4,7 @@
const { Pool } = require('pg'); const { Pool } = require('pg');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const { syncApplication } = require('./google-sheets'); const { syncApplication } = require('./google-sheets');
const { createPayment } = require('./mollie'); const { createPayment, TICKET_LABELS, calculateAmount } = require('./mollie');
// Initialize PostgreSQL connection pool // Initialize PostgreSQL connection pool
const pool = new Pool({ const pool = new Pool({
@ -24,10 +24,23 @@ const smtp = nodemailer.createTransport({
tls: { rejectUnauthorized: false }, tls: { rejectUnauthorized: false },
}); });
// Week labels for email display
const WEEK_LABELS = {
week1: 'Week 1: Return to the Commons (Aug 24-30)',
week2: 'Week 2: Post-Capitalist Production (Aug 31-Sep 6)',
week3: 'Week 3: Future Living (Sep 7-13)',
week4: 'Week 4: Governance & Funding Models (Sep 14-20)',
};
// Email templates // Email templates
const confirmationEmail = (application) => ({ const confirmationEmail = (application) => {
subject: 'Application Received - Valley of the Commons', const ticketLabel = TICKET_LABELS[application.contribution_amount] || application.contribution_amount || 'Not selected';
html: ` const amount = application.contribution_amount ? calculateAmount(application.contribution_amount, (application.weeks || []).length) : null;
const weeksHtml = (application.weeks || []).map(w => `<li>${WEEK_LABELS[w] || w}</li>`).join('');
return {
subject: 'Application Received - Valley of the Commons',
html: `
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;"> <div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
<h1 style="color: #2d5016; margin-bottom: 24px;">Thank You for Applying!</h1> <h1 style="color: #2d5016; margin-bottom: 24px;">Thank You for Applying!</h1>
@ -35,9 +48,29 @@ const confirmationEmail = (application) => ({
<p>We've received your application to join <strong>Valley of the Commons</strong> (August 24 - September 20, 2026).</p> <p>We've received your application to join <strong>Valley of the Commons</strong> (August 24 - September 20, 2026).</p>
<div style="background: #f5f5f0; padding: 20px; border-radius: 8px; margin: 24px 0;">
<h3 style="margin-top: 0; color: #2d5016;">Your Booking Summary</h3>
<table style="width: 100%; border-collapse: collapse;">
<tr>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Ticket:</strong></td>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">${ticketLabel}</td>
</tr>
${amount ? `<tr>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Amount:</strong></td>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">&euro;${amount}</td>
</tr>` : ''}
<tr>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Attendance:</strong></td>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">${application.attendance_type === 'full' ? 'Full 4 weeks' : 'Partial'}</td>
</tr>
</table>
${weeksHtml ? `<p style="margin-top: 12px; margin-bottom: 0;"><strong>Weeks selected:</strong></p><ul style="margin-top: 4px; margin-bottom: 0;">${weeksHtml}</ul>` : ''}
</div>
<div style="background: #f5f5f0; padding: 20px; border-radius: 8px; margin: 24px 0;"> <div style="background: #f5f5f0; padding: 20px; border-radius: 8px; margin: 24px 0;">
<h3 style="margin-top: 0; color: #2d5016;">What happens next?</h3> <h3 style="margin-top: 0; color: #2d5016;">What happens next?</h3>
<ol style="margin-bottom: 0;"> <ol style="margin-bottom: 0;">
<li>Complete your payment (if you haven't already)</li>
<li>Our team will review your application</li> <li>Our team will review your application</li>
<li>We may reach out with follow-up questions</li> <li>We may reach out with follow-up questions</li>
<li>You'll receive a decision within 2-3 weeks</li> <li>You'll receive a decision within 2-3 weeks</li>
@ -64,7 +97,8 @@ const confirmationEmail = (application) => ({
</p> </p>
</div> </div>
` `
}); };
};
const adminNotificationEmail = (application) => ({ const adminNotificationEmail = (application) => ({
subject: `New Application: ${application.first_name} ${application.last_name}`, subject: `New Application: ${application.first_name} ${application.last_name}`,
@ -235,6 +269,7 @@ module.exports = async function handler(req, res) {
] ]
); );
const weeksSelected = Array.isArray(data.weeks) ? data.weeks : [];
const application = { const application = {
id: result.rows[0].id, id: result.rows[0].id,
submitted_at: result.rows[0].submitted_at, submitted_at: result.rows[0].submitted_at,
@ -253,6 +288,8 @@ module.exports = async function handler(req, res) {
referral_name: data.referral_name, referral_name: data.referral_name,
arrival_date: data.arrival_date, arrival_date: data.arrival_date,
departure_date: data.departure_date, departure_date: data.departure_date,
weeks: weeksSelected,
contribution_amount: data.contribution_amount,
}; };
// Sync to Google Sheets (fire-and-forget backup) // Sync to Google Sheets (fire-and-forget backup)