'use client' import { useEffect, useRef, useState } from 'react' import { useActionState } from 'react' import { useFormStatus } from 'react-dom' import { toast } from 'sonner' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogClose, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Textarea } from '@/components/ui/textarea' import { PrioritySelect } from '@/components/shared/priority-select' import { PbiStatusSelect } from '@/components/shared/pbi-status-select' import { createPbiAction, updatePbiAction } from '@/actions/pbis' import type { PbiStatusApi } from '@/lib/task-status' export interface PbiDialogPbi { id: string title: string priority: number description?: string | null code?: string | null status?: PbiStatusApi } type CreateState = { mode: 'create'; productId: string; defaultPriority?: number } type EditState = { mode: 'edit'; pbi: PbiDialogPbi; productId: string } export type PbiDialogState = CreateState | EditState interface PbiDialogProps { state: PbiDialogState | null onClose: () => void } function SubmitButton({ label }: { label: string }) { const { pending } = useFormStatus() return ( ) } export function PbiDialog({ state, onClose }: PbiDialogProps) { const isEdit = state?.mode === 'edit' const pbi = isEdit ? state.pbi : null const initialPriority = isEdit ? pbi!.priority : (state?.defaultPriority ?? 2) const [priority, setPriority] = useState(initialPriority) const initialStatus: PbiStatusApi = isEdit ? (pbi!.status ?? 'ready') : 'ready' const [status, setStatus] = useState(initialStatus) // Sync priority + status when dialog opens for a different PBI or switches create/edit mode useEffect(() => { if (state) { // eslint-disable-next-line react-hooks/set-state-in-effect setPriority(isEdit ? (state as EditState).pbi.priority : ((state as CreateState).defaultPriority ?? 2)) setStatus(isEdit ? ((state as EditState).pbi.status ?? 'ready') : 'ready') } }, [state, isEdit]) const [createState, createAction] = useActionState( async (_prev: unknown, fd: FormData) => { const result = await createPbiAction(_prev, fd) if (result?.success) { toast.success('PBI aangemaakt'); onClose() } else if (typeof result?.error === 'string') toast.error(result.error) return result }, undefined ) const [updateState, updateAction] = useActionState( async (_prev: unknown, fd: FormData) => { const result = await updatePbiAction(_prev, fd) if (result?.success) { toast.success('PBI opgeslagen'); onClose() } else if (typeof result?.error === 'string') toast.error(result.error) return result }, undefined ) const activeState = isEdit ? updateState : createState const error = typeof activeState?.error === 'string' ? activeState.error : null const fieldError = (field: string) => { const err = activeState?.error if (!err || typeof err === 'string') return undefined return (err as Record)[field]?.[0] } const titleRef = useRef(null) useEffect(() => { if (state) { setTimeout(() => titleRef.current?.focus(), 50) } }, [state]) return ( { if (!open) onClose() }}> {isEdit ? 'PBI bewerken' : 'Nieuw PBI'}
{isEdit && } {!isEdit && }
{fieldError('code') &&

{fieldError('code')}

}
{fieldError('title') &&

{fieldError('title')}

}