 3fab69cb00
			
		
	
	3fab69cb00
	
	
	
		
			
			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.).
		
	
		
			
				
	
	
		
			196 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:em2rp/providers/local_user_provider.dart';
 | |
| import 'package:em2rp/utils/colors.dart';
 | |
| import 'package:em2rp/views/calendar_page.dart';
 | |
| import 'package:em2rp/views/my_account_page.dart';
 | |
| import 'package:em2rp/views/user_management_page.dart';
 | |
| import 'package:em2rp/views/data_management_page.dart';
 | |
| import 'package:em2rp/views/equipment_management_page.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| import 'package:em2rp/views/widgets/image/profile_picture.dart';
 | |
| import 'package:provider/provider.dart';
 | |
| import 'package:em2rp/utils/permission_gate.dart';
 | |
| 
 | |
| class MainDrawer extends StatelessWidget {
 | |
|   final String currentPage;
 | |
| 
 | |
|   const MainDrawer({
 | |
|     super.key,
 | |
|     required this.currentPage,
 | |
|   });
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return Consumer<LocalUserProvider>(
 | |
|       builder: (context, userProvider, child) {
 | |
|         final hasUser = userProvider.currentUser != null;
 | |
| 
 | |
|         return Drawer(
 | |
|           child: ListView(
 | |
|             padding: EdgeInsets.zero,
 | |
|             children: <Widget>[
 | |
|               DrawerHeader(
 | |
|                 decoration: BoxDecoration(
 | |
|                   image: DecorationImage(
 | |
|                     image: const AssetImage('assets/EM2_NsurB.jpg'),
 | |
|                     fit: BoxFit.cover,
 | |
|                     colorFilter: ColorFilter.mode(
 | |
|                       AppColors.noir.withAlpha(102),
 | |
|                       BlendMode.darken,
 | |
|                     ),
 | |
|                   ),
 | |
|                 ),
 | |
|                 child: Container(
 | |
|                   padding: const EdgeInsets.all(16.0),
 | |
|                   alignment: Alignment.bottomLeft,
 | |
|                   child: SingleChildScrollView(
 | |
|                     child: Column(
 | |
|                       crossAxisAlignment: CrossAxisAlignment.start,
 | |
|                       mainAxisAlignment: MainAxisAlignment.end,
 | |
|                       children: [
 | |
|                         if (hasUser)
 | |
|                           ProfilePictureWidget(
 | |
|                             userId: userProvider.currentUser!.uid,
 | |
|                             radius: 30,
 | |
|                           )
 | |
|                         else
 | |
|                           const CircleAvatar(
 | |
|                             radius: 30,
 | |
|                             child: Icon(Icons.account_circle, size: 45),
 | |
|                           ),
 | |
|                         const SizedBox(height: 8),
 | |
|                         Text(
 | |
|                           hasUser
 | |
|                               ? 'Bonjour, ${userProvider.currentUser!.firstName}'
 | |
|                               : 'Bonjour, Utilisateur',
 | |
|                           style: const TextStyle(
 | |
|                             color: AppColors.blanc,
 | |
|                             fontSize: 18,
 | |
|                             fontWeight: FontWeight.bold,
 | |
|                             shadows: [
 | |
|                               Shadow(
 | |
|                                 blurRadius: 3.0,
 | |
|                                 color: AppColors.noir,
 | |
|                                 offset: Offset(1.0, 1.0),
 | |
|                               ),
 | |
|                             ],
 | |
|                           ),
 | |
|                         ),
 | |
|                       ],
 | |
|                     ),
 | |
|                   ),
 | |
|                 ),
 | |
|               ),
 | |
|               ListTile(
 | |
|                 leading: const Icon(Icons.calendar_today),
 | |
|                 title: const Text('Calendrier'),
 | |
|                 selected: currentPage == '/calendar',
 | |
|                 selectedColor: AppColors.rouge,
 | |
|                 onTap: () {
 | |
|                   Navigator.pop(context);
 | |
|                   Navigator.pushReplacement(
 | |
|                     context,
 | |
|                     MaterialPageRoute(
 | |
|                         builder: (context) => const CalendarPage()),
 | |
|                   );
 | |
|                 },
 | |
|               ),
 | |
|               PermissionGate(
 | |
|                 requiredPermissions: const ['view_equipment'],
 | |
|                 child: ListTile(
 | |
|                   leading: const Icon(Icons.inventory),
 | |
|                   title: const Text('Gestion du Matériel'),
 | |
|                   selected: currentPage == '/equipment_management',
 | |
|                   selectedColor: AppColors.rouge,
 | |
|                   onTap: () {
 | |
|                     Navigator.pop(context);
 | |
|                     Navigator.pushReplacement(
 | |
|                       context,
 | |
|                       MaterialPageRoute(
 | |
|                           builder: (context) =>
 | |
|                           const EquipmentManagementPage()),
 | |
|                     );
 | |
|                   },
 | |
|                 ),
 | |
|               ),
 | |
|               PermissionGate(
 | |
|                 requiredPermissions: const ['view_equipment'],
 | |
|                 child: ListTile(
 | |
|                   leading: const Icon(Icons.inventory_2),
 | |
|                   title: const Text('Containers'),
 | |
|                   selected: currentPage == '/container_management',
 | |
|                   selectedColor: AppColors.rouge,
 | |
|                   onTap: () {
 | |
|                     Navigator.pop(context);
 | |
|                     Navigator.pushNamed(context, '/container_management');
 | |
|                   },
 | |
|                 ),
 | |
|               ),
 | |
|               ExpansionTileTheme(
 | |
|                 data: const ExpansionTileThemeData(
 | |
|                   iconColor: AppColors.noir,
 | |
|                   collapsedIconColor: AppColors.noir,
 | |
|                 ),
 | |
|                 child: ExpansionTile(
 | |
|                   leading: const Icon(Icons.settings),
 | |
|                   title: const Text('Paramètres'),
 | |
|                   children: <Widget>[
 | |
|                     ListTile(
 | |
|                       leading: const Icon(Icons.account_circle),
 | |
|                       title: const Text('Mon Compte'),
 | |
|                       selected: currentPage == '/my_account',
 | |
|                       selectedColor: AppColors.rouge,
 | |
|                       onTap: () {
 | |
|                         Navigator.pop(context);
 | |
|                         Navigator.pushReplacement(
 | |
|                           context,
 | |
|                           MaterialPageRoute(
 | |
|                               builder: (context) => const MyAccountPage()),
 | |
|                         );
 | |
|                       },
 | |
|                     ),
 | |
|                     PermissionGate(
 | |
|                       requiredPermissions: const ['view_all_users'],
 | |
|                       child: ListTile(
 | |
|                         leading: const Icon(Icons.group),
 | |
|                         title: const Text('Gestion des Utilisateurs'),
 | |
|                         selected: currentPage == '/user_management',
 | |
|                         selectedColor: AppColors.rouge,
 | |
|                         onTap: () {
 | |
|                           Navigator.pop(context);
 | |
|                           Navigator.pushReplacement(
 | |
|                             context,
 | |
|                             MaterialPageRoute(
 | |
|                                 builder: (context) =>
 | |
|                                     const UserManagementPage()),
 | |
|                           );
 | |
|                         },
 | |
|                       ),
 | |
|                     ),
 | |
|                     PermissionGate(
 | |
|                       requiredPermissions: const ['edit_data'],
 | |
|                       child:  ListTile(
 | |
|                         leading: const Icon(Icons.data_usage),
 | |
|                         title: const Text('Gestion des Données'),
 | |
|                         selected: currentPage == '/data_management',
 | |
|                         selectedColor: AppColors.rouge,
 | |
|                         onTap: () {
 | |
|                           Navigator.pop(context);
 | |
|                           Navigator.pushReplacement(
 | |
|                             context,
 | |
|                             MaterialPageRoute(
 | |
|                                 builder: (context) => const DataManagementPage()),
 | |
|                           );
 | |
|                         },
 | |
|                       ),
 | |
|                     ),
 | |
|                   ],
 | |
|                 ),
 | |
|               ),
 | |
|             ],
 | |
|           ),
 | |
|         );
 | |
|       },
 | |
|     );
 | |
|   }
 | |
| }
 |