feat: affichage images produit dans la liste avec thumbnail et compteur
This commit is contained in:
@@ -19,6 +19,7 @@ export async function GET(req: NextRequest): Promise<NextResponse<ProductListRes
|
||||
stock: p.stock,
|
||||
status: p.status as CatalogProduct['status'],
|
||||
shopifyUrl: `https://${domain}/admin/products/${p.shopifyId}`,
|
||||
images: p.images ?? [],
|
||||
}))
|
||||
|
||||
if (statusFilter !== 'all') {
|
||||
|
||||
@@ -36,6 +36,7 @@ export function ProductTable({ products, loading }: Props) {
|
||||
<thead>
|
||||
<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">Images</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">Stock</th>
|
||||
@@ -48,6 +49,18 @@ export function ProductTable({ products, loading }: Props) {
|
||||
{displayed.map((p) => (
|
||||
<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">
|
||||
{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-gray-300">{p.price} €</td>
|
||||
<td className="py-3 pr-4 text-gray-300">{p.stock}</td>
|
||||
|
||||
@@ -31,6 +31,7 @@ interface ShopifyAPIProduct {
|
||||
body_html: string
|
||||
status: string
|
||||
variants: ShopifyVariant[]
|
||||
images: Array<{ src: string }>
|
||||
}
|
||||
|
||||
function toSyncProduct(p: ShopifyAPIProduct): ShopifyProductFull {
|
||||
@@ -43,6 +44,7 @@ function toSyncProduct(p: ShopifyAPIProduct): ShopifyProductFull {
|
||||
price: p.variants[0]?.price ?? '0.00',
|
||||
stock: p.variants[0]?.inventory_quantity ?? 0,
|
||||
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[] = []
|
||||
|
||||
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) {
|
||||
const res = await fetch(url, { headers })
|
||||
|
||||
@@ -9,7 +9,8 @@ export interface CatalogProduct {
|
||||
price: string // "29.99"
|
||||
stock: number // inventory_quantity variante 1
|
||||
status: 'active' | 'draft' | 'archived'
|
||||
shopifyUrl: string // https://materiaux-destock.myshopify.com/admin/products/<id>
|
||||
shopifyUrl: string
|
||||
images: string[]
|
||||
}
|
||||
|
||||
/** Filtres appliqués à la liste */
|
||||
|
||||
+2
-1
@@ -13,7 +13,8 @@ export interface SyncProduct {
|
||||
|
||||
/** Produit Shopify enrichi pour la comparaison */
|
||||
export interface ShopifyProductFull extends SyncProduct {
|
||||
shopifyId: string // ID numérique Shopify (string)
|
||||
shopifyId: string
|
||||
images?: string[]
|
||||
}
|
||||
|
||||
/** Un changement unitaire calculé par computeDiff */
|
||||
|
||||
Reference in New Issue
Block a user