import { useState, useCallback } from 'react'; import { inventoryApi } from '@/lib/api'; interface Photo { thumbnail_url: string; full_url: string; uploaded_at: string; } interface UsePhotoUploadReturn { upload: (file: File, itemId: number) => Promise; isLoading: boolean; error: string | null; } const ACCEPTED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif']; const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB export function usePhotoUpload(): UsePhotoUploadReturn { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const validateFile = useCallback((file: File): { valid: boolean; error?: string } => { // Validate file size if (file.size > MAX_FILE_SIZE) { return { valid: false, error: 'File too large, max 10MB', }; } // Validate MIME type if (!ACCEPTED_MIME_TYPES.includes(file.type)) { return { valid: false, error: 'Invalid image format', }; } return { valid: true }; }, []); const upload = useCallback( async (file: File, itemId: number): Promise => { setError(null); setIsLoading(true); try { // Validate file (synchronously) const validation = validateFile(file); if (!validation.valid) { const errorMsg = validation.error || 'File validation failed'; setError(errorMsg); setIsLoading(false); throw new Error(errorMsg); } // Create FormData for multipart upload const formData = new FormData(); formData.append('file', file); // Upload to backend const response = await inventoryApi.uploadItemPhoto(itemId, formData); // Handle response if (response.status === 'ok' && response.photo) { const photo: Photo = { thumbnail_url: response.photo.thumbnail_url, full_url: response.photo.full_url, uploaded_at: response.photo.uploaded_at, }; setIsLoading(false); return photo; } throw new Error('Invalid response from server'); } catch (err: any) { const errorMsg = err.message || 'Upload failed'; setError(errorMsg); setIsLoading(false); throw new Error(errorMsg); } }, [validateFile] ); return { upload, isLoading, error, }; }