Files
EM2_ERP/em2rp/lib/main.dart
ElPoyo 3fab69cb00 feat: Gestion complète des containers et refactorisation du matériel
Ajout de la gestion des containers (création, édition, suppression, affichage des détails).
Introduction d'un système de génération de QR codes unifié et d'un mode de sélection multiple.

**Features:**
- **Gestion des Containers :**
    - Nouvelle page de gestion des containers (`container_management_page.dart`) avec recherche et filtres.
    - Formulaire de création/édition de containers (`container_form_page.dart`) avec génération d'ID automatique.
    - Page de détails d'un container (`container_detail_page.dart`) affichant son contenu et ses caractéristiques.
    - Ajout des routes et du provider (`ContainerProvider`) nécessaires.
- **Modèle de Données :**
    - Ajout du `ContainerModel` pour représenter les boîtes, flight cases, etc.
    - Le modèle `EquipmentModel` a été enrichi avec des caractéristiques physiques (poids, dimensions).
- **QR Codes :**
    - Nouveau service unifié (`UnifiedPDFGeneratorService`) pour générer des PDFs de QR codes pour n'importe quelle entité.
    - Services `PDFGeneratorService` et `ContainerPDFGeneratorService` transformés en wrappers pour maintenir la compatibilité.
    - Amélioration de la performance de la génération de QR codes en masse.
- **Interface Utilisateur (UI/UX) :**
    - Nouvelle page de détails pour le matériel (`equipment_detail_page.dart`).
    - Ajout d'un `SelectionModeMixin` pour gérer la sélection multiple dans les pages de gestion.
    - Dialogues réutilisables pour l'affichage de QR codes (`QRCodeDialog`) et la sélection de format d'impression (`QRCodeFormatSelectorDialog`).
    - Ajout d'un bouton "Gérer les boîtes" sur la page de gestion du matériel.

**Refactorisation :**
- L' `IdGenerator` a été déplacé dans le répertoire `utils` et étendu pour gérer les containers.
- Mise à jour de nombreuses dépendances `pubspec.yaml` vers des versions plus récentes.
- Séparation de la logique d'affichage des containers et du matériel dans des widgets dédiés (`ContainerHeaderCard`, `EquipmentParentContainers`, etc.).
2025-10-29 10:57:42 +01:00

209 lines
6.9 KiB
Dart

import 'package:em2rp/providers/users_provider.dart';
import 'package:em2rp/providers/event_provider.dart';
import 'package:em2rp/providers/equipment_provider.dart';
import 'package:em2rp/providers/container_provider.dart';
import 'package:em2rp/providers/maintenance_provider.dart';
import 'package:em2rp/providers/alert_provider.dart';
import 'package:em2rp/utils/auth_guard_widget.dart';
import 'package:em2rp/views/calendar_page.dart';
import 'package:em2rp/views/login_page.dart';
import 'package:em2rp/views/equipment_management_page.dart';
import 'package:em2rp/views/container_management_page.dart';
import 'package:em2rp/views/container_form_page.dart';
import 'package:em2rp/views/container_detail_page.dart';
import 'package:em2rp/models/container_model.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'utils/colors.dart';
import 'views/my_account_page.dart';
import 'views/user_management_page.dart';
import 'package:provider/provider.dart';
import 'providers/local_user_provider.dart';
import 'services/user_service.dart';
import 'views/reset_password_page.dart';
import 'config/env.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await FirebaseAuth.instance.setPersistence(Persistence.LOCAL);
runApp(
MultiProvider(
providers: [
// Injection du service UserService
Provider<UserService>(create: (_) => UserService()),
// LocalUserProvider pour la gestion de l'authentification
ChangeNotifierProvider<LocalUserProvider>(
create: (context) => LocalUserProvider()),
// Injection des Providers en utilisant UserService
ChangeNotifierProvider<UsersProvider>(
create: (context) => UsersProvider(context.read<UserService>()),
),
// EventProvider pour la gestion des événements
ChangeNotifierProvider<EventProvider>(
create: (context) => EventProvider(),
),
// Providers pour la gestion du matériel
ChangeNotifierProvider<EquipmentProvider>(
create: (context) => EquipmentProvider(),
),
ChangeNotifierProvider<ContainerProvider>(
create: (context) => ContainerProvider(),
),
ChangeNotifierProvider<MaintenanceProvider>(
create: (context) => MaintenanceProvider(),
),
ChangeNotifierProvider<AlertProvider>(
create: (context) => AlertProvider(),
),
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'EM2 ERP',
theme: ThemeData(
primarySwatch: Colors.red,
primaryColor: AppColors.noir,
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: AppColors.rouge),
textTheme: const TextTheme(
bodyMedium: TextStyle(color: AppColors.noir),
),
inputDecorationTheme: const InputDecorationTheme(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: AppColors.noir),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: AppColors.gris),
),
labelStyle: TextStyle(color: AppColors.noir),
hintStyle: TextStyle(color: AppColors.gris),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
foregroundColor: AppColors.blanc,
backgroundColor: AppColors.noir,
),
),
),
locale: const Locale('fr', 'FR'),
supportedLocales: const [
Locale('fr', 'FR'),
],
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
home: const AutoLoginWrapper(),
routes: {
'/login': (context) => const LoginPage(),
'/calendar': (context) => const AuthGuard(child: CalendarPage()),
'/my_account': (context) => const AuthGuard(child: MyAccountPage()),
'/user_management': (context) => const AuthGuard(
requiredPermission: "view_all_users", child: UserManagementPage()),
'/reset_password': (context) {
final args = ModalRoute.of(context)!.settings.arguments
as Map<String, dynamic>;
return ResetPasswordPage(
email: args['email'] as String,
actionCode: args['actionCode'] as String,
);
},
'/equipment_management': (context) => const AuthGuard(
requiredPermission: "view_equipment",
child: EquipmentManagementPage()),
'/container_management': (context) => const AuthGuard(
requiredPermission: "view_equipment",
child: ContainerManagementPage()),
'/container_form': (context) {
final args = ModalRoute.of(context)?.settings.arguments;
return AuthGuard(
requiredPermission: "manage_equipment",
child: ContainerFormPage(
container: args as ContainerModel?,
),
);
},
'/container_detail': (context) {
final container = ModalRoute.of(context)!.settings.arguments as ContainerModel;
return AuthGuard(
requiredPermission: "view_equipment",
child: ContainerDetailPage(container: container),
);
},
},
);
}
}
class AutoLoginWrapper extends StatefulWidget {
const AutoLoginWrapper({super.key});
@override
State<AutoLoginWrapper> createState() => _AutoLoginWrapperState();
}
class _AutoLoginWrapperState extends State<AutoLoginWrapper> {
@override
void initState() {
super.initState();
_autoLogin();
}
Future<void> _autoLogin() async {
try {
final localAuthProvider =
Provider.of<LocalUserProvider>(context, listen: false);
// Vérifier si l'utilisateur est déjà connecté
if (FirebaseAuth.instance.currentUser == null && Env.isDevelopment) {
// Connexion automatique en mode développement
await localAuthProvider.signInWithEmailAndPassword(
Env.devAdminEmail,
Env.devAdminPassword,
);
}
// Charger les données utilisateur
await localAuthProvider.loadUserData();
if (mounted) {
Navigator.of(context).pushReplacementNamed('/calendar');
}
} catch (e) {
print('Auto login failed: $e');
if (mounted) {
Navigator.of(context).pushReplacementNamed('/login');
}
}
}
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
}