import { useEffect, useState } from 'react' import { HardDrive, Trash2, RefreshCw, Play } from 'lucide-react' import { api } from '../api/client' interface Backup { path: string; filename: string; size: number; createdAt: string } const fmtSize = (b: number) => b > 1024 * 1024 * 1024 ? `${(b / 1024 / 1024 / 1024).toFixed(1)} GB` : `${(b / 1024 / 1024).toFixed(0)} MB` export default function Backup() { const [backups, setBackups] = useState([]) const [loading, setLoading] = useState(false) const [backing, setBacking] = useState(false) const [accounts, setAccounts] = useState<{ id: number; username: string }[]>([]) const [selectedAccount, setSelectedAccount] = useState('') const fetch = async () => { setLoading(true) try { const [b, a] = await Promise.all([api.get('/nixserver/backup/list'), api.get('/nixserver/accounts?limit=100')]) setBackups(b.data.data) setAccounts(a.data.data.items) } finally { setLoading(false) } } useEffect(() => { fetch() }, []) const backupAccount = async () => { if (!selectedAccount) return alert('Select an account') setBacking(true) try { await api.post(`/nixserver/backup/account/${selectedAccount}`); fetch() } catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Backup failed') } finally { setBacking(false) } } const backupServer = async () => { if (!confirm('Start a full server backup? This may take a while.')) return setBacking(true) try { await api.post('/nixserver/backup/server'); fetch() } catch (err: unknown) { alert((err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Backup failed') } finally { setBacking(false) } } const del = async (path: string) => { if (!confirm('Delete this backup?')) return try { await api.delete('/nixserver/backup', { data: { path } }); fetch() } catch {} } return (

Backup

{backups.length} backup files

{/* Actions */}

Account Backup

Full Server Backup

Backs up /etc, /home, and /var/www

{/* Backup list */}
{['Filename', 'Size', 'Created', ''].map(h => )} {backups.map(b => ( ))} {!loading && backups.length === 0 && }
{h}
{b.filename} {fmtSize(b.size)} {new Date(b.createdAt).toLocaleString()}
No backups
) }