import React from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { CustomDropdown } from './shared/CustomDropdown'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Loader2, Save, X } from 'lucide-react'; import { Asset, AssetCreateRequest, AssetUpdateRequest, AssetCreateSchema, AssetUpdateSchema, ASSET_TYPES, ASSET_CONDITIONS } from '@/types/asset-management'; interface AssetFormProps { asset?: Asset; onSubmit: (data: AssetCreateRequest | AssetUpdateRequest) => Promise; onCancel: () => void; isSubmitting?: boolean; title?: string; } type AssetFormValues = { assetCode: string; assetType: string; brandModel: string; serialNumber: string; assetCondition: string; }; const AssetForm: React.FC = ({ asset, onSubmit, onCancel, isSubmitting = false, title }) => { const isEditing = !!asset; const formTitle = title || (isEditing ? 'Edit Asset' : 'Create New Asset'); const form = useForm({ resolver: zodResolver(isEditing ? AssetUpdateSchema.omit({ assetID: true }) : AssetCreateSchema), defaultValues: { assetCode: asset?.assetCode || '', assetType: asset?.assetType || '', brandModel: asset?.brandModel || '', serialNumber: asset?.serialNumber || '', assetCondition: asset?.assetCondition || '', }, }); const handleSubmit = async (values: AssetFormValues) => { try { if (isEditing && asset) { const updateData: AssetUpdateRequest = { assetID: asset.assetID, ...values, }; await onSubmit(updateData); } else { const createData: AssetCreateRequest = values; await onSubmit(createData); } } catch (error) { console.error('Form submission error:', error); // Set form errors if validation failed if (error instanceof Error) { if (error.message.includes('Serial number')) { form.setError('serialNumber', { type: 'manual', message: 'This serial number is already in use. Please enter a unique serial number.' }); } else if (error.message.includes('Brand model')) { form.setError('brandModel', { type: 'manual', message: 'Invalid brand model format.' }); } else if (error.message.includes('Asset type')) { form.setError('assetType', { type: 'manual', message: 'Please select a valid asset type.' }); } else { // Set a general form error form.setError('root', { type: 'manual', message: error.message }); } } } }; return ( {formTitle}
{/* Display form-level errors */} {form.formState.errors.root && (

{form.formState.errors.root.message}

)} {/* Asset Code */} ( Asset Code * )} /> {/* Asset Type */} ( Asset Type * ({ value: type, label: type }))} value={field.value} onChange={field.onChange} placeholder="Select asset type" error={!!form.formState.errors.assetType} aria-label="Asset type selection" aria-describedby={form.formState.errors.assetType ? 'assetType-error' : undefined} /> )} /> {/* Brand/Model */} ( Brand/Model * )} /> {/* Serial Number */} ( Serial Number * )} /> {/* Asset Condition */} ( Asset Condition * ({ value: condition, label: condition }))} value={field.value} onChange={field.onChange} placeholder="Select asset condition" error={!!form.formState.errors.assetCondition} aria-label="Asset condition selection" aria-describedby={form.formState.errors.assetCondition ? 'assetCondition-error' : undefined} /> )} /> {/* Form Actions */}
); }; export default AssetForm;