diff --git a/src/features/grid/api/get-product-rows.ts b/src/features/grid/api/get-product-rows.ts index 9568e8b..a46478a 100644 --- a/src/features/grid/api/get-product-rows.ts +++ b/src/features/grid/api/get-product-rows.ts @@ -303,6 +303,14 @@ async function buildProductRows(input: GetProductRowsInput): Promise((best, r) => r.dernierereception && r.dernierereception > best ? r.dernierereception : best, ""); if (dernLiv) product.derniereLivraison = dernLiv; + + // Map store-specific delivery dates + product.derniereLivraisonByStore = {}; + for (const r of sitesStock) { + if (r.site && r.dernierereception) { + product.derniereLivraisonByStore[r.site] = r.dernierereception; + } + } } // ─── Phase 8 : Ranking réseau ──────────────────────────────────────── diff --git a/src/features/grid/components/heatmap-grid.tsx b/src/features/grid/components/heatmap-grid.tsx index 7668e61..0db0306 100644 --- a/src/features/grid/components/heatmap-grid.tsx +++ b/src/features/grid/components/heatmap-grid.tsx @@ -48,6 +48,11 @@ function formatMonthLabel(key: string): string { return `${names[m - 1]} ${key.slice(2, 4)}`; } +function formatDate(iso?: string): string { + if (!iso) return "—"; + return new Date(iso).toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit", year: "numeric" }); +} + /** * Returns premium styling and color for stores based on the store name's hash. * This guarantees a consistent color for a given store, regardless of its position in the list. @@ -458,10 +463,17 @@ export function HeatmapGrid({ onSelectionChange, isAdmin }: HeatmapGridProps) {
{r.workingStores.map((magasin) => { const config = getStoreConfig(magasin); + const lastLivDate = r.derniereLivraisonByStore?.[magasin]; + const storeName = SITE_LABELS[magasin]?.nom ?? magasin; + const tooltipTitle = `Magasin : ${storeName}\n${ + lastLivDate + ? `Dernière entrée en stock : ${formatDate(lastLivDate)}` + : "Aucune entrée enregistrée" + }`; return (
>; /** Per-store reception breakdown (site → YYYYMM → qté reçue) */ receptions12mByStore?: Record>; + /** Per-store last delivery/reception date (site → ISO date string) */ + derniereLivraisonByStore?: Record; /** Per-store CA totals */ caByStore?: Record; /** Per-store quantity totals */ diff --git a/task.md b/task.md index e01d029..84cfcf7 100644 --- a/task.md +++ b/task.md @@ -1,20 +1,33 @@ -# Plan - Implémentation de l'overlay de chargement premium (Glassmorphism) +# Plan - Date de dernière entrée en stock par magasin ## Contexte -L'utilisateur souhaite ajouter un indicateur visuel de chargement lors du chargement de la grille. L'option retenue est un overlay de démarrage en verre dépoli (glassmorphism) semi-bloquant. Cet overlay affiche la progression du streaming en temps réel et propose un bouton pour ignorer l'overlay et explorer directement les premières données déjà chargées. +L'utilisateur souhaite ajouter la date de la dernière entrée en stock (dernière réception) pour chaque magasin dans la grille. Pour éviter d'alourdir la présentation visuelle, l'information sera intégrée de manière élégante et ergonomique directement sous forme d'infobulle premium (tooltip) au survol des badges de magasins ( Nancy "F" et Houdemont "H" ) sous la colonne Désignation. ## Focus Actuel -Validation finale et dépôt propre. +Spécification et implémentation du plan d'action structuré selon les piliers de l'architecture BMAD. -## Master Plan -- [x] Définir le concept de design avec l'utilisateur (Fait: Option A sélectionnée) -- [x] Modifier `src/features/grid/components/grid-client.tsx` (Fait) -- [x] Vérifier la compilation globale avec `rtk tsc` (Fait: aucune erreur) -- [x] Valider l'esthétique et le comportement en simulant le chargement (Fait) -- [x] Mettre à jour Git (commit et push) (Fait) +## Master Plan (BMAD) + +### 1. [x] BUSINESS & UX CONCEPT +- [x] Valider la présentation ergonomique : l'information s'affichera dans l'infobulle (tooltip) au survol de chaque badge magasin (ex: "Frouard (Nancy)\nDernière entrée en stock : 12/05/2026"). +- [x] Zéro surcharge visuelle sur la grille principale. + +### 2. [x] MODEL +- [x] Modifier l'interface `ProductRow` dans `src/types/grid.ts` pour ajouter le champ facultatif `derniereLivraisonByStore?: Record;` qui associera chaque magasin (`site`) à sa date de dernière réception. + +### 3. [x] APPLICATION / API +- [x] Modifier `src/features/grid/api/get-product-rows.ts` (Phase 7) pour alimenter le dictionnaire `product.derniereLivraisonByStore` lors du parcours des lignes de `cube_stock`. + +### 4. [x] DATA & PRESENTATION (UI) +- [x] Modifier `src/features/grid/components/heatmap-grid.tsx` pour récupérer et afficher cette date dans le `title` du badge magasin : + - Si une date existe : `"Magasin : [Nom du magasin]\nDernière entrée en stock : [Date formatée]"` + - Si aucune date : `"Magasin : [Nom du magasin]\nAucune entrée enregistrée"` +- [x] Vérifier la compilation globale avec `rtk tsc`. ## Progress Log -- **2026-05-26 13:58** : Choix du design validé par l'utilisateur (Option A : Overlay de démarrage en glassmorphism avec option d'exploration). Initialisation du plan dans `task.md`. -- **2026-05-26 14:00** : Intégration de l'overlay de chargement premium en verre dépoli (glassmorphism) semi-bloquant avec indicateur dynamique et bouton d'exploration. -- **2026-05-26 14:01** : Vérification de la compilation avec `rtk tsc` réussie. -- **2026-05-26 14:02** : Push réussi des optimisations et de l'overlay vers `origin/main`. +- **2026-05-26 14:52** : Initialisation du plan d'action BMAD dans `task.md`. +- **2026-05-26 15:47** : Implémentation du plan d'action complétée avec succès. + - Champ `derniereLivraisonByStore` ajouté à l'interface `ProductRow`. + - Mapping des dates de dernière réception par site alimenté lors du fetch du stock. + - Intégration du tooltip premium ergonomique sur les badges de magasins dans la colonne Désignation. + - Compilation vérifiée (aucune régression sur les fichiers modifiés).