import React, { useState, useEffect } from 'react'; import { Eye, CheckCircle, XCircle } from 'lucide-react'; import { comms } from '../communication'; import { PanelHeader } from './common/PanelHeader'; import { CyberPanel } from './common/CyberPanel'; interface PortData { cartSize: string; enabled?: boolean; confirm?: boolean; rid: string; rid_trust?: boolean; rid_new?: boolean; sid: string; sid0?: string; sid_trust?: boolean; qty: string; qty_trust?: boolean; qty_rq?: boolean; vname: string; vname_trust?: boolean; vlot: string; vlot_trust?: boolean; mfgdate: string; mfgdate_trust?: boolean; partno: string; partno_trust?: boolean; reelSize: string; rid2?: string; sid2?: string; qty2?: string; vname2?: string; vlot2?: string; mfgdate2?: string; partno2?: string; batch?: string; qtymax?: string; barcodeCount?: number; regexCount?: number; } interface VisionData { left: PortData; center: PortData; right: PortData; } const fieldLabels = ['RID', 'SID', 'QTY', 'VNAME', 'VLOT', 'MFG', 'PART', 'SIZE', 'BATCH']; export const VisionDataPanel: React.FC = () => { const [data, setData] = useState(null); useEffect(() => { const unsubscribe = comms.subscribe((msg: any) => { if (msg?.type === 'VISION_DATA_UPDATE' && msg.data) { setData(msg.data); } }); return () => { unsubscribe(); }; }, []); const getTrustColor = (trust?: boolean) => { if (trust === undefined) return 'text-slate-400'; return trust ? 'text-lime-400' : 'text-slate-400'; }; const getCompareColor = (val1: string, val2?: string) => { if (!val2 || val2 === '') return ''; return val1 !== val2 ? 'text-red-400' : ''; }; const renderPortColumn = (port: PortData | undefined, title: string, isCenter: boolean = false) => { if (!port) return null; const values = [ { val: port.rid, val2: port.rid2, trust: port.rid_trust }, { val: port.sid, val2: port.sid2, trust: port.sid_trust }, { val: port.qty, val2: port.qty2, trust: port.qty_trust, rq: port.qty_rq }, { val: port.vname, val2: port.vname2, trust: port.vname_trust }, { val: port.vlot, val2: port.vlot2, trust: port.vlot_trust }, { val: port.mfgdate, val2: port.mfgdate2, trust: port.mfgdate_trust }, { val: port.partno, val2: port.partno2, trust: port.partno_trust }, { val: port.reelSize === 'None' ? '--' : port.reelSize, val2: undefined, trust: undefined }, { val: port.batch || '-', val2: undefined, trust: undefined }, ]; const headerBg = port.enabled === false ? 'bg-orange-600/80' : (port.confirm ? 'bg-lime-600/80' : 'bg-slate-700/80'); const headerText = port.enabled === false ? 'DISABLE' : port.cartSize; return (
{/* Header */}
{headerText} ({title})
{/* Values */}
{values.map((item, idx) => (
{fieldLabels[idx]} {item.rq ? `RQ:${item.val}` : item.val || '-'} {isCenter && item.trust !== undefined && ( item.trust ? : )}
))} {/* Center-specific fields */} {isCenter && ( <>
MAX {port.qtymax || '-'}
BCD {port.barcodeCount ?? 0}
REGEX {port.regexCount ?? 0}
)}
); }; return (
{!data ? (
Waiting for data...
) : (
{renderPortColumn(data.left, 'LEFT')} {renderPortColumn(data.center, 'CENTER', true)} {renderPortColumn(data.right, 'RIGHT')}
)}
); };