import { useEffect, useState } from "react"; import { Alert, Box, Button, CircularProgress, Stack, Typography } from "@mui/material"; import CalendarMonthOutlinedIcon from "@mui/icons-material/CalendarMonthOutlined"; import DownloadOutlinedIcon from "@mui/icons-material/DownloadOutlined"; import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import { api, getApiErrorMessage } from "../api"; import { useI18n } from "../i18n/I18nProvider"; type ProviderStatus = { connected: boolean; writable: boolean }; type CalendarStatus = { google: ProviderStatus; microsoft: ProviderStatus }; type EventKind = "follow-up" | "deadline"; type CalendarEventResult = { provider: string; id?: string; webUrl?: string }; export default function ApplicationCalendarActions({ jobId, followUpAt, deadline }: { jobId: number; followUpAt?: string | null; deadline?: string | null }) { const { t } = useI18n(); const [status, setStatus] = useState(null); const [busy, setBusy] = useState(""); const [error, setError] = useState(""); const [created, setCreated] = useState(null); useEffect(() => { let active = true; api.get("/calendar/status") .then((response) => { if (active) setStatus(response.data); }) .catch(() => { if (active) setStatus({ google: { connected: false, writable: false }, microsoft: { connected: false, writable: false } }); }); return () => { active = false; }; }, []); const create = async (provider: "google" | "microsoft", kind: EventKind) => { setBusy(`${provider}-${kind}`); setError(""); setCreated(null); try { const response = await api.post(`/calendar/jobs/${jobId}/events`, { provider, kind }); setCreated(response.data); } catch (err) { setError(getApiErrorMessage(err, t("calendarCreateFailed"))); } finally { setBusy(""); } }; const download = async (kind: EventKind) => { setBusy(`ics-${kind}`); setError(""); try { const response = await api.get(`/calendar/jobs/${jobId}/events.ics`, { params: { kind }, responseType: "blob" }); const url = URL.createObjectURL(response.data); const anchor = document.createElement("a"); anchor.href = url; anchor.download = `jobjakt-${jobId}-${kind}.ics`; anchor.click(); URL.revokeObjectURL(url); } catch (err) { setError(getApiErrorMessage(err, t("calendarDownloadFailed"))); } finally { setBusy(""); } }; const rows: Array<{ kind: EventKind; title: string }> = [ ...(followUpAt ? [{ kind: "follow-up" as const, title: t("calendarFollowUp") }] : []), ...(deadline ? [{ kind: "deadline" as const, title: t("calendarDeadline") }] : []), ]; if (rows.length === 0) return {t("calendarNoDates")}; if (!status) return {t("loading")}; return ( {t("calendarHelp")} {(status.google.connected && !status.google.writable) || (status.microsoft.connected && !status.microsoft.writable) ? ( {t("calendarReconnect")}}>{t("calendarPermissionNeeded")} ) : null} {error ? {error} : null} {created ? ( }>{t("calendarOpen")} : undefined}> {t("calendarCreated")} ) : null} {rows.map((row) => ( {row.title} {status.google.writable ? : null} {status.microsoft.writable ? : null} ))} ); }