import React from 'react'; import { Button } from '../../../shared-minimal/components/Button'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import dayjs from 'dayjs'; import { useCreateDocument } from '../hooks/useDocuments'; import { documentsApi } from '../api/documents.api'; import type { DocumentType } from '../types/documents.types'; import { useVehicles } from '../../vehicles/hooks/useVehicles'; import type { Vehicle } from '../../vehicles/types/vehicles.types'; interface DocumentFormProps { onSuccess?: () => void; onCancel?: () => void; } export const DocumentForm: React.FC = ({ onSuccess, onCancel }) => { const [documentType, setDocumentType] = React.useState('insurance'); const [vehicleID, setVehicleID] = React.useState(''); const [title, setTitle] = React.useState(''); const [notes, setNotes] = React.useState(''); // Insurance fields const [insuranceCompany, setInsuranceCompany] = React.useState(''); const [policyNumber, setPolicyNumber] = React.useState(''); const [effectiveDate, setEffectiveDate] = React.useState(''); const [expirationDate, setExpirationDate] = React.useState(''); const [bodilyInjuryPerson, setBodilyInjuryPerson] = React.useState(''); const [bodilyInjuryIncident, setBodilyInjuryIncident] = React.useState(''); const [propertyDamage, setPropertyDamage] = React.useState(''); const [premium, setPremium] = React.useState(''); // Registration fields const [licensePlate, setLicensePlate] = React.useState(''); const [registrationExpirationDate, setRegistrationExpirationDate] = React.useState(''); const [registrationCost, setRegistrationCost] = React.useState(''); // Manual fields const [scanForMaintenance, setScanForMaintenance] = React.useState(false); const [file, setFile] = React.useState(null); const [uploadProgress, setUploadProgress] = React.useState(0); const [error, setError] = React.useState(null); const { data: vehicles } = useVehicles(); const create = useCreateDocument(); const resetForm = () => { setTitle(''); setNotes(''); setInsuranceCompany(''); setPolicyNumber(''); setEffectiveDate(''); setExpirationDate(''); setBodilyInjuryPerson(''); setBodilyInjuryIncident(''); setPropertyDamage(''); setPremium(''); setLicensePlate(''); setRegistrationExpirationDate(''); setRegistrationCost(''); setScanForMaintenance(false); setFile(null); setUploadProgress(0); setError(null); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!vehicleID) { setError('Please select a vehicle.'); return; } if (!title.trim()) { setError('Please enter a title.'); return; } try { const details: Record = {}; let issued_date: string | undefined; let expiration_date: string | undefined; if (documentType === 'insurance') { details.insuranceCompany = insuranceCompany || undefined; details.policyNumber = policyNumber || undefined; details.bodilyInjuryPerson = bodilyInjuryPerson || undefined; details.bodilyInjuryIncident = bodilyInjuryIncident || undefined; details.propertyDamage = propertyDamage || undefined; details.premium = premium ? parseFloat(premium) : undefined; issued_date = effectiveDate || undefined; expiration_date = expirationDate || undefined; } else if (documentType === 'registration') { details.licensePlate = licensePlate || undefined; details.cost = registrationCost ? parseFloat(registrationCost) : undefined; expiration_date = registrationExpirationDate || undefined; } // Manual type: no details or dates, just scanForMaintenance flag const created = await create.mutateAsync({ vehicleId: vehicleID, documentType: documentType, title: title.trim(), notes: notes.trim() || undefined, details: Object.keys(details).length > 0 ? details : undefined, issuedDate: issued_date, expirationDate: expiration_date, scanForMaintenance: documentType === 'manual' ? scanForMaintenance : undefined, }); if (file) { const allowed = new Set(['application/pdf', 'image/jpeg', 'image/png']); if (!file.type || !allowed.has(file.type)) { setError('Unsupported file type. Allowed: PDF, JPG/JPEG, PNG.'); return; } try { await documentsApi.uploadWithProgress(created.id, file, (pct) => setUploadProgress(pct)); } catch (uploadErr: any) { const status = uploadErr?.response?.status; if (status === 415) { setError('Unsupported file type. Allowed: PDF, JPG/JPEG, PNG.'); return; } setError(uploadErr?.message || 'Failed to upload file'); return; } } resetForm(); onSuccess?.(); } catch (err: any) { const status = err?.response?.status; if (status === 415) { setError('Unsupported file type. Allowed: PDF, JPG/JPEG, PNG.'); } else { setError(err?.message || 'Failed to create document'); } } finally { setUploadProgress(0); } }; const vehicleLabel = (v: Vehicle) => { if (v.nickname && v.nickname.trim().length > 0) return v.nickname.trim(); const parts = [v.year, v.make, v.model, v.trimLevel].filter(Boolean); const primary = parts.join(' ').trim(); if (primary.length > 0) return primary; if (v.vin && v.vin.length > 0) return v.vin; return v.id.slice(0, 8) + '...'; }; return (
setTitle(e.target.value)} required />
{documentType === 'insurance' && ( <>
setInsuranceCompany(e.target.value)} />
setPolicyNumber(e.target.value)} />
setEffectiveDate(newValue?.format('YYYY-MM-DD') || '')} format="MM/DD/YYYY" slotProps={{ textField: { fullWidth: true, sx: { '& .MuiOutlinedInput-root': { minHeight: 44, }, }, }, }} />
setExpirationDate(newValue?.format('YYYY-MM-DD') || '')} format="MM/DD/YYYY" slotProps={{ textField: { fullWidth: true, sx: { '& .MuiOutlinedInput-root': { minHeight: 44, }, }, }, }} />
setBodilyInjuryPerson(e.target.value)} />
setBodilyInjuryIncident(e.target.value)} />
setPropertyDamage(e.target.value)} />
setPremium(e.target.value)} />
)} {documentType === 'registration' && ( <>
setLicensePlate(e.target.value)} />
setRegistrationExpirationDate(newValue?.format('YYYY-MM-DD') || '')} format="MM/DD/YYYY" slotProps={{ textField: { fullWidth: true, sx: { '& .MuiOutlinedInput-root': { minHeight: 44, }, }, }, }} />
setRegistrationCost(e.target.value)} />
)} {documentType === 'manual' && (
(Coming soon)
)}