/** * CertConfirmDialog -- Confirmation dialog for certificate operations. * * - Rotate: Standard confirmation with consequence text. * - Revoke: Type-to-confirm (must type hostname), destructive red styling. * * Uses the project's existing Dialog primitives (Radix react-dialog). */ import { useState, useEffect } from 'react' import { AlertTriangle, RefreshCw, XCircle } from 'lucide-react' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' interface CertConfirmDialogProps { open: boolean onOpenChange: (open: boolean) => void action: 'rotate' | 'revoke' deviceHostname: string onConfirm: () => void } export function CertConfirmDialog({ open, onOpenChange, action, deviceHostname, onConfirm, }: CertConfirmDialogProps) { const [confirmText, setConfirmText] = useState('') const isRevoke = action === 'revoke' const canConfirm = isRevoke ? confirmText === deviceHostname : true // Reset confirm text when dialog opens/closes or action changes useEffect(() => { if (open) { setConfirmText('') } }, [open, action]) const handleConfirm = () => { if (!canConfirm) return onConfirm() } return (
{isRevoke ? ( ) : ( )}
{isRevoke ? 'Revoke Certificate' : 'Rotate Certificate'}
{isRevoke ? `This will permanently revoke the certificate for ${deviceHostname}. The device will fall back to insecure TLS mode.` : `This will generate a new certificate for ${deviceHostname}. The old certificate will be superseded.`}
{/* Warning callout */}

{isRevoke ? 'This action cannot be undone. The device will lose its verified TLS certificate and revert to self-signed mode until a new certificate is deployed.' : 'The current certificate will be marked as superseded. A new certificate will be signed and deployed to the device.'}

{/* Type-to-confirm for revoke */} {isRevoke && (
setConfirmText(e.target.value)} placeholder={deviceHostname} autoComplete="off" autoFocus />
)}
) }