"use client"; import { IconCloudUpload } from "@tabler/icons-react"; import { useRef, useState } from "react"; import { toast } from "sonner"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { CardContent, CardDescription, CardTitle } from "@/components/ui/card"; import { Spinner } from "@/components/ui/spinner"; export function BackupRestoreSection() { const [restoring, setRestoring] = useState(false); const [restoreDialogOpen, setRestoreDialogOpen] = useState(false); const [selectedFile, setSelectedFile] = useState(null); const fileInputRef = useRef(null); async function handleRestore(file: File) { setRestoring(true); try { const formData = new FormData(); formData.append("file", file); const res = await fetch("/api/backup/restore", { method: "POST", body: formData, }); if (!res.ok) { const data = await res.json(); throw new Error(data.error || "Restore failed"); } toast.success("Database restored. Reloading..."); setTimeout(() => window.location.reload(), 1500); } catch (err) { const message = err instanceof Error ? err.message : "Restore failed"; toast.error(message); } finally { setRestoring(false); if (fileInputRef.current) fileInputRef.current.value = ""; } } return (
Restore Upload a .db file to replace the current database. A safety backup is created first.
{ const file = e.target.files?.[0]; if (file) { setSelectedFile(file); setRestoreDialogOpen(true); } }} /> Restore database? This will replace your entire database with the uploaded file. A safety backup of your current data will be created first. Active sessions may need to refresh after restore. { setRestoreDialogOpen(false); setSelectedFile(null); if (fileInputRef.current) fileInputRef.current.value = ""; }} > Cancel { if (selectedFile) handleRestore(selectedFile); setRestoreDialogOpen(false); setSelectedFile(null); }} > Restore
); }