'use client'; /** * Invite-Verwaltung (plan.md Abschnitt 3): Link erstellen, Liste mit * Status (Aktiv/Abgelaufen/Verwendet) und Zaehleruebersicht. */ import { useState } from 'react'; import { useRouter } from 'next/navigation'; import { Button, Card, ErrorMessage, Badge } from '@/components/ui/ui'; export interface InviteRow { id: string; expiresAt: Date | null; usedAt: Date | null; createdAt: Date; } export function InviteManager({ calendarId, invites, }: { calendarId: string; invites: InviteRow[]; }) { const router = useRouter(); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); const [lastInviteUrl, setLastInviteUrl] = useState(null); async function createInvite() { setBusy(true); setError(null); try { const response = await fetch(`/api/calendars/${calendarId}/invites`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ calendarId }), }); if (!response.ok) { const data = (await response.json()) as { error?: string }; setError(data.error ?? 'Erstellen fehlgeschlagen.'); return; } const data = (await response.json()) as { inviteUrl: string }; setLastInviteUrl(data.inviteUrl); router.refresh(); } catch { setError('Netzwerkfehler. Bitte erneut versuchen.'); } finally { setBusy(false); } } const now = new Date(); const active = invites.filter( (invite) => invite.usedAt === null && (invite.expiresAt === null || invite.expiresAt > now), ).length; const expired = invites.filter( (invite) => invite.usedAt === null && invite.expiresAt !== null && invite.expiresAt <= now, ).length; const used = invites.filter((invite) => invite.usedAt !== null).length; return (

Einladungen

{lastInviteUrl && (

Neuer Invite-Link (einmalig anzeigen):

{lastInviteUrl}
)}
Aktiv: {active} Abgelaufen: {expired} Verwendet: {used}
{invites.length === 0 ? (

Noch keine Einladungen erstellt.

) : (
    {invites.slice(0, 10).map((invite) => (
  • Erstellt {invite.createdAt.toLocaleDateString('de-DE')} {invite.usedAt ? 'Verwendet' : invite.expiresAt && invite.expiresAt <= now ? 'Abgelaufen' : 'Aktiv'}
  • ))}
)}
); }