import { useEffect, useState } from "react"; import { ByteSize, formatBytes } from "~/client/components/bytes-size"; import { Card } from "~/client/components/ui/card"; import { Progress } from "~/client/components/ui/progress"; import { type BackupProgressEvent, useServerEvents } from "~/client/hooks/use-server-events"; import { formatDuration } from "~/utils/utils"; type Props = { scheduleId: number; }; export const BackupProgressCard = ({ scheduleId }: Props) => { const { addEventListener } = useServerEvents(); const [progress, setProgress] = useState(null); useEffect(() => { const unsubscribe = addEventListener("backup:progress", (data) => { const progressData = data as BackupProgressEvent; if (progressData.scheduleId === scheduleId) { setProgress(progressData); } }); const unsubscribeComplete = addEventListener("backup:completed", (data) => { const completedData = data as { scheduleId: number }; if (completedData.scheduleId === scheduleId) { setProgress(null); } }); return () => { unsubscribe(); unsubscribeComplete(); }; }, [addEventListener, scheduleId]); if (!progress) { return (
Backup in progress
); } const percentDone = Math.round(progress.percent_done * 100); const currentFile = progress.current_files[0] || ""; const fileName = currentFile.split("/").pop() || currentFile; const speed = formatBytes(progress.bytes_done / progress.seconds_elapsed); return (
Backup in progress
{percentDone}%

Files

{progress.files_done.toLocaleString()} / {progress.total_files.toLocaleString()}

Data

/

Elapsed

{formatDuration(progress.seconds_elapsed)}

Speed

{progress.seconds_elapsed > 0 ? `${speed.text} ${speed.unit}/s` : "Calculating..."}

{fileName && (

Current file

{fileName}

)} ); };