import { mdiCash, mdiFolderZipOutline } from "@mdi/js"; import Icon from "@mdi/react"; import DownloadIcon from "@mui/icons-material/Download"; import UploadIcon from "@mui/icons-material/Upload"; import { Alert, Button, Card, CardActions, CardContent, CardHeader, Grid, Typography, } from "@mui/material"; import { BackupApi } from "../api/BackupApi"; import { useAccounts } from "../hooks/AccountsListProvider"; import { useAlert } from "../hooks/context_providers/AlertDialogProvider"; import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider"; import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider"; import { useSnackbar } from "../hooks/context_providers/SnackbarProvider"; import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer"; import { RouterLink } from "../widgets/RouterLink"; import excelIcon from "./excel.svg"; export function BackupRoute(): React.ReactElement { return ( {/* ZIP */} } label="ZIP" description={ <> Perform an exhaustive export or import (of accounts, inbox, movements and files). } importWarning="Existing data will be COMPLETELY ERASED, before starting import!" exportURL={BackupApi.ZIPExportURL} onImport={(f) => BackupApi.ZIPImport(f)} acceptedFiles={"application/zip"} /> {/* FinancesManager */} } label="FinancesManager" description={ <> Import and export movements using{" "} FinancesManager {" "} file format (does not support file attachments). } importWarning="Existing data will not be touched, movement will be inserted in newly created accounts." exportURL={BackupApi.FinancesManagerExportURL} onImport={(f) => BackupApi.FinancesManagerImport(f)} /> {/* Excel */} } label="Excel" description={"Export data in Excel format"} exportURL={BackupApi.ExcelExportURL()} /> ); } function ImportExportModal(p: { icon: React.ReactElement; label: string; description: string | React.ReactElement; importWarning?: string; exportURL: string; onImport?: (file: File) => Promise; acceptedFiles?: string; }): React.ReactElement { const confirm = useConfirm(); const alert = useAlert(); const snackbar = useSnackbar(); const loadingMessage = useLoadingMessage(); const accounts = useAccounts(); const doImport = async () => { try { const fileEl = document.createElement("input"); fileEl.type = "file"; if (p.acceptedFiles) fileEl.accept = p.acceptedFiles; fileEl.click(); // Wait for a file to be chosen await new Promise((res) => { fileEl.addEventListener("change", () => { res(null); }); }); if (fileEl.files?.length === 0) return; if ( !(await confirm( <>

Do you really want to perform import from {p.label}?

{p.importWarning && ( {p.importWarning} )} , `Import from ${p.label}`, "Perform import" )) ) return; loadingMessage.show("Performing import..."); await p.onImport!(fileEl.files![0]); snackbar("The import was successuflly executed!"); accounts.reload(); } catch (e) { console.error("Failed to perform import!", e); alert(`Failed to perform import! ${e}`); } finally { loadingMessage.hide(); } }; return ( {p.description} {" "} ); }