feat(plan4): page /produits avec catalogue Shopify + filtres
This commit is contained in:
@@ -1,9 +1,56 @@
|
|||||||
|
'use client'
|
||||||
|
import { useState, useEffect, useMemo } from 'react'
|
||||||
import { Header } from '@/components/layout/Header'
|
import { Header } from '@/components/layout/Header'
|
||||||
|
import { ProductFiltersBar } from '@/components/products/ProductFiltersBar'
|
||||||
|
import { ProductTable } from '@/components/products/ProductTable'
|
||||||
|
import type { CatalogProduct, ProductFilters } from '@/types/products'
|
||||||
|
|
||||||
export default function ProduitsPage() {
|
export default function ProduitsPage() {
|
||||||
|
const [allProducts, setAllProducts] = useState<CatalogProduct[]>([])
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [filters, setFilters] = useState<ProductFilters>({ status: 'all', search: '' })
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLoading(true)
|
||||||
|
setError(null)
|
||||||
|
const params = filters.status !== 'all' ? `?status=${filters.status}` : ''
|
||||||
|
fetch(`/api/products/list${params}`)
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data.error) throw new Error(data.error)
|
||||||
|
setAllProducts(data.products)
|
||||||
|
})
|
||||||
|
.catch((e: Error) => setError(e.message))
|
||||||
|
.finally(() => setLoading(false))
|
||||||
|
}, [filters.status])
|
||||||
|
|
||||||
|
const displayed = useMemo(() => {
|
||||||
|
if (!filters.search.trim()) return allProducts
|
||||||
|
const q = filters.search.toLowerCase()
|
||||||
|
return allProducts.filter(
|
||||||
|
(p) => p.title.toLowerCase().includes(q) || p.ref.toLowerCase().includes(q),
|
||||||
|
)
|
||||||
|
}, [allProducts, filters.search])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header title="📦 Produits" />
|
<Header title="Produits" />
|
||||||
<div className="p-6"><p className="text-gray-400 text-sm">Module Produits — à implémenter (Plan 4)</p></div>
|
<div className="p-6">
|
||||||
|
<div className="bg-slate-800 rounded-xl p-6">
|
||||||
|
<ProductFiltersBar
|
||||||
|
filters={filters}
|
||||||
|
total={displayed.length}
|
||||||
|
onChange={(f) => setFilters((prev) => ({ ...prev, ...f }))}
|
||||||
|
/>
|
||||||
|
{error && (
|
||||||
|
<div className="mb-4 p-3 bg-red-900/30 border border-red-700 rounded-lg text-red-300 text-sm">
|
||||||
|
{error}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ProductTable products={displayed} loading={loading} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user