import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Database, Download, Upload, Lock, CheckCircle, AlertCircle, Loader2, } from "lucide-react"; import { useDataExport } from "../../hooks/useDataExport"; import { useDataImport } from "../../hooks/useDataImport"; import type { ExportMode, ExportFormat } from "../../services/dataExportService"; import ImportConfirmModal from "./ImportConfirmModal"; export default function DataManagementCard() { const { t } = useTranslation(); const exportHook = useDataExport(); const importHook = useDataImport(); // Export form state const [exportMode, setExportMode] = useState( "transactions_with_categories" ); const [exportFormat, setExportFormat] = useState("json"); const [encryptExport, setEncryptExport] = useState(false); const [exportPassword, setExportPassword] = useState(""); const [exportPasswordConfirm, setExportPasswordConfirm] = useState(""); // Import password state const [importPassword, setImportPassword] = useState(""); // CSV is only valid for transaction modes const csvDisabled = exportMode === "categories_only"; if (csvDisabled && exportFormat === "csv") { setExportFormat("json"); } const passwordsMatch = exportPassword === exportPasswordConfirm; const passwordValid = !encryptExport || (exportPassword.length >= 8 && passwordsMatch); const handleExport = () => { exportHook.performExport( exportMode, exportFormat, encryptExport ? exportPassword : undefined ); }; const handleImportPasswordSubmit = () => { importHook.readWithPassword(importPassword); setImportPassword(""); }; return ( <>

{t("settings.dataManagement.title")}

{/* === EXPORT SECTION === */}

{t("settings.dataManagement.export.title")}

{/* Export mode */}
{/* Export format */}
{/* Encryption */}
{encryptExport && (
setExportPassword(e.target.value)} className="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--background)] text-sm" /> setExportPasswordConfirm(e.target.value)} className="w-full px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--background)] text-sm" /> {exportPassword.length > 0 && exportPassword.length < 8 && (

{t("settings.dataManagement.export.passwordTooShort")}

)} {exportPassword.length >= 8 && exportPasswordConfirm.length > 0 && !passwordsMatch && (

{t("settings.dataManagement.export.passwordMismatch")}

)}
)}
{/* Export button */} {/* Export feedback */} {exportHook.state.status === "success" && (
{t("settings.dataManagement.export.success")}
)} {exportHook.state.status === "error" && (
{exportHook.state.error}
)}
{/* Divider */}
{/* === IMPORT SECTION === */}

{t("settings.dataManagement.import.title")}

{t("settings.dataManagement.import.description")}

{/* Import button */} {/* Password prompt for encrypted files */} {importHook.state.status === "needsPassword" && (

{t("settings.dataManagement.import.passwordRequired")}

setImportPassword(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && importPassword) handleImportPasswordSubmit(); }} className="flex-1 px-3 py-2 rounded-lg border border-[var(--border)] bg-[var(--background)] text-sm" autoFocus />
)} {/* Import feedback */} {importHook.state.status === "success" && (
{t("settings.dataManagement.import.success")}
)} {importHook.state.status === "error" && (
{importHook.state.error}
)}
{/* Import confirmation modal */} {importHook.state.status === "confirming" && importHook.state.summary && importHook.state.importType && ( )} {importHook.state.status === "importing" && importHook.state.summary && importHook.state.importType && ( {}} onCancel={() => {}} /> )} ); }