'use client'; import { useForm, FieldError } 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 { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card } from '@/components/ui/card'; import { useRouter } from 'next/navigation'; import { useCreateDrawing } from '@/hooks/use-drawing'; import { useContractDrawingCategories, useShopMainCategories, useShopSubCategories, useProjects, } from '@/hooks/use-master-data'; import { useState, useEffect } from 'react'; import { Loader2 } from 'lucide-react'; import { Textarea } from '@/components/ui/textarea'; // Base Schema const baseSchema = z.object({ drawingType: z.enum(['CONTRACT', 'SHOP', 'AS_BUILT']), projectId: z.string().min(1, 'Project is required'), file: z.instanceof(File, { message: 'File is required' }), }); // Contract Schema const contractSchema = baseSchema.extend({ drawingType: z.literal('CONTRACT'), contractDrawingNo: z.string().min(1, 'Drawing Number is required'), title: z.string().min(3, 'Title is required'), volumeId: z.string().optional(), // Select input returns string usually (changed to string for input compatibility) volumePage: z .string() .transform((val) => Number(val)) .optional(), // Input type number returns string mapCatId: z.string().min(1, 'Category is required'), }); // Shop Schema const shopSchema = baseSchema.extend({ drawingType: z.literal('SHOP'), drawingNumber: z.string().min(1, 'Drawing Number is required'), mainCategoryId: z.string().min(1, 'Main Category is required'), subCategoryId: z.string().min(1, 'Sub Category is required'), // Revision Fields revisionLabel: z.string().default('0'), title: z.string().min(3, 'Revision Title is required'), legacyDrawingNumber: z.string().optional(), description: z.string().optional(), }); // As Built Schema const asBuiltSchema = baseSchema.extend({ drawingType: z.literal('AS_BUILT'), drawingNumber: z.string().min(1, 'Drawing Number is required'), mainCategoryId: z.string().min(1, 'Main Category is required'), subCategoryId: z.string().min(1, 'Sub Category is required'), // Revision Fields revisionLabel: z.string().default('0'), title: z.string().min(1, 'Title is required'), legacyDrawingNumber: z.string().optional(), description: z.string().optional(), }); const formSchema = z.discriminatedUnion('drawingType', [contractSchema, shopSchema, asBuiltSchema]); type DrawingFormData = z.infer; export function DrawingUploadForm() { const router = useRouter(); // Project list const { data: projects = [], isLoading: isLoadingProjects } = useProjects(); // Selected project for category fetching const [selectedProjectId, setSelectedProjectId] = useState(undefined); // Hooks — categories depend on selected project const { data: contractCategories } = useContractDrawingCategories(selectedProjectId); const { data: shopMainCats } = useShopMainCategories(selectedProjectId as number); const [selectedShopMainCat, setSelectedShopMainCat] = useState(); const { data: shopSubCats } = useShopSubCategories(selectedProjectId as number, selectedShopMainCat); const { register, handleSubmit, setValue, watch, formState: { errors }, } = useForm({ resolver: zodResolver(formSchema), defaultValues: { drawingType: 'CONTRACT', } as DrawingFormData, }); // Type-safe error access for discriminated union fields const formErrors = errors as Record; const drawingType = watch('drawingType'); const watchedProjectId = watch('projectId'); const createMutation = useCreateDrawing(drawingType); // When project changes, update selectedProjectId for category hooks useEffect(() => { if (!watchedProjectId) { setSelectedProjectId(undefined); return; } // Try to resolve UUID→INT from projects list, or pass UUID directly const project = projects.find( (p: { id: string; uuid?: string }) => p.id === watchedProjectId || p.uuid === watchedProjectId ) as { id: string; uuid?: string } | undefined; setSelectedProjectId(project?.id ?? watchedProjectId); }, [watchedProjectId, projects]); const onSubmit = (data: DrawingFormData) => { const formData = new FormData(); // Common fields formData.append('projectId', String(data.projectId)); formData.append('file', data.file); if (data.drawingType === 'CONTRACT') { formData.append('contractDrawingNo', data.contractDrawingNo); formData.append('title', data.title); formData.append('mapCatId', data.mapCatId); if (data.volumeId) formData.append('volumeId', data.volumeId); if (data.volumePage) formData.append('volumePage', String(data.volumePage)); } else if (data.drawingType === 'SHOP') { formData.append('drawingNumber', data.drawingNumber); formData.append('mainCategoryId', data.mainCategoryId); formData.append('subCategoryId', data.subCategoryId); formData.append('revisionLabel', data.revisionLabel || '0'); formData.append('title', data.title); // Revision Title if (data.legacyDrawingNumber) formData.append('legacyDrawingNumber', data.legacyDrawingNumber); if (data.description) formData.append('description', data.description); // Date default to now } else if (data.drawingType === 'AS_BUILT') { formData.append('drawingNumber', data.drawingNumber); formData.append('mainCategoryId', data.mainCategoryId); formData.append('subCategoryId', data.subCategoryId); formData.append('revisionLabel', data.revisionLabel || '0'); formData.append('title', data.title); if (data.legacyDrawingNumber) formData.append('legacyDrawingNumber', data.legacyDrawingNumber); if (data.description) formData.append('description', data.description); } createMutation.mutate(formData, { onSuccess: () => { router.push('/drawings'); }, }); }; return (

Drawing Information

{/* Project Selector */}
{errors.projectId &&

{errors.projectId.message}

}
{/* CONTRACT FIELDS */} {drawingType === 'CONTRACT' && ( <>
{formErrors.contractDrawingNo && (

{formErrors.contractDrawingNo.message}

)}
{formErrors.title &&

{formErrors.title.message}

}
{formErrors.mapCatId &&

{formErrors.mapCatId.message}

}
)} {/* SHOP FIELDS */} {drawingType === 'SHOP' && ( <>
{formErrors.drawingNumber && (

{formErrors.drawingNumber.message}

)}
{formErrors.mainCategoryId && (

{formErrors.mainCategoryId.message}

)}
{formErrors.subCategoryId && (

{formErrors.subCategoryId.message}

)}
{formErrors.title &&

{formErrors.title.message}

}