'use client'; import { useState, useRef } from 'react'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { Sparkles, Upload, X, Loader2, Download, RefreshCw } from 'lucide-react'; import { API_BASE } from '@/lib/api'; interface TryItOnModalProps { isOpen: boolean; onClose: () => void; productName: string; productCategory: string; productImage?: string; } export function TryItOnModal({ isOpen, onClose, productName, productCategory, productImage }: TryItOnModalProps) { const [userImage, setUserImage] = useState(null); const [generating, setGenerating] = useState(false); const [resultImage, setResultImage] = useState(null); const [error, setError] = useState(''); const fileInputRef = useRef(null); if (!isOpen) return null; const handleImageUpload = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; if (file.size > 5 * 1024 * 1024) { setError('Image too large. Max 5MB.'); return; } const reader = new FileReader(); reader.onloadend = () => { setUserImage(reader.result as string); setResultImage(null); setError(''); }; reader.readAsDataURL(file); }; const generate = async () => { if (!userImage) return; setGenerating(true); setError(''); setResultImage(null); try { // Build a contextual prompt based on the product category let prompt = ''; const cat = (productCategory || '').toLowerCase(); if (cat.includes('fashion') || cat.includes('clothing')) { prompt = `A person wearing ${productName}, photorealistic, commercial fashion photography, full body shot, studio lighting, the person is posing naturally wearing this outfit`; } else if (cat.includes('beauty') || cat.includes('cosmetic')) { prompt = `A person applying/wearing ${productName}, photorealistic, beauty editorial photography, close-up face shot, studio lighting, natural makeup look`; } else if (cat.includes('accessor') || cat.includes('watch') || cat.includes('jewelry') || cat.includes('bag')) { prompt = `A person holding/wearing ${productName}, photorealistic, commercial product photography, the person is showcasing the product naturally, studio lighting`; } else if (cat.includes('shoe') || cat.includes('sneaker')) { prompt = `A person wearing ${productName} on their feet, photorealistic, commercial photography, full body shot showing the shoes, studio lighting`; } else if (cat.includes('phone') || cat.includes('electronic') || cat.includes('gadget')) { prompt = `A person holding ${productName} in their hand, photorealistic, commercial product photography, natural pose, studio lighting`; } else { prompt = `A person with ${productName}, photorealistic, commercial photography, natural pose, studio lighting, high quality`; } const resp = await fetch(`${API_BASE}/api/try-on`, { credentials: 'include', method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userImage, productPrompt: prompt, productName, productCategory, }), }); const data = await resp.json(); if (data.success && data.image) { setResultImage(data.image); } else { setError(data.error || 'Generation failed. Please try again.'); } } catch (err) { setError('Network error. Please try again.'); } setGenerating(false); }; const reset = () => { setUserImage(null); setResultImage(null); setError(''); }; return (
e.stopPropagation()} > {/* Header */}

Try It On

AI-powered virtual try-on

{/* Body */}
{/* Product context */}
{productImage && ( {productName} )}
{productName}
{productCategory}
{/* Result image (if generated) */} {resultImage && (
Try-on result
)} {/* Upload area (when no result) */} {!resultImage && ( <> {userImage ? (
Your photo
) : ( )} {error && (
{error}
)} {userImage && !generating && ( )} {generating && (

Generating your try-on...

This takes ~10-15 seconds

)} )} {/* Privacy note */}

Your photo is processed securely and not stored. Results are AI-generated.

); }