'use client'; /** * Kalenderverwaltung (Admin): alle Kalender als Karten. * * - Klick auf die Karte oeffnet das Kalender-Modal (Tag/Woche/Monat * mit Reservierungen ansehen/anlegen/loeschen). * - Stift-Icon oeffnet ein Bearbeiten-Modal (PATCH /api/calendars/[id]). * - "Kalender erstellen" oeffnet ein Erstellen-Modal (POST /api/calendars). * - Alle Modals sind per X-Icon, ESC und Hintergrund-Klick schliessbar. */ import { appFetch } from '@/lib/client-fetch'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; import { Button, Card, ErrorMessage, Input, Label } from '@/components/ui/ui'; import { ModalShell } from '@/components/ui/ModalShell'; import { CalendarCard, getCardGradient } from '@/components/calendar/CalendarCard'; import { CalendarModal } from '@/components/calendar/CalendarModal'; import { EditCalendarModal } from '@/components/admin/EditCalendarModal'; /** Daten eines Kalenders fuer die Karten-Ansicht (serverseitig geladen). */ export interface ManagedCalendar { id: string; title: string; description: string | null; timezone: string; isActive: boolean; ownerEmail: string; isOwn: boolean; memberCount: number; reservationCount: number; /** Maximale Reservierungsdauer in Minuten; 0 = unbegrenzt. */ maxReservationMinutes: number; /** Duerven Member die Titel fremder Reservierungen sehen? */ showTitleToMembers: boolean; /** Duerven Member die Notizen fremder Reservierungen sehen? */ showNotesToMembers: boolean; } /** Formularwerte zum Erstellen/Bearbeiten eines Kalenders. */ interface CalendarFormValues { title: string; description: string | null; timezone: string; } export function CalendarManager({ initialCalendars, currentUserId, isAdmin, }: { initialCalendars: ManagedCalendar[]; currentUserId: string; isAdmin: boolean; }) { const router = useRouter(); const [isCreating, setIsCreating] = useState(false); /** Aktuell im Bearbeiten-Modal geoeffneter Kalender (null = geschlossen). */ const [editingCalendar, setEditingCalendar] = useState(null); /** Aktuell im Kalender-Modal geoeffneter Kalender (null = geschlossen). */ const [openCalendar, setOpenCalendar] = useState(null); const [isPending, setIsPending] = useState(false); const [error, setError] = useState(null); /** Erstellt einen neuen Kalender (POST /api/calendars). */ async function createCalendar(values: CalendarFormValues) { setIsPending(true); setError(null); try { const response = await appFetch('/api/calendars', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(values), }); if (!response.ok) { const data = (await response.json().catch(() => ({}))) as { error?: string }; setError(data.error ?? 'Erstellen fehlgeschlagen.'); return; } setIsCreating(false); router.refresh(); } catch { setError('Netzwerkfehler. Bitte erneut versuchen.'); } finally { setIsPending(false); } } /** * Aktualisiert einen Kalender: wird von EditCalendarModal selbst * ausgefuehrt (PATCH inkl. router.refresh()); hier nur Schliessen. */ return (

Kalender verwalten

{initialCalendars.length} Kalender · eigene und Kalender anderer Benutzer

{error && !isCreating && !editingCalendar && !openCalendar && ( )} {initialCalendars.length === 0 ? (

Noch keine Kalender vorhanden. Erstelle deinen ersten Kalender.

) : (
    {initialCalendars.map((calendar, index) => (
  • { setError(null); setEditingCalendar(calendar); }} onOpen={() => { setError(null); setOpenCalendar(calendar); }} />
  • ))}
)} {openCalendar && ( setOpenCalendar(null)} /> )} {isCreating && ( { setIsCreating(false); setError(null); }} onCreate={createCalendar} /> )} {editingCalendar && ( { setEditingCalendar(null); setError(null); }} /> )}
); } /** Modal: Neuen Kalender erstellen (POST /api/calendars). */ function CreateCalendarModal({ isPending, error, onClose, onCreate, }: { isPending: boolean; error: string | null; onClose: () => void; onCreate: (values: CalendarFormValues) => void; }) { function handleSubmit(event: React.FormEvent) { event.preventDefault(); const formData = new FormData(event.currentTarget); onCreate({ title: String(formData.get('title') ?? '').trim(), description: String(formData.get('description') ?? '').trim() || null, timezone: String(formData.get('timezone') ?? '').trim(), }); } return (
); }