Feature #1149
openFeature #1147: Tiers réels — 2 pools (maintenance/évolutions) + flux/SLA + page /offres + jauge à 2 indicateurs
Frontend — Page /offres (formules complètes), jauge profil à 2 indicateurs, TierCard, lien « Demander une mise à niveau »
0%
issue:1147 — spec dans l'épopée + description
Description
## Objectif
Exposer le vrai modèle de formules côté UI : une **page /offres** complète, une **jauge profil à 2 indicateurs** (maintenance + évolutions), une `TierCard` corrigée, et brancher « Demander une mise à niveau » → /offres. Dépend du backend 2 pools (#enfant backend de #1147).
## Dépendances
Dépend du nouveau contrat API 2 pools (enfant backend de #1147) : `CreditBalanceOut`/`TierOut` exposant maintenance_remaining/evolution_remaining (nullable=illimité), streams, ratios/is_low par pool.
## Portée (src/, App Router, Atomic Design, next-intl, TDD)
- **Page `/offres`** (route App Router, accessible connecté) : les 4 formules en colonnes/cartes avec, pour chacune : prix, maintenance & évolutions (« illimité » si NULL), flux, 1ʳᵉ livraison, SLA incident (P1/P2/P3), humain/CTO, et les bullets RUN/BUILD/PROTECT/ADVISE (contenu i18n, voir #1147). Bandeau « + tout ce que contient la formule en dessous ». **Formule actuelle** mise en évidence (badge). Légende « Comment lire les SLA ». CTA par formule (« Prendre rendez-vous »/contact) + CTA upgrade. Reprendre l'esthétique « OmDev — Nos offres · prix mensuel fixe ».
- **Jauge profil** : remplacer la jauge unique par **2 indicateurs** (maintenance + évolutions). Quand un pool est illimité (NULL) afficher « illimité » (pas de % ni de couleur « bas »). Conserver les seuils de couleur (vert >50 / orange / rouge <10) pour les pools finis. Réutiliser/adapter `CreditGauge`.
- **TierCard** : afficher les deux pools (maintenance/évolutions, « illimité » géré), flux, prix ; couleur distinctive par formule. Le bouton « Demander une mise à niveau » pointe vers **/offres** (plus de mailto).
- **Page admin** : afficher/ajuster les deux pools (le contrôle d'ajustement choisit le pool ; griser/masquer l'ajustement sur un pool illimité). Le tableau montre maintenance + évolutions.
- **i18n** : ajouter tout le contenu des formules (titres, taglines, bullets RUN/BUILD/PROTECT/ADVISE, SLA, légende) dans `en.ts` ET `fr.ts` (fr = vraie traduction ; en = miroir typé). Placeholders ICU identiques.
## Acceptance criteria
- [ ] /offres présente les 4 formules avec tous les détails (#1147), formule actuelle mise en évidence, légende SLA.
- [ ] « Demander une mise à niveau » ouvre /offres.
- [ ] La jauge profil montre 2 indicateurs ; « illimité » géré sans faux « bas » ni % ; seuils couleur conservés pour pools finis.
- [ ] TierCard montre les deux pools + flux ; couleur par formule.
- [ ] La page admin gère les deux pools (ajustement par pool, illimité non ajustable).
- [ ] Clés i18n en.ts ET fr.ts cohérentes (tsc vert).
- [ ] `npx vitest run && npx tsc --noEmit && npx eslint . && npm run build` verts.
Files
RA Updated by Redmine Admin about 1 month ago
- Status changed from Submitted to Spec
RA Updated by Redmine Admin about 1 month ago
- File offres-after.png offres-after.png added
RA Updated by Redmine Admin about 1 month ago
- File jauge-2-indicateurs.png jauge-2-indicateurs.png added
RA Updated by Redmine Admin about 1 month ago
RA Updated by Redmine Admin about 1 month ago
- File offres-mockup.html offres-mockup.html added
RA Updated by Redmine Admin about 1 month ago
- File jauge-mockup.html jauge-mockup.html added
RA Updated by Redmine Admin about 1 month ago
## Brief design — #1149 (épopée #1147, vrai modèle 2 pools)
*Designer agent — maquettes + preuve before/after. Source de vérité du contenu = #1147 (matrice + copies + légende SLA). Aucune nouvelle teinte : on réutilise les tokens de niveau §MC.5 et les seuils §MC.3.*
### Design-system (additif, `docs/design/design-system.md`)
- **Nouvelle section §OF « Offres / Plans »** (OF.1 shell §UR.1 → OF.7 i18n) : grille 4 colonnes, `TierColumn`, formule actuelle mise en évidence, légende SLA, lien upgrade → `/offres`, états & a11y, namespace i18n `offers`.
- **Mise à jour additive §MC.3** : jauge à **2 indicateurs** (maintenance + évolutions), traitement « illimité », seuils conservés ; + note **page admin 2 pools** (sélecteur de pool sur le stepper §AG.3b, illimité non ajustable).
### 1. Page `/offres` (after — `offres-after.png` / `offres-mockup.html`)
**Atomic Design** : *page* `app/offres/page.tsx` sur le *template* §UR.1 (TopBar §7b.4 + bande sticky §TB.1, fil d'Ariane `← Mon compte`) → organism **`OffersGrid`** de molecules **`TierColumn`** + organism **`SlaLegend`**. Atomes réutilisés : `Badge` §v2.3, `Button` §7b.1, pastille-point `pdot`, barre 4-segments §MC.5.
- 4 colonnes **Démarrage 2 500 € · Maintenance 4 200 € · Évolutions 9 700 € · Pilotage 16 000 €**, accent = **token de niveau §MC.5** (slate / cyan `status-quality` / violet `status-spec` / emerald `brand-700`) — **aucune nouvelle couleur**.
- Chaque carte : prix/mois, tagline, **Maintenance** + **Évolutions** (« illimité » dans la couleur du niveau quand NULL), **Flux** (1/1/2/4), **1ʳᵉ livraison** (—/48 h/24 h/12 h), **Incident P1/P2/P3** (pastille `danger`/`warning`/`muted` + mot + délai — §SO.severity-map), ligne **humain/CTO**, bandeau **« + tout ce que contient {formule en dessous} »**, bullets **RUN/BUILD/PROTECT/ADVISE** (copie #1147), barre de progression, **CTA « Prendre rendez-vous »** par formule.
- **Formule actuelle** (OF.3) : bordure pleine + ombre teintée au niveau, **`Badge` « Formule actuelle »**, CTA en `solid`.
- **Légende « Comment lire les SLA »** (OF.4) : Réponse / Correctif livré / Première livraison / Flux + clé de sévérité P1/P2/P3, note prix fixe sans TJM / 100 % du code au client.
- **« Demander une mise à niveau »** (TierCard profil §MC.5 **et** admin) → **lien `next/link` vers `/offres`**, **plus de `mailto:`**.
### 2. Jauge profil à 2 indicateurs (after — `jauge-2-indicateurs.png` / `jauge-mockup.html`)
`CreditGauge` réutilisé/adapté, enveloppé par une molecule `CreditGauges` (deux anneaux côte à côte, **anneau SVG natif — pas recharts**). Trois cas démontrés :
- **Démarrage** = deux pools **finis** (100 maint / 10 évo) → deux anneaux pleins verts « Sain » (seuils §MC.3 inchangés).
- **Pool épuisé** → maintenance « Attention » (`warning-fg`), évolutions 0 % « Critique » (`danger-fg`) — indicateurs indépendants.
- **Illimité (NULL)** → anneau pointillé décoratif `brand-700`/55 %, centre **« ∞ illimité »**, pastille **neutre « illimité »** — **pas de %, pas de couleur « bas », jamais de faux rouge**.
- **Seuils conservés pour les pools finis** : vert > 50 % / orange < 30 % / rouge < 10 %. `aria-label` portant le verdict ou « illimité » (§7, jamais la couleur seule).
### Preuve before/after
- **`offres-after.png`** — page `/offres` complète. **`jauge-2-indicateurs.png`** — les 3 cas de la jauge. **`before-reconstruction.png`** — état actuel.
- **« Before » = reconstruction** (noté dans §OF/§MC.3) : **`/offres` est une page neuve** (n'existe pas) et l'app est derrière l'auth (non pilotable headless) → le before reconstruit l'état actuel = jauge **unique** (un seul pool, §MC.3 livré #1133) + bouton upgrade en **`mailto:`**. Captures via le daemon gstack `/browse`.
### i18n
Namespace **`offers`** (page) + ajouts au namespace **`account`** (jauge : `creditsMaintenance`, `creditsEvolutions`, `creditsUnlimited`, `creditsUncapped`, `creditsUnlimitedAria`). Toutes les clés dans **`en.ts` ET `fr.ts`** (vraie trad FR, placeholders ICU identiques, `Translated<typeof en>`). Copies de formule + bullets RUN/BUILD/PROTECT/ADVISE depuis #1147.
→ Transition **Spec → Design**.
RA Updated by Redmine Admin about 1 month ago
- Status changed from Spec to Design
RA Updated by Redmine Admin about 1 month ago
- Status changed from Design to In development
RA Updated by Redmine Admin about 1 month ago
- Status changed from In development to QA
- branch set to feat/1149-offres-two-pool
- pr_url set to https://github.com/omdev-tech/PipeLiner-Client/pull/74
PR ouverte vers `dev` : https://github.com/omdev-tech/PipeLiner-Client/pull/74
Frontend du modèle 2 pools (épopée #1147), branché sur le backend #1148 déjà mergé sur `dev`.
**Livré (src/, App Router, Atomic Design, next-intl, TDD) :**
- **Page `/offres`** (`app/offres/page.tsx`, accessible connecté) : organism `OffersGrid` → molecules `TierColumn` + organism `SlaLegend`. Les 4 formules avec prix, maintenance & évolutions (« illimité » si NULL), flux (1/1/2/4), 1ʳᵉ livraison, incident P1/P2/P3, humain/CTO, bullets RUN/BUILD/PROTECT/ADVISE (copie #1147 → i18n), bandeau « + tout ce que contient {formule} », formule actuelle mise en évidence (badge), légende « Comment lire les SLA », CTA « Prendre rendez-vous » par formule.
- **Jauge profil à 2 indicateurs** : molecule `CreditGauges` (maintenance + évolutions). Pool illimité → « ∞ illimité » (pas de %, neutre, jamais « bas ») ; pools finis → seuils vert>50/orange/rouge<10 conservés. `CreditGauge` étendu (mode illimité + taille compacte, SVG natif, pas recharts).
- **TierCard** : deux pools (illimité géré) + flux + prix ; « Demander une mise à niveau » pointe désormais vers `/offres` (plus de mailto).
- **Page admin** : colonnes par pool avec verdict/pastille par pool + stepper par pool ; pool illimité → « illimité » + stepper masqué ; l'ajustement envoie `{ pool, delta }`.
- **Contrat API #1148** adapté partout (types, hooks, composants, tests) : `TierOut`/`CreditBalanceOut`/`ClientSummary` en 2 pools ; anciens champs single-pool supprimés.
- **i18n** : namespace `offers` + ajouts `account`/`adminClients`/`common` dans `en.ts` ET `fr.ts` (fr = vraie trad, placeholders ICU identiques).
- **design-system** : section §OF ajoutée + note §MC.3 (jauge 2 indicateurs) + note admin 2 pools.
**Gates verts** : `npx vitest run` (640 ok) · `npx tsc --noEmit` · `npx eslint .` · `npm run build`.
Branche : `feat/1149-offres-two-pool`. Transition : En développement → QA.