'use client'; import React, { useRef, useEffect, useState, useMemo } from 'react'; import { Card } from './ui/card'; import { Button } from './ui/button'; import { Input } from './ui/input'; import { Label } from './ui/label'; import { Slider } from './ui/slider'; import { Switch } from './ui/switch'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'; import { ScrollArea } from './ui/scroll-area'; import { Badge } from './ui/badge'; import { Separator } from './ui/separator'; import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs'; import NeonAnalyzerChart from './visualizations/NeonAnalyzerChart'; // Chart Panel Component export const ChartPanel: React.FC<{ metrics?: { epoch: number; loss: number; accuracy: number; val_loss?: number; val_accuracy?: number }[]; jobStatus?: string; isLoading: boolean; freeze: () => void; resume: () => void; exportMetrics: () => void; currentEpoch?: number; totalEpochs?: number; currentAccuracy?: number; currentLoss?: number; backendConnected?: boolean | null; }> = ({ metrics = [], jobStatus = 'idle', isLoading, freeze, resume, exportMetrics, currentEpoch = 0, totalEpochs = 0, currentAccuracy = 0, currentLoss = 0, backendConnected = null, }) => { const containerRef = useRef(null); const [size, setSize] = useState({ width: 800, height: 600 }); useEffect(() => { const handleResize = () => { if (containerRef.current) { const rect = containerRef.current.getBoundingClientRect(); setSize({ width: Math.max(300, rect.width - 40), // Minimum width with padding height: Math.max(200, rect.height - 120) // Account for header and padding }); } }; handleResize(); const resizeObserver = new ResizeObserver(handleResize); if (containerRef.current) { resizeObserver.observe(containerRef.current); } return () => { resizeObserver.disconnect(); window.removeEventListener('resize', handleResize); }; }, []); // Format metrics for the chart const traces = [ { data: metrics.map(m => m.accuracy), color: '#39ff14', // Neon green label: 'Accuracy' }, { data: metrics.map(m => m.loss), color: '#ff00ff', // Neon pink label: 'Loss' }, { data: metrics.map(m => m.val_accuracy || 0), color: '#00ffe7', // Neon cyan label: 'Val Acc' } ]; // Ensure traces have valid data const validTraces = traces.filter(trace => trace.data.length > 0); const hasValidData = validTraces.length > 0 && validTraces[0].data.length > 0; // Status display text and colors const statusText = typeof jobStatus === 'string' && jobStatus.length > 0 ? jobStatus.toUpperCase() : 'IDLE'; const isRunning = jobStatus === 'running'; const isCompleted = jobStatus === 'completed'; const isFailed = jobStatus === 'failed'; // Get status-specific styling const getStatusStyling = () => { if (backendConnected === false) { return { badgeClass: 'bg-[#ff6600]/10 text-[#ff6600] border-[#ff6600]/30', headerClass: 'text-[#ff6600]', text: 'OFFLINE' }; } else if (backendConnected === null) { return { badgeClass: 'bg-[#ffff00]/10 text-[#ffff00] border-[#ffff00]/30', headerClass: 'text-[#ffff00]', text: 'CONNECTING' }; } else if (isRunning) { return { badgeClass: 'bg-[#39ff14]/10 text-[#39ff14] border-[#39ff14]/30', headerClass: 'text-[#39ff14]', text: 'LIVE TRAINING' }; } else if (isCompleted) { return { badgeClass: 'bg-[#00ffe7]/10 text-[#00ffe7] border-[#00ffe7]/30', headerClass: 'text-[#00ffe7]', text: 'COMPLETED' }; } else if (isFailed) { return { badgeClass: 'bg-[#ff0080]/10 text-[#ff0080] border-[#ff0080]/30', headerClass: 'text-[#ff0080]', text: 'FAILED' }; } else { return { badgeClass: 'bg-[#00ffe7]/10 text-[#00ffe7] border-[#00ffe7]/30', headerClass: 'text-[#00ffe7]', text: 'READY' }; } }; const statusStyling = getStatusStyling(); return (
{/* Header */}

SPECTRUM ANALYZER

{statusStyling.text} {backendConnected && currentEpoch > 0 && (
EPOCH: {currentEpoch}/{totalEpochs} | ACC: {(currentAccuracy || 0).toFixed(1)}% | LOSS: {(currentLoss || 0).toFixed(4)}
)}
{/* Chart Content */}
{backendConnected === false ? (
⚠️

Backend Offline

) : backendConnected === null ? (
🔄

Connecting to training backend...

) : hasValidData ? ( ) : (
📊

No training data available

)}
); }; // Terminal Panel Component export const TerminalPanel: React.FC<{ logs: Array<{ time: string; level: string; message: string }> | string[]; isPolling?: boolean; clearLogs: () => void; exportLogs: () => void; stopJob: () => void; }> = ({ logs, isPolling = false, clearLogs, exportLogs, stopJob }) => { const visibleLogs = useMemo(() => logs.slice(-50), [logs]); const renderLogLine = (log, index) => { if (typeof log === 'string') { return (
{log}
); } return (
{log.timestamp} [{log.level}] {log.message}
); }; return (

NEURAL LOG

{isPolling ? 'ACTIVE' : 'STANDBY'}
LINES: {visibleLogs.length}
{visibleLogs.length === 0 ? (
📟

No logs available

Start training to see real-time output

) : ( visibleLogs.map((log, index) => renderLogLine(log, index)) )}
); }; // Controls Panel Component export const ControlsPanel: React.FC<{ onTrainingStart?: (jobId: string) => void; isTraining?: boolean; currentJobId?: string | null; jobStatus?: import('@/lib/training-api').JobStatus | null; backendConnected?: boolean | null; }> = ({ onTrainingStart, isTraining = false, currentJobId, jobStatus, backendConnected = null }) => { // Form state for training parameters const [formData, setFormData] = React.useState({ modelName: 'ZPE_Quantum_Neural_Net', totalEpochs: 60, batchSize: 32, learningRate: 0.001, weightDecay: 0.0001, baseConfigId: '', sequenceLength: 32, labelSmoothing: 0.1, mixupAlpha: 1.0, // ZPE Parameters momentumParams: [0.9, 0.85, 0.8, 0.75, 0.7, 0.65], strengthParams: [0.35, 0.3, 0.25, 0.2, 0.15, 0.1], noiseParams: [0.3, 0.25, 0.2, 0.15, 0.1, 0.05], couplingParams: [0.85, 0.8, 0.75, 0.7, 0.65, 0.6], }); const [isSubmitting, setIsSubmitting] = React.useState(false); // Import the API const { trainingAPI } = React.useMemo(() => { // We'll import this dynamically to avoid SSR issues return require('@/lib/training-api'); }, []); // Handle form field updates const updateField = (field: string, value: any) => { setFormData(prev => ({ ...prev, [field]: value })); }; // Handle ZPE parameter updates const updateZPEParam = (paramType: 'momentumParams' | 'strengthParams' | 'noiseParams' | 'couplingParams', index: number, value: number) => { setFormData(prev => ({ ...prev, [paramType]: prev[paramType].map((v, i) => i === index ? value : v) })); }; // Handle training submission const handleStartTraining = async () => { if (isSubmitting || isTraining || !backendConnected) return; try { setIsSubmitting(true); console.log('🚀 Submitting training request with params:', formData); // Prepare parameters for backend API const trainingParams = { model_name: formData.modelName, total_epochs: formData.totalEpochs, batch_size: formData.batchSize, learning_rate: formData.learningRate, sequence_length: formData.sequenceLength, label_smoothing: formData.labelSmoothing, mixup_alpha: formData.mixupAlpha, base_config_id: formData.baseConfigId || undefined, weightDecay: formData.weightDecay, momentumParams: formData.momentumParams, strengthParams: formData.strengthParams, noiseParams: formData.noiseParams, couplingParams: formData.couplingParams, }; // Call the backend API const response = await trainingAPI.startTraining(trainingParams); if (response.status === 'training_started' && response.job_id) { console.log('✅ Training started successfully:', response.job_id); onTrainingStart?.(response.job_id); } else { throw new Error('Unexpected response from training API'); } } catch (error) { console.error('❌ Training start failed:', error); alert(`Training failed to start: ${error instanceof Error ? error.message : 'Unknown error'}`); } finally { setIsSubmitting(false); } }; return (

NEURAL CONTROLS

{backendConnected === false ? 'OFFLINE' : isTraining ? 'TRAINING' : 'READY'}
{/* Backend Offline Banner */} {backendConnected === false && (
⚠️

Training Backend Offline

Connect to backend server to enable training

)} Neural Hyper Model Config

NEURAL TRAINING

{/* Real-time Training Stats */} {isTraining && jobStatus && backendConnected && (
TRAINING STATUS
Epoch: {jobStatus.current_epoch}/{jobStatus.total_epochs}
Accuracy: {(jobStatus.accuracy || 0).toFixed(2)}%
Loss: {(jobStatus.loss || 0).toFixed(4)}
)}

HYPERPARAMETERS

updateField('learningRate', value[0] / 1000)} disabled={!backendConnected} /> updateField('learningRate', parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
updateField('totalEpochs', parseInt(e.target.value) || 0)} disabled={!backendConnected} />
updateField('weightDecay', parseFloat(e.target.value) || 0)} disabled={!backendConnected} />

MODEL CONFIG

General ZPE Quantum
updateField('modelName', e.target.value)} disabled={!backendConnected} />
updateField('totalEpochs', parseInt(e.target.value) || 0)} disabled={!backendConnected} />
updateField('batchSize', parseInt(e.target.value) || 0)} disabled={!backendConnected} />
updateField('learningRate', parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
updateField('weightDecay', parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
updateField('baseConfigId', e.target.value)} placeholder="e.g., config_123456" disabled={!backendConnected} />

ZPE CONFIGURATION

{formData.momentumParams.map((value, index) => (
updateZPEParam('momentumParams', index, parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
))}
{formData.strengthParams.map((value, index) => (
updateZPEParam('strengthParams', index, parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
))}
{formData.noiseParams.map((value, index) => (
updateZPEParam('noiseParams', index, parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
))}
{formData.couplingParams.map((value, index) => (
updateZPEParam('couplingParams', index, parseFloat(e.target.value) || 0)} disabled={!backendConnected} />
))}

QUANTUM CONFIGURATION

⚛️

Quantum parameters coming soon...

); }; // Job History Panel Component export const JobHistoryPanel: React.FC = () => { return (

Job History

View previous, past and ongoing training jobs.
No training jobs found.
); };