mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-17 20:30:07 +02:00
feat: add NoSalesTab component to display products without sales in the last 6 months
This commit is contained in:
1 parent
687009dba1
commit
6492f93bf4
4 files changed
+364
-19
No files matched your search
@@ -1,11 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState, useTransition, useCallback } from "react";
|
||||
import { useEffect, useRef, useState, useTransition, useCallback, useMemo } from "react";
|
||||
import { HeatmapGrid } from "@/features/grid/components/heatmap-grid";
|
||||
import { FloatingSummaryBar } from "@/features/grid/components/floating-summary-bar";
|
||||
import { BulkActionToolbar } from "@/features/grid/components/bulk-action-toolbar";
|
||||
import { GridFilterBar } from "@/features/grid/components/grid-filter-bar";
|
||||
import { ExportDropdown } from "@/features/grid/components/export-dropdown";
|
||||
import { NoSalesTab, countNoSalesIn6Months } from "@/features/grid/components/no-sales-tab";
|
||||
import { useGridStore } from "@/features/grid/store/use-grid-store";
|
||||
import { useSaveDrafts } from "@/features/grid/hooks/use-save-drafts";
|
||||
import { useInfiniteGrid } from "@/features/grid/hooks/use-infinite-grid";
|
||||
@@ -38,6 +39,9 @@ export function GridClient({ initialRows, initialTotal, codeFournisseur, nomFour
|
||||
const [selectedCodeins, setSelectedCodeins] = useState<string[]>([]);
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [saveStatus, setSaveStatus] = useState<"idle" | "success" | "error">("idle");
|
||||
const [activeTab, setActiveTab] = useState<"grid" | "no-sales">("grid");
|
||||
|
||||
const noSalesCount = useMemo(() => countNoSalesIn6Months(rows), [rows]);
|
||||
|
||||
const visibleCodeins = initialRows.map(r => r.codein);
|
||||
const { save, hasDrafts, count } = useSaveDrafts(magasin, visibleCodeins);
|
||||
@@ -181,26 +185,68 @@ export function GridClient({ initialRows, initialTotal, codeFournisseur, nomFour
|
||||
<GridFilterBar fournisseurs={fournisseurs} magasins={magasins} />
|
||||
</div>
|
||||
|
||||
{/* Bulk toolbar (contextual) */}
|
||||
<div className="shrink-0 print:hidden">
|
||||
<BulkActionToolbar
|
||||
selectedCodeins={selectedCodeins}
|
||||
onClearSelection={() => setSelectedCodeins([])}
|
||||
/>
|
||||
{/* Tab switcher */}
|
||||
<div className="shrink-0 flex gap-0 print:hidden" style={{ borderBottom: "1px solid var(--border)" }}>
|
||||
{(["grid", "no-sales"] as const).map(tab => {
|
||||
const isActive = activeTab === tab;
|
||||
return (
|
||||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className="flex items-center gap-1.5 px-4 py-2 text-[13px] font-medium transition-colors"
|
||||
style={{
|
||||
color: isActive ? "var(--text-primary)" : "var(--text-muted)",
|
||||
borderBottom: isActive ? "2px solid var(--accent)" : "2px solid transparent",
|
||||
marginBottom: "-1px",
|
||||
}}
|
||||
>
|
||||
{tab === "grid" ? "Assortiment" : "Sans vente 6 mois"}
|
||||
{tab === "no-sales" && noSalesCount > 0 && (
|
||||
<span className="inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full text-[10px] font-bold"
|
||||
style={{
|
||||
background: isActive ? "var(--accent)" : "var(--bg-elevated)",
|
||||
color: isActive ? "white" : "var(--text-secondary)",
|
||||
border: "1px solid var(--border)",
|
||||
}}
|
||||
>
|
||||
{noSalesCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Main grid */}
|
||||
<div className="flex-1 min-h-0 min-w-0">
|
||||
<HeatmapGrid
|
||||
onSelectionChange={setSelectedCodeins}
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
</div>
|
||||
{/* Bulk toolbar (contextual) — uniquement sur l'onglet grille */}
|
||||
{activeTab === "grid" && (
|
||||
<div className="shrink-0 print:hidden">
|
||||
<BulkActionToolbar
|
||||
selectedCodeins={selectedCodeins}
|
||||
onClearSelection={() => setSelectedCodeins([])}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Summary bar */}
|
||||
<div className="print:hidden">
|
||||
<FloatingSummaryBar />
|
||||
</div>
|
||||
{/* Main content */}
|
||||
{activeTab === "grid" ? (
|
||||
<div className="flex-1 min-h-0 min-w-0">
|
||||
<HeatmapGrid
|
||||
onSelectionChange={setSelectedCodeins}
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex-1 min-h-0 min-w-0 flex flex-col">
|
||||
<NoSalesTab />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Summary bar — uniquement sur l'onglet grille */}
|
||||
{activeTab === "grid" && (
|
||||
<div className="print:hidden">
|
||||
<FloatingSummaryBar />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user