diff --git a/frontend/src/app/app.component.scss b/frontend/src/app/app.component.scss index 23766c9..e075593 100644 --- a/frontend/src/app/app.component.scss +++ b/frontend/src/app/app.component.scss @@ -1,12 +1,12 @@ :host { display: flex; flex-direction: column; - height: 100vh; + height: 100dvh; min-height: 0; } .nav-bar { - flex: 0 0 auto; + flex: 0 0 auto; // hauteur naturelle (même si les liens passent sur plusieurs lignes) display: flex; flex-wrap: wrap; align-items: center; @@ -37,18 +37,10 @@ } } - -/* Le contenu routé occupe toute la hauteur restante sous le menu. - Les vues qui le souhaitent (ex. consultation) peuvent ainsi figer leur mise en page - et ne faire défiler qu'une sous-zone interne. */ +/* Le contenu routé occupe la hauteur restante sous le menu et défile si nécessaire. + Les vues courtes gardent leur hauteur naturelle (aucun flex:1 imposé aux enfants). */ main { flex: 1 1 auto; min-height: 0; - display: flex; - flex-direction: column; -} - -main > * { - flex: 1 1 auto; - min-height: 0; + overflow-y: auto; } diff --git a/frontend/src/app/features/auth/login/login.component.ts b/frontend/src/app/features/auth/login/login.component.ts index 1d6db7e..897ca0f 100644 --- a/frontend/src/app/features/auth/login/login.component.ts +++ b/frontend/src/app/features/auth/login/login.component.ts @@ -56,7 +56,14 @@ export class LoginComponent implements OnInit { }); this.authService.compteExiste().subscribe({ - next: (resultat) => this.compteExiste.set(resultat.existe), + next: (resultat) => { + this.compteExiste.set(resultat.existe); + // Première utilisation (aucun compte) : on va directement à l'inscription + // pour simplifier le parcours, plutôt que d'afficher la connexion. + if (!resultat.existe) { + this.router.navigate(['/register']); + } + }, // En cas d'échec, on conserve la valeur par défaut (masque l'inscription). error: () => this.compteExiste.set(true) }); diff --git a/frontend/src/app/features/bareme/bareme.component.scss b/frontend/src/app/features/bareme/bareme.component.scss index b266631..133771b 100644 --- a/frontend/src/app/features/bareme/bareme.component.scss +++ b/frontend/src/app/features/bareme/bareme.component.scss @@ -1,6 +1,7 @@ .bareme { padding: 1.5rem; max-width: 960px; + margin: 0 auto; } h1 { diff --git a/frontend/src/app/features/carte-trajets/carte-trajets.component.ts b/frontend/src/app/features/carte-trajets/carte-trajets.component.ts index 3b4499a..a374502 100644 --- a/frontend/src/app/features/carte-trajets/carte-trajets.component.ts +++ b/frontend/src/app/features/carte-trajets/carte-trajets.component.ts @@ -158,9 +158,18 @@ export class CarteTrajetsComponent implements AfterViewInit, OnChanges, OnDestro try { if (!this.L) { - this.L = await import('leaflet'); + const mod = await import('leaflet'); + // Leaflet est un module CommonJS : selon l'interop du bundler (dev vs prod), + // l'API peut se trouver sur le module lui-même ou sous `default`. On normalise. + const candidate = mod as unknown as { default?: typeof import('leaflet') }; + const api = candidate.default ?? (mod as typeof import('leaflet')); + // Vérifie que l'API attendue est présente (sinon l'init échouerait silencieusement). + this.L = (api && typeof (api as { map?: unknown }).map === 'function') + ? api + : (mod as typeof import('leaflet')); } - } catch { + } catch (e) { + console.error('Échec du chargement de Leaflet :', e); this.basculerErreur('La librairie de carte n\'a pas pu être chargée.'); return; } @@ -188,7 +197,8 @@ export class CarteTrajetsComponent implements AfterViewInit, OnChanges, OnDestro this.tileLayer.addTo(this.map); this.layerGroup = L.layerGroup().addTo(this.map); - } catch { + } catch (e) { + console.error('Échec de l\'initialisation de la carte Leaflet :', e); this.basculerErreur('La carte n\'a pas pu être initialisée.'); return; } @@ -446,5 +456,15 @@ export class CarteTrajetsComponent implements AfterViewInit, OnChanges, OnDestro this.map.remove(); this.map = null; } + // Filet de sécurité : si une initialisation précédente a échoué APRÈS que Leaflet + // ait marqué le conteneur (`_leaflet_id`) mais AVANT l'assignation de `this.map`, + // le node reste « déjà initialisé » et un nouvel appel à `L.map()` lèverait + // « Map container is already initialized » (Réessayer resterait alors sans effet). + // On nettoie donc explicitement le marqueur et le contenu résiduel du conteneur. + const node = this.mapContainer?.nativeElement as (HTMLElement & { _leaflet_id?: number }) | undefined; + if (node) { + delete node._leaflet_id; + node.innerHTML = ''; + } } } diff --git a/frontend/src/app/features/consultation-jour/consultation-jour.component.scss b/frontend/src/app/features/consultation-jour/consultation-jour.component.scss index 6305073..a11a072 100644 --- a/frontend/src/app/features/consultation-jour/consultation-jour.component.scss +++ b/frontend/src/app/features/consultation-jour/consultation-jour.component.scss @@ -1,7 +1,11 @@ :host { display: block; + // La vue occupe toute la hauteur de
(qui vaut le viewport moins la barre de + // navigation, quelle que soit sa hauteur réelle grâce au layout flex global). + // overflow:hidden : aucune scrollbar de page ; seule la sous-zone liste défile. height: 100%; min-height: 0; + overflow: hidden; } .consultation { diff --git a/frontend/src/app/features/montants-regles/montants-regles.component.scss b/frontend/src/app/features/montants-regles/montants-regles.component.scss index a26d771..3a3813c 100644 --- a/frontend/src/app/features/montants-regles/montants-regles.component.scss +++ b/frontend/src/app/features/montants-regles/montants-regles.component.scss @@ -1,6 +1,7 @@ .montants-regles { padding: 1.5rem; max-width: 720px; + margin: 0 auto; } h1 { diff --git a/frontend/src/app/features/profil/profil.component.scss b/frontend/src/app/features/profil/profil.component.scss index de01dbb..f0803ef 100644 --- a/frontend/src/app/features/profil/profil.component.scss +++ b/frontend/src/app/features/profil/profil.component.scss @@ -1,6 +1,7 @@ .profil { padding: 1.5rem; max-width: 640px; + margin: 0 auto; } h1 { diff --git a/frontend/src/app/features/resume-annuel/resume-annuel.component.scss b/frontend/src/app/features/resume-annuel/resume-annuel.component.scss index d30ed70..c39106d 100644 --- a/frontend/src/app/features/resume-annuel/resume-annuel.component.scss +++ b/frontend/src/app/features/resume-annuel/resume-annuel.component.scss @@ -1,6 +1,7 @@ .resume-annuel { padding: 1.5rem; max-width: 640px; + margin: 0 auto; } h1 { diff --git a/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss b/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss index 31e3eb7..8024a0f 100644 --- a/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss +++ b/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss @@ -1,6 +1,7 @@ .resume-mensuel { padding: 1.5rem; max-width: 900px; + margin: 0 auto; } h1 { diff --git a/frontend/src/app/features/vehicules/vehicules.component.scss b/frontend/src/app/features/vehicules/vehicules.component.scss index faa43a3..2379498 100644 --- a/frontend/src/app/features/vehicules/vehicules.component.scss +++ b/frontend/src/app/features/vehicules/vehicules.component.scss @@ -1,6 +1,7 @@ .vehicules { padding: 1.5rem; max-width: 720px; + margin: 0 auto; } h1 { diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 911aad8..3e8900f 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -1,5 +1,15 @@ /* You can add global styles to this file, and also import other style files */ +/* Reset global minimal : supprime la marge par défaut du body (sinon 100dvh + 8px + provoque une scrollbar de page parasite) et fixe une base de rendu cohérente. */ +html, body { + margin: 0; + padding: 0; +} +*, *::before, *::after { + box-sizing: border-box; +} + /* Styles globaux des éléments de carte injectés par Leaflet (hors encapsulation des composants) : pastilles de marqueurs et contenu des infobulles. */ .carte-marqueur {