import React, { useState, useEffect, useCallback } from 'react'; import { Button } from '@/components/ui/index'; import { RefreshCw, Plus } from 'lucide-react'; import { BackupJobList } from '@/components/Proxmox'; import { listProxmoxClusters, listProxmoxBackupJobs } from '@/lib/proxmoxClient'; import type { ClusterInfo } from '@/lib/domain'; import { toast } from 'sonner'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/index'; import { Input } from '@/components/ui/index'; import { Label } from '@/components/ui/index'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/index'; export function ProxmoxBackupPage() { const [clusters, setClusters] = useState([]); const [selectedClusterId, setSelectedClusterId] = useState(''); // eslint-disable-next-line @typescript-eslint/no-explicit-any const [jobs, setJobs] = useState([]); const [isLoading, setIsLoading] = useState(false); const [showNewJobDialog, setShowNewJobDialog] = useState(false); // New job form state const [jobName, setJobName] = useState(''); const [jobNode, setJobNode] = useState(''); const [jobSchedule, setJobSchedule] = useState(''); const [jobVms, setJobVms] = useState(''); useEffect(() => { listProxmoxClusters() .then((cls) => { setClusters(cls); if (cls.length > 0) setSelectedClusterId(cls[0].id); }) .catch((err) => { console.error('Failed to load clusters:', err); toast.error('Failed to load clusters'); }); }, []); const loadJobs = useCallback(async (clusterId: string) => { if (!clusterId) return; setIsLoading(true); try { const data = await listProxmoxBackupJobs(clusterId, ''); setJobs(data); } catch (err) { console.error('Failed to load backup jobs:', err); toast.error('Failed to load backup jobs'); } finally { setIsLoading(false); } }, []); useEffect(() => { if (selectedClusterId) loadJobs(selectedClusterId); }, [selectedClusterId, loadJobs]); const handleNewJob = () => { setJobName(''); setJobNode(''); setJobSchedule(''); setJobVms(''); setShowNewJobDialog(true); }; const handleSubmitNewJob = async () => { if (!jobName || !jobNode || !jobSchedule) { toast.error('Job name, node, and schedule are required'); return; } try { toast.info(`Creating backup job ${jobName} - implementation pending`); setShowNewJobDialog(false); } catch (error) { console.error('Failed to create backup job:', error); toast.error(`Failed to create backup job: ${error}`); } }; if (clusters.length === 0 && !isLoading) { return (

Backup Jobs

Manage Proxmox backup schedules

No Proxmox clusters configured.

Add a remote connection first.

); } return (

Backup Jobs

Manage Proxmox backup schedules

{clusters.length > 1 && ( )}
loadJobs(selectedClusterId)} /> Create New Backup Job
setJobName(e.target.value)} placeholder="daily-backup" />
setJobNode(e.target.value)} placeholder="pve" />
setJobSchedule(e.target.value)} placeholder="0 2 * * *" />

Example: "0 2 * * *" for daily at 2:00 AM

setJobVms(e.target.value)} placeholder="100, 101, 102" />
); }