"use client"; import { useEffect, useState } from "react"; /* ───────────────────────────────────────────────────────── * TASK ROWS * * 0ms rows enter staggered (80ms apart) * 600ms row 1 ring sweeps 0 → 66% * 1500ms row 1 expands — detail steps drop down * 3900ms row 1 collapses; row 2 flips to Failed + retry * 5300ms row 2 resolves to Completed * The status run completes once; task details stay clickable. * ───────────────────────────────────────────────────────── */ const TICKS = [600, 900, 2400, 1400, 2400, 600]; function useTick(intervals: number[]) { const [tick, setTick] = useState(0); useEffect(() => { if (tick >= intervals.length - 1) return; const t = setTimeout(() => setTick((x) => x + 1), intervals[tick]); return () => clearTimeout(t); }, [tick, intervals]); return tick; } function SpinnerRing({ active, children }: { active?: boolean; children?: React.ReactNode }) { const size = 24, stroke = 2; const r = (size - stroke) / 2; const c = 2 * Math.PI * r; return ( {active && ( )} {children} ); } function Badge({ tone, children }: { tone: "red" | "green"; children: React.ReactNode }) { return ( {children} ); } const XIcon = ( ); const CheckIcon = ( ); const RetryIcon = ( ); export default function TaskRows({ variant = "Capsules" }: { variant?: string }) { const tick = useTick(TICKS); const [manualOpen, setManualOpen] = useState>({}); const row2: "pending" | "failed" | "done" = tick < 3 ? "pending" : tick === 3 ? "failed" : "done"; const rows = [ { key: "verify", badge: {CheckIcon}, label: "Verified vendor records", amount: "12 suppliers", pill: ( Completed ), details: [ { label: "Matched tax and contact IDs", meta: "12/12" }, { label: "Flagged stale records", meta: "0" }, ], }, { key: "index", badge: 2, label: "Build reorder task list", amount: "7 SKUs", pill: null, details: [ { label: "Reading POS export", meta: "3 files" }, { label: "Scoring stockout risk", meta: "68%" }, ], }, { key: "draft", badge: row2 === "pending" ? ( 3 ) : row2 === "failed" ? ( {XIcon} ) : ( {CheckIcon} ), label: "Draft supplier emails", amount: "2 messages", pill: row2 === "failed" ? ( Failed {RetryIcon} ) : row2 === "done" ? ( Completed ) : null, details: [ { label: "Cone supplier follow-up", meta: "draft" }, { label: "Pistachio reorder note", meta: "draft" }, ], }, ]; const list = variant === "List"; return (
{rows.map((row, i) => { const open = manualOpen[row.key] ?? (row.key === "index" && tick === 2); return (
{/* dropdown detail — same expandable grammar as Chain of Thought */}
{row.details.map((d, j) => (
{d.label} {d.meta}
))}
); })}
); }