diff --git a/backend/__pycache__/seed.cpython-312.pyc b/backend/__pycache__/seed.cpython-312.pyc index de7faa2..f8ae05c 100644 Binary files a/backend/__pycache__/seed.cpython-312.pyc and b/backend/__pycache__/seed.cpython-312.pyc differ diff --git a/src/app/admin/admin-stats-dashboard.component.ts b/src/app/admin/admin-stats-dashboard.component.ts index 6c42012..daaebaf 100644 --- a/src/app/admin/admin-stats-dashboard.component.ts +++ b/src/app/admin/admin-stats-dashboard.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject, AfterViewInit, OnDestroy, ViewChild, ElementRef, NgZone } from '@angular/core'; +import { Component, OnInit, inject, AfterViewChecked, OnDestroy, ViewChild, ElementRef, NgZone } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Chart, registerables } from 'chart.js'; @@ -25,7 +25,7 @@ Chart.register(...registerables); templateUrl: './admin-stats-dashboard.component.html', styleUrl: './admin-stats-dashboard.component.scss', }) -export class AdminStatsDashboardComponent implements OnInit, AfterViewInit, OnDestroy { +export class AdminStatsDashboardComponent implements OnInit, AfterViewChecked, OnDestroy { private readonly statsService: StatsService = inject(StatsService); private readonly ngZone = inject(NgZone); @@ -70,13 +70,29 @@ export class AdminStatsDashboardComponent implements OnInit, AfterViewInit, OnDe // ── Leaflet ───────────────────────────────────────────── private map: L.Map | null = null; private markersLayer: L.LayerGroup | null = null; + private mapInitialized = false; ngOnInit(): void { this.loadAll(); } - ngAfterViewInit(): void { - // Initialize Leaflet map + ngAfterViewChecked(): void { + // The map container is inside an @else block gated by loading=true. + // ngAfterViewInit fires before loading completes, so the element + // doesn't exist yet. ngAfterViewChecked detects when it appears. + if (this.mapInitialized) return; + if (!this.mapContainerRef) return; + + this.mapInitialized = true; + this.ngZone.runOutsideAngular(() => { + // Defer one frame so the browser has laid out the container + requestAnimationFrame(() => { + requestAnimationFrame(() => this._initMap()); + }); + }); + } + + private _initMap(): void { this.map = L.map(this.mapContainerRef.nativeElement, { center: [20, 0], zoom: 2, @@ -88,6 +104,12 @@ export class AdminStatsDashboardComponent implements OnInit, AfterViewInit, OnDe attribution: '© OpenStreetMap contributors © CARTO', maxZoom: 19, }).addTo(this.map); + + // Ensure Leaflet uses the correct container size + this.map.invalidateSize(); + + // Data may have loaded in ngOnInit before the view was ready + this._updateMapMarkers(); } ngOnDestroy(): void {