import { useRef, useState } from 'react'; import { fileToBase64, resizeAvatarImage, UndecodableImageError } from '../imageUtils'; import { hasConsent, setConsent } from '../storage'; import type { WidgetTranslations } from '../i18n'; interface AvatarUploadProps { onAvatarSaved: (imageData: string) => void; onCancel?: () => void; t: WidgetTranslations['upload']; // Pre-existing saved avatar (e.g. a returning visitor routed back here only // to re-confirm consent). Seeding the preview from it opens the component // directly in the preview+consent state instead of forcing a new file pick. initialPreview?: string | null; } export function AvatarUpload({ onAvatarSaved, onCancel, t, initialPreview }: AvatarUploadProps) { const fileInputRef = useRef(null); const [preview, setPreview] = useState(initialPreview ?? null); const [isProcessing, setIsProcessing] = useState(false); const [error, setError] = useState(null); const [consented, setConsented] = useState(hasConsent()); const handleFileSelect = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setError(null); try { setIsProcessing(true); const base64 = await fileToBase64(file); const resized = await resizeAvatarImage(base64); setPreview(resized); } catch (err) { // Refuse only when the image is genuinely undecodable; anything the // browser can decode is normalized and used. setError(err instanceof UndecodableImageError ? t.unreadableImage : t.processingFailed); console.error('Error processing image:', err); } finally { setIsProcessing(false); } }; const handleConfirm = () => { // Consent is required before we ever generate an AI try-on from the shopper's photo. if (preview && consented) { onAvatarSaved(preview); // Reset file input for next upload if (fileInputRef.current) { fileInputRef.current.value = ''; } } }; const handleConsentChange = (e: React.ChangeEvent) => { const checked = e.target.checked; setConsented(checked); if (checked) { setConsent(); } }; const handleRetake = () => { setPreview(null); setError(null); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); const files = e.dataTransfer.files; if (files.length > 0) { const file = files[0]; // Simulate file input change event const event = { target: { files: { 0: file, length: 1 }, }, } as unknown as React.ChangeEvent; handleFileSelect(event); } }; return (

{t.title}

{t.description}

{error &&
{error}
} {!preview ? (
); }