Scrum4Me/components/sprint/start-sprint-button.tsx

95 lines
2.8 KiB
TypeScript

'use client'
import { useState, useActionState } from 'react'
import { useFormStatus } from 'react-dom'
import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { createSprintAction } from '@/actions/sprints'
interface StartSprintButtonProps {
productId: string
}
function SubmitButton() {
const { pending } = useFormStatus()
return (
<Button type="submit" disabled={pending}>
{pending ? 'Aanmaken…' : 'Sprint starten'}
</Button>
)
}
export function StartSprintButton({ productId }: StartSprintButtonProps) {
const [open, setOpen] = useState(false)
const router = useRouter()
const [state, formAction] = useActionState(
async (_prev: unknown, fd: FormData) => {
const result = await createSprintAction(_prev, fd)
if (result.success) {
setOpen(false)
router.push(`/products/${productId}/sprint`)
}
return result
},
undefined
)
const globalError = typeof state?.error === 'string' ? state.error : undefined
return (
<>
<Button size="sm" onClick={() => setOpen(true)}>
Sprint starten
</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle>Nieuwe Sprint starten</DialogTitle>
</DialogHeader>
<form action={formAction} className="space-y-4 p-1">
<input type="hidden" name="productId" value={productId} />
<div className="space-y-1.5">
<label className="text-sm font-medium text-foreground">
Sprint Goal <span className="text-error">*</span>
</label>
<Textarea
name="sprint_goal"
required
rows={3}
placeholder="Wat wil je aan het einde van deze Sprint bereikt hebben?"
autoFocus
/>
{typeof state?.error === 'object' && (state.error as Record<string, string[]>).sprint_goal && (
<p className="text-xs text-error">{(state.error as Record<string, string[]>).sprint_goal[0]}</p>
)}
</div>
{globalError && (
<div className="bg-error-container text-error-container-foreground rounded-lg px-3 py-2 text-sm border-l-4 border-error">
{globalError}
</div>
)}
<div className="flex gap-2 justify-end">
<Button type="button" variant="ghost" onClick={() => setOpen(false)}>
Annuleren
</Button>
<SubmitButton />
</div>
</form>
</DialogContent>
</Dialog>
</>
)
}