+
+
+ Delivery
+
+ {products.length > 0 && (
+
+ )}
+
+
+ {product && (
+ <>
+ {/* Progress hero */}
+
+
+
+
{product.name}
+
{totals.pct}% complete
+
+ {totals.done} of {totals.total} tasks done ยท {totals.remaining} remaining
+
+
+
+
+
+
+ {/* Column breakdown */}
+
+ {COLUMNS.map((c) => (
+
+
{LABEL[c]}
+
{totals.counts[c]}
+
+ ))}
+
+
+ {/* Quality (from analytics) */}
+ {analytics && (
+
+
+
+
+
+ )}
+
+ {/* Per team */}
+
Teams
+
+ {teams.map((t) => {
+ const pct = t.total > 0 ? Math.round((t.done / t.total) * 100) : 0
+ return (
+
+
{t.team.name}
+
+
{t.done}/{t.total} ยท {pct}%
+
+ )
+ })}
+ {teams.length === 0 &&
No teams on this product yet.
}
+
+
+ {/* Remaining */}
+
+ Remaining ({totals.remaining})
+
+
+ {teams.flatMap((t) => t.remaining.map((task) => ({ task, team: t.team.name }))).slice(0, 40).map(({ task, team }) => (
+
+ {LABEL[task.status] ?? task.status}
+ {task.title}
+ {team}
+
+ ))}
+ {totals.remaining === 0 &&
๐ Nothing remaining โ everything is done.
}
+
+ >
+ )}
+
+