'use client' import { useState, useEffect, useCallback } from 'react' import { useTheme } from '@/lib/ThemeContext' import { Sidebar } from '@/components/Sidebar' import { ThemeToggle } from '@/components/ThemeToggle' import { LanguageDropdown } from '@/components/LanguageDropdown' import { calendarApi } from '@/lib/schulkalender/api' import type { PublicEvent, SchoolCalendarConfig, SchoolEvent } from './types' import { BUNDESLAENDER } from './types' import { MonthView } from './_components/MonthView' import { BundeslandWizard } from './_components/BundeslandWizard' import { EventModal } from './_components/EventModal' import { DayDetail } from './_components/DayDetail' import { RolloverWizard } from './_components/RolloverWizard' import { ParentManager } from './_components/ParentManager' function monthRange(year: number, month: number): { from: string; to: string } { // Render the visible 6-week grid worth of holidays (covers prev/next month edges). const from = new Date(Date.UTC(year, month - 1, 1)) from.setUTCDate(from.getUTCDate() - 7) const to = new Date(Date.UTC(year, month, 0)) to.setUTCDate(to.getUTCDate() + 14) return { from: from.toISOString().slice(0, 10), to: to.toISOString().slice(0, 10) } } export default function SchulkalenderPage() { const { isDark } = useTheme() const today = new Date() const [year, setYear] = useState(today.getFullYear()) const [month, setMonth] = useState(today.getMonth() + 1) const [config, setConfig] = useState(null) const [holidays, setHolidays] = useState([]) const [schoolEvents, setSchoolEvents] = useState([]) const [configLoading, setConfigLoading] = useState(true) const [error, setError] = useState(null) const [openDay, setOpenDay] = useState(null) const [showAddModal, setShowAddModal] = useState(false) const [showRollover, setShowRollover] = useState(false) const loadConfig = useCallback(async () => { setConfigLoading(true) try { const cfg = await calendarApi.getConfig() setConfig(cfg) setError(null) } catch (e) { setError(e instanceof Error ? e.message : 'Config laden fehlgeschlagen') } finally { setConfigLoading(false) } }, []) useEffect(() => { loadConfig() }, [loadConfig]) const loadHolidays = useCallback(async () => { if (!config?.bundesland) return const { from, to } = monthRange(year, month) try { const [hd, ev] = await Promise.all([ calendarApi.listHolidays(config.bundesland, from, to), calendarApi.listEvents(from, to), ]) setHolidays(hd || []) setSchoolEvents(ev || []) setError(null) } catch (e) { setError(e instanceof Error ? e.message : 'Ferien/Events laden fehlgeschlagen') } }, [config, year, month]) useEffect(() => { loadHolidays() }, [loadHolidays]) const handleSaveBundesland = async (bundesland: string) => { const cfg = await calendarApi.upsertConfig({ bundesland }) setConfig(cfg) } const goPrev = () => { if (month === 1) { setYear(y => y - 1); setMonth(12) } else setMonth(m => m - 1) } const goNext = () => { if (month === 12) { setYear(y => y + 1); setMonth(1) } else setMonth(m => m + 1) } const goToday = () => { const t = new Date() setYear(t.getFullYear()) setMonth(t.getMonth() + 1) } const bundeslandName = config ? BUNDESLAENDER.find(b => b.code === config.bundesland)?.name || config.bundesland : '' return (

Schulkalender

{config ? `Ferien und Feiertage fuer ${bundeslandName}` : 'Ferien, Feiertage und Schultermine'}

{error && (
{error}
)} {configLoading ? (
Laedt…
) : !config ? ( ) : ( <> setOpenDay(iso)} onAddEvent={() => setShowAddModal(true)} onRollover={() => setShowRollover(true)} /> {openDay && ( setOpenDay(null)} onDeleted={() => { loadHolidays(); setOpenDay(null) }} /> )} {showAddModal && ( setShowAddModal(false)} onCreated={() => { setShowAddModal(false); loadHolidays() }} /> )} {showRollover && ( setShowRollover(false)} onDone={() => { setShowRollover(false); loadHolidays() }} /> )}
)}
) }