import { useEffect, useRef } from 'react'; function compactnessDelta(step, prevStep) { if (!step || !step.metrics) return null; const curr = step.metrics.compactness; if (curr == null) return null; if (prevStep && prevStep.metrics && prevStep.metrics.compactness != null) { return curr - prevStep.metrics.compactness; } return curr; } function foldAssignment(fold) { if (!fold) return null; const t = fold.type || ''; if (t === 'valley') return 'V'; if (t === 'mountain') return 'M'; if (t === 'pleat') return 'P'; if (t === 'crimp') return 'C'; return t.charAt(0).toUpperCase() || null; } function foldLabel(fold) { if (!fold) return ''; const type = fold.type || 'fold'; const angle = fold.angle != null ? ` ${fold.angle}°` : ''; return `${type.toUpperCase()} FOLD${angle}`; } export default function StepFeed({ steps, currentStep }) { const feedRef = useRef(null); const activeRef = useRef(null); useEffect(() => { if (activeRef.current) { activeRef.current.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); } }, [currentStep]); if (!steps || steps.length === 0) { return (
NO STEPS LOADED
); } return (
{steps.map((step, idx) => { const stepNum = idx + 1; const isActive = currentStep === stepNum; const delta = compactnessDelta(step, idx > 0 ? steps[idx - 1] : null); const asgn = foldAssignment(step.fold); const label = foldLabel(step.fold); const m = step.metrics || {}; return (
#{stepNum} {label} {asgn && ( {asgn} )}
{delta !== null && (
{'\u0394'} compact:{' '} = 0 ? 'delta-positive' : 'delta-negative'}> {delta >= 0 ? '+' : ''}{delta.toFixed(3)} {m.max_strain != null && ( {' '}| strain: {m.max_strain.toFixed(4)} {m.is_valid != null && ( | {m.is_valid ? '✓' : '✗'} )} )}
)}
); })}
); }