feat: implement infinite grid pagination with server-side data fetching and custom hook

This commit is contained in:
Michael committed 2026-04-02 17:17:32 +02:00
1 parent 4db7faa41f
commit 2893114fca
6 files changed
+302 -27

No files matched your search

+6 -6
View File
@@ -33,16 +33,16 @@ export default async function GridPage({ searchParams }: GridPageProps) {
return <SupplierSelectionLanding fournisseurs={fournisseurs} />;
}
// 3. Load product data — résultat mis en cache 5 min par fournisseur (unstable_cache).
// La première requête est lente mais les suivantes (refresh, navigation) sont instantanées.
console.log(`\n>>> [GridPage] Fetching data for: ${codeFournisseur}, shop: ${magasin}`);
const rows = await getGridData(codeFournisseur, magasin, filters);
console.log(`>>> [GridPage] Received ${rows.length} rows from getGridData`);
// 3. Load product data — pagination pour ne pas crasher le JS client
console.log(`\n>>> [GridPage] Fetching page 0 for: ${codeFournisseur}, shop: ${magasin}`);
const { rows: initialRows, total } = await getGridData(codeFournisseur, magasin, filters, 0, 200);
console.log(`>>> [GridPage] Received ${initialRows.length}/${total} rows from getGridData`);
const selectedFournisseur = fournisseurs.find((f: { code: string; nom: string }) => f.code === codeFournisseur);
return (
<GridClient
initialRows={rows}
initialRows={initialRows}
initialTotal={total}
codeFournisseur={codeFournisseur}
nomFournisseur={selectedFournisseur?.nom || "Fournisseur inconnu"}
fournisseurs={fournisseurs}
+44
View File
@@ -0,0 +1,44 @@
import { NextRequest, NextResponse } from "next/server";
import { getProductRows } from "@/features/grid/api/get-product-rows";
import { auth } from "@/lib/auth";
export async function GET(request: NextRequest) {
const session = await auth();
if (!session) {
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
}
const { searchParams } = request.nextUrl;
const codeFournisseur = searchParams.get("fournisseur");
if (!codeFournisseur) {
return NextResponse.json({ error: "Paramètre 'fournisseur' requis" }, { status: 400 });
}
const page = parseInt(searchParams.get("page") ?? "0", 10);
const pageSize = parseInt(searchParams.get("pageSize") ?? "200", 10);
const search = searchParams.get("search") ?? undefined;
const gamme = searchParams.get("gamme") ?? undefined;
const code3 = searchParams.get("code3") ?? undefined;
try {
const result = await getProductRows({
codeFournisseur,
page: isNaN(page) ? 0 : page,
pageSize: isNaN(pageSize) ? 200 : pageSize,
search,
gamme: gamme || null,
code3: code3 || null,
});
return NextResponse.json(result, {
status: 200,
headers: {
"Cache-Control": "private, max-age=30, stale-while-revalidate=60",
},
});
} catch (error) {
console.error("[GET /api/grid/rows] Error:", error);
return NextResponse.json({ error: "Erreur lors de la récupération des données" }, { status: 500 });
}
}