import { useState, useCallback } from 'react'; import { inventoryApi } from '@/lib/api'; import { CropBounds } from './useCropHandles'; interface ItemFormData { name: string; category: string; item_type: string; quantity: number; barcode?: string; part_number?: string; box_label?: string; } interface UploadedPhoto { thumbnail_url: string; full_url: string; uploaded_at: string; } interface UseItemCreateReturn { step: 'details' | 'photo' | 'preview' | 'confirm'; formData: ItemFormData; setFormData: (data: Partial) => void; uploadedPhoto: UploadedPhoto | null; cropBounds: CropBounds | null; setCropBounds: (bounds: CropBounds | null) => void; isLoading: boolean; error: string | null; photoError: string | null; goToStep: (step: 'details' | 'photo' | 'preview' | 'confirm') => void; nextStep: () => void; prevStep: () => void; uploadPhoto: (file: File, photoItemId?: number) => Promise; submitItem: (userId: number) => Promise; reset: () => void; } const initialFormData: ItemFormData = { name: '', category: '', item_type: '', quantity: 1, barcode: '', part_number: '', box_label: '', }; export function useItemCreate(): UseItemCreateReturn { const [step, setStep] = useState<'details' | 'photo' | 'preview' | 'confirm'>('details'); const [formData, setFormDataState] = useState(initialFormData); const [uploadedPhoto, setUploadedPhoto] = useState(null); const [cropBounds, setCropBounds] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [photoError, setPhotoError] = useState(null); const [itemId, setItemId] = useState(null); const setFormData = useCallback((data: Partial) => { setFormDataState((prev) => ({ ...prev, ...data })); }, []); const goToStep = useCallback((newStep: 'details' | 'photo' | 'preview' | 'confirm') => { setError(null); setPhotoError(null); setStep(newStep); }, []); const nextStep = useCallback(() => { const steps: Array<'details' | 'photo' | 'preview' | 'confirm'> = ['details', 'photo', 'preview', 'confirm']; const currentIndex = steps.indexOf(step); if (currentIndex < steps.length - 1) { goToStep(steps[currentIndex + 1]); } }, [step, goToStep]); const prevStep = useCallback(() => { const steps: Array<'details' | 'photo' | 'preview' | 'confirm'> = ['details', 'photo', 'preview', 'confirm']; const currentIndex = steps.indexOf(step); if (currentIndex > 0) { goToStep(steps[currentIndex - 1]); } }, [step, goToStep]); const uploadPhoto = useCallback( async (file: File, photoItemId?: number) => { const idToUse = photoItemId || itemId; if (!idToUse) { setPhotoError('Item must be created before uploading photo'); return; } setPhotoError(null); setIsLoading(true); try { const formDataUpload = new FormData(); formDataUpload.append('file', file); // If crop bounds are set, add them to the request if (cropBounds) { formDataUpload.append('crop_bounds', JSON.stringify(cropBounds)); } const response = await inventoryApi.uploadItemPhoto(idToUse, formDataUpload); if (response.status === 'ok' && response.photo) { setUploadedPhoto({ thumbnail_url: response.photo.thumbnail_url, full_url: response.photo.full_url, uploaded_at: response.photo.uploaded_at, }); setIsLoading(false); } else { throw new Error('Invalid response from server'); } } catch (err: any) { const errorMsg = err.message || 'Photo upload failed'; setPhotoError(errorMsg); setIsLoading(false); throw new Error(errorMsg); } }, [itemId, cropBounds] ); const submitItem = useCallback( async (userId: number) => { setError(null); setIsLoading(true); try { // Validate form data if (!formData.name.trim()) { const errorMsg = 'Item name is required'; setError(errorMsg); setIsLoading(false); return undefined; } if (!formData.category) { const errorMsg = 'Category is required'; setError(errorMsg); setIsLoading(false); return undefined; } if (!formData.item_type) { const errorMsg = 'Item type is required'; setError(errorMsg); setIsLoading(false); return undefined; } // Create item first (without photo) const createdItem = await inventoryApi.createItem(userId, formData); if (!createdItem.id) { const errorMsg = 'Failed to create item'; setError(errorMsg); setIsLoading(false); return undefined; } setItemId(createdItem.id); setIsLoading(false); return createdItem; } catch (err: any) { const errorMsg = err.message || 'Failed to create item'; setError(errorMsg); setIsLoading(false); return undefined; } }, [formData] ); const reset = useCallback(() => { setStep('details'); setFormDataState(initialFormData); setUploadedPhoto(null); setCropBounds(null); setItemId(null); setError(null); setPhotoError(null); }, []); return { step, formData, setFormData, uploadedPhoto, cropBounds, setCropBounds, isLoading, error, photoError, goToStep, nextStep, prevStep, uploadPhoto, submitItem, reset, }; }