Enhance UI with hamburger menu, GPS modal, and search functionality; update styles for better responsiveness
This commit is contained in:
@@ -27,11 +27,37 @@ export class Home implements OnInit {
|
||||
error = signal<string | null>(null);
|
||||
gettingLocation = signal(false);
|
||||
locationDenied = signal(false);
|
||||
|
||||
// Menú hamburguesa
|
||||
menuOpen = signal(false);
|
||||
searchQuery = signal('');
|
||||
searchResults = signal<Municipi[]>([]);
|
||||
searching = signal(false);
|
||||
|
||||
// Modal GPS
|
||||
showGpsModal = signal(false);
|
||||
gpsPermissionAsked = signal(false);
|
||||
|
||||
constructor(private meteocatService: MeteocatService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getCurrentLocation();
|
||||
// Verificar si ya se pidió permiso GPS antes
|
||||
const gpsRejected = localStorage.getItem('gpsRejected');
|
||||
const gpsAsked = localStorage.getItem('gpsAsked');
|
||||
|
||||
if (gpsRejected === 'true') {
|
||||
// Usuario rechazó GPS previamente, cargar datos por defecto
|
||||
this.gpsPermissionAsked.set(true);
|
||||
this.loadWeatherData(this.municipiCodi());
|
||||
} else if (gpsAsked === 'true') {
|
||||
// Ya se pidió permiso antes, intentar obtener ubicación automáticamente
|
||||
this.gpsPermissionAsked.set(true);
|
||||
this.getCurrentLocation();
|
||||
} else {
|
||||
// Primera vez, mostrar modal
|
||||
this.showGpsModal.set(true);
|
||||
this.loadWeatherData(this.municipiCodi()); // Cargar datos por defecto mientras
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentLocation(): void {
|
||||
@@ -51,6 +77,11 @@ export class Home implements OnInit {
|
||||
|
||||
console.log(`Ubicación GPS obtenida: ${lat}, ${lon}`);
|
||||
|
||||
// Marcar que el usuario aceptó GPS
|
||||
localStorage.setItem('gpsAsked', 'true');
|
||||
localStorage.removeItem('gpsRejected');
|
||||
this.locationDenied.set(false);
|
||||
|
||||
// Buscar municipio más cercano
|
||||
this.meteocatService.getMunicipiCercano(lat, lon).subscribe({
|
||||
next: (municipi) => {
|
||||
@@ -70,7 +101,12 @@ export class Home implements OnInit {
|
||||
(error) => {
|
||||
console.warn('Error obteniendo ubicación:', error.message);
|
||||
this.gettingLocation.set(false);
|
||||
this.locationDenied.set(true);
|
||||
|
||||
// Solo mostrar banner si el usuario lo solicitó manualmente
|
||||
if (!this.gpsPermissionAsked()) {
|
||||
this.locationDenied.set(true);
|
||||
}
|
||||
|
||||
// Usar municipio por defecto si se deniega el permiso
|
||||
this.loadWeatherData(this.municipiCodi());
|
||||
},
|
||||
@@ -170,4 +206,90 @@ export class Home implements OnInit {
|
||||
this.locationDenied.set(false);
|
||||
this.getCurrentLocation();
|
||||
}
|
||||
|
||||
acceptGpsModal(): void {
|
||||
this.showGpsModal.set(false);
|
||||
this.gpsPermissionAsked.set(true);
|
||||
localStorage.setItem('gpsAsked', 'true');
|
||||
this.getCurrentLocation();
|
||||
}
|
||||
|
||||
rejectGpsModal(): void {
|
||||
this.showGpsModal.set(false);
|
||||
this.gpsPermissionAsked.set(true);
|
||||
localStorage.setItem('gpsRejected', 'true');
|
||||
localStorage.setItem('gpsAsked', 'true');
|
||||
// Ya tenemos los datos cargados por defecto
|
||||
}
|
||||
|
||||
toggleMenu(): void {
|
||||
this.menuOpen.set(!this.menuOpen());
|
||||
}
|
||||
|
||||
closeMenu(): void {
|
||||
this.menuOpen.set(false);
|
||||
this.searchQuery.set('');
|
||||
this.searchResults.set([]);
|
||||
}
|
||||
|
||||
onSearchInput(event: Event): void {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const query = input.value.trim();
|
||||
this.searchQuery.set(query);
|
||||
|
||||
if (query.length < 2) {
|
||||
this.searchResults.set([]);
|
||||
return;
|
||||
}
|
||||
|
||||
this.searching.set(true);
|
||||
this.meteocatService.searchMunicipis(query).subscribe({
|
||||
next: (results) => {
|
||||
this.searchResults.set(results);
|
||||
this.searching.set(false);
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error searching municipis:', err);
|
||||
this.searching.set(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
selectMunicipi(municipi: Municipi): void {
|
||||
console.log(`Seleccionado municipio: ${municipi.nom} (${municipi.codi})`);
|
||||
this.municipiCodi.set(municipi.codi);
|
||||
this.closeMenu();
|
||||
this.loadWeatherData(municipi.codi);
|
||||
}
|
||||
|
||||
getLastUpdateDate(): string | null {
|
||||
const horaria = this.prediccioHoraria();
|
||||
if (!horaria || horaria.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const lastDate = new Date(horaria[0].dataHora);
|
||||
const now = new Date();
|
||||
const diffMinutes = Math.floor((now.getTime() - lastDate.getTime()) / 60000);
|
||||
|
||||
if (diffMinutes < 60) {
|
||||
return `fa ${diffMinutes} minuts`;
|
||||
} else if (diffMinutes < 1440) {
|
||||
const hours = Math.floor(diffMinutes / 60);
|
||||
return `fa ${hours} ${hours === 1 ? 'hora' : 'hores'}`;
|
||||
} else {
|
||||
const options: Intl.DateTimeFormatOptions = {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
};
|
||||
return lastDate.toLocaleDateString('ca-ES', options);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error calculating last update date:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user