Photos for vehicles
This commit is contained in:
@@ -7,8 +7,9 @@ import { useForm } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
import { Button } from '../../../shared-minimal/components/Button';
|
||||
import { CreateVehicleRequest } from '../types/vehicles.types';
|
||||
import { CreateVehicleRequest, Vehicle } from '../types/vehicles.types';
|
||||
import { vehiclesApi } from '../api/vehicles.api';
|
||||
import { VehicleImageUpload } from './VehicleImageUpload';
|
||||
|
||||
const vehicleSchema = z
|
||||
.object({
|
||||
@@ -57,8 +58,9 @@ const vehicleSchema = z
|
||||
interface VehicleFormProps {
|
||||
onSubmit: (data: CreateVehicleRequest) => void;
|
||||
onCancel: () => void;
|
||||
initialData?: Partial<CreateVehicleRequest>;
|
||||
initialData?: Partial<CreateVehicleRequest> & { id?: string; imageUrl?: string };
|
||||
loading?: boolean;
|
||||
onImageUpdate?: (vehicle: Vehicle) => void;
|
||||
}
|
||||
|
||||
export const VehicleForm: React.FC<VehicleFormProps> = ({
|
||||
@@ -66,6 +68,7 @@ export const VehicleForm: React.FC<VehicleFormProps> = ({
|
||||
onCancel,
|
||||
initialData,
|
||||
loading,
|
||||
onImageUpdate,
|
||||
}) => {
|
||||
const [years, setYears] = useState<number[]>([]);
|
||||
const [makes, setMakes] = useState<string[]>([]);
|
||||
@@ -80,6 +83,10 @@ export const VehicleForm: React.FC<VehicleFormProps> = ({
|
||||
const [loadingDropdowns, setLoadingDropdowns] = useState(false);
|
||||
const hasInitialized = useRef(false);
|
||||
const isInitializing = useRef(false);
|
||||
const [currentImageUrl, setCurrentImageUrl] = useState<string | undefined>(initialData?.imageUrl);
|
||||
|
||||
const isEditMode = !!initialData?.id;
|
||||
const vehicleId = initialData?.id;
|
||||
|
||||
const {
|
||||
register,
|
||||
@@ -332,8 +339,53 @@ export const VehicleForm: React.FC<VehicleFormProps> = ({
|
||||
}
|
||||
}, [watchedYear, selectedMake, selectedModel, watch('trimLevel')]);
|
||||
|
||||
const handleImageUpload = async (file: File) => {
|
||||
if (!vehicleId) return;
|
||||
const updated = await vehiclesApi.uploadImage(vehicleId, file);
|
||||
setCurrentImageUrl(updated.imageUrl);
|
||||
onImageUpdate?.(updated);
|
||||
};
|
||||
|
||||
const handleImageRemove = async () => {
|
||||
if (!vehicleId) return;
|
||||
await vehiclesApi.deleteImage(vehicleId);
|
||||
setCurrentImageUrl(undefined);
|
||||
if (initialData) {
|
||||
onImageUpdate?.({ ...initialData, imageUrl: undefined } as Vehicle);
|
||||
}
|
||||
};
|
||||
|
||||
const vehicleForImage: Vehicle = {
|
||||
id: vehicleId || '',
|
||||
userId: '',
|
||||
vin: initialData?.vin || '',
|
||||
make: initialData?.make,
|
||||
model: initialData?.model,
|
||||
year: initialData?.year,
|
||||
color: initialData?.color,
|
||||
odometerReading: initialData?.odometerReading || 0,
|
||||
isActive: true,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
imageUrl: currentImageUrl,
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
||||
{isEditMode && (
|
||||
<div className="mb-6">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Vehicle Photo
|
||||
</label>
|
||||
<VehicleImageUpload
|
||||
vehicle={vehicleForImage}
|
||||
onUpload={handleImageUpload}
|
||||
onRemove={handleImageRemove}
|
||||
disabled={loading || loadingDropdowns}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
VIN or License Plate <span className="text-red-500">*</span>
|
||||
|
||||
Reference in New Issue
Block a user