import React, { useState, useEffect } from 'react'; import { Target, CheckCircle2, Loader2, AlertCircle } from 'lucide-react'; import { TechButton } from './common/TechButton'; import { comms } from '../communication'; interface InitializeModalProps { isOpen: boolean; onClose: () => void; } type AxisStatus = 'pending' | 'initializing' | 'completed'; interface AxisState { name: string; status: AxisStatus; progress: number; } export const InitializeModal: React.FC = ({ isOpen, onClose }) => { const [axes, setAxes] = useState([ { name: 'PZ_PICK', status: 'pending', progress: 0 }, { name: 'PL_UPDN', status: 'pending', progress: 0 }, { name: 'PR_UPDN', status: 'pending', progress: 0 }, { name: 'PL_MOVE', status: 'pending', progress: 0 }, { name: 'PR_MOVE', status: 'pending', progress: 0 }, { name: 'Z_THETA', status: 'pending', progress: 0 }, { name: 'PX_PICK', status: 'pending', progress: 0 }, ]); const [isInitializing, setIsInitializing] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const [statusInterval, setStatusInterval] = useState | null>(null); // Reset state when modal closes useEffect(() => { if (!isOpen) { setAxes([ { name: 'PZ_PICK', status: 'pending', progress: 0 }, { name: 'PL_UPDN', status: 'pending', progress: 0 }, { name: 'PR_UPDN', status: 'pending', progress: 0 }, { name: 'PL_MOVE', status: 'pending', progress: 0 }, { name: 'PR_MOVE', status: 'pending', progress: 0 }, { name: 'Z_THETA', status: 'pending', progress: 0 }, { name: 'PX_PICK', status: 'pending', progress: 0 }, ]); setIsInitializing(false); setErrorMessage(null); if (statusInterval) { clearInterval(statusInterval); setStatusInterval(null); } } }, [isOpen]); // Cleanup interval on unmount useEffect(() => { return () => { if (statusInterval) { clearInterval(statusInterval); } }; }, [statusInterval]); const updateStatus = async () => { try { const statusJson = await comms.getInitializeStatus(); const status = JSON.parse(statusJson); if (!status.isInitializing) { // Initialization complete if (statusInterval) { clearInterval(statusInterval); setStatusInterval(null); } setIsInitializing(false); // Check if all axes are home set const allComplete = status.axes.every((axis: any) => axis.isHomeSet); if (allComplete) { // Auto close after 1 second setTimeout(() => { onClose(); }, 1000); } } // Update axis states setAxes(prev => { return prev.map(axis => { const backendAxis = status.axes.find((a: any) => a.name === axis.name); if (backendAxis) { const progress = backendAxis.progress; const isComplete = backendAxis.isHomeSet; return { ...axis, progress, status: isComplete ? 'completed' : progress > 0 ? 'initializing' : 'pending' }; } return axis; }); }); } catch (error) { console.error('[InitializeModal] Status update error:', error); } }; const startInitialization = async () => { try { setErrorMessage(null); const result = await comms.initializeDevice(); if (!result.success) { setErrorMessage(result.message); return; } setIsInitializing(true); // Start polling for status updates every 200ms const interval = setInterval(updateStatus, 200); setStatusInterval(interval); } catch (error: any) { setErrorMessage(error.message || 'Failed to start initialization'); console.error('[InitializeModal] Initialization error:', error); } }; if (!isOpen) return null; const allCompleted = axes.every(a => a.status === 'completed'); return (

DEVICE INITIALIZATION

{errorMessage && (
INITIALIZATION ERROR
                                {errorMessage}
                            
)}
{axes.map((axis, index) => (
{axis.status === 'completed' ? ( ) : axis.status === 'initializing' ? ( ) : (
)} {axis.name}
{axis.status === 'completed' ? 'COMPLETED' : axis.status === 'initializing' ? `${Math.round(axis.progress)}%` : 'WAITING'}
{/* Progress Bar */}
))}
{allCompleted && (
✓ ALL AXES INITIALIZED SUCCESSFULLY
)}
CANCEL {isInitializing ? 'INITIALIZING...' : 'START INITIALIZATION'}
); };