"use client"; import { useState } from "react"; import styles from "./CalendarFeedPanel.module.css"; export function CalendarFeedPanel({ initiallyConfigured }: { initiallyConfigured: boolean }) { const [configured, setConfigured] = useState(initiallyConfigured); const [loading, setLoading] = useState(false); const [url, setUrl] = useState(null); const [copied, setCopied] = useState(false); const [error, setError] = useState(null); async function generate() { setLoading(true); setError(null); setCopied(false); try { const res = await fetch("/api/admin/calendar-feed/regenerate", { method: "POST", credentials: "include" }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError(data.error || "Der Kalender-Link konnte nicht erzeugt werden."); return; } setUrl(data.url); setConfigured(true); } catch { setError("Verbindung fehlgeschlagen."); } finally { setLoading(false); } } async function copy() { if (!url) return; try { await navigator.clipboard.writeText(url); setCopied(true); } catch { // Clipboard API can be unavailable (e.g. insecure context) — the // input is still selectable/copyable by hand in that case. } } return (

Kalender synchronisieren

Abonniere deinen persönlichen Kalender in Apple Kalender, Google Kalender, Outlook, Thunderbird oder einer anderen iCalendar-kompatiblen App. Der Link enthält ein geheimes Zugriffstoken — teile ihn nicht.

{!url && (

{configured ? "Ein Kalender-Link ist eingerichtet." : "Es ist noch kein Kalender-Link eingerichtet."}

)} {!url && ( )} {error &&

{error}

} {url && (

Wird nur jetzt einmal angezeigt — bitte gleich kopieren.

e.currentTarget.select()} />
{copied &&

In die Zwischenablage kopiert.

}
)}

Apple Kalender: Ablage → Neues Kalenderabonnement → Link einfügen.
Google Kalender: Weitere Kalender „+“ → Per URL → Link einfügen.
Outlook: Kalender hinzufügen → Aus dem Internet abonnieren → Link einfügen.
Thunderbird: Kalender → Neuer Kalender → Im Netzwerk → Link einfügen.

); }