 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.).
		
	
		
			
				
	
	
		
			178 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:flutter/material.dart';
 | |
| import 'package:provider/provider.dart';
 | |
| import 'package:em2rp/utils/colors.dart';
 | |
| import 'package:em2rp/models/container_model.dart';
 | |
| import 'package:em2rp/providers/container_provider.dart';
 | |
| 
 | |
| /// Widget pour afficher les containers parents d'un équipement
 | |
| class EquipmentParentContainers extends StatefulWidget {
 | |
|   final List<String> parentBoxIds;
 | |
| 
 | |
|   const EquipmentParentContainers({
 | |
|     super.key,
 | |
|     required this.parentBoxIds,
 | |
|   });
 | |
| 
 | |
|   @override
 | |
|   State<EquipmentParentContainers> createState() => _EquipmentParentContainersState();
 | |
| }
 | |
| 
 | |
| class _EquipmentParentContainersState extends State<EquipmentParentContainers> {
 | |
|   List<ContainerModel> _containers = [];
 | |
|   bool _isLoading = true;
 | |
| 
 | |
|   @override
 | |
|   void initState() {
 | |
|     super.initState();
 | |
|     _loadContainers();
 | |
|   }
 | |
| 
 | |
|   Future<void> _loadContainers() async {
 | |
|     if (widget.parentBoxIds.isEmpty) {
 | |
|       setState(() {
 | |
|         _isLoading = false;
 | |
|       });
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     setState(() {
 | |
|       _isLoading = true;
 | |
|     });
 | |
| 
 | |
|     try {
 | |
|       final containerProvider = context.read<ContainerProvider>();
 | |
|       final List<ContainerModel> containers = [];
 | |
| 
 | |
|       for (final boxId in widget.parentBoxIds) {
 | |
|         final container = await containerProvider.getContainerById(boxId);
 | |
|         if (container != null) {
 | |
|           containers.add(container);
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       setState(() {
 | |
|         _containers = containers;
 | |
|         _isLoading = false;
 | |
|       });
 | |
|     } catch (e) {
 | |
|       setState(() {
 | |
|         _isLoading = false;
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     if (widget.parentBoxIds.isEmpty) {
 | |
|       return const SizedBox.shrink();
 | |
|     }
 | |
| 
 | |
|     return Card(
 | |
|       elevation: 2,
 | |
|       child: Padding(
 | |
|         padding: const EdgeInsets.all(20),
 | |
|         child: Column(
 | |
|           crossAxisAlignment: CrossAxisAlignment.start,
 | |
|           children: [
 | |
|             Row(
 | |
|               children: [
 | |
|                 const Icon(Icons.inventory_2, color: AppColors.rouge, size: 20),
 | |
|                 const SizedBox(width: 8),
 | |
|                 const Text(
 | |
|                   'Containers',
 | |
|                   style: TextStyle(
 | |
|                     fontSize: 18,
 | |
|                     fontWeight: FontWeight.bold,
 | |
|                   ),
 | |
|                 ),
 | |
|               ],
 | |
|             ),
 | |
|             const Divider(height: 24),
 | |
|             if (_isLoading)
 | |
|               const Center(
 | |
|                 child: Padding(
 | |
|                   padding: EdgeInsets.all(16.0),
 | |
|                   child: CircularProgressIndicator(),
 | |
|                 ),
 | |
|               )
 | |
|             else if (_containers.isEmpty)
 | |
|               const Center(
 | |
|                 child: Padding(
 | |
|                   padding: EdgeInsets.all(16.0),
 | |
|                   child: Text(
 | |
|                     'Cet équipement n\'est dans aucun container',
 | |
|                     style: TextStyle(color: Colors.grey),
 | |
|                   ),
 | |
|                 ),
 | |
|               )
 | |
|             else
 | |
|               ListView.separated(
 | |
|                 shrinkWrap: true,
 | |
|                 physics: const NeverScrollableScrollPhysics(),
 | |
|                 itemCount: _containers.length,
 | |
|                 separatorBuilder: (context, index) => const Divider(height: 1),
 | |
|                 itemBuilder: (context, index) {
 | |
|                   final container = _containers[index];
 | |
|                   return _buildContainerTile(container);
 | |
|                 },
 | |
|               ),
 | |
|           ],
 | |
|         ),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   Widget _buildContainerTile(ContainerModel container) {
 | |
|     return ListTile(
 | |
|       contentPadding: const EdgeInsets.symmetric(vertical: 8),
 | |
|       leading: Icon(
 | |
|         _getTypeIcon(container.type),
 | |
|         color: AppColors.rouge,
 | |
|         size: 32,
 | |
|       ),
 | |
|       title: Text(
 | |
|         container.id,
 | |
|         style: const TextStyle(fontWeight: FontWeight.bold),
 | |
|       ),
 | |
|       subtitle: Column(
 | |
|         crossAxisAlignment: CrossAxisAlignment.start,
 | |
|         children: [
 | |
|           Text(container.name),
 | |
|           const SizedBox(height: 4),
 | |
|           Text(
 | |
|             containerTypeLabel(container.type),
 | |
|             style: TextStyle(
 | |
|               fontSize: 12,
 | |
|               color: Colors.grey.shade600,
 | |
|             ),
 | |
|           ),
 | |
|         ],
 | |
|       ),
 | |
|       trailing: const Icon(Icons.chevron_right),
 | |
|       onTap: () {
 | |
|         Navigator.pushNamed(
 | |
|           context,
 | |
|           '/container_detail',
 | |
|           arguments: container,
 | |
|         );
 | |
|       },
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   IconData _getTypeIcon(ContainerType type) {
 | |
|     switch (type) {
 | |
|       case ContainerType.flightCase:
 | |
|         return Icons.work;
 | |
|       case ContainerType.pelicase:
 | |
|         return Icons.work_outline;
 | |
|       case ContainerType.bag:
 | |
|         return Icons.shopping_bag;
 | |
|       case ContainerType.openCrate:
 | |
|         return Icons.inventory_2;
 | |
|       case ContainerType.toolbox:
 | |
|         return Icons.handyman;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 |