'use client' import { useState, useTransition, useRef } from 'react' import { useRouter } from 'next/navigation' 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 { createSprintWithPbisAction } from '@/actions/sprints' interface NewSprintDialogProps { open: boolean productId: string pbiIds: string[] onOpenChange: (open: boolean) => void onCreated?: (sprintId: string) => void } function todayLocalDate() { return new Date().toLocaleDateString('en-CA') } export function NewSprintDialog({ open, productId, pbiIds, onOpenChange, onCreated, }: NewSprintDialogProps) { const [sprintGoal, setSprintGoal] = useState('') const [startDate, setStartDate] = useState(todayLocalDate()) const [endDate, setEndDate] = useState(todayLocalDate()) const [error, setError] = useState(null) const [dirty, setDirty] = useState(false) const [isPending, startTransition] = useTransition() const formRef = useRef(null) const router = useRouter() function reset() { setSprintGoal('') setStartDate(todayLocalDate()) setEndDate(todayLocalDate()) setError(null) setDirty(false) } const closeGuard = useDirtyCloseGuard(dirty, () => { onOpenChange(false) reset() }) function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!sprintGoal.trim() || pbiIds.length === 0) return setError(null) startTransition(async () => { const result = await createSprintWithPbisAction({ productId, sprint_goal: sprintGoal.trim(), start_date: startDate || null, end_date: endDate || null, pbi_ids: pbiIds, }) if ('error' in result) { setError(result.error) toast.error(result.error) return } toast.success('Nieuwe sprint aangemaakt') reset() onCreated?.(result.sprintId) router.push(`/products/${productId}/sprint/${result.sprintId}`) }) } const handleKeyDown = useDialogSubmitShortcut(() => formRef.current?.requestSubmit()) return ( <> { if (!o) closeGuard.attemptClose() else onOpenChange(o) }} >
Nieuwe sprint

{pbiIds.length} PBI{pbiIds.length === 1 ? '' : "'s"} worden in deze sprint geplaatst

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