feat: affichage images produit dans la liste avec thumbnail et compteur

This commit is contained in:
2026-06-24 14:27:35 +02:00
parent 41f5c245d4
commit 93a616e997
5 changed files with 21 additions and 3 deletions
+1
View File
@@ -19,6 +19,7 @@ export async function GET(req: NextRequest): Promise<NextResponse<ProductListRes
stock: p.stock, stock: p.stock,
status: p.status as CatalogProduct['status'], status: p.status as CatalogProduct['status'],
shopifyUrl: `https://${domain}/admin/products/${p.shopifyId}`, shopifyUrl: `https://${domain}/admin/products/${p.shopifyId}`,
images: p.images ?? [],
})) }))
if (statusFilter !== 'all') { if (statusFilter !== 'all') {
+13
View File
@@ -36,6 +36,7 @@ export function ProductTable({ products, loading }: Props) {
<thead> <thead>
<tr className="text-left text-gray-400 border-b border-slate-700"> <tr className="text-left text-gray-400 border-b border-slate-700">
<th className="pb-3 pr-4 font-medium">Référence</th> <th className="pb-3 pr-4 font-medium">Référence</th>
<th className="pb-3 pr-4 font-medium">Images</th>
<th className="pb-3 pr-4 font-medium">Titre</th> <th className="pb-3 pr-4 font-medium">Titre</th>
<th className="pb-3 pr-4 font-medium">Prix</th> <th className="pb-3 pr-4 font-medium">Prix</th>
<th className="pb-3 pr-4 font-medium">Stock</th> <th className="pb-3 pr-4 font-medium">Stock</th>
@@ -48,6 +49,18 @@ export function ProductTable({ products, loading }: Props) {
{displayed.map((p) => ( {displayed.map((p) => (
<tr key={p.shopifyId} className="border-b border-slate-700/50 hover:bg-slate-700/30 transition-colors"> <tr key={p.shopifyId} className="border-b border-slate-700/50 hover:bg-slate-700/30 transition-colors">
<td className="py-3 pr-4 font-mono text-indigo-300">{p.ref}</td> <td className="py-3 pr-4 font-mono text-indigo-300">{p.ref}</td>
<td className="py-3 pr-4">
{p.images.length > 0 ? (
<div className="flex items-center gap-1.5">
<img src={p.images[0]} alt="" className="w-8 h-8 object-cover rounded border border-slate-600" />
{p.images.length > 1 && (
<span className="text-xs text-gray-400">+{p.images.length - 1}</span>
)}
</div>
) : (
<span className="text-xs text-gray-600"></span>
)}
</td>
<td className="py-3 pr-4 text-white">{p.title}</td> <td className="py-3 pr-4 text-white">{p.title}</td>
<td className="py-3 pr-4 text-gray-300">{p.price} </td> <td className="py-3 pr-4 text-gray-300">{p.price} </td>
<td className="py-3 pr-4 text-gray-300">{p.stock}</td> <td className="py-3 pr-4 text-gray-300">{p.stock}</td>
+3 -1
View File
@@ -31,6 +31,7 @@ interface ShopifyAPIProduct {
body_html: string body_html: string
status: string status: string
variants: ShopifyVariant[] variants: ShopifyVariant[]
images: Array<{ src: string }>
} }
function toSyncProduct(p: ShopifyAPIProduct): ShopifyProductFull { function toSyncProduct(p: ShopifyAPIProduct): ShopifyProductFull {
@@ -43,6 +44,7 @@ function toSyncProduct(p: ShopifyAPIProduct): ShopifyProductFull {
price: p.variants[0]?.price ?? '0.00', price: p.variants[0]?.price ?? '0.00',
stock: p.variants[0]?.inventory_quantity ?? 0, stock: p.variants[0]?.inventory_quantity ?? 0,
status: p.status === 'active' ? 'active' : 'draft', status: p.status === 'active' ? 'active' : 'draft',
images: (p.images ?? []).map(i => i.src),
} }
} }
@@ -69,7 +71,7 @@ async function fetchByStatus(status: 'active' | 'draft'): Promise<ShopifyProduct
const all: ShopifyProductFull[] = [] const all: ShopifyProductFull[] = []
let url: string | null = let url: string | null =
`${baseUrl}/products.json?limit=250&fields=id,title,handle,status,body_html,variants&status=${status}` `${baseUrl}/products.json?limit=250&fields=id,title,handle,status,body_html,variants,images&status=${status}`
while (url) { while (url) {
const res = await fetch(url, { headers }) const res = await fetch(url, { headers })
+2 -1
View File
@@ -9,7 +9,8 @@ export interface CatalogProduct {
price: string // "29.99" price: string // "29.99"
stock: number // inventory_quantity variante 1 stock: number // inventory_quantity variante 1
status: 'active' | 'draft' | 'archived' status: 'active' | 'draft' | 'archived'
shopifyUrl: string // https://materiaux-destock.myshopify.com/admin/products/<id> shopifyUrl: string
images: string[]
} }
/** Filtres appliqués à la liste */ /** Filtres appliqués à la liste */
+2 -1
View File
@@ -13,7 +13,8 @@ export interface SyncProduct {
/** Produit Shopify enrichi pour la comparaison */ /** Produit Shopify enrichi pour la comparaison */
export interface ShopifyProductFull extends SyncProduct { export interface ShopifyProductFull extends SyncProduct {
shopifyId: string // ID numérique Shopify (string) shopifyId: string
images?: string[]
} }
/** Un changement unitaire calculé par computeDiff */ /** Un changement unitaire calculé par computeDiff */