fix(frontend): lockup logo via texte reel plutot qu'un raster recadre
Recomposer icone+texte en une seule image bitmap (recadrage pixel de l'asset source) donnait un rendu bruite et un espacement fige, impossible a ajuster proprement (cause du "gros espace entre le texte et l'image" remonte). Nouveau composant ev-brand : icone PNG nette + texte "EnerVision" reel en police systeme, tailles liees en em pour que le lockup grossisse en gardant le meme rapport, et un ecart controlable en CSS plutot que fige dans un fichier image.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.0 KiB |
@@ -1,7 +1,7 @@
|
||||
<div class="auth-page">
|
||||
<form class="auth-card-wrapper" [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<ev-card>
|
||||
<img src="/logo.png" alt="EnerVision" class="auth-logo" />
|
||||
<ev-brand class="auth-brand" />
|
||||
<h1>Nouveau mot de passe</h1>
|
||||
<p class="auth-subtitle">Votre mot de passe est provisoire, vous devez le modifier avant de continuer</p>
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ ev-card {
|
||||
0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.auth-logo {
|
||||
display: block;
|
||||
height: 96px;
|
||||
margin: 0 auto 1.5rem;
|
||||
.auth-brand {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
font-size: 2.1rem;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
||||
@@ -5,11 +5,12 @@ import { AuthService } from '../../../core/services/auth.service';
|
||||
import { Button } from '../../../shared/components/ui/button/button';
|
||||
import { Card } from '../../../shared/components/ui/card/card';
|
||||
import { Alert } from '../../../shared/components/ui/alert/alert';
|
||||
import { Brand } from '../../../shared/components/ui/brand/brand';
|
||||
|
||||
@Component({
|
||||
selector: 'app-change-password',
|
||||
standalone: true,
|
||||
imports: [ReactiveFormsModule, Button, Card, Alert],
|
||||
imports: [ReactiveFormsModule, Button, Card, Alert, Brand],
|
||||
templateUrl: './change-password.html',
|
||||
styleUrl: './change-password.scss',
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="auth-page">
|
||||
<form class="auth-card-wrapper" [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<ev-card>
|
||||
<img src="/logo.png" alt="EnerVision" class="auth-logo" />
|
||||
<ev-brand class="auth-brand" />
|
||||
<h1>Connexion</h1>
|
||||
<p class="auth-subtitle">Accédez à votre espace EnerVision</p>
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ ev-card {
|
||||
0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.auth-logo {
|
||||
display: block;
|
||||
height: 96px;
|
||||
margin: 0 auto 1.5rem;
|
||||
.auth-brand {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
font-size: 2.1rem;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
||||
@@ -6,11 +6,12 @@ import { AuthService } from '../../../core/services/auth.service';
|
||||
import { Button } from '../../../shared/components/ui/button/button';
|
||||
import { Card } from '../../../shared/components/ui/card/card';
|
||||
import { Alert } from '../../../shared/components/ui/alert/alert';
|
||||
import { Brand } from '../../../shared/components/ui/brand/brand';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
standalone: true,
|
||||
imports: [ReactiveFormsModule, Button, Card, Alert],
|
||||
imports: [ReactiveFormsModule, Button, Card, Alert, Brand],
|
||||
templateUrl: './login.html',
|
||||
styleUrl: './login.scss',
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="dashboard">
|
||||
<header class="dashboard__header">
|
||||
<div class="dashboard__brand">
|
||||
<img src="/logo.png" alt="EnerVision" class="dashboard__logo" />
|
||||
<ev-brand class="dashboard__logo" />
|
||||
<div>
|
||||
<h1>Vue d'ensemble</h1>
|
||||
<p class="dashboard__subtitle">Consommation instantanée du parc</p>
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
}
|
||||
|
||||
.dashboard__logo {
|
||||
height: 48px;
|
||||
width: auto;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.dashboard__subtitle {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { Alert, AlertSeverity } from '../../shared/models/alert.model';
|
||||
import { Card } from '../../shared/components/ui/card/card';
|
||||
import { Alert as EvAlert } from '../../shared/components/ui/alert/alert';
|
||||
import { Badge, BadgeTone } from '../../shared/components/ui/badge/badge';
|
||||
import { Brand } from '../../shared/components/ui/brand/brand';
|
||||
|
||||
const REFRESH_INTERVAL_MS = 10000;
|
||||
const UNAVAILABLE_MESSAGE =
|
||||
@@ -28,7 +29,7 @@ const TON_PAR_SEVERITE: Record<AlertSeverity, BadgeTone> = {
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
standalone: true,
|
||||
imports: [DecimalPipe, ConsumptionGauge, SiteLoadChart, Card, EvAlert, Badge],
|
||||
imports: [DecimalPipe, ConsumptionGauge, SiteLoadChart, Card, EvAlert, Badge, Brand],
|
||||
templateUrl: './dashboard.html',
|
||||
styleUrl: './dashboard.scss',
|
||||
})
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<img src="/logo-icon.png" alt="" class="ev-brand__icon" />
|
||||
<span class="ev-brand__name">EnerVision</span>
|
||||
@@ -0,0 +1,19 @@
|
||||
:host {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.45em;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ev-brand__icon {
|
||||
height: 1.3em;
|
||||
width: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.ev-brand__name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { Brand } from './brand';
|
||||
|
||||
describe('Brand', () => {
|
||||
it("affiche l'icône et le nom EnerVision", async () => {
|
||||
await TestBed.configureTestingModule({ imports: [Brand] }).compileComponents();
|
||||
const fixture = TestBed.createComponent(Brand);
|
||||
fixture.detectChanges();
|
||||
|
||||
const icon = fixture.nativeElement.querySelector('img.ev-brand__icon');
|
||||
expect(icon).toBeTruthy();
|
||||
expect(fixture.nativeElement.textContent).toContain('EnerVision');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ev-brand',
|
||||
standalone: true,
|
||||
templateUrl: './brand.html',
|
||||
styleUrl: './brand.scss',
|
||||
})
|
||||
export class Brand {}
|
||||
@@ -60,19 +60,27 @@ dans le tableau `imports` du composant qui l'utilise.
|
||||
```html
|
||||
<ev-badge tone="danger">critique</ev-badge>
|
||||
```
|
||||
- **`<ev-brand>`** (`brand/`) : lockup icône + « EnerVision », sans input. La taille se pilote
|
||||
entièrement via `font-size` (l'icône et le texte sont exprimés en `em`, donc ils grossissent
|
||||
ensemble en gardant le même écart proportionnel) : une page l'agrandit simplement avec
|
||||
`ev-brand { font-size: 2.1rem; }`. Ne pas recomposer icône + texte en une seule image bitmap :
|
||||
un essai en ce sens (recadrage pixel de l'asset source) a produit un rendu bruité et un espacement
|
||||
figé, impossible à ajuster proprement.
|
||||
```html
|
||||
<ev-brand />
|
||||
```
|
||||
|
||||
## Logo
|
||||
|
||||
`apps/frontend/public/logo.png` (192×128, recadré et compressé depuis l'asset source du projet)
|
||||
est affiché en en-tête des pages d'authentification et du tableau de bord :
|
||||
```html
|
||||
<img src="logo.png" alt="EnerVision" class="auth-logo" />
|
||||
```
|
||||
Le favicon reste `apps/frontend/public/favicon.ico` (non remplacé par ce chantier).
|
||||
L'icône seule (sans le mot-symbole), recadrée depuis l'asset source du projet, vit à deux
|
||||
endroits qui doivent rester synchronisés si le logo change un jour :
|
||||
`apps/frontend/public/logo-icon.png` (utilisée par `<ev-brand>`) et
|
||||
`apps/backend/app/static/logo-icon.png` (référencée par `/docs`, favicon Swagger, et `/redoc` via
|
||||
l'extension `x-logo` du schéma OpenAPI, voir `app/main.py`). Le mot-symbole « EnerVision » n'est
|
||||
jamais une image : c'est le texte du composant `<ev-brand>`, en police système.
|
||||
|
||||
Côté backend, l'icône seule (sans le mot-symbole) est servie depuis
|
||||
`apps/backend/app/static/logo-icon.png` et référencée par `/docs` (favicon Swagger) et `/redoc`
|
||||
(logo natif via l'extension `x-logo` du schéma OpenAPI, voir `app/main.py`).
|
||||
Le favicon `apps/frontend/public/favicon.ico` est généré depuis la même icône (multi-tailles
|
||||
16 à 256px).
|
||||
|
||||
## Règle pour toute nouvelle page
|
||||
|
||||
|
||||
Reference in New Issue
Block a user