import * as React from "react"; import { Box, Container, Paper, Typography, TextField, Button, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, IconButton, CircularProgress, Alert, Snackbar, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Switch, FormControlLabel, Chip, } from "@mui/material"; import DeleteIcon from "@mui/icons-material/Delete"; import AddCircleIcon from "@mui/icons-material/AddCircle"; import RefreshIcon from "@mui/icons-material/Refresh"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; import { useReportSnapshotsList, useCreateSnapshot, useDeleteSnapshot, } from "./features/report-snapshots"; import type { ReportSnapshot } from "./features/report-snapshots"; function formatDate(iso: string) { const d = new Date(iso); return d.toLocaleString(); } export default function ReportSnapshots() { const [ignoreSelf, setIgnoreSelf] = React.useState(true); const [startDate, setStartDate] = React.useState(""); const [endDate, setEndDate] = React.useState(""); const [minAmount, setMinAmount] = React.useState(""); const [maxAmount, setMaxAmount] = React.useState(""); const [snackbar, setSnackbar] = React.useState<{ message: string; severity: "success" | "error" } | null>(null); const [deleteTarget, setDeleteTarget] = React.useState(null); const [createdSnapshotId, setCreatedSnapshotId] = React.useState(null); const { data: listData, isLoading, isFetching, refetch } = useReportSnapshotsList(); const createMutation = useCreateSnapshot(); const deleteMutation = useDeleteSnapshot(); const snapshots = listData?.data ?? []; const handleCreate = async () => { try { const result = await createMutation.mutateAsync({ ignore_self: ignoreSelf || null, start_date: startDate ? new Date(startDate).toISOString() : null, end_date: endDate ? new Date(endDate).toISOString() : null, min_amount: minAmount ? parseFloat(minAmount) : null, max_amount: maxAmount ? parseFloat(maxAmount) : null, }); const snapshotId = (result as any)?.snapshot_id; if (snapshotId) { setCreatedSnapshotId(snapshotId); setSnackbar({ message: `Snapshot created: ${snapshotId}`, severity: "success" }); } else { setSnackbar({ message: "Snapshot created", severity: "success" }); } resetForm(); } catch (err: any) { setSnackbar({ message: err?.response?.data?.detail || "Failed to create snapshot", severity: "error" }); } }; const resetForm = () => { setIgnoreSelf(false); setStartDate(""); setEndDate(""); setMinAmount(""); setMaxAmount(""); }; const handleDelete = async () => { if (!deleteTarget) return; try { await deleteMutation.mutateAsync(deleteTarget.snapshot_id); setSnackbar({ message: "Snapshot deleted", severity: "success" }); } catch { setSnackbar({ message: "Failed to delete snapshot", severity: "error" }); } setDeleteTarget(null); }; return ( Report Snapshots Generate New Snapshot setIgnoreSelf(e.target.checked)} />} label="Ignore self-transfers" /> setStartDate(e.target.value)} size="small" InputLabelProps={{ shrink: true }} sx={{ flex: 1 }} /> setEndDate(e.target.value)} size="small" InputLabelProps={{ shrink: true }} sx={{ flex: 1 }} /> setMinAmount(e.target.value)} size="small" sx={{ flex: 1 }} /> setMaxAmount(e.target.value)} size="small" sx={{ flex: 1 }} /> {createdSnapshotId && ( setCreatedSnapshotId(null)}> Snapshot created: {createdSnapshotId}. Use it in the Dashboard snapshot selector. )} Existing Snapshots refetch()} disabled={isFetching}> {isLoading ? ( ) : snapshots.length === 0 ? ( No snapshots yet ) : ( Snapshot ID Created Query Actions {snapshots.map((snap: ReportSnapshot) => ( {snap.snapshot_id} { navigator.clipboard.writeText(snap.snapshot_id); setSnackbar({ message: "Copied!", severity: "success" }); }} sx={{ opacity: 0.5, '&:hover': { opacity: 1 } }} > {formatDate(snap.created_at)} {snap.query ? ( {snap.query.accounts && } {snap.query.ignore_self && } {snap.query.start_date && } {snap.query.end_date && } ) : ( )} setDeleteTarget(snap)}> ))}
)}
setSnackbar(null)} anchorOrigin={{ vertical: "bottom", horizontal: "center" }} > {snackbar ? setSnackbar(null)}>{snackbar.message} : undefined} setDeleteTarget(null)}> Delete Snapshot? This will permanently delete the report snapshot.
); }