diff --git a/app/api/events/[slug]/register/route.ts b/app/api/events/[slug]/register/route.ts index 9ab37477..00598310 100644 --- a/app/api/events/[slug]/register/route.ts +++ b/app/api/events/[slug]/register/route.ts @@ -13,7 +13,7 @@ export async function POST( ) { try { const { slug } = await params; - + // Check environment variables before creating Supabase client if (!process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) { return NextResponse.json( @@ -21,7 +21,7 @@ export async function POST( { status: 503 } ); } - + let supabase; try { supabase = await createClient(); @@ -31,10 +31,10 @@ export async function POST( { status: 503 } ); } - + // Get the current user const { data: { user }, error: authError } = await supabase.auth.getUser(); - + if (authError || !user) { return NextResponse.json( { error: 'Authentication required' }, @@ -45,7 +45,7 @@ export async function POST( // Get the event by slug const { data: event, error: eventError } = await supabase .from('events') - .select('id, title, capacity, registered, registration_required, price, payment') + .select('id, title, slug, capacity, registered, registration_required, price, payment, date, time, location, organizer, company_id, companies(email)') .eq('slug', slug) .single(); @@ -105,7 +105,7 @@ export async function POST( // Update event registration count await supabase .from('events') - .update({ + .update({ registered: event.registered + 1, updated_at: new Date().toISOString() }) @@ -120,6 +120,36 @@ export async function POST( // Don't fail the registration if analytics tracking fails } + // Send confirmation emails + try { + const { sendEventRegistrationEmails } = await import('@/lib/email/event-emails'); + + // Get company email if available + const companyEmail = Array.isArray(event.companies) && event.companies.length > 0 + ? event.companies[0]?.email + : undefined; + + await sendEventRegistrationEmails({ + userEmail: user.email!, + userName: user.user_metadata?.full_name || user.email!, + event: { + title: event.title, + date: event.date, + time: event.time, + location: event.location, + slug: event.slug, + organizer: event.organizer, + capacity: event.capacity, + registered: event.registered + 1, + organizerEmail: companyEmail + }, + registrationId: registration.id.toString() + }); + } catch (emailError) { + console.error('Error sending registration emails:', emailError); + // Don't fail the registration if email sending fails + } + return NextResponse.json({ success: true, data: registration, @@ -142,7 +172,7 @@ export async function DELETE( ) { try { const { slug } = await params; - + // Check environment variables before creating Supabase client if (!process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) { return NextResponse.json( @@ -150,7 +180,7 @@ export async function DELETE( { status: 503 } ); } - + let supabase; try { supabase = await createClient(); @@ -160,10 +190,10 @@ export async function DELETE( { status: 503 } ); } - + // Get the current user const { data: { user }, error: authError } = await supabase.auth.getUser(); - + if (authError || !user) { return NextResponse.json( { error: 'Authentication required' }, @@ -195,7 +225,7 @@ export async function DELETE( // Update event registration count await supabase .from('events') - .update({ + .update({ registered: Math.max(0, event.registered - 1), updated_at: new Date().toISOString() }) diff --git a/lib/email/event-emails.ts b/lib/email/event-emails.ts new file mode 100644 index 00000000..25a2e673 --- /dev/null +++ b/lib/email/event-emails.ts @@ -0,0 +1,387 @@ +// Email templates for event registration notifications + +import { Resend } from 'resend' + +interface EmailParams { + to: string + subject: string + html: string +} + +// Base email template matching existing Codeunia style +const getEmailTemplate = (content: string) => ` + + +
+ + +| + + | +
+ Hi ${params.userName}, +
+ ++ Great news! You're successfully registered for ${params.eventTitle}. +
+ +
+ ✓ Your registration is confirmed
+ ✓ You'll receive event updates via email
+ ✓ Add this event to your calendar
+
| + 📅 Date: + | ++ ${new Date(params.eventDate).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })} + | +
| + 🕐 Time: + | ++ ${params.eventTime} + | +
| + 📍 Location: + | ++ ${params.eventLocation} + | +
| + 👤 Organizer: + | ++ ${params.organizer} + | +
+ Looking forward to seeing you at the event! +
+ +
+ Best regards,
+ Codeunia Team
+
+ Great news! Someone just registered for your event ${params.eventTitle}. +
+ +| + Name: + | ++ ${params.participantName} + | +
| + Email: + | ++ ${params.participantEmail} + | +
+ ${params.currentRegistrations} / ${params.capacity} +
+ ++ ${percentageFilled}% filled • ${params.capacity - params.currentRegistrations} spots remaining +
++ ⚠️ Almost Full! Your event is ${percentageFilled}% full. Consider increasing capacity or preparing a waitlist. +
++ Keep up the great work! Your event is attracting interest. +
+ ` + + return { + subject: `🎉 New Registration: ${params.eventTitle} (${params.currentRegistrations}/${params.capacity})`, + html: getEmailTemplate(content) + } +} + +// Send event registration emails +export async function sendEventRegistrationEmails(params: { + userEmail: string + userName: string + event: { + title: string + date: string + time: string + location: string + slug: string + organizer?: string + capacity?: number + registered?: number + organizerEmail?: string + } + registrationId: string +}) { + try { + // Check if Resend is configured + if (!process.env.RESEND_API_KEY) { + console.warn('⚠️ RESEND_API_KEY not configured. Emails not sent:', { + userEmail: params.userEmail, + eventTitle: params.event.title, + }) + return { success: false, error: 'Email service not configured' } + } + + const resend = new Resend(process.env.RESEND_API_KEY) + + // Send confirmation email to user + const confirmationTemplate = getEventRegistrationConfirmationEmail({ + userName: params.userName, + eventTitle: params.event.title, + eventDate: params.event.date, + eventTime: params.event.time, + eventLocation: params.event.location, + eventSlug: params.event.slug, + organizer: params.event.organizer + }) + + const { data: confirmationData, error: confirmationError } = await resend.emails.send({ + from: 'Codeunia