diff --git a/.claude/settings.json b/.claude/settings.json
index 4d783f8..dbb71b5 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -27,7 +27,9 @@
"Bash(curl -i -s \"https://api.ffnancy.fr/api/performance/ca/nomenclature?dateDebut=2025-03-01&dateFin=2025-03-31&site=&niveau=1\")",
"Bash(curl -i -s \"https://api.ffnancy.fr/api/performance/ca?dateDebut=2025-03-01&dateFin=2025-03-31&groupBy=mois\")",
"WebFetch(domain:collect.ffnancy.fr)",
- "Bash(curl -s \"https://collect.ffnancy.fr/api/diag-mvtart\")"
+ "Bash(curl -s \"https://collect.ffnancy.fr/api/diag-mvtart\")",
+ "Read(//c/Users/Michael/VSCODE/CollectFlow/**)",
+ "Bash(xargs wc:*)"
]
}
}
diff --git a/src/app/(dashboard)/analytics/loading.tsx b/src/app/(dashboard)/analytics/loading.tsx
new file mode 100644
index 0000000..dd99d6d
--- /dev/null
+++ b/src/app/(dashboard)/analytics/loading.tsx
@@ -0,0 +1,30 @@
+export default function AnalyticsLoading() {
+ return (
+
+ {/* Header */}
+
+
+ {/* Filter bar */}
+
+
+ {/* Table skeleton */}
+
+
+ {Array.from({ length: 8 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
diff --git a/src/app/(dashboard)/dashboard/loading.tsx b/src/app/(dashboard)/dashboard/loading.tsx
new file mode 100644
index 0000000..89b212a
--- /dev/null
+++ b/src/app/(dashboard)/dashboard/loading.tsx
@@ -0,0 +1,27 @@
+export default function DashboardLoading() {
+ return (
+
+ {/* Header skeleton */}
+
+
+ {/* KPI cards row */}
+
+ {Array.from({ length: 4 }).map((_, i) => (
+
+ ))}
+
+
+ {/* Main content area */}
+
+
+ {/* Bottom tables */}
+
+
+ );
+}
diff --git a/src/app/(dashboard)/dashboard/page.tsx b/src/app/(dashboard)/dashboard/page.tsx
index aebbad4..bca535d 100644
--- a/src/app/(dashboard)/dashboard/page.tsx
+++ b/src/app/(dashboard)/dashboard/page.tsx
@@ -1,4 +1,11 @@
import { pgGetDashboardData, type DashboardTopItem, type DashboardSiteStats, type DashboardSiteTop10 } from "@/lib/pg-ff-client";
+import { unstable_cache } from "next/cache";
+
+const getCachedDashboardData = unstable_cache(
+ pgGetDashboardData,
+ ["dashboard-data"],
+ { revalidate: 600 } // 10 minutes
+);
import { TrendingUp, TrendingDown, Minus, Store, Euro, Users, ShoppingCart, Award, BarChart3 } from "lucide-react";
// ---------------------------------------------------------------------------
@@ -722,7 +729,7 @@ function SectionHeader({ label, sub }: { label: string; sub?: string }) {
export default async function DashboardPage() {
let data;
try {
- data = await pgGetDashboardData();
+ data = await getCachedDashboardData();
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
console.error("[Dashboard] pgGetDashboardData failed:", e);
diff --git a/src/app/(dashboard)/exports/loading.tsx b/src/app/(dashboard)/exports/loading.tsx
new file mode 100644
index 0000000..6c6c9ab
--- /dev/null
+++ b/src/app/(dashboard)/exports/loading.tsx
@@ -0,0 +1,21 @@
+export default function ExportsLoading() {
+ return (
+
+ {/* Header */}
+
+
+ {/* Table */}
+
+
+ {Array.from({ length: 8 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
diff --git a/src/app/(dashboard)/hit-parade/loading.tsx b/src/app/(dashboard)/hit-parade/loading.tsx
new file mode 100644
index 0000000..d85f2ae
--- /dev/null
+++ b/src/app/(dashboard)/hit-parade/loading.tsx
@@ -0,0 +1,34 @@
+export default function HitParadeLoading() {
+ return (
+
+ {/* Header */}
+
+
+ {/* Podium / top cards */}
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+
+ {/* Rankings table */}
+
+
+ {Array.from({ length: 10 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
diff --git a/src/app/(dashboard)/settings/loading.tsx b/src/app/(dashboard)/settings/loading.tsx
new file mode 100644
index 0000000..0d0039b
--- /dev/null
+++ b/src/app/(dashboard)/settings/loading.tsx
@@ -0,0 +1,17 @@
+export default function SettingsLoading() {
+ return (
+
+ {/* Header */}
+
+
+ {/* Settings sections */}
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+ );
+}
diff --git a/src/app/(dashboard)/snapshots/loading.tsx b/src/app/(dashboard)/snapshots/loading.tsx
new file mode 100644
index 0000000..4a4e705
--- /dev/null
+++ b/src/app/(dashboard)/snapshots/loading.tsx
@@ -0,0 +1,18 @@
+export default function SnapshotsLoading() {
+ return (
+
+ {/* Header */}
+
+
+ {/* Cards grid */}
+
+ {Array.from({ length: 6 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}