'use client'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Button } from '@/components/ui/button'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { useCreateEpic, useUpdateEpic } from '@/lib/hooks/use-epics'; import type { Epic, WorkItemPriority } from '@/types/project'; import { toast } from 'sonner'; import { Loader2 } from 'lucide-react'; import { useAuthStore } from '@/stores/authStore'; const epicSchema = z.object({ projectId: z.string().min(1, 'Project is required'), name: z .string() .min(1, 'Name is required') .max(200, 'Name must be less than 200 characters'), description: z .string() .max(2000, 'Description must be less than 2000 characters') .optional(), priority: z.enum(['Low', 'Medium', 'High', 'Critical']), estimatedHours: z .number() .min(0, 'Estimated hours must be positive') .optional() .or(z.literal('')), }); type EpicFormValues = z.infer; interface EpicFormProps { epic?: Epic; projectId?: string; onSuccess?: () => void; onCancel?: () => void; } export function EpicForm({ epic, projectId, onSuccess, onCancel }: EpicFormProps) { const isEditing = !!epic; const createEpic = useCreateEpic(); const updateEpic = useUpdateEpic(); const user = useAuthStore((state) => state.user); const form = useForm({ resolver: zodResolver(epicSchema), defaultValues: { projectId: epic?.projectId || projectId || '', name: epic?.name || '', description: epic?.description || '', priority: epic?.priority || 'Medium', estimatedHours: epic?.estimatedHours || ('' as any), }, }); async function onSubmit(data: EpicFormValues) { try { if (!user?.id) { toast.error('User not authenticated'); return; } if (isEditing && epic) { await updateEpic.mutateAsync({ id: epic.id, data: { name: data.name, description: data.description, priority: data.priority, estimatedHours: typeof data.estimatedHours === 'number' ? data.estimatedHours : undefined, }, }); toast.success('Epic updated successfully'); } else { await createEpic.mutateAsync({ projectId: data.projectId, name: data.name, description: data.description, priority: data.priority, estimatedHours: typeof data.estimatedHours === 'number' ? data.estimatedHours : undefined, createdBy: user.id, }); toast.success('Epic created successfully'); } onSuccess?.(); } catch (error) { const message = error instanceof Error ? error.message : 'Operation failed'; toast.error(message); } } const isLoading = createEpic.isPending || updateEpic.isPending; return (
( Epic Name * A clear, concise name for this epic )} /> ( Description