Files
myeasycms-v2/apps/web/app/[locale]/home/[account]/events/[eventId]/page.tsx

191 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 { createEventManagementApi } from '@kit/event-management/api';
import { formatDate } from '@kit/shared/dates';
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 { 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="text-primary h-5 w-5" />
<div>
<p className="text-muted-foreground text-xs">Datum</p>
<p className="font-semibold">
{formatDate(e.event_date as string)}
</p>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="flex items-center gap-3 p-4">
<Clock className="text-primary h-5 w-5" />
<div>
<p className="text-muted-foreground text-xs">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="text-primary h-5 w-5" />
<div>
<p className="text-muted-foreground text-xs">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="text-primary h-5 w-5" />
<div>
<p className="text-muted-foreground text-xs">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-muted-foreground text-sm 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="text-muted-foreground py-6 text-center text-sm">
Noch keine Anmeldungen
</p>
) : (
<div className="rounded-md border">
<table className="w-full text-sm">
<thead>
<tr className="bg-muted/50 border-b">
<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="hover:bg-muted/30 border-b"
>
<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">
{formatDate(reg.created_at as string)}
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</CardContent>
</Card>
</div>
</CmsPageShell>
);
}