import { Card, CardContent } from "~/client/components/ui/card"; import { ByteSize } from "~/client/components/bytes-size"; import { useRootLoaderData } from "~/client/hooks/use-root-loader-data"; import type { ResticSnapshotSummaryDto } from "@zerobyte/core/restic"; import { formatDuration } from "~/utils/utils"; type Props = { summary?: ResticSnapshotSummaryDto | null; }; const getDurationLabel = (start: string, end: string) => { const startMs = new Date(start).getTime(); const endMs = new Date(end).getTime(); if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs < startMs) return "-"; return formatDuration(Math.round((endMs - startMs) / 1000)); }; export const BackupSummaryCard = ({ summary }: Props) => { const { locale } = useRootLoaderData(); if (!summary) return null; const formatCount = (value: number) => value.toLocaleString(locale); const durationLabel = getDurationLabel(summary.backup_start, summary.backup_end); const topStats = [ { label: "Data added", value: , }, { label: "Data stored", value: , }, { label: "Files processed", value: formatCount(summary.total_files_processed), }, { label: "Bytes processed", value: , }, { label: "Duration", value: durationLabel, }, ]; const detailStats = [ { label: "New files", value: formatCount(summary.files_new) }, { label: "Changed files", value: formatCount(summary.files_changed) }, { label: "Unmodified files", value: formatCount(summary.files_unmodified) }, { label: "New dirs", value: formatCount(summary.dirs_new) }, { label: "Changed dirs", value: formatCount(summary.dirs_changed) }, { label: "Unmodified dirs", value: formatCount(summary.dirs_unmodified) }, { label: "Data blobs", value: formatCount(summary.data_blobs) }, { label: "Tree blobs", value: formatCount(summary.tree_blobs) }, ]; return ( {topStats.map((stat) => ( {stat.label} {stat.value} ))} {detailStats.map((stat) => ( {stat.value} {stat.label} ))} ); };