"use client"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; type Backup = { name: string; size: string; createdAt: string; }; export function BackupManager() { const queryClient = useQueryClient(); const [confirmRestore, setConfirmRestore] = useState(null); const [result, setResult] = useState<{ ok: boolean; message: string } | null>(null); const { data: backups = [] } = useQuery({ queryKey: ["backups"], queryFn: () => fetch("/api/backups").then((r) => r.json()), staleTime: 30_000, }); const createBackup = useMutation({ mutationFn: async () => { const res = await fetch("/api/backups", { method: "POST" }); return res.json(); }, onSuccess: (data) => { setResult({ ok: true, message: data.message || "Backup created" }); queryClient.invalidateQueries({ queryKey: ["backups"] }); }, onError: (err) => { setResult({ ok: false, message: err.message }); }, }); const restore = useMutation({ mutationFn: async (name: string) => { setConfirmRestore(null); const res = await fetch("/api/backups/restore", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name }), }); return res.json(); }, onSuccess: (data) => { setResult({ ok: data.success, message: data.message }); queryClient.invalidateQueries({ queryKey: ["status"] }); }, onError: (err) => { setResult({ ok: false, message: err.message }); }, }); const deleteBackup = useMutation({ mutationFn: async (name: string) => { await fetch("/api/backups", { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name }), }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["backups"] }); }, }); const isBusy = createBackup.isPending || restore.isPending; return (
World Backups Auto-backup every 6 hours. {backups.length} backup(s) stored.
{result && ( {result.message} )} {restore.isPending && ( Restoring world backup... Server will restart. This may take a minute. )} {backups.length === 0 ? (

No backups yet. Click "Backup Now" to create one.

) : (
    {backups.map((b) => (
  • {b.name}

    {new Date(b.createdAt).toLocaleString()} — {b.size}

    {confirmRestore === b.name ? ( <> ) : ( <> )}
  • ))}
)}
); }