refactor: Encapsulates drawer menu selection

Replaces separate menu and submenu indices with a dedicated `SelectedDrawerState` class.

This change centralizes the logic for determining the active drawer item, improving readability and maintainability of the drawer component. It simplifies selection checks by providing a unified `isSelected` method.
This commit is contained in:
mandreshope 2025-07-23 17:12:24 +03:00
parent 63d5a21079
commit 6ebc49709a

View File

@ -12,32 +12,35 @@ class DrawerComponent extends ConsumerStatefulWidget {
super.key, super.key,
this.isOperationExpanded = true, this.isOperationExpanded = true,
this.isSettingsExpanded = false, this.isSettingsExpanded = false,
this.selectedMenuIndex = 0, this.selectedState = const SelectedDrawerState(
this.selectedSubMenuIndex = 0, menuIndex: 0,
subMenuIndex: 0,
),
}); });
final bool isOperationExpanded; final bool isOperationExpanded;
final bool isSettingsExpanded; final bool isSettingsExpanded;
final int selectedMenuIndex; final SelectedDrawerState selectedState;
final int selectedSubMenuIndex;
@override @override
ConsumerState<DrawerComponent> createState() => _DrawerComponentState(); ConsumerState<DrawerComponent> createState() => _DrawerComponentState();
} }
class _DrawerComponentState extends ConsumerState<DrawerComponent> { class _DrawerComponentState extends ConsumerState<DrawerComponent> {
bool _isOperationExpanded = false; late bool _isOperationExpanded;
bool _isSettingsExpanded = false; late bool _isSettingsExpanded;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_isOperationExpanded = widget.isOperationExpanded; _isOperationExpanded = widget.isOperationExpanded;
_isSettingsExpanded = widget.isSettingsExpanded; _isSettingsExpanded = widget.isSettingsExpanded;
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final selected = widget.selectedState;
return Drawer( return Drawer(
backgroundColor: AppTheme.of(context).primaryBackground, backgroundColor: AppTheme.of(context).primaryBackground,
child: Padding( child: Padding(
@ -75,84 +78,82 @@ class _DrawerComponentState extends ConsumerState<DrawerComponent> {
const Divider(), const Divider(),
// === ExpansionTile Opérations // === Opérations
_ExpansionTileComponent( _ExpansionTileComponent(
leadingIcon: Icons.inbox, leadingIcon: Icons.inbox,
isExpanded: _isOperationExpanded, isExpanded: _isOperationExpanded,
onExpansionChanged: (expanded) { onExpansionChanged: (expanded) =>
setState(() => _isOperationExpanded = expanded); setState(() => _isOperationExpanded = expanded),
},
title: 'Opérations', title: 'Opérations',
isActive: widget.selectedMenuIndex == 0, isActive: selected.isSelected(menu: 0),
children: [ children: [
_ListTile( _ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
leadingIcon: Icons.move_to_inbox,
isActive: widget.selectedSubMenuIndex == 0,
title: 'Réceptions', title: 'Réceptions',
), isActive: selected.isSelected(menu: 0, sub: 0),
_ListTile( leadingIcon: Icons.move_to_inbox,
contentPadding: const EdgeInsets.symmetric(horizontal: 40), contentPadding: const EdgeInsets.symmetric(horizontal: 40),
leadingIcon: Icons.local_shipping,
title: 'Livraisons',
isActive: widget.selectedSubMenuIndex == 1,
), ),
_ListTile( _ListTile(
title: 'Livraisons',
isActive: selected.isSelected(menu: 0, sub: 1),
leadingIcon: Icons.local_shipping,
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
),
_ListTile(
title: 'Inventaires',
isActive: selected.isSelected(menu: 0, sub: 2),
leadingIcon: Icons.inventory,
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
onTap: () { onTap: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
ProductListRoute().push(context); ProductListRoute().push(context);
}, },
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
leadingIcon: Icons.inventory,
title: 'Inventaires',
isActive: widget.selectedSubMenuIndex == 2,
), ),
], ],
), ),
// === Produits // === Produits
_ListTile( _ListTile(
title: "Produits",
leadingIcon: Icons.insert_chart,
trailing: const Icon(Icons.keyboard_arrow_right),
isActive: selected.isSelected(menu: 1),
contentPadding: const EdgeInsetsDirectional.symmetric( contentPadding: const EdgeInsetsDirectional.symmetric(
horizontal: 10, horizontal: 10,
), ),
leadingIcon: Icons.insert_chart,
title: "Produits",
isActive: widget.selectedMenuIndex == 1,
trailing: const Icon(Icons.keyboard_arrow_right),
), ),
// === Historique // === Historique
_ListTile( _ListTile(
title: "Historiques",
leadingIcon: Icons.history,
trailing: const Icon(Icons.keyboard_arrow_right),
isActive: selected.isSelected(menu: 2),
contentPadding: const EdgeInsetsDirectional.symmetric( contentPadding: const EdgeInsetsDirectional.symmetric(
horizontal: 10, horizontal: 10,
), ),
leadingIcon: Icons.history,
title: "Historiques",
trailing: const Icon(Icons.keyboard_arrow_right),
isActive: widget.selectedMenuIndex == 2,
), ),
// === ExpansionTile Paramètres // === Paramètres
_ExpansionTileComponent( _ExpansionTileComponent(
isActive: widget.selectedMenuIndex == 3,
isExpanded: _isSettingsExpanded,
onExpansionChanged: (expanded) {
setState(() => _isSettingsExpanded = expanded);
},
leadingIcon: Icons.settings,
title: "Paramètres", title: "Paramètres",
isExpanded: _isSettingsExpanded,
onExpansionChanged: (expanded) =>
setState(() => _isSettingsExpanded = expanded),
isActive: selected.isSelected(menu: 3),
leadingIcon: Icons.settings,
children: [ children: [
_ListTile( _ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
leadingIcon: Icons.lock_open,
title: 'Connexion Odoo', title: 'Connexion Odoo',
isActive: widget.selectedSubMenuIndex == 3, isActive: selected.isSelected(menu: 3, sub: 3),
leadingIcon: Icons.lock_open,
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
), ),
_ListTile( _ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
leadingIcon: Icons.group,
title: 'Gestion des utilisateurs', title: 'Gestion des utilisateurs',
isActive: widget.selectedSubMenuIndex == 4, isActive: selected.isSelected(menu: 3, sub: 4),
leadingIcon: Icons.group,
contentPadding: const EdgeInsets.symmetric(horizontal: 40),
), ),
], ],
), ),
@ -183,6 +184,20 @@ class _DrawerComponentState extends ConsumerState<DrawerComponent> {
} }
} }
class SelectedDrawerState {
const SelectedDrawerState({
required this.menuIndex,
required this.subMenuIndex,
});
final int menuIndex;
final int subMenuIndex;
bool isSelected({required int menu, int? sub}) {
if (sub == null) return menuIndex == menu;
return menuIndex == menu && subMenuIndex == sub;
}
}
class _ListTile extends StatelessWidget { class _ListTile extends StatelessWidget {
const _ListTile({ const _ListTile({
Key? key, Key? key,