From d1e78e91e47781ad31f9655b3714498a8eee312e Mon Sep 17 00:00:00 2001 From: Mathieu Date: Tue, 9 Jun 2026 21:00:45 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20s=C3=A9lection=20manuelle=20de=20produi?= =?UTF-8?q?t=20Shopify=20quand=20r=C3=A9f.=20introuvable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(dashboard)/images/page.tsx | 3 +- src/components/images/ImageCard.tsx | 59 +++++++++++++++++++++++++++++ src/hooks/useImages.ts | 9 ++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/app/(dashboard)/images/page.tsx b/src/app/(dashboard)/images/page.tsx index f7a8983..5e3000c 100644 --- a/src/app/(dashboard)/images/page.tsx +++ b/src/app/(dashboard)/images/page.tsx @@ -10,7 +10,7 @@ import { useImages } from '@/hooks/useImages' import type { ImageItem } from '@/types/images' function ImagesPageInner() { - const { items, addFiles, setFeather, rotate, uploadOne, uploadAll, removeItem } = useImages() + const { items, addFiles, setFeather, rotate, uploadOne, uploadAll, removeItem, assignProduct } = useImages() const [lightboxItem, setLightboxItem] = useState(null) return ( @@ -42,6 +42,7 @@ function ImagesPageInner() { onUpload={uploadOne} onRemove={removeItem} onOpenLightbox={setLightboxItem} + onAssignProduct={assignProduct} /> ))} diff --git a/src/components/images/ImageCard.tsx b/src/components/images/ImageCard.tsx index 77a490c..597ec9c 100644 --- a/src/components/images/ImageCard.tsx +++ b/src/components/images/ImageCard.tsx @@ -9,6 +9,7 @@ interface ImageCardProps { onUpload: (id: string) => void onRemove: (id: string) => void onOpenLightbox: (item: ImageItem) => void + onAssignProduct: (id: string, shopifyProductId: string, shopifyProductTitle: string) => void } const STATUS_LABELS: Record = { @@ -36,6 +37,59 @@ function BlobThumbnail({ blob, alt }: { blob: Blob; alt: string }) { return {alt} } +function ProductSearch({ itemId, onAssign }: { itemId: string; onAssign: (id: string, shopifyProductId: string, title: string) => void }) { + const [query, setQuery] = useState('') + const [results, setResults] = useState<{ shopifyId: string; title: string }[]>([]) + const [loading, setLoading] = useState(false) + + async function search() { + if (!query.trim()) return + setLoading(true) + try { + const res = await fetch(`/api/products/search?ref=${encodeURIComponent(query.trim())}`) + const data = await res.json() + if (data.found) setResults([{ shopifyId: data.shopifyId, title: data.title }]) + else setResults([]) + } finally { + setLoading(false) + } + } + + return ( +
+
+ setQuery(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && search()} + placeholder="Rechercher un produit…" + className="flex-1 px-2 py-1 text-xs bg-slate-800 border border-slate-600 rounded text-slate-200 placeholder-slate-500 focus:outline-none focus:border-indigo-500" + /> + +
+ {results.length === 0 && !loading && query && ( +

Aucun résultat

+ )} + {results.map((r) => ( + + ))} +
+ ) +} + export function ImageCard({ item, onFeatherChange, @@ -43,6 +97,7 @@ export function ImageCard({ onUpload, onRemove, onOpenLightbox, + onAssignProduct, }: ImageCardProps) { const statusInfo = STATUS_LABELS[item.status] ?? { label: item.status, color: 'text-slate-400' } const isProcessing = ['pending', 'converting', 'processing', 'searching', 'uploading'].includes(item.status) @@ -88,6 +143,10 @@ export function ImageCard({ {item.error &&

{item.error}

} + {item.status === 'not_found' && ( + + )} + {/* Contrôles feather + rotation */}