feat: Add dashboard page displaying network KPIs and store statistics, along with a new PostgreSQL data client.

This commit is contained in:
Michael committed 2026-03-21 19:18:41 +01:00
1 parent a705d0043d
commit 46c799bd60
2 files changed
+10 -2

No files matched your search

+4
View File
@@ -106,6 +106,7 @@ function NetworkKpiCard({
padding: "1.5rem", padding: "1.5rem",
position: "relative", position: "relative",
overflow: "hidden", overflow: "hidden",
boxShadow: "0 4px 24px rgba(0,0,0,0.18), 0 1px 4px rgba(0,0,0,0.12)",
}} }}
> >
{/* Decorative glow */} {/* Decorative glow */}
@@ -204,6 +205,7 @@ function StoreCard({ site, dateHier, dateN1 }: { site: DashboardSiteStats; dateH
border: "1px solid var(--border)", border: "1px solid var(--border)",
overflow: "hidden", overflow: "hidden",
position: "relative", position: "relative",
boxShadow: "0 4px 24px rgba(0,0,0,0.18), 0 1px 4px rgba(0,0,0,0.12)",
}} }}
> >
{/* Top accent bar */} {/* Top accent bar */}
@@ -363,6 +365,7 @@ function Top10Table({ title, items, sortKey, accent }: {
overflow: "hidden", overflow: "hidden",
flex: 1, flex: 1,
minWidth: 0, minWidth: 0,
boxShadow: `0 4px 24px rgba(0,0,0,0.18), 0 0 0 0px ${accent.bar}`,
}} }}
> >
{/* Table header */} {/* Table header */}
@@ -604,6 +607,7 @@ export default async function DashboardPage() {
padding: "1.5rem 2rem", padding: "1.5rem 2rem",
position: "relative", position: "relative",
overflow: "hidden", overflow: "hidden",
boxShadow: "0 4px 24px rgba(0,0,0,0.18), 0 1px 4px rgba(0,0,0,0.12)",
}} }}
> >
{/* subtle background pattern */} {/* subtle background pattern */}
+6 -2
View File
@@ -561,14 +561,18 @@ export async function pgGetDashboardData(): Promise<DashboardData> {
n1BySite.set(s.site, { ca: Number(s.ca_ttc) || 0, trafic: Number(s.trafic) || 0 }); n1BySite.set(s.site, { ca: Number(s.ca_ttc) || 0, trafic: Number(s.trafic) || 0 });
} }
// Si le 2ème appel a renvoyé des données (n1BySite.size > 0), on utilise le jour de semaine N-1.
// Sinon (appel échoué ou jour sans données), on retombe sur ca_ttc_n1 de l'API (même date calendaire).
const weekdayN1Available = n1BySite.size > 0;
const sites: DashboardSiteStats[] = (apiResult.sites ?? []).map(s => { const sites: DashboardSiteStats[] = (apiResult.sites ?? []).map(s => {
const n1 = n1BySite.get(s.site); const n1 = n1BySite.get(s.site);
return { return {
site: s.site, site: s.site,
ca_hier: Number(s.ca_ttc) || 0, ca_hier: Number(s.ca_ttc) || 0,
ca_n1: n1?.ca ?? 0, // uniquement jour de semaine N-1, jamais date calendaire ca_n1: weekdayN1Available ? (n1?.ca ?? 0) : (Number(s.ca_ttc_n1) || 0),
tickets_hier: Number(s.trafic) || 0, tickets_hier: Number(s.trafic) || 0,
tickets_n1: n1?.trafic ?? 0, // idem tickets_n1: weekdayN1Available ? (n1?.trafic ?? 0) : (Number(s.trafic_n1) || 0),
qte_hier: 0, qte_hier: 0,
marge_hier: 0, marge_hier: 0,
lignes_hier: 0, lignes_hier: 0,