- Photos: guests and hosts can download all event photos as a ZIP; HEIC/HEIF uploads are now accepted, with a WebP thumbnail generated for gallery display while the original file is preserved for download; uploader name now always shows as a caption - Hosts can send a thank-you note (email/SMS) to guests who RSVP'd yes - Guests can add the event to Google Calendar or download an .ics file, and see a live countdown to the event - Hosts can override a theme's primary/accent colors per event - New textures for a few themes' card backgrounds
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { prisma } from '@/lib/prisma';
|
|
import { requireEventAccess } from '@/lib/eventAccess';
|
|
|
|
// Quote every field per RFC 4180 and double up embedded quotes - simplest
|
|
// rule that's correct for names/notes containing commas, quotes, or newlines.
|
|
function csvField(value: string): string {
|
|
return `"${value.replace(/"/g, '""')}"`;
|
|
}
|
|
|
|
function csvRow(fields: string[]): string {
|
|
return fields.map(csvField).join(',') + '\r\n';
|
|
}
|
|
|
|
export async function GET(_request: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
const { id } = await params;
|
|
const { event } = await requireEventAccess(id);
|
|
|
|
const rsvps = await prisma.rsvp.findMany({ where: { eventId: id }, orderBy: { createdAt: 'asc' } });
|
|
|
|
let csv = csvRow(['Name', 'Status', 'Guests', 'Email', 'Phone', 'Note', 'Responded at (UTC)']);
|
|
for (const rsvp of rsvps) {
|
|
csv += csvRow([
|
|
rsvp.guestName,
|
|
rsvp.status,
|
|
String(rsvp.numGuests),
|
|
rsvp.guestEmail ?? '',
|
|
rsvp.guestPhone ?? '',
|
|
rsvp.note,
|
|
rsvp.createdAt.toISOString(),
|
|
]);
|
|
}
|
|
|
|
return new NextResponse(csv, {
|
|
headers: {
|
|
'Content-Type': 'text/csv; charset=utf-8',
|
|
'Content-Disposition': `attachment; filename="${event.slug}-rsvps.csv"`,
|
|
},
|
|
});
|
|
}
|