import { useEffect } from 'react'; import { useMutation } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { X, Stethoscope, CheckCircle2, XCircle, MinusCircle, Loader2 } from 'lucide-react'; import { api, type CameraDiagnoseResult, type CameraDiagnoseStage } from '../api/client'; interface CameraDiagnoseModalProps { printerId: number; printerName: string | null; onClose: () => void; } function StageIcon({ status }: { status: CameraDiagnoseStage['status'] }) { if (status === 'ok') return ; if (status === 'failed') return ; return ; } export function CameraDiagnoseModal({ printerId, printerName, onClose }: CameraDiagnoseModalProps) { const { t } = useTranslation(); // Kick the diagnostic off as soon as the modal mounts. There's no // "Start" button — opening the modal IS the test. The mutation // shape is right here: we want a one-shot POST with isPending / // data / error, not a cached query. const diagnose = useMutation({ mutationFn: () => api.diagnoseCamera(printerId), }); useEffect(() => { diagnose.mutate(); // Intentionally only on mount — re-running needs the user to click "Retry". // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [onClose]); const result = diagnose.data as CameraDiagnoseResult | undefined; return (
e.stopPropagation()} >

{t('camera.diagnose.modalTitle', { name: printerName || '' })}

{diagnose.isPending && (
{t('camera.diagnose.running')}
)} {diagnose.isError && (
{t('camera.diagnose.runFailed', { error: (diagnose.error as Error).message })}
)} {result && ( <> {/* Per-stage results */}
    {result.stages.map((stage) => (
  1. {t(`camera.diagnose.stage.${stage.name}`)}
    {stage.code && (
    {stage.code}
    )}
    {stage.duration_ms} ms
  2. ))}
{/* Summary + remediation */}
{t(`camera.diagnose.summary.${result.summary_code}`, { defaultValue: t('camera.diagnose.summary.unknown_failure'), })}
{/* Metadata for support triage */}
{t('camera.diagnose.meta.protocol')}: {result.protocol} {' • '} {t('camera.diagnose.meta.port')}: {result.port} {' • '} {t('camera.diagnose.meta.profile')}: {result.profile}
)}
); }