"use client"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { FileUpload } from "@/components/common/file-upload"; import { useRouter } from "next/navigation"; import { Loader2 } from "lucide-react"; import { useCreateCorrespondence, useUpdateCorrespondence } from "@/hooks/use-correspondence"; import { Organization } from "@/types/organization"; import { useOrganizations, useProjects, useCorrespondenceTypes, useDisciplines } from "@/hooks/use-master-data"; import { CreateCorrespondenceDto } from "@/types/dto/correspondence/create-correspondence.dto"; // Updated Zod Schema with all required fields const correspondenceSchema = z.object({ projectId: z.number().min(1, "Please select a Project"), documentTypeId: z.number().min(1, "Please select a Document Type"), disciplineId: z.number().optional(), subject: z.string().min(5, "Subject must be at least 5 characters"), description: z.string().optional(), fromOrganizationId: z.number().min(1, "Please select From Organization"), toOrganizationId: z.number().min(1, "Please select To Organization"), importance: z.enum(["NORMAL", "HIGH", "URGENT"]), attachments: z.array(z.instanceof(File)).optional(), }); type FormData = z.infer; export function CorrespondenceForm({ initialData, id }: { initialData?: any, id?: number }) { const router = useRouter(); const createMutation = useCreateCorrespondence(); const updateMutation = useUpdateCorrespondence(); // Fetch master data for dropdowns const { data: projects, isLoading: isLoadingProjects } = useProjects(); const { data: organizations, isLoading: isLoadingOrgs } = useOrganizations(); const { data: correspondenceTypes, isLoading: isLoadingTypes } = useCorrespondenceTypes(); const { data: disciplines, isLoading: isLoadingDisciplines } = useDisciplines(); // Extract initial values if editing const currentRev = initialData?.revisions?.find((r: any) => r.isCurrent) || initialData?.revisions?.[0]; const defaultValues: Partial = { projectId: initialData?.projectId || undefined, documentTypeId: initialData?.correspondenceTypeId || undefined, disciplineId: initialData?.disciplineId || undefined, subject: currentRev?.title || "", description: currentRev?.description || "", fromOrganizationId: initialData?.originatorId || undefined, toOrganizationId: currentRev?.details?.to_organization_id || undefined, importance: currentRev?.details?.importance || "NORMAL", }; const { register, handleSubmit, setValue, watch, formState: { errors }, } = useForm({ resolver: zodResolver(correspondenceSchema), defaultValues: defaultValues as any, }); // Watch for controlled inputs const projectId = watch("projectId"); const documentTypeId = watch("documentTypeId"); const disciplineId = watch("disciplineId"); const fromOrgId = watch("fromOrganizationId"); const toOrgId = watch("toOrganizationId"); const onSubmit = (data: FormData) => { const payload: CreateCorrespondenceDto = { projectId: data.projectId, typeId: data.documentTypeId, disciplineId: data.disciplineId, title: data.subject, description: data.description, originatorId: data.fromOrganizationId, details: { to_organization_id: data.toOrganizationId, importance: data.importance }, }; if (id && initialData) { // UPDATE Mode updateMutation.mutate({ id, data: payload }, { onSuccess: () => router.push(`/correspondences/${id}`) }); } else { // CREATE Mode createMutation.mutate(payload, { onSuccess: () => router.push("/correspondences"), }); } }; const isPending = createMutation.isPending || updateMutation.isPending; return (
{/* Document Metadata Section */}
{/* Project Dropdown */}
{errors.projectId && (

{errors.projectId.message}

)}
{/* Document Type Dropdown */}
{errors.documentTypeId && (

{errors.documentTypeId.message}

)}
{/* Discipline Dropdown (Optional) */}
{/* Subject */}
{errors.subject && (

{errors.subject.message}

)}
{/* Description */}