Intègre l'identité visuelle officielle (planche fournie) : - Assets ajoutés (frontend/src/assets/images/) : logo-icon, logo-carre, logo-horizontal (réservé aux PDF, non encore câblé), favicon. - Favicon : src/favicon.ico régénéré depuis favicon.png (16/32/48, via Pillow) pour remplacer l'icône Angular par défaut ; PNG référencé en priorité dans index.html avec cache-busting (?v=) pour contourner le cache favicon des navigateurs Chromium (Chrome/Brave). - Barre de navigation : logo-icon en tête (fond blanc localisé pour ressortir sur l'anthracite), couleurs de charte (fond anthracite, lien actif bleu IAD, survol orange). - Pages d'authentification (login, register, forgot-password, reset-password) : logo carré centré au-dessus du formulaire, boutons en bleu IAD. - Palette officielle en variables CSS globales (styles.scss) : --couleur-orange, --couleur-bleu, --couleur-anthracite, --couleur-gris-clair (+ déclinaisons de survol). - Harmonisation des boutons d'action à fond bleu (texte) sur toute l'app : survol orange (véhicules, profil, barème, montants réglés, résumés mensuel/ annuel, onboarding, formulaire de trajet, dialog de confirmation, carte). Exclusions volontaires : boutons rouges (suppression), boutons à icône, boutons secondaires à fond blanc, indicateurs d'état sélectionné/actif. Specs : design.md complété (section Charte graphique : palette, convention de survol, rôle de chaque asset).
68 lines
2.3 KiB
HTML
68 lines
2.3 KiB
HTML
<section class="login">
|
|
<img class="login__logo" src="assets/images/logo-carre.png" alt="SchotzIAD — Mon activité, mon outil" width="180" height="145" />
|
|
<h1>Connexion</h1>
|
|
|
|
<form [formGroup]="form" (ngSubmit)="seConnecter()" novalidate>
|
|
@if (erreur()) {
|
|
<p class="erreur-globale" role="alert">{{ erreur() }}</p>
|
|
}
|
|
|
|
<div class="champ">
|
|
<label for="email">Adresse email</label>
|
|
<input
|
|
id="email"
|
|
type="email"
|
|
formControlName="email"
|
|
autocomplete="username"
|
|
autocapitalize="none"
|
|
spellcheck="false"
|
|
[attr.aria-invalid]="form.get('email')?.invalid && form.get('email')?.touched"
|
|
aria-describedby="email-erreur"
|
|
/>
|
|
@if (form.get('email')?.touched && form.get('email')?.invalid) {
|
|
<p id="email-erreur" class="erreur" role="alert">
|
|
@if (form.get('email')?.hasError('required')) {
|
|
L'adresse email est obligatoire.
|
|
} @else if (form.get('email')?.hasError('email')) {
|
|
L'adresse email n'est pas valide.
|
|
}
|
|
</p>
|
|
}
|
|
</div>
|
|
|
|
<div class="champ">
|
|
<label for="motDePasse">Mot de passe</label>
|
|
<input
|
|
id="motDePasse"
|
|
type="password"
|
|
formControlName="motDePasse"
|
|
autocomplete="current-password"
|
|
[attr.aria-invalid]="form.get('motDePasse')?.invalid && form.get('motDePasse')?.touched"
|
|
aria-describedby="motDePasse-erreur"
|
|
/>
|
|
@if (form.get('motDePasse')?.touched && form.get('motDePasse')?.invalid) {
|
|
<p id="motDePasse-erreur" class="erreur" role="alert">
|
|
@if (form.get('motDePasse')?.hasError('required')) {
|
|
Le mot de passe est obligatoire.
|
|
} @else if (form.get('motDePasse')?.hasError('minlength')) {
|
|
Le mot de passe doit comporter au moins 8 caractères.
|
|
}
|
|
</p>
|
|
}
|
|
</div>
|
|
|
|
<div class="actions">
|
|
<button type="submit" class="btn-principal" [disabled]="soumissionEnCours()">
|
|
{{ soumissionEnCours() ? 'Connexion…' : 'Se connecter' }}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<nav class="liens" aria-label="Actions du compte">
|
|
<a routerLink="/forgot-password">Mot de passe oublié ?</a>
|
|
@if (!compteExiste()) {
|
|
<a routerLink="/register">Créer un compte</a>
|
|
}
|
|
</nav>
|
|
</section>
|