Guide UI

Référence UI canonique — layout, en-têtes de page, couleurs, typographie, tables, boutons et notifications.

Objet

Référence UI faisant autorité pour Pulse my Promo, destinée aux humains et aux assistants IA. Le dashboard admin est la référence canonique : toute nouvelle page ou tout refactor s'aligne sur les valeurs ci-dessous. Les tokens vivent dans app/mypromo/app/app.config.ts et app/mypromo/app/assets/css/main.css ; ne pas dupliquer de valeurs codées en dur qui les contredisent.

Shell / layout

Source de référence : app/mypromo/app/layouts/admin.vue.

  • Header collant : sticky top-0 z-50 border-b border-default bg-default/95 backdrop-blur, container w-full max-w-none px-4 sm:px-6 lg:px-8.
  • Contrôles en haut à droite, dans cet ordre : Mentions légales (UButton ghost neutral size="sm") → ULocaleSelect (size="sm", class="w-28", locales [fr, en]) → menu utilisateur / déconnexion (NavSessionManager).
  • CGU gate : modale montée au niveau du layout, pilotée par useCguGate().
  • Sidebar : collapsible resizable — pas seulement redimensionnable, elle se replie aussi en rail d'icônes via le bouton UDashboardSidebarCollapse (ancré en absolute sur le bord du panneau). min-size 16 / default-size 20 / max-size 28, border-e border-default bg-muted/25. L'en-tête de sidebar est une simple barre h-14 border-b border-default (sans libellé texte) qui ne porte que le bouton de repli et aligne la sidebar sur la barre de navigation du panneau. À l'état replié (collapsed), la navigation passe en icônes seules via la prop :compact de NavDashboardSidebarNav : les titres de section deviennent sr-only et chaque bouton affiche uniquement son icône, avec title / aria-label portant le libellé pour l'accessibilité.
  • Shell partagée : ce shell (header du haut + sidebar sans en-tête texte + pas de footer + collapse en rail d'icônes) est identique sur les trois espaces (admin, distributeur, industriel). La seule différence inter-espaces est le CartPreview ajouté dans le slot #right de la navbar du panel, côté industriel.
  • Navbar du panel : h-14 border-b border-default, titre text-sm font-semibold text-highlighted, description text-xs text-dimmed.
  • Wrapper de contenu de page (div racine de chaque page) : space-y-6 px-4 py-8 sm:px-6 sm:py-10 lg:px-8. Largeur pleine du panel, pas de max-w sur le contenu.

En-tête de page

Utiliser <PageHeader> (générique) ou <AdminPageHeader> (preset admin). Structure : fil d'Ariane → titre → description → actions.

  • Container : flex flex-wrap items-start justify-between gap-4.
  • Fil d'Ariane (UBreadcrumb) : text-[12px], link text-stone-500 hover:text-stone-900, separator text-stone-300.
  • Titre h1 : mt-1 text-2xl font-semibold tracking-tight text-pulse-800.
  • Description : mt-1 text-sm text-stone-500 max-w-2xl.
  • Actions : slot #actions, à droite du titre, boutons size="md".
<PageHeader
  :title="t('...')"
  :description="t('...')"
  :root="{ label: 'Admin', to: '/admin' }"
  :breadcrumbs="[{ label: t('...') }]"
>
  <template #actions>
    <UButton color="neutral" variant="outline" icon="i-lucide-refresh-cw">{{ t('common.actions.refresh') }}</UButton>
  </template>
</PageHeader>

Couleurs

RôleCouleurUsage
primarypulse (teal)CTA, booking, activation — jamais décoratif
secondaryindigovues distributeur / admin, contrepoint
successtealconfirmation, KYB validé
infobluenotifications neutres
warningamberétats en attente, KYB en attente
errorrederreurs, destructif
neutralstonesurfaces, textes, base chaude

Titres de page : text-pulse-800. La couleur primaire porte le sens « agir ici » — jamais décorative.

Typographie

Police : Public Sans.

NiveauClasses
Titre de pagetext-2xl font-semibold tracking-tight text-pulse-800
Titre de section / tabletext-sm font-semibold text-highlighted
Corpstext-sm
Méta / secondairetext-xs text-dimmed
Texte d'aide / explicatiftext-xs text-toned

dimmed pour ce qu'on survole, toned pour ce qu'on lit. text-dimmed est un gris clair (contraste ≈ 2,6 sur fond blanc) : il convient à une méta-donnée qu'on balaie du regard — un horodatage, un compteur, un libellé de champ redondant — mais il est sous le seuil WCAG AA (4,5 pour du texte courant). Dès qu'une phrase doit réellement être lue pour comprendre l'écran (mode d'emploi d'un graphique, règle métier qui explique un filtrage), utiliser text-toned (contraste ≈ 7,6, conforme AA et AAA). La taille reste text-xs : c'est la couleur qui porte la hiérarchie, pas la taille.

Avis / notifications

  • Feedback de page (persistant) : <UAlert variant="subtle" :color :title>, placé juste sous le PageHeader. Couleur sémantique (success / error / warning).
  • Confirmations transitoires : useToast (thème neutral, icône colorée porteuse du sens).

Tables

  • Base : <AkDataList> (de @aidalinfo/nuxt-ui-kit), mode server via useServerAdminList (recherche / pagination / tri / sync URL) ou mode client.
  • Titre : via le slot #header d'AkDataList, avec <AppDataListHeader :title> (titre text-sm font-semibold text-highlighted).
  • Toute nouvelle table utilise AkDataList. UTable / TableTemplate restent uniquement sur le legacy déjà en place.
<AkDataList :data="rows" :columns="columns" mode="server">
  <template #header>
    <AppDataListHeader :title="t('...')" />
  </template>
</AkDataList>

Cartes de section (boxes)

  • Pour regrouper du contenu non tabellaire sous un en-tête titré (formulaires, panneaux de détail…), utiliser <AppSectionCard> plutôt qu'un <UCard> + #header fait main.
  • Contrat : prop title (obligatoire), description?, slot #actions (actions à droite de l'en-tête), slot par défaut (corps).
  • Le titre reprend le style de section (text-sm font-semibold text-highlighted) ; l'en-tête gris et le contour arrondi proviennent des tokens UCard (app.config.ts).
  • Les boutons de ces cartes (en-tête #actions comme corps) utilisent size="sm".
  • Hors périmètre : tables (voir AkDataList), mini-cartes de métriques, cartes à en-tête visuel/image.
<AppSectionCard :title="t('...')" :description="t('...')">
  <template #actions>
    <UButton size="sm" color="neutral" variant="outline">…</UButton>
  </template>
  <!-- contenu -->
</AppSectionCard>

Boutons

  • Taille par défaut md.
  • CTA principal : solid primary (seule élévation colorée).
  • Actions secondaires : neutral en outline / soft / ghost selon le niveau.
  • Navigation / actions discrètes : size="sm" variant="ghost".