import { zodResolver } from '@hookform/resolvers/zod'; import { Camera, Search, Upload, X } from 'lucide-react'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { useCreateClosetItem } from '@/hooks/useClosetQueries'; import { UPLOAD_CONFIG } from '@/lib/config'; import { CLOTHING_CATEGORIES } from '@/types'; const addItemSchema = z.object({ name: z.string().min(1, 'Name is required'), brand: z.string().min(1, 'Brand is required'), category: z.string().min(1, 'Category is required'), }); type AddItemFormData = z.infer; interface AddItemModalProps { isOpen: boolean; onClose: () => void; } export default function AddItemModal({ isOpen, onClose }: AddItemModalProps) { const [mode, setMode] = useState<'choice' | 'manual' | 'search'>('choice'); const [imageFile, setImageFile] = useState(null); const [imagePreview, setImagePreview] = useState(null); const createItemMutation = useCreateClosetItem(); const form = useForm({ resolver: zodResolver(addItemSchema), defaultValues: { name: '', brand: '', category: '', }, }); const handleImageChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { if (file.size > UPLOAD_CONFIG.MAX_FILE_SIZE) { toast.error( `Image size must be less than ${UPLOAD_CONFIG.MAX_FILE_SIZE_MB}MB` ); return; } if (!file.type.startsWith('image/')) { toast.error('Please select a valid image file'); return; } setImageFile(file); const reader = new FileReader(); reader.onloadend = () => { setImagePreview(reader.result as string); }; reader.readAsDataURL(file); } }; const removeImage = () => { setImageFile(null); setImagePreview(null); const fileInput = document.getElementById( 'image-upload' ) as HTMLInputElement; if (fileInput) fileInput.value = ''; }; const onSubmit = (data: AddItemFormData) => { createItemMutation.mutate( { ...data, imageFile: imageFile ?? undefined, }, { onSuccess: () => { onClose(); form.reset(); setImageFile(null); setImagePreview(null); }, } ); }; const handleClose = () => { onClose(); setMode('choice'); form.reset(); setImageFile(null); setImagePreview(null); }; const handleSearchProducts = () => { window.location.href = '/search'; handleClose(); }; return ( {mode === 'choice' ? 'Add to Closet' : mode === 'manual' ? 'Add with Photos' : 'Search Products'} {mode === 'choice' ? (
setMode('manual')} >

Add with Photos

Upload photos of items you own

Search Items

Find items from brand catalogs

) : mode === 'manual' ? (
{imagePreview ? (
Preview
) : (

Click to upload or drag and drop

PNG, JPG, HEIC up to {UPLOAD_CONFIG.MAX_FILE_SIZE_MB}MB

)}
( Name )} /> ( Brand )} /> ( Category )} /> ) : null} {mode === 'choice' && ( )}
); }