import { useState, useEffect } from "react"; import { Calendar, RefreshCw, Trash2, Copy, Check } from "lucide-react"; interface Props { staffId: string; staffName: string; } export function CalendarSyncSection({ staffId }: Props) { const [token, setToken] = useState(null); const [loading, setLoading] = useState(false); const [actionLoading, setActionLoading] = useState<"generate" | "revoke" | null>(null); const [error, setError] = useState(null); const [copied, setCopied] = useState(false); const [showRevokeConfirm, setShowRevokeConfirm] = useState(false); useEffect(() => { fetchToken(); }, [staffId]); async function fetchToken() { setLoading(true); setError(null); try { const res = await fetch(`/api/staff/${staffId}`); if (!res.ok) throw new Error("Failed to fetch staff data"); const data = await res.json(); setToken(data.icalToken || null); } catch (e) { setError(e instanceof Error ? e.message : "Failed to load"); } finally { setLoading(false); } } async function generateToken() { setActionLoading("generate"); setError(null); try { const res = await fetch(`/api/staff/${staffId}/ical-token`, { method: "POST" }); if (!res.ok) { const err = await res.json(); throw new Error(err.error || "Failed to generate token"); } const data = await res.json(); setToken(data.icalToken); } catch (e) { setError(e instanceof Error ? e.message : "Failed to generate token"); } finally { setActionLoading(null); } } async function revokeToken() { if (!showRevokeConfirm) { setShowRevokeConfirm(true); return; } setActionLoading("revoke"); setError(null); try { const res = await fetch(`/api/staff/${staffId}/ical-token`, { method: "DELETE" }); if (!res.ok) { const err = await res.json(); throw new Error(err.error || "Failed to revoke token"); } setToken(null); } catch (e) { setError(e instanceof Error ? e.message : "Failed to revoke token"); } finally { setActionLoading(null); setShowRevokeConfirm(false); } } async function copyFeedUrl() { if (!token) return; const url = `${window.location.origin}/api/calendar/${staffId}.ics?token=${token}`; await navigator.clipboard.writeText(url); setCopied(true); setTimeout(() => setCopied(false), 2000); } const feedUrl = token ? `/api/calendar/${staffId}.ics?token=${token}` : null; return (

Calendar Sync

Generate a calendar feed link to share your upcoming appointments with any calendar app that supports iCal (Apple Calendar, Google Calendar, Outlook).

{error && (
{error}
)} {loading ? (
Loading...
) : token ? (
{showRevokeConfirm ? (

Revoke your calendar feed link? Anyone with the current link will lose access.

) : (
)}

Regenerating will create a new URL and invalidate the old one.

) : (

You don't have a calendar feed set up yet.

)}
); }