diff --git a/src/app/(dashboard)/images/page.tsx b/src/app/(dashboard)/images/page.tsx index 71f2e16..b9760ab 100644 --- a/src/app/(dashboard)/images/page.tsx +++ b/src/app/(dashboard)/images/page.tsx @@ -5,6 +5,7 @@ import { DropZone } from '@/components/images/DropZone' import { ImageCard } from '@/components/images/ImageCard' import { Lightbox } from '@/components/images/Lightbox' import { GlobalActions } from '@/components/images/GlobalActions' +import { MockupModalFromImage } from '@/components/mockup/MockupModalFromImage' import { ErrorBoundary } from '@/components/common/ErrorBoundary' import { useImages } from '@/hooks/useImages' import type { ImageItem } from '@/types/images' @@ -12,6 +13,12 @@ import type { ImageItem } from '@/types/images' function ImagesPageInner() { const { items, addFiles, setFeather, setAlphaThreshold, rotate, uploadOne, uploadAll, removeItem, assignProduct, reprocess, detour } = useImages() const [lightboxItem, setLightboxItem] = useState(null) + const [mockupItem, setMockupItem] = useState(null) + + const openMockup = useCallback((id: string) => { + const item = items.find(i => i.id === id) + if (item) setMockupItem(item) + }, [items]) const [selected, setSelected] = useState>(new Set()) const toggleSelect = useCallback((id: string, value: boolean) => { @@ -101,6 +108,7 @@ function ImagesPageInner() { onAssignProduct={assignProduct} onReprocess={reprocess} onDetour={detour} + onMockup={openMockup} /> ))} @@ -116,6 +124,9 @@ function ImagesPageInner() { setLightboxItem(null)} /> + {mockupItem && ( + setMockupItem(null)} /> + )} ) } diff --git a/src/components/images/ImageCard.tsx b/src/components/images/ImageCard.tsx index 0b74946..e35491f 100644 --- a/src/components/images/ImageCard.tsx +++ b/src/components/images/ImageCard.tsx @@ -15,6 +15,7 @@ interface ImageCardProps { onAssignProduct: (id: string, shopifyProductId: string, shopifyProductTitle: string) => void onReprocess: (id: string) => void onDetour: (id: string) => void + onMockup: (id: string) => void } const STATUS_LABELS: Record = { @@ -110,6 +111,7 @@ export function ImageCard({ onAssignProduct, onReprocess, onDetour, + onMockup, }: ImageCardProps) { const statusInfo = STATUS_LABELS[item.status] ?? { label: item.status, color: 'text-slate-400' } const isProcessing = ['pending', 'converting', 'processing', 'searching', 'uploading'].includes(item.status) @@ -231,6 +233,15 @@ export function ImageCard({ ✂️ Détourer )} + {(item.status === 'ready' || item.status === 'uploaded' || item.status === 'skipped' || item.status === 'converted') && ( + + )} {(item.status === 'ready' || item.status === 'uploaded' || item.status === 'skipped' || item.status === 'error') && item.rawPngBlob && ( + + +
+ + {/* Famille */} +
+

Famille

+ +
+ + {/* Template */} +
+
+

Template

+ + +
+ {filteredTemplates.length === 0 ? ( +

Aucun template pour cette famille. Uploadez-en un.

+ ) : ( +
+ {filteredTemplates.map(t => ( + + ))} +
+ )} +
+ + {/* Instruction libre */} +
+ + setInstruction(e.target.value)} + placeholder="Ex: fond beige, lumière naturelle, ambiance chaleureuse…" + className="w-full 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" + /> +
+ + + + {error &&

{error}

} + + {/* Résultat */} + {resultB64 && ( +
+ Mockup +
+ setInstruction(e.target.value)} + placeholder="Modifier l'instruction et regénérer…" + 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" + /> + +
+
+ + {item.shopifyProductId ? ( + uploadedUrl ? ( +

✓ Uploadé sur Shopify

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

Pas de produit associé

+ )} +
+
+ )} +
+ + + ) +}