Scrum4Me/app/(app)/insights/components/sprint-info-strip.tsx
Janpeter Visser 0454eede74
feat(insights): port unique files from closed bundle-PRs (#41)
Re-introduce the 3 unique files from closed PRs #37 and #40 that
overlap-merged with already-landed sub-PRs (#34, #35, #36, #38, #39):

- app/(app)/insights/page.tsx — Server Component dat alle helpers
  parallel aanroept en de 5 sectie-Cards rendert (Sprint Health,
  Plan-quality, Agent throughput, Velocity, Backlog health)
- app/(app)/insights/components/sprint-info-strip.tsx — chips per
  active sprint met productname + goal + dagen-over + taakcount
- app/(app)/insights/components/alignment-trend.tsx — Recharts
  LineChart die % ALIGNED jobs per sprint over laatste 5 sprints toont
- lib/insights/verify-stats.ts — TrendPoint type + getAlignmentTrend
  helper (uitgebreid van PR #38)

Plus dependency: recharts (was in package.json van #37/#40 die we
sloten).

Tests: 290/290 groen, tsc clean, lint clean.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 16:44:53 +02:00

45 lines
1.3 KiB
TypeScript

'use client'
interface SprintInfo {
sprintId: string
productName: string
sprintGoal: string
taskCount: number
daysLeft: number
}
interface Props {
sprints: SprintInfo[]
}
function daysLeftColor(daysLeft: number): string {
if (daysLeft >= 3) return 'text-[color:var(--status-done)]'
if (daysLeft >= 1) return 'text-[color:var(--priority-medium)]'
return 'text-[color:var(--priority-critical)]'
}
function truncate(text: string, max: number): string {
return text.length > max ? text.slice(0, max) + '…' : text
}
export function SprintInfoStrip({ sprints }: Props) {
if (sprints.length === 0) return null
return (
<div className="flex flex-wrap gap-2">
{sprints.map(s => (
<div
key={s.sprintId}
className="flex items-center gap-3 rounded-lg border border-border bg-surface-container px-3 py-2 text-sm"
>
<span className="font-medium text-foreground">{s.productName}</span>
<span className="text-muted-foreground">{truncate(s.sprintGoal, 60)}</span>
<span className={`font-mono tabular-nums ${daysLeftColor(s.daysLeft)}`}>
{s.daysLeft > 0 ? `${s.daysLeft}d over` : `${Math.abs(s.daysLeft)}d over tijd`}
</span>
<span className="text-muted-foreground">{s.taskCount} tasks</span>
</div>
))}
</div>
)
}