- 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>
57 lines
2.2 KiB
TypeScript
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>
|
|
)
|
|
}
|