import { useRef, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { api } from "../../api"; import { useAuth } from "../../auth"; import { useConfirm } from "../../confirm"; import { useToast } from "../../toast"; import Icon from "../../components/Icon"; /** * Backup zurückladen – zweistufig wie der CSV-Import: erst prüfen lassen, was * in der Datei steckt, dann bewusst bestätigen. Der Server schreibt beim Prüfen * nichts. */ export default function RestoreCard() { const { t } = useTranslation(); const toast = useToast(); const confirm = useConfirm(); const navigate = useNavigate(); const { logout } = useAuth(); const dateiFeld = useRef(null); const [datei, setDatei] = useState(null); const [vorschau, setVorschau] = useState(null); const [modus, setModus] = useState("replace"); const [fehler, setFehler] = useState(null); const [busy, setBusy] = useState(false); function zuruecksetzen() { setDatei(null); setVorschau(null); setFehler(null); if (dateiFeld.current) dateiFeld.current.value = ""; } async function pruefen(f) { setDatei(f); setVorschau(null); setFehler(null); if (!f) return; setBusy(true); try { setVorschau(await api.restorePreview(f)); } catch (err) { setFehler(err.message); } finally { setBusy(false); } } async function einspielen() { const systemweit = vorschau.scope === "system"; if (modus === "replace") { const ok = await confirm({ title: t("restore.confirmTitle"), message: systemweit ? t("restore.confirmSystem") : t("restore.confirmReplace"), confirmLabel: t("restore.start"), danger: true, }); if (!ok) return; } setBusy(true); setFehler(null); try { const res = await api.restoreBackup(datei, systemweit ? "replace" : modus); if (res.logout_required) { // Die eigene Sitzung wurde beim Ersetzen der Benutzertabelle mit // gelöscht – sauber abmelden statt in 401er zu laufen. toast(t("restore.doneSystem")); await logout(); navigate("/login"); return; } toast(t("restore.done")); zuruecksetzen(); // Konten, Kategorien und Einstellungen sind komplett andere – neu laden // ist ehrlicher als jeden Zwischenspeicher einzeln zu erneuern. window.location.reload(); } catch (err) { setFehler(err.message); setBusy(false); } } return (

{t("restore.title")}

{t("restore.hint")}

{fehler && (
{fehler}
)} {busy && !vorschau &&

{t("common.loading")}

} {vorschau && ( <>
{vorschau.scope === "system" ? t("restore.scopeSystem", { n: vorschau.user_count }) : t("restore.scopeUser", { name: vorschau.username || "?" })}
{t("restore.exportedAt", { when: vorschau.exported_at || "?" })}
{vorschau.tables.map((z) => ( ))} {vorschau.tables.length === 0 && ( )}
{z.label} {z.count}
{t("restore.empty")}
{vorschau.notes.map((n) => (
{n}
))} {vorschau.scope === "user" && ( )}

{vorschau.scope === "system" || modus === "replace" ? t("restore.modeReplaceHint") : t("restore.modeMergeHint")}

)}
); }