import { useRef, useEffect, useState } from 'react' const STATUS_STYLES = { pending: 'bg-gray-600/60 text-gray-200 border-gray-500', completed: 'bg-green-800/60 text-green-200 border-green-600', rerun: 'bg-red-800/60 text-red-200 border-red-600', } export const DEVICE_ACCENT_CLASSES = [ 'bg-sky-400', 'bg-emerald-400', 'bg-amber-400', 'bg-rose-400', 'bg-cyan-400', 'bg-lime-400', 'bg-orange-400', 'bg-fuchsia-400', ] export function getDeviceAccentClass(device) { if (!device) return 'bg-gray-500' let hash = 0 for (let i = 0; i < device.length; i += 1) { hash = (hash * 31 + device.charCodeAt(i)) >>> 0 } return DEVICE_ACCENT_CLASSES[hash % DEVICE_ACCENT_CLASSES.length] } function formatConfig(config) { if (!config || typeof config !== 'object') return '—' const entries = Object.entries(config) if (entries.length === 0) return '—' const formattedEntries = entries .map(([band, data]) => { if (!data || typeof data !== 'object') return null const testpoint = data.test_point || data['Test Point'] const sta = data.sta || data.STA // Only display if both testpoint and sta are present if (!testpoint || !sta) return null return `${band}: ${testpoint}→${sta}` }) .filter(Boolean) return formattedEntries.length > 0 ? formattedEntries.join('; ') : '—' } export default function TestCard({ test, isPrevious = false }) { const style = STATUS_STYLES[test.status] ?? STATUS_STYLES.pending const deviceAccentClass = getDeviceAccentClass(test.device) const cardRef = useRef(null) const [tooltipPos, setTooltipPos] = useState({ top: '0px', left: '0px' }) const [isHovered, setIsHovered] = useState(false) useEffect(() => { const cardElement = cardRef.current if (!cardElement) return const handleMouseMove = (e) => { // Position tooltip near the cursor, with 10px offset const top = e.clientY + 10 const left = e.clientX + 10 setTooltipPos({ top: `${top}px`, left: `${left}px`, }) } const handleMouseEnter = () => { setIsHovered(true) } const handleMouseLeave = () => { setIsHovered(false) } cardElement.addEventListener('mouseenter', handleMouseEnter) cardElement.addEventListener('mouseleave', handleMouseLeave) cardElement.addEventListener('mousemove', handleMouseMove) return () => { cardElement.removeEventListener('mouseenter', handleMouseEnter) cardElement.removeEventListener('mouseleave', handleMouseLeave) cardElement.removeEventListener('mousemove', handleMouseMove) } }, []) return (
{/* Hover tooltip — follows cursor */} {isHovered && (

Type: {test.test_type ?? '—'}

Rotation: {test.rotation ?? '—'}

Device:

Config: {formatConfig(test.config)}

)}
) }