Files

115 lines
3.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/theme/app_theme.dart';
import '../../core/widgets/app_widgets.dart';
import '../notifications/notification_service.dart';
import '../alerts/alerts_provider.dart';
import 'citizen_home_screen.dart';
import '../alerts/alerts_screen.dart';
import 'house_screen.dart';
import '../profile/profile_screen.dart';
class MainShell extends ConsumerStatefulWidget {
const MainShell({super.key});
@override
ConsumerState<MainShell> createState() => _MainShellState();
}
class _MainShellState extends ConsumerState<MainShell> {
int _currentIndex = 0;
static const List<Widget> _screens = [
CitizenHomeScreen(),
AlertsScreen(),
MyHouseScreen(),
ProfileScreen(),
];
@override
void initState() {
super.initState();
NotificationService.onFcmMessage.addListener(_onGlobalPush);
}
@override
void dispose() {
NotificationService.onFcmMessage.removeListener(_onGlobalPush);
super.dispose();
}
void _onGlobalPush() {
final msg = NotificationService.onFcmMessage.lastMessage;
if (msg?.notification != null) {
final title = msg!.notification!.title ?? 'Nueva Alerta';
final body = msg.notification!.body ?? '';
ref.read(alertsProvider.notifier).addAlert(title, body);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: AppTheme.primaryDark,
behavior: SnackBarBehavior.floating,
margin: const EdgeInsets.all(16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
duration: const Duration(seconds: 5),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.notifications_active,
color: Colors.white,
size: 20,
),
const SizedBox(width: 8),
Expanded(
child: Text(
title,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
),
const SizedBox(height: 4),
Text(
body,
style: const TextStyle(color: Colors.white70, fontSize: 13),
),
],
),
action: SnackBarAction(
label: 'VER',
textColor: AppTheme.primaryLight,
onPressed: () => setState(() => _currentIndex = 1),
),
),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Renderiza únicamente la pantalla activa para desmontar vistas nativas
// (p. ej. FlutterMap) cuando la pestaña no está activa, evitando que
// queden superpuestas sobre la UI de otras pestañas.
body: _screens[_currentIndex],
bottomNavigationBar: AppBottomNav(
currentIndex: _currentIndex,
onTap: (i) => setState(() => _currentIndex = i),
),
);
}
}