feat(ui): improve mobile equipment card and unify travel cost dialog

This commit is contained in:
ElPoyo
2026-06-05 19:26:07 +02:00
parent cb94badafe
commit 752b86ec58
8 changed files with 179 additions and 53 deletions
+72 -5
View File
@@ -523,6 +523,7 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
Widget _buildEquipmentCard(EquipmentModel equipment) {
final isSelected = isItemSelected(equipment.id);
final isMobile = MediaQuery.of(context).size.width < 800;
// ✅ RepaintBoundary pour isoler le repaint de chaque carte
return RepaintBoundary(
@@ -563,9 +564,12 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// 1. leading selection or icon
if (isSelectionMode)
Padding(
@@ -642,15 +646,15 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
// 3. Status Badge OR Quantity Display (centered vertically in the row!)
Padding(
padding: const EdgeInsets.only(right: 16),
padding: EdgeInsets.only(right: (!isSelectionMode && !isMobile) ? 16 : 0),
child: (equipment.category == EquipmentCategory.consumable ||
equipment.category == EquipmentCategory.cable)
? _buildQuantityDisplay(equipment)
: EquipmentStatusBadge(equipment: equipment),
),
// 4. Trailing Action Buttons
if (!isSelectionMode)
// 4. Trailing Action Buttons (Desktop inline)
if (!isSelectionMode && !isMobile)
Row(
mainAxisSize: MainAxisSize.min,
children: [
@@ -711,6 +715,69 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
),
],
),
if (!isSelectionMode && isMobile) ...[
const Divider(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// Bouton Restock (uniquement pour consommables/câbles avec permission)
if (equipment.category == EquipmentCategory.consumable ||
equipment.category == EquipmentCategory.cable)
PermissionGate(
requiredPermissions: const ['manage_equipment'],
child: IconButton(
icon: const Icon(Icons.add_shopping_cart,
color: AppColors.rouge, size: 20),
tooltip: 'Restock',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => _showRestockDialog(equipment),
),
),
if (equipment.category == EquipmentCategory.consumable ||
equipment.category == EquipmentCategory.cable)
const SizedBox(width: 16),
// Bouton QR Code
IconButton(
icon: const Icon(Icons.qr_code, color: AppColors.rouge, size: 20),
tooltip: 'QR Code',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => showDialog(
context: context,
builder: (context) =>
QRCodeDialog.forEquipment(equipment),
),
),
const SizedBox(width: 16),
// Bouton Modifier (permission required)
PermissionGate(
requiredPermissions: const ['manage_equipment'],
child: IconButton(
icon: const Icon(Icons.edit, color: AppColors.rouge, size: 20),
tooltip: 'Modifier',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => _editEquipment(equipment),
),
),
const SizedBox(width: 16),
// Bouton Supprimer (permission required)
PermissionGate(
requiredPermissions: const ['manage_equipment'],
child: IconButton(
icon: const Icon(Icons.delete, color: Colors.red, size: 20),
tooltip: 'Supprimer',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => _deleteEquipment(equipment),
),
),
],
),
],
],
),
),
),
),