import { useCallback, useEffect, useState } from "react"; import { toast } from "sonner"; import { usePluginApi, useTranslation, type SettingsComponentProps, } from "@termix/plugin-sdk/frontend"; import { Button } from "@termix/plugin-sdk/ui"; export interface AcmeStatus { tls: { enabled: boolean; certificate: { issuer: string; names: string[]; notAfter: string; selfSigned: boolean; } | null; }; state: { lastAttemptAt: string | null; lastIssuedAt: string | null; lastError: string | null; }; autoRenew: boolean; missing: string | null; } function errorMessage(error: unknown): string { const data = (error as { response?: { data?: { error?: string } } })?.response ?.data; if (data?.error) return data.error; return error instanceof Error ? error.message : String(error); } export function AcmeStatusSetting({ running }: SettingsComponentProps) { const { t } = useTranslation(); const api = usePluginApi(); const [status, setStatus] = useState(null); const [requesting, setRequesting] = useState(false); const load = useCallback(async () => { try { const { data } = await api.get("/status"); setStatus(data); } catch { setStatus(null); } }, [api]); useEffect(() => { if (running) void load(); }, [running, load]); async function request() { setRequesting(true); try { const { data } = await api.post<{ reloadMessage?: string }>("/request"); toast.success(t("status.issued")); if (data.reloadMessage) toast.info(data.reloadMessage); } catch (error) { toast.error(errorMessage(error)); } finally { setRequesting(false); await load(); } } const cert = status?.tls.certificate; return (
{t("status.title")} {cert ? ( <> {t("status.names", { names: cert.names.join(", ") || "-" })} {t("status.issuer", { issuer: cert.issuer })} {t("status.expires", { date: new Date(cert.notAfter).toLocaleDateString(), })} ) : ( {t("status.none")} )} {status?.state.lastIssuedAt && ( {t("status.lastIssued", { date: new Date(status.state.lastIssuedAt).toLocaleString(), })} )} {status?.state.lastError && ( {t("status.lastError", { error: status.state.lastError })} )} {status?.missing && ( {t("status.missing")} )}
); }