diff --git a/src/components/mockup/MockupGenerator.tsx b/src/components/mockup/MockupGenerator.tsx new file mode 100644 index 0000000..f0b199c --- /dev/null +++ b/src/components/mockup/MockupGenerator.tsx @@ -0,0 +1,170 @@ +'use client' +import { useState, useEffect } from 'react' +import type { MockupTemplate } from '@/types/mockup' + +interface Props { + productCutoutBase64: string + productName: string + shopifyId?: string + family: string + dimensions?: string + onUploaded?: (url: string) => void +} + +export function MockupGenerator({ productCutoutBase64, productName, shopifyId, family, dimensions, onUploaded }: Props) { + const [templates, setTemplates] = useState([]) + const [selectedTemplate, setSelectedTemplate] = useState(null) + const [instruction, setInstruction] = useState('') + const [generating, setGenerating] = useState(false) + const [resultB64, setResultB64] = useState(null) + const [uploading, setUploading] = useState(false) + const [error, setError] = useState(null) + const [uploadedUrl, setUploadedUrl] = useState(null) + + useEffect(() => { + fetch('/api/mockup/templates') + .then(r => r.json()) + .then((data: MockupTemplate[]) => { + const filtered = data.filter(t => !family || t.family === family || t.family === 'Tous') + setTemplates(filtered.length > 0 ? filtered : data) + }) + }, [family]) + + const generate = async () => { + if (!selectedTemplate) return + setGenerating(true) + setError(null) + setResultB64(null) + try { + const res = await fetch('/api/mockup/generate', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + templateId: selectedTemplate, + productImageBase64: productCutoutBase64, + productName, + family, + dimensions: dimensions || undefined, + instruction: instruction || undefined, + }), + }) + const data = await res.json() + if (!res.ok) throw new Error(data.error) + setResultB64(data.imageBase64) + } catch (e) { + setError(e instanceof Error ? e.message : 'Erreur') + } finally { + setGenerating(false) + } + } + + const upload = async () => { + if (!resultB64 || !shopifyId) return + setUploading(true) + try { + const filename = `${productName.toLowerCase().replace(/\s+/g, '-')}-mockup.jpg` + const res = await fetch('/api/images/upload', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ shopifyProductId: shopifyId, imageBase64: resultB64, filename }), + }) + const data = await res.json() + if (!res.ok) throw new Error(data.error) + setUploadedUrl(data.url) + onUploaded?.(data.url) + } catch (e) { + setError(e instanceof Error ? e.message : 'Erreur upload') + } finally { + setUploading(false) + } + } + + return ( +
+
+ + {templates.length === 0 ? ( +

Aucun template disponible — ajoutez-en dans la bibliothèque.

+ ) : ( +
+ {templates.map(t => ( + + ))} +
+ )} +
+ + {dimensions ? ( +

Dimensions : {dimensions}

+ ) : ( +

Dimensions non renseignées — le mockup peut ne pas être à l'échelle.

+ )} + + + + {error &&

{error}

} + + {resultB64 && ( +
+ Mockup généré + +
+ setInstruction(e.target.value)} + placeholder="Instruction supplémentaire (optionnel)…" + className="flex-1 bg-slate-700 border border-slate-600 rounded px-2 py-1.5 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500" + /> + +
+ + {uploadedUrl ? ( +

✓ Uploadé sur Shopify

+ ) : ( + + )} +
+ )} +
+ ) +}