Files
siop2/apps/web/src/components/avatar.tsx
pr-daaif 9778629827 feat(r1.2): écrans web du référentiel — 7 écrans fidèles à maquette-r1
- Sites : liste + carte Leaflet/OSM réelle (pins maquette, positions
  PostGIS), création en modale avec position posée au clic sur la carte
- Fiche site : arbre site→zones, appareils rattachés, ajout de zone
- Ascenseurs : table dense, filtres site/statut, strie rouge à l'arrêt ;
  fiche appareil (organes ± ajout/retrait, statut, QR réel) ; création
  identité → rattachement → organes ; étiquette A6 imprimable (objet
  papier, window.print n'imprime qu'elle)
- Personnes & équipes : invitation → lien d'activation affiché à copier
  (pas d'email en R1, décision explicite), renvoi de lien, équipes ;
  page /activation (choix du mot de passe, connexion directe)
- Catégories : ajout, renommage inline, désactivation
- navigation et actions pilotées par la matrice (usePermissions) —
  l'API re-vérifie chaque requête
- e2e Playwright : recette R1 officielle rejouée intégralement (site →
  zone → appareil+organe → étiquette → invitation → activation) +
  parcours « la matrice pilote l'UI » ; purge idempotente en globalSetup
- alias Vite @siop/shared → source TS (exports nommés CJS ↯ workspace lié)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:06:45 +01:00

43 lines
988 B
TypeScript

import { cn } from '@/lib/cn';
/** Couleur d'avatar par rôle (tokens uniquement — répartition de la maquette). */
const ROLE_TOKEN: Record<string, string> = {
Administrateur: 'var(--graf-1)',
Dispatcher: 'var(--primaire)',
Technicien: 'var(--graf-3)',
'Technicien limité': 'var(--st-encours)',
Gestionnaire: 'var(--graf-4)',
Demandeur: 'var(--st-annule)',
'Vue seule': 'var(--safran)',
};
export function Avatar({
initials,
roleName,
className,
}: {
initials: string;
roleName?: string;
className?: string;
}) {
const couleur = roleName ? ROLE_TOKEN[roleName] : undefined;
return (
<span
className={cn('avatar', className)}
style={couleur ? { background: couleur } : undefined}
aria-hidden="true"
>
{initials}
</span>
);
}
export function initialsOf(displayName: string): string {
return displayName
.split(/\s+/)
.filter(Boolean)
.slice(0, 2)
.map((w) => w[0]!.toUpperCase())
.join('');
}