692 lines
28 KiB
Dart
692 lines
28 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:provider/provider.dart';
|
||
import 'package:em2rp/models/equipment_model.dart';
|
||
import 'package:em2rp/providers/equipment_provider.dart';
|
||
import 'package:em2rp/providers/local_user_provider.dart';
|
||
import 'package:em2rp/services/equipment_service.dart';
|
||
import 'package:em2rp/utils/colors.dart';
|
||
import 'package:em2rp/views/widgets/nav/custom_app_bar.dart';
|
||
import 'package:intl/intl.dart';
|
||
import 'package:em2rp/views/equipment_form/brand_model_selector.dart';
|
||
import 'package:em2rp/views/equipment_form/id_generator.dart';
|
||
|
||
class EquipmentFormPage extends StatefulWidget {
|
||
final EquipmentModel? equipment;
|
||
|
||
const EquipmentFormPage({super.key, this.equipment});
|
||
|
||
@override
|
||
State<EquipmentFormPage> createState() => _EquipmentFormPageState();
|
||
}
|
||
|
||
class _EquipmentFormPageState extends State<EquipmentFormPage> {
|
||
final _formKey = GlobalKey<FormState>();
|
||
final EquipmentService _equipmentService = EquipmentService();
|
||
|
||
// Controllers
|
||
final TextEditingController _identifierController = TextEditingController();
|
||
final TextEditingController _brandController = TextEditingController();
|
||
final TextEditingController _modelController = TextEditingController();
|
||
final TextEditingController _purchasePriceController = TextEditingController();
|
||
final TextEditingController _rentalPriceController = TextEditingController();
|
||
final TextEditingController _totalQuantityController = TextEditingController();
|
||
final TextEditingController _criticalThresholdController = TextEditingController();
|
||
final TextEditingController _notesController = TextEditingController();
|
||
final TextEditingController _quantityToAddController = TextEditingController(text: '1');
|
||
|
||
// State variables
|
||
EquipmentCategory _selectedCategory = EquipmentCategory.other;
|
||
EquipmentStatus _selectedStatus = EquipmentStatus.available;
|
||
DateTime? _purchaseDate;
|
||
DateTime? _lastMaintenanceDate;
|
||
DateTime? _nextMaintenanceDate;
|
||
List<String> _selectedParentBoxIds = [];
|
||
List<EquipmentModel> _availableBoxes = [];
|
||
bool _isLoading = false;
|
||
bool _isLoadingBoxes = true;
|
||
bool _addMultiple = false;
|
||
String? _selectedBrand;
|
||
List<String> _filteredModels = [];
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_loadAvailableBoxes();
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
final provider = Provider.of<EquipmentProvider>(context, listen: false);
|
||
provider.loadBrands();
|
||
provider.loadModels();
|
||
});
|
||
if (widget.equipment != null) {
|
||
_populateFields();
|
||
}
|
||
}
|
||
|
||
void _populateFields() {
|
||
final equipment = widget.equipment!;
|
||
_identifierController.text = equipment.id;
|
||
_brandController.text = equipment.brand ?? '';
|
||
_selectedBrand = equipment.brand;
|
||
_modelController.text = equipment.model ?? '';
|
||
_selectedCategory = equipment.category;
|
||
_selectedStatus = equipment.status;
|
||
_purchasePriceController.text = equipment.purchasePrice?.toStringAsFixed(2) ?? '';
|
||
_rentalPriceController.text = equipment.rentalPrice?.toStringAsFixed(2) ?? '';
|
||
_totalQuantityController.text = equipment.totalQuantity?.toString() ?? '';
|
||
_criticalThresholdController.text = equipment.criticalThreshold?.toString() ?? '';
|
||
_purchaseDate = equipment.purchaseDate;
|
||
_lastMaintenanceDate = equipment.lastMaintenanceDate;
|
||
_nextMaintenanceDate = equipment.nextMaintenanceDate;
|
||
_selectedParentBoxIds = List.from(equipment.parentBoxIds);
|
||
_notesController.text = equipment.notes ?? '';
|
||
|
||
if (_selectedBrand != null && _selectedBrand!.isNotEmpty) {
|
||
_loadFilteredModels(_selectedBrand!);
|
||
}
|
||
}
|
||
|
||
Future<void> _loadAvailableBoxes() async {
|
||
try {
|
||
final boxes = await _equipmentService.getBoxes();
|
||
setState(() {
|
||
_availableBoxes = boxes;
|
||
_isLoadingBoxes = false;
|
||
});
|
||
} catch (e) {
|
||
setState(() {
|
||
_isLoadingBoxes = false;
|
||
});
|
||
if (mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(content: Text('Erreur lors du chargement des boîtes : $e')),
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
Future<void> _loadFilteredModels(String brand) async {
|
||
try {
|
||
final equipmentProvider = Provider.of<EquipmentProvider>(context, listen: false);
|
||
final models = await equipmentProvider.loadModelsByBrand(brand);
|
||
setState(() {
|
||
_filteredModels = models;
|
||
});
|
||
} catch (e) {
|
||
setState(() {
|
||
_filteredModels = [];
|
||
});
|
||
}
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_identifierController.dispose();
|
||
_brandController.dispose();
|
||
_modelController.dispose();
|
||
_purchasePriceController.dispose();
|
||
_rentalPriceController.dispose();
|
||
_totalQuantityController.dispose();
|
||
_criticalThresholdController.dispose();
|
||
_notesController.dispose();
|
||
_quantityToAddController.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
bool get _isConsumable => _selectedCategory == EquipmentCategory.consumable || _selectedCategory == EquipmentCategory.cable;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final localUserProvider = Provider.of<LocalUserProvider>(context);
|
||
final hasManagePermission = localUserProvider.hasPermission('manage_equipment');
|
||
final isEditing = widget.equipment != null;
|
||
|
||
return Scaffold(
|
||
appBar: CustomAppBar(
|
||
title: isEditing ? 'Modifier l\'équipement' : 'Nouvel équipement',
|
||
),
|
||
body: _isLoading
|
||
? const Center(child: CircularProgressIndicator())
|
||
: SingleChildScrollView(
|
||
padding: const EdgeInsets.all(24.0),
|
||
child: Form(
|
||
key: _formKey,
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
children: [
|
||
// Identifiant (généré ou saisi)
|
||
TextFormField(
|
||
controller: _identifierController,
|
||
decoration: InputDecoration(
|
||
labelText: 'Identifiant *',
|
||
border: const OutlineInputBorder(),
|
||
prefixIcon: const Icon(Icons.tag),
|
||
hintText: isEditing ? null : 'Laissez vide pour générer automatiquement',
|
||
helperText: isEditing ? 'Non modifiable' : 'Format auto: {Marque4Chars}_{Modèle}',
|
||
),
|
||
enabled: !isEditing,
|
||
),
|
||
const SizedBox(height: 16),
|
||
|
||
// Case à cocher "Ajouter plusieurs" (uniquement en mode création)
|
||
if (!isEditing) ...[
|
||
Row(
|
||
children: [
|
||
Expanded(
|
||
flex: 2,
|
||
child: CheckboxListTile(
|
||
title: const Text('Ajouter plusieurs équipements'),
|
||
subtitle: const Text('Créer plusieurs équipements numérotés'),
|
||
value: _addMultiple,
|
||
contentPadding: EdgeInsets.zero,
|
||
onChanged: (bool? value) {
|
||
setState(() {
|
||
_addMultiple = value ?? false;
|
||
});
|
||
},
|
||
),
|
||
),
|
||
if (_addMultiple) ...[
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
child: TextFormField(
|
||
controller: _quantityToAddController,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Quantité ou range',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.plus_one),
|
||
hintText: '5 ou 6-18',
|
||
helperText: 'Ex: 5 ou 6-18',
|
||
),
|
||
keyboardType: TextInputType.text,
|
||
validator: (value) {
|
||
if (_addMultiple) {
|
||
if (value == null || value.isEmpty) return 'Requis';
|
||
// Vérifier si c'est un nombre simple ou une range
|
||
if (value.contains('-')) {
|
||
final parts = value.split('-');
|
||
if (parts.length != 2) return 'Format invalide';
|
||
final start = int.tryParse(parts[0].trim());
|
||
final end = int.tryParse(parts[1].trim());
|
||
if (start == null || end == null) return 'Nombres invalides';
|
||
if (start >= end) return 'Le début doit être < fin';
|
||
if (end - start > 100) return 'Max 100 équipements';
|
||
} else {
|
||
final num = int.tryParse(value);
|
||
if (num == null || num < 1 || num > 100) return '1-100';
|
||
}
|
||
}
|
||
return null;
|
||
},
|
||
),
|
||
),
|
||
],
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
],
|
||
|
||
// Sélecteur Marque/Modèle
|
||
BrandModelSelector(
|
||
brandController: _brandController,
|
||
modelController: _modelController,
|
||
selectedBrand: _selectedBrand,
|
||
filteredModels: _filteredModels,
|
||
onBrandChanged: (brand) {
|
||
setState(() {
|
||
_selectedBrand = brand;
|
||
});
|
||
if (brand != null && brand.isNotEmpty) {
|
||
_loadFilteredModels(brand);
|
||
} else {
|
||
setState(() {
|
||
_filteredModels = [];
|
||
});
|
||
}
|
||
},
|
||
onModelsChanged: (models) {
|
||
setState(() {
|
||
_filteredModels = models;
|
||
});
|
||
},
|
||
),
|
||
const SizedBox(height: 16),
|
||
|
||
// Catégorie et Statut
|
||
Row(
|
||
children: [
|
||
Expanded(
|
||
child: DropdownButtonFormField<EquipmentCategory>(
|
||
value: _selectedCategory,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Catégorie *',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.category),
|
||
),
|
||
items: EquipmentCategory.values.map((category) {
|
||
return DropdownMenuItem(
|
||
value: category,
|
||
child: Text(_getCategoryLabel(category)),
|
||
);
|
||
}).toList(),
|
||
onChanged: (value) {
|
||
if (value != null) {
|
||
setState(() {
|
||
_selectedCategory = value;
|
||
});
|
||
}
|
||
},
|
||
),
|
||
),
|
||
// Afficher le statut uniquement si ce n'est pas un consommable ou câble
|
||
if (!_isConsumable) ...[
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
child: DropdownButtonFormField<EquipmentStatus>(
|
||
value: _selectedStatus,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Statut *',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.info),
|
||
),
|
||
items: EquipmentStatus.values.map((status) {
|
||
return DropdownMenuItem(
|
||
value: status,
|
||
child: Text(_getStatusLabel(status)),
|
||
);
|
||
}).toList(),
|
||
onChanged: (value) {
|
||
if (value != null) {
|
||
setState(() {
|
||
_selectedStatus = value;
|
||
});
|
||
}
|
||
},
|
||
),
|
||
),
|
||
],
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
|
||
// Prix
|
||
if (hasManagePermission) ...[
|
||
Row(
|
||
children: [
|
||
Expanded(
|
||
child: TextFormField(
|
||
controller: _purchasePriceController,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Prix d\'achat (€)',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.euro),
|
||
),
|
||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))],
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
child: TextFormField(
|
||
controller: _rentalPriceController,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Prix de location (€)',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.attach_money),
|
||
),
|
||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
],
|
||
|
||
// Quantités pour consommables
|
||
if (_isConsumable) ...[
|
||
const Divider(),
|
||
const Text('Gestion des quantités', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||
const SizedBox(height: 16),
|
||
Row(
|
||
children: [
|
||
Expanded(
|
||
child: TextFormField(
|
||
controller: _totalQuantityController,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Quantité totale',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.inventory),
|
||
),
|
||
keyboardType: TextInputType.number,
|
||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
child: TextFormField(
|
||
controller: _criticalThresholdController,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Seuil critique',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.warning),
|
||
),
|
||
keyboardType: TextInputType.number,
|
||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
],
|
||
|
||
// Boîtes parentes
|
||
const Divider(),
|
||
const Text('Boîtes parentes', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||
const SizedBox(height: 8),
|
||
_isLoadingBoxes
|
||
? const Center(child: CircularProgressIndicator())
|
||
: _buildParentBoxesSelector(),
|
||
const SizedBox(height: 16),
|
||
|
||
// Dates
|
||
const Divider(),
|
||
const Text('Dates', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||
const SizedBox(height: 16),
|
||
_buildDateField(label: 'Date d\'achat', icon: Icons.shopping_cart, value: _purchaseDate, onTap: () => _selectDate(context, 'purchase')),
|
||
const SizedBox(height: 16),
|
||
_buildDateField(label: 'Dernière maintenance', icon: Icons.build, value: _lastMaintenanceDate, onTap: () => _selectDate(context, 'lastMaintenance')),
|
||
const SizedBox(height: 16),
|
||
_buildDateField(label: 'Prochaine maintenance', icon: Icons.event, value: _nextMaintenanceDate, onTap: () => _selectDate(context, 'nextMaintenance')),
|
||
const SizedBox(height: 16),
|
||
|
||
// Notes
|
||
const Divider(),
|
||
TextFormField(
|
||
controller: _notesController,
|
||
decoration: const InputDecoration(
|
||
labelText: 'Notes',
|
||
border: OutlineInputBorder(),
|
||
prefixIcon: Icon(Icons.notes),
|
||
),
|
||
maxLines: 3,
|
||
),
|
||
const SizedBox(height: 24),
|
||
|
||
// Boutons
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: [
|
||
TextButton(
|
||
onPressed: () => Navigator.pop(context),
|
||
child: const Text('Annuler'),
|
||
),
|
||
const SizedBox(width: 16),
|
||
ElevatedButton(
|
||
onPressed: _saveEquipment,
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: AppColors.rouge,
|
||
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
|
||
),
|
||
child: Text(isEditing ? 'Enregistrer' : 'Créer', style: const TextStyle(color: Colors.white)),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildParentBoxesSelector() {
|
||
if (_availableBoxes.isEmpty) {
|
||
return const Card(
|
||
child: Padding(
|
||
padding: EdgeInsets.all(16.0),
|
||
child: Text('Aucune boîte disponible'),
|
||
),
|
||
);
|
||
}
|
||
|
||
return Card(
|
||
child: Column(
|
||
children: _availableBoxes.map((box) {
|
||
final isSelected = _selectedParentBoxIds.contains(box.id);
|
||
return CheckboxListTile(
|
||
title: Text(box.name),
|
||
subtitle: box.model != null ? Text('Modèle: {box.model}') : null,
|
||
value: isSelected,
|
||
onChanged: (bool? value) {
|
||
setState(() {
|
||
if (value == true) {
|
||
_selectedParentBoxIds.add(box.id);
|
||
} else {
|
||
_selectedParentBoxIds.remove(box.id);
|
||
}
|
||
});
|
||
},
|
||
);
|
||
}).toList(),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildDateField({required String label, required IconData icon, required DateTime? value, required VoidCallback onTap}) {
|
||
return InkWell(
|
||
onTap: onTap,
|
||
child: InputDecorator(
|
||
decoration: InputDecoration(
|
||
labelText: label,
|
||
border: const OutlineInputBorder(),
|
||
prefixIcon: Icon(icon),
|
||
suffixIcon: value != null
|
||
? IconButton(
|
||
icon: const Icon(Icons.clear),
|
||
onPressed: () {
|
||
setState(() {
|
||
if (label.contains('achat')) {
|
||
_purchaseDate = null;
|
||
} else if (label.contains('Dernière')) {
|
||
_lastMaintenanceDate = null;
|
||
} else if (label.contains('Prochaine')) {
|
||
_nextMaintenanceDate = null;
|
||
}
|
||
});
|
||
},
|
||
)
|
||
: null,
|
||
),
|
||
child: Text(
|
||
value != null ? DateFormat('dd/MM/yyyy').format(value) : 'Sélectionner une date',
|
||
style: TextStyle(color: value != null ? Colors.black : Colors.grey),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Future<void> _selectDate(BuildContext context, String field) async {
|
||
final DateTime? picked = await showDatePicker(
|
||
context: context,
|
||
initialDate: DateTime.now(),
|
||
firstDate: DateTime(2000),
|
||
lastDate: DateTime(2100),
|
||
);
|
||
|
||
if (picked != null) {
|
||
setState(() {
|
||
switch (field) {
|
||
case 'purchase':
|
||
_purchaseDate = picked;
|
||
break;
|
||
case 'lastMaintenance':
|
||
_lastMaintenanceDate = picked;
|
||
break;
|
||
case 'nextMaintenance':
|
||
_nextMaintenanceDate = picked;
|
||
break;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
Future<void> _saveEquipment() async {
|
||
if (!_formKey.currentState!.validate()) return;
|
||
|
||
setState(() => _isLoading = true);
|
||
|
||
try {
|
||
final equipmentProvider = Provider.of<EquipmentProvider>(context, listen: false);
|
||
final isEditing = widget.equipment != null;
|
||
|
||
int? availableQuantity;
|
||
if (_isConsumable && _totalQuantityController.text.isNotEmpty) {
|
||
final totalQuantity = int.parse(_totalQuantityController.text);
|
||
if (isEditing && widget.equipment!.availableQuantity != null) {
|
||
availableQuantity = widget.equipment!.availableQuantity;
|
||
} else {
|
||
availableQuantity = totalQuantity;
|
||
}
|
||
}
|
||
|
||
// Validation marque/modèle obligatoires
|
||
String brand = _brandController.text.trim();
|
||
String model = _modelController.text.trim();
|
||
|
||
if (brand.isEmpty || model.isEmpty) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
const SnackBar(content: Text('La marque et le modèle sont obligatoires')),
|
||
);
|
||
return;
|
||
}
|
||
|
||
// Génération d'identifiant si vide
|
||
List<String> ids = [];
|
||
List<int> numbers = [];
|
||
|
||
if (!isEditing && _identifierController.text.isEmpty) {
|
||
// Gérer la range ou nombre simple
|
||
final quantityText = _quantityToAddController.text.trim();
|
||
if (_addMultiple && quantityText.contains('-')) {
|
||
// Range: ex "6-18"
|
||
final parts = quantityText.split('-');
|
||
final start = int.parse(parts[0].trim());
|
||
final end = int.parse(parts[1].trim());
|
||
for (int i = start; i <= end; i++) {
|
||
numbers.add(i);
|
||
}
|
||
} else if (_addMultiple) {
|
||
// Nombre simple
|
||
final nbToAdd = int.tryParse(quantityText) ?? 1;
|
||
for (int i = 1; i <= nbToAdd; i++) {
|
||
numbers.add(i);
|
||
}
|
||
}
|
||
|
||
// Générer les IDs
|
||
if (numbers.isEmpty) {
|
||
String baseId = EquipmentIdGenerator.generate(brand: brand, model: model, number: null);
|
||
String uniqueId = await EquipmentIdGenerator.ensureUniqueId(baseId, _equipmentService);
|
||
ids.add(uniqueId);
|
||
} else {
|
||
for (final num in numbers) {
|
||
String baseId = EquipmentIdGenerator.generate(brand: brand, model: model, number: num);
|
||
String uniqueId = await EquipmentIdGenerator.ensureUniqueId(baseId, _equipmentService);
|
||
ids.add(uniqueId);
|
||
}
|
||
}
|
||
} else {
|
||
ids.add(_identifierController.text.trim());
|
||
}
|
||
|
||
// Création des équipements
|
||
for (final id in ids) {
|
||
final now = DateTime.now();
|
||
final equipment = EquipmentModel(
|
||
id: id,
|
||
name: id, // Utilisation de l'identifiant comme nom
|
||
brand: brand,
|
||
model: model,
|
||
category: _selectedCategory,
|
||
status: _selectedStatus,
|
||
purchasePrice: _purchasePriceController.text.isNotEmpty ? double.tryParse(_purchasePriceController.text) : null,
|
||
rentalPrice: _rentalPriceController.text.isNotEmpty ? double.tryParse(_rentalPriceController.text) : null,
|
||
totalQuantity: _isConsumable ? int.tryParse(_totalQuantityController.text) : null,
|
||
criticalThreshold: _isConsumable ? int.tryParse(_criticalThresholdController.text) : null,
|
||
purchaseDate: _purchaseDate,
|
||
lastMaintenanceDate: _lastMaintenanceDate,
|
||
nextMaintenanceDate: _nextMaintenanceDate,
|
||
parentBoxIds: _selectedParentBoxIds,
|
||
notes: _notesController.text,
|
||
createdAt: isEditing ? (widget.equipment?.createdAt ?? now) : now,
|
||
updatedAt: now,
|
||
availableQuantity: availableQuantity,
|
||
);
|
||
if (isEditing) {
|
||
await equipmentProvider.updateEquipment(
|
||
equipment.id,
|
||
equipment.toMap(),
|
||
);
|
||
} else {
|
||
await equipmentProvider.addEquipment(equipment);
|
||
}
|
||
}
|
||
|
||
if (mounted) {
|
||
Navigator.pop(context, true);
|
||
}
|
||
} catch (e) {
|
||
if (mounted) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(content: Text('Erreur lors de l\'enregistrement : $e')),
|
||
);
|
||
}
|
||
} finally {
|
||
if (mounted) setState(() => _isLoading = false);
|
||
}
|
||
}
|
||
|
||
// Correction des enums dans _getCategoryLabel
|
||
String _getCategoryLabel(EquipmentCategory category) {
|
||
switch (category) {
|
||
case EquipmentCategory.lighting:
|
||
return 'Lumière';
|
||
case EquipmentCategory.sound:
|
||
return 'Son';
|
||
case EquipmentCategory.video:
|
||
return 'Vidéo';
|
||
case EquipmentCategory.effect:
|
||
return 'Effet';
|
||
case EquipmentCategory.structure:
|
||
return 'Structure';
|
||
case EquipmentCategory.consumable:
|
||
return 'Consommable';
|
||
case EquipmentCategory.cable:
|
||
return 'Câble';
|
||
case EquipmentCategory.other:
|
||
default:
|
||
return 'Autre';
|
||
}
|
||
}
|
||
|
||
// Correction des enums dans _getStatusLabel
|
||
String _getStatusLabel(EquipmentStatus status) {
|
||
switch (status) {
|
||
case EquipmentStatus.available:
|
||
return 'Disponible';
|
||
case EquipmentStatus.inUse:
|
||
return 'En prestation';
|
||
case EquipmentStatus.rented:
|
||
return 'Loué';
|
||
case EquipmentStatus.lost:
|
||
return 'Perdu';
|
||
case EquipmentStatus.outOfService:
|
||
return 'HS';
|
||
case EquipmentStatus.maintenance:
|
||
return 'Maintenance';
|
||
default:
|
||
return 'Autre';
|
||
}
|
||
}
|
||
}
|