app mobile allarmi prima
This commit is contained in:
212
lib/main.dart
Normal file
212
lib/main.dart
Normal file
@@ -0,0 +1,212 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'utils/theme.dart';
|
||||
import 'utils/constants.dart';
|
||||
import 'services/auth_service.dart';
|
||||
import 'services/api_service.dart';
|
||||
import 'services/notification_service.dart';
|
||||
import 'screens/login_screen.dart';
|
||||
import 'screens/main_screen.dart';
|
||||
import 'screens/allarme_detail_screen.dart';
|
||||
|
||||
// GlobalKey per accedere al Navigator
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// Inizializza Firebase
|
||||
await Firebase.initializeApp();
|
||||
|
||||
// Inizializza servizio notifiche
|
||||
await NotificationService().initialize();
|
||||
|
||||
runApp(const TerrainMonitorApp());
|
||||
}
|
||||
|
||||
class TerrainMonitorApp extends StatefulWidget {
|
||||
const TerrainMonitorApp({super.key});
|
||||
|
||||
@override
|
||||
State<TerrainMonitorApp> createState() => _TerrainMonitorAppState();
|
||||
}
|
||||
|
||||
class _TerrainMonitorAppState extends State<TerrainMonitorApp> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_setupNotificationListener();
|
||||
}
|
||||
|
||||
void _setupNotificationListener() {
|
||||
// Listener per tap su notifiche
|
||||
NotificationService().onMessageTap.listen((RemoteMessage message) {
|
||||
_handleNotificationTap(message);
|
||||
});
|
||||
}
|
||||
|
||||
void _handleNotificationTap(RemoteMessage message) async {
|
||||
final data = message.data;
|
||||
print('Gestione tap notifica: $data');
|
||||
|
||||
// Naviga alla schermata di dettaglio allarme
|
||||
if (data.containsKey('alarm_id')) {
|
||||
final allarmeId = int.tryParse(data['alarm_id'] ?? '');
|
||||
if (allarmeId != null) {
|
||||
try {
|
||||
// Fetch allarme dal server
|
||||
final apiService = ApiService();
|
||||
final allarme = await apiService.getAllarme(allarmeId);
|
||||
|
||||
navigatorKey.currentState?.push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AllarmeDetailScreen(allarme: allarme),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
print('Errore caricamento allarme: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
navigatorKey: navigatorKey,
|
||||
title: AppConstants.appName,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: ThemeMode.light,
|
||||
home: const SplashScreen(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SplashScreen extends StatefulWidget {
|
||||
const SplashScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SplashScreen> createState() => _SplashScreenState();
|
||||
}
|
||||
|
||||
class _SplashScreenState extends State<SplashScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkAuth();
|
||||
}
|
||||
|
||||
Future<void> _checkAuth() async {
|
||||
// Attendi un momento per mostrare lo splash
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
|
||||
// Prova auto-login
|
||||
final authService = AuthService();
|
||||
final isAuthenticated = await authService.autoLogin();
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
isAuthenticated ? const MainScreen() : const LoginScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.primaryGradient,
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Logo
|
||||
Container(
|
||||
width: 150,
|
||||
height: 150,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 30,
|
||||
offset: const Offset(0, 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.terrain,
|
||||
size: 70,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'ASE',
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSizes.paddingXL),
|
||||
|
||||
// Titolo
|
||||
const Text(
|
||||
AppConstants.appName,
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSizes.paddingS),
|
||||
|
||||
// Sottotitolo
|
||||
Text(
|
||||
AppConstants.companyName,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white.withOpacity(0.9),
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSizes.paddingXL * 2),
|
||||
|
||||
// Loading indicator
|
||||
const CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
||||
),
|
||||
const SizedBox(height: AppSizes.paddingM),
|
||||
|
||||
Text(
|
||||
'Caricamento...',
|
||||
style: TextStyle(
|
||||
color: Colors.white.withOpacity(0.8),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user