import { useState } from 'react' import { Loader2 } from 'lucide-react' import { configApi } from '@/lib/api' import { toast } from '@/components/ui/toast' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '@/components/ui/dialog' import { RestorePreview } from './RestorePreview' interface RestoreButtonProps { tenantId: string deviceId: string commitSha: string backupDate: string deviceHostname: string open: boolean onOpenChange: (open: boolean) => void onComplete: () => void } type RestorePhase = 'preview' | 'pushing' | 'verifying' | 'done' export function RestoreButton({ tenantId, deviceId, commitSha, backupDate, deviceHostname, open, onOpenChange, onComplete, }: RestoreButtonProps) { const [phase, setPhase] = useState('preview') const handleRestore = async () => { setPhase('pushing') // Show verifying state after 30s (halfway through the 60s settle wait) const verifyTimer = setTimeout(() => { setPhase('verifying') }, 30_000) try { const result = await configApi.restore(tenantId, deviceId, commitSha) clearTimeout(verifyTimer) setPhase('done') if (result.status === 'committed') { toast({ title: 'Config restored', description: result.message, }) onComplete() onOpenChange(false) } else if (result.status === 'reverted') { toast({ title: 'Restore reverted', description: result.message, variant: 'destructive', }) onComplete() onOpenChange(false) } else { toast({ title: 'Restore failed', description: result.message, variant: 'destructive', }) onOpenChange(false) } } catch (err: unknown) { clearTimeout(verifyTimer) setPhase('preview') const message = err instanceof Error ? err.message : 'Restore operation failed' toast({ title: 'Restore failed', description: message, variant: 'destructive', }) } } const isRunning = phase === 'pushing' || phase === 'verifying' const handleOpenChange = (nextOpen: boolean) => { if (isRunning) return if (!nextOpen) setPhase('preview') onOpenChange(nextOpen) } const statusText = () => { switch (phase) { case 'pushing': return 'Pushing config to device...' case 'verifying': return 'Waiting for verification (~60s total)...' default: return null } } return ( Restore Config This will push the config from{' '} {backupDate} to{' '} {deviceHostname}. The system will create a safety backup and auto-revert if the device becomes unreachable. {phase === 'preview' && ( void handleRestore()} onCancel={() => handleOpenChange(false)} /> )} {isRunning && (
{statusText()}
)}
) }