"use client"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { cn } from "@/lib/utils"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; import { CopyField, SettingsCard, SettingsSection, whiteButton, } from "@/components/settings/settings-parts"; import { ClinicLocationSection } from "@/components/settings/settings-location"; import { PatientPortalSection } from "@/components/settings/settings-portal"; import { getNetworkEnabled, getSigningKey, listSignedRecords, rotateSigningKey, setNetworkEnabled, type SharedRecord, type SigningKey, } from "@/lib/signing"; import { listWalletUpdates, type WalletUpdate } from "@/lib/wallet-updates"; import { notify } from "@/lib/toast"; function formatDate(iso: string): string { return new Date(iso).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric", }); } export function SigningPanel() { const { t } = useTranslation(); const [key, setKey] = useState(null); const [records, setRecords] = useState([]); const [updates, setUpdates] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [rotating, setRotating] = useState(false); const [networkOn, setNetworkOn] = useState(false); const [networkSaving, setNetworkSaving] = useState(false); useEffect(() => { let active = true; Promise.all([ getSigningKey(), listSignedRecords().catch(() => []), listWalletUpdates().catch(() => []), getNetworkEnabled().catch(() => false), ]) .then(([k, r, u, n]) => { if (!active) return; setKey(k); setRecords(r); setUpdates(u); setNetworkOn(n); setError(null); }) .catch(() => { if (active) setError(t("settings.signing.loadError")); }) .finally(() => { if (active) setLoading(false); }); return () => { active = false; }; }, [t]); const rotate = async () => { setRotating(true); try { const next = await rotateSigningKey(); setKey(next); notify.success( t("settings.signing.rotateSuccessTitle"), t("settings.signing.rotateSuccessBody"), ); } catch { notify.error( t("settings.signing.rotateErrorTitle"), t("settings.signing.rotateError"), ); } finally { setRotating(false); } }; const toggleNetwork = async (next: boolean) => { setNetworkSaving(true); // Optimistic — revert on failure. setNetworkOn(next); try { const saved = await setNetworkEnabled(next); setNetworkOn(saved); notify.success( next ? t("settings.network.joinedTitle") : t("settings.network.leftTitle"), next ? t("settings.network.joinedBody") : t("settings.network.leftBody"), ); } catch { setNetworkOn(!next); notify.error( t("settings.network.errorTitle"), t("settings.network.error"), ); } finally { setNetworkSaving(false); } }; const recordStatusLabel = (status: SharedRecord["status"]): string => t( `settings.signing.records.status${ status.charAt(0).toUpperCase() + status.slice(1) }`, ); return ( <>

{t("settings.signing.keyTitle")}

{t("settings.signing.active")}

{t("settings.signing.keyDescription")}

Ed25519

{key ? t("settings.signing.createdAtLabel", { date: formatDate(key.createdAt), }) : loading ? t("settings.signing.loading") : error ?? ""}

{key?.rotatedAt ? (

{t("settings.signing.rotatedAtLabel", { date: formatDate(key.rotatedAt), })}

) : null}

{t("settings.network.toggleLabel")}

{networkOn ? t("settings.network.statusConnected") : t("settings.network.statusOff")}

{t("settings.network.toggleDesc")}

{(["sign", "approve", "verify"] as const).map((step, index) => (
{index + 1}

{t(`settings.signing.steps.${step}`)}

{t(`settings.signing.steps.${step}Desc`)}

))}

{t("settings.signing.backupLabel")}

{t("settings.signing.backupDesc")}

{t("settings.signing.comingSoon")}
{records.length === 0 ? (

{t("settings.signing.noPending")}

) : ( {records.map((record) => (

{record.walletNumber}

{record.shareMode === "temporary" ? t("settings.signing.records.temporary") : t("settings.signing.records.permanent")} {record.shareExpiresAt ? ` · ${t("settings.signing.records.expires", { date: formatDate(record.shareExpiresAt), })}` : ""}

{recordStatusLabel(record.status)}
))}
)}
{updates.length === 0 ? (

{t("walletUpdatesList.none")}

) : ( {updates.map((update) => (

{update.changes.join(" · ") || `#${update.fileNumber}`}

#{update.fileNumber} · {formatDate(update.createdAt)}

{t(`walletPush.status.${update.status}.title`)}
))}
)}
); }