"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { createSprint } from "@/app/(frontend)/projects/actions"; interface CreateSprintDialogProps { readonly projectId: number; readonly open: boolean; readonly onOpenChange: (open: boolean) => void; } export function CreateSprintDialog({ projectId, open, onOpenChange }: CreateSprintDialogProps) { const router = useRouter(); const [name, setName] = useState(""); const [goal, setGoal] = useState(""); const [startDate, setStartDate] = useState(""); const [endDate, setEndDate] = useState(""); const [capacity, setCapacity] = useState(""); const [pending, setPending] = useState(false); const [error, setError] = useState(null); function reset() { setName(""); setGoal(""); setStartDate(""); setEndDate(""); setCapacity(""); setPending(false); setError(null); } async function handleSubmit() { const trimmedName = name.trim(); const parsedCapacity = capacity ? Number(capacity) : null; if (!trimmedName) { setError("Sprint name is required."); return; } if (parsedCapacity !== null && (!Number.isInteger(parsedCapacity) || parsedCapacity < 0)) { setError("Capacity must be a whole number of points."); return; } setPending(true); setError(null); try { const result = await createSprint({ projectId, name: trimmedName, goal: goal.trim() || undefined, startDate: startDate || undefined, endDate: endDate || undefined, capacity: parsedCapacity ?? undefined, }); if (!result.success) { setError(result.error ?? "Could not create the sprint."); setPending(false); return; } onOpenChange(false); reset(); toast.success("Sprint created"); router.refresh(); } catch (caught) { setError(caught instanceof Error ? caught.message : "Could not create the sprint."); setPending(false); } } return ( { onOpenChange(nextOpen); if (!nextOpen) reset(); }} > Create sprint Define a focused delivery window for this project.
{ event.preventDefault(); void handleSubmit(); }} >
setName(event.target.value)} disabled={pending} />