'use client' import { useRef, useState, useTransition } from 'react' import { useRouter } from 'next/navigation' import Link from 'next/link' import { toast } from 'sonner' import { Button } from '@/components/ui/button' import { Textarea } from '@/components/ui/textarea' import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog' import { useDirtyCloseGuard, DirtyCloseGuardDialog, } from '@/components/shared/use-dirty-close-guard' import { useDialogSubmitShortcut } from '@/components/shared/use-dialog-submit-shortcut' import { entityDialogContentClasses, entityDialogFooterClasses, entityDialogHeaderClasses, } from '@/components/shared/entity-dialog-layout' import { updateSprintAction } from '@/actions/sprints' import { debugProps } from '@/lib/debug' interface SprintEditDialogProps { open: boolean productId: string sprint: { id: string code: string sprint_goal: string start_date?: string | null end_date?: string | null } onOpenChange: (open: boolean) => void } function toDateInput(value: string | null | undefined): string { if (!value) return '' // Accept ISO datetime or YYYY-MM-DD; output YYYY-MM-DD. const d = new Date(value) if (Number.isNaN(d.getTime())) return '' return d.toLocaleDateString('en-CA') } export function SprintEditDialog({ open, productId, sprint, onOpenChange, }: SprintEditDialogProps) { const [goal, setGoal] = useState(sprint.sprint_goal) const [startDate, setStartDate] = useState(toDateInput(sprint.start_date)) const [endDate, setEndDate] = useState(toDateInput(sprint.end_date)) const [error, setError] = useState(null) const [dirty, setDirty] = useState(false) const [isPending, startTransition] = useTransition() const formRef = useRef(null) const router = useRouter() function reset() { setGoal(sprint.sprint_goal) setStartDate(toDateInput(sprint.start_date)) setEndDate(toDateInput(sprint.end_date)) setError(null) setDirty(false) } const closeGuard = useDirtyCloseGuard(dirty, () => { onOpenChange(false) reset() }) function handleSubmit(e: React.FormEvent) { e.preventDefault() const trimmed = goal.trim() if (!trimmed) return setError(null) startTransition(async () => { const result = await updateSprintAction({ sprintId: sprint.id, fields: { goal: trimmed, startAt: startDate || null, endAt: endDate || null, }, }) if ('error' in result) { setError(result.error) toast.error(result.error) return } toast.success('Sprint bijgewerkt') onOpenChange(false) router.refresh() }) } const handleKeyDown = useDialogSubmitShortcut(() => formRef.current?.requestSubmit(), ) return ( <> { if (!o) closeGuard.attemptClose() else onOpenChange(o) }} >
Sprint {sprint.code} bewerken

Wijzig sprint-doel en datums. Voor afronding (per-story DONE/OPEN beslissing) ga naar de sprint-pagina.

setDirty(true)} className="flex-1 overflow-y-auto px-6 py-6 space-y-6" >