Files
myeasycms-v2/apps/web/app/[locale]/home/[account]/events/[eventId]/page.tsx
2026-03-29 19:44:57 +02:00

183 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Link from 'next/link';
import {
CalendarDays,
MapPin,
Users,
Euro,
Clock,
UserPlus,
} from 'lucide-react';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
import { createEventManagementApi } from '@kit/event-management/api';
import { CmsPageShell } from '~/components/cms-page-shell';
import { EmptyState } from '~/components/empty-state';
interface PageProps {
params: Promise<{ account: string; eventId: string }>;
}
const STATUS_LABEL: Record<string, string> = {
draft: 'Entwurf',
published: 'Veröffentlicht',
registration_open: 'Anmeldung offen',
registration_closed: 'Anmeldung geschlossen',
cancelled: 'Abgesagt',
completed: 'Abgeschlossen',
};
const STATUS_VARIANT: Record<string, 'secondary' | 'default' | 'info' | 'outline' | 'destructive'> = {
draft: 'secondary',
published: 'default',
registration_open: 'info',
registration_closed: 'outline',
cancelled: 'destructive',
completed: 'outline',
};
export default async function EventDetailPage({ params }: PageProps) {
const { account, eventId } = await params;
const client = getSupabaseServerClient();
const api = createEventManagementApi(client);
const [event, registrations] = await Promise.all([
api.getEvent(eventId),
api.getRegistrations(eventId),
]);
if (!event) return <div>Veranstaltung nicht gefunden</div>;
const e = event as Record<string, unknown>;
return (
<CmsPageShell account={account} title={String(e.name)}>
<div className="flex w-full flex-col gap-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold">{String(e.name)}</h1>
<Badge variant={STATUS_VARIANT[String(e.status)] ?? 'secondary'} className="mt-1">
{STATUS_LABEL[String(e.status)] ?? String(e.status)}
</Badge>
</div>
<Button>
<UserPlus className="mr-2 h-4 w-4" />
Anmelden
</Button>
</div>
{/* Detail Cards */}
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
<Card>
<CardContent className="flex items-center gap-3 p-4">
<CalendarDays className="h-5 w-5 text-primary" />
<div>
<p className="text-xs text-muted-foreground">Datum</p>
<p className="font-semibold">
{e.event_date
? new Date(String(e.event_date)).toLocaleDateString('de-DE')
: '—'}
</p>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="flex items-center gap-3 p-4">
<Clock className="h-5 w-5 text-primary" />
<div>
<p className="text-xs text-muted-foreground">Uhrzeit</p>
<p className="font-semibold">
{String(e.start_time ?? '—')} {String(e.end_time ?? '—')}
</p>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="flex items-center gap-3 p-4">
<MapPin className="h-5 w-5 text-primary" />
<div>
<p className="text-xs text-muted-foreground">Ort</p>
<p className="font-semibold">{String(e.location ?? '—')}</p>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="flex items-center gap-3 p-4">
<Users className="h-5 w-5 text-primary" />
<div>
<p className="text-xs text-muted-foreground">Anmeldungen</p>
<p className="font-semibold">
{registrations.length} / {String(e.capacity ?? '∞')}
</p>
</div>
</CardContent>
</Card>
</div>
{/* Description */}
{e.description ? (
<Card>
<CardHeader>
<CardTitle>Beschreibung</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground whitespace-pre-wrap">
{String(e.description)}
</p>
</CardContent>
</Card>
) : null}
{/* Registrations Table */}
<Card>
<CardHeader>
<CardTitle>Anmeldungen ({registrations.length})</CardTitle>
</CardHeader>
<CardContent>
{registrations.length === 0 ? (
<p className="py-6 text-center text-sm text-muted-foreground">
Noch keine Anmeldungen
</p>
) : (
<div className="rounded-md border">
<table className="w-full text-sm">
<thead>
<tr className="border-b bg-muted/50">
<th className="p-3 text-left font-medium">Name</th>
<th className="p-3 text-left font-medium">E-Mail</th>
<th className="p-3 text-left font-medium">Elternteil</th>
<th className="p-3 text-left font-medium">Datum</th>
</tr>
</thead>
<tbody>
{registrations.map((reg: Record<string, unknown>) => (
<tr key={String(reg.id)} className="border-b hover:bg-muted/30">
<td className="p-3 font-medium">
{String(reg.last_name ?? '')}, {String(reg.first_name ?? '')}
</td>
<td className="p-3">{String(reg.email ?? '—')}</td>
<td className="p-3">{String(reg.parent_name ?? '—')}</td>
<td className="p-3">
{reg.created_at
? new Date(String(reg.created_at)).toLocaleDateString('de-DE')
: '—'}
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</CardContent>
</Card>
</div>
</CmsPageShell>
);
}