feat: organizers, meetups UI, Plausible analytics, and migration tooling
- Add organizer model/API, admin and public organizer pages, meetup cards - Refresh events/home/contact; add calendar dialog and carousel components - Optional Plausible via NEXT_PUBLIC_PLAUSIBLE_* env vars in root layout - Prisma migration, seed updates, baseline-and-migrate script Made-with: Cursor
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { prisma } from '../db/prisma';
|
||||
import { respondIfOrganizerMigrationNeeded } from '../lib/prismaMigrationHint';
|
||||
|
||||
const router = Router();
|
||||
|
||||
@@ -92,6 +93,7 @@ router.get('/ics', async (_req: Request, res: Response) => {
|
||||
const meetups = await prisma.meetup.findMany({
|
||||
where: { date: { gte: cutoff } },
|
||||
orderBy: { date: 'asc' },
|
||||
include: { organizer: true },
|
||||
});
|
||||
|
||||
const siteUrl = (process.env.FRONTEND_URL || 'https://belgianbitcoinembassy.org').replace(
|
||||
@@ -129,8 +131,11 @@ router.get('/ics', async (_req: Request, res: Response) => {
|
||||
lines.push(fold(`LOCATION:${escapeIcs(meetup.location)}`));
|
||||
}
|
||||
lines.push(fold(`URL:${eventUrl}`));
|
||||
const orgName = meetup.organizer?.name || 'Belgian Bitcoin Embassy';
|
||||
lines.push(
|
||||
'ORGANIZER;CN=Belgian Bitcoin Embassy:mailto:info@belgianbitcoinembassy.org'
|
||||
fold(
|
||||
`ORGANIZER;CN=${escapeIcs(orgName)}:mailto:info@belgianbitcoinembassy.org`
|
||||
)
|
||||
);
|
||||
// 15-minute reminder alarm
|
||||
lines.push('BEGIN:VALARM');
|
||||
@@ -156,6 +161,7 @@ router.get('/ics', async (_req: Request, res: Response) => {
|
||||
res.send(icsBody);
|
||||
} catch (err) {
|
||||
console.error('Calendar ICS error:', err);
|
||||
if (respondIfOrganizerMigrationNeeded(err, res)) return;
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user