import { VStack, HStack, Field, Input, Select, Checkbox, Button, Text, Alert, AlertIcon, AlertTitle, Badge, createListCollection, Spinner, } from "@chakra-ui/react"; import { useState } from "react"; import { FaSync, FaCheckCircle, FaExclamationCircle } from "react-icons/fa"; import useApi from "../../../lib/useApi"; interface ICSSettingsProps { roomId?: string; roomName?: string; icsUrl?: string; icsEnabled?: boolean; icsFetchInterval?: number; icsLastSync?: string; icsLastEtag?: string; onChange: (settings: Partial) => void; isOwner?: boolean; } export interface ICSSettingsData { ics_url: string; ics_enabled: boolean; ics_fetch_interval: number; } const fetchIntervalOptions = [ { label: "1 minute", value: "1" }, { label: "5 minutes", value: "5" }, { label: "10 minutes", value: "10" }, { label: "30 minutes", value: "30" }, { label: "1 hour", value: "60" }, ]; export default function ICSSettings({ roomId, roomName, icsUrl = "", icsEnabled = false, icsFetchInterval = 5, icsLastSync, icsLastEtag, onChange, isOwner = true, }: ICSSettingsProps) { const [syncStatus, setSyncStatus] = useState< "idle" | "syncing" | "success" | "error" >("idle"); const [syncMessage, setSyncMessage] = useState(""); const [testResult, setTestResult] = useState(""); const api = useApi(); const fetchIntervalCollection = createListCollection({ items: fetchIntervalOptions, }); const handleTestConnection = async () => { if (!api || !icsUrl || !roomName) return; setSyncStatus("syncing"); setTestResult(""); try { // First update the room with the ICS URL await api.v1RoomsPartialUpdate({ roomId: roomId || roomName, requestBody: { ics_url: icsUrl, ics_enabled: true, ics_fetch_interval: icsFetchInterval, }, }); // Then trigger a sync const result = await api.v1RoomsTriggerIcsSync({ roomName }); if (result.status === "success") { setSyncStatus("success"); setTestResult( `Successfully synced! Found ${result.events_found} events.`, ); } else { setSyncStatus("error"); setTestResult(result.error || "Sync failed"); } } catch (err: any) { setSyncStatus("error"); setTestResult(err.body?.detail || "Failed to test ICS connection"); } }; const handleManualSync = async () => { if (!api || !roomName) return; setSyncStatus("syncing"); setSyncMessage(""); try { const result = await api.v1RoomsTriggerIcsSync({ roomName }); if (result.status === "success") { setSyncStatus("success"); setSyncMessage( `Sync complete! Found ${result.events_found} events, ` + `created ${result.events_created}, updated ${result.events_updated}.`, ); } else { setSyncStatus("error"); setSyncMessage(result.error || "Sync failed"); } } catch (err: any) { setSyncStatus("error"); setSyncMessage(err.body?.detail || "Failed to sync calendar"); } // Clear status after 5 seconds setTimeout(() => { setSyncStatus("idle"); setSyncMessage(""); }, 5000); }; if (!isOwner) { return null; // ICS settings only visible to room owner } return ( Calendar Integration (ICS) onChange({ ics_enabled: e.checked })} > Enable ICS calendar sync {icsEnabled && ( <> ICS Calendar URL onChange({ ics_url: e.target.value })} /> Enter the ICS URL from Google Calendar, Outlook, or other calendar services Sync Interval { const value = parseInt(details.value[0]); onChange({ ics_fetch_interval: value }); }} > {fetchIntervalOptions.map((option) => ( {option.label} ))} How often to check for calendar updates {icsUrl && ( {roomName && icsLastSync && ( )} )} {testResult && ( {testResult} )} {syncMessage && ( {syncMessage} )} {icsLastSync && ( Last sync: {new Date(icsLastSync).toLocaleString()} {icsLastEtag && ( ETag: {icsLastEtag.slice(0, 8)}... )} )} )} ); }