Scrum4Me/components/sprint/planning-left.tsx
janpeter visser d92e548f88 feat: ST-301-ST-312 M3 Sprint Backlog en Sprint Planning
- useSprintStore met sprintStoryOrder/taskOrder (ST-301)
- Sprint aanmaken modal met Sprint Goal validatie (ST-302)
- Sprint Backlog pagina SplitPane layout met Sprint Goal header (ST-303)
- Stories toevoegen aan Sprint via knop in rechterpaneel (ST-304)
- Sprint Backlog volgorde aanpassen via dnd-kit (ST-305)
- Story uit Sprint verwijderen met status terug naar OPEN (ST-306)
- Sprint Planning pagina SplitPane met story selectie (ST-307)
- Taken aanmaken inline in rechterpaneel (ST-308)
- Taak drag-and-drop verticaal met optimistische update (ST-309)
- Taakstatus toggle TO_DO/IN_PROGRESS/DONE met voortgangsindicator (ST-310)
- Taak inline bewerken en verwijderen (ST-311)
- Sprint afronden dialoog met per-story Done/Terug keuze (ST-312)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 11:51:27 +02:00

57 lines
2.2 KiB
TypeScript

'use client'
import { useSelectionStore } from '@/stores/selection-store'
import { PanelNavBar } from '@/components/shared/panel-nav-bar'
import { Badge } from '@/components/ui/badge'
import { cn } from '@/lib/utils'
import type { SprintStory } from './sprint-backlog'
const PRIORITY_COLORS: Record<number, string> = {
1: 'bg-priority-critical/15 text-priority-critical border-priority-critical/30',
2: 'bg-priority-high/15 text-priority-high border-priority-high/30',
3: 'bg-priority-medium/15 text-priority-medium border-priority-medium/30',
4: 'bg-priority-low/15 text-priority-low border-priority-low/30',
}
const PRIORITY_LABELS: Record<number, string> = { 1: 'Kritiek', 2: 'Hoog', 3: 'Gemiddeld', 4: 'Laag' }
interface PlanningLeftProps {
stories: SprintStory[]
}
export function PlanningLeft({ stories }: PlanningLeftProps) {
const { selectedStoryId, selectStory } = useSelectionStore()
return (
<div className="flex flex-col h-full">
<PanelNavBar title="Sprint Backlog" />
<div className="flex-1 overflow-y-auto">
{stories.length === 0 ? (
<p className="text-sm text-muted-foreground text-center mt-8 px-4">
Geen stories in de Sprint.
</p>
) : (
stories.map(story => (
<div
key={story.id}
onClick={() => selectStory(story.id)}
className={cn(
'flex items-center gap-3 px-4 py-2.5 border-b border-border cursor-pointer transition-colors hover:bg-surface-container',
selectedStoryId === story.id && 'bg-primary-container text-primary-container-foreground'
)}
>
<div className="flex-1 min-w-0">
<p className="text-sm truncate">{story.title}</p>
<div className="flex items-center gap-1.5 mt-0.5">
<Badge className={cn('text-[10px] px-1.5 py-0 border', PRIORITY_COLORS[story.priority])}>
{PRIORITY_LABELS[story.priority]}
</Badge>
<span className="text-xs text-muted-foreground">{story.doneCount}/{story.taskCount} klaar</span>
</div>
</div>
</div>
))
)}
</div>
</div>
)
}