From 7d778097501c845333d3876f15d5c3687a5bd272 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 24 Jul 2025 14:51:07 +0300 Subject: [PATCH] Refactor CustomExpansionTile and SpaceDetailsDialogHelper for improved functionality and UI consistency - Updated CustomExpansionTile to enhance selection state handling and UI responsiveness. - Integrated success and error snackbars in SpaceDetailsDialogHelper for better user feedback during space creation and updates. - Removed redundant comments and improved code readability. --- lib/common/widgets/custom_expansion_tile.dart | 45 ++++++++----------- .../helpers/space_details_dialog_helper.dart | 22 ++++----- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/lib/common/widgets/custom_expansion_tile.dart b/lib/common/widgets/custom_expansion_tile.dart index 74151ca2..7bb74a74 100644 --- a/lib/common/widgets/custom_expansion_tile.dart +++ b/lib/common/widgets/custom_expansion_tile.dart @@ -5,19 +5,20 @@ class CustomExpansionTile extends StatefulWidget { final String title; final List? children; final bool initiallyExpanded; - final bool isSelected; // Add this to track selection - final bool? isExpanded; // External control over expansion - final ValueChanged? onExpansionChanged; // Notify when expansion changes - final VoidCallback? onItemSelected; // Callback for selecting the item + final bool isSelected; + final bool? isExpanded; + final ValueChanged? onExpansionChanged; + final VoidCallback? onItemSelected; - CustomExpansionTile({ + const CustomExpansionTile({ + super.key, required this.title, this.children, this.initiallyExpanded = false, - this.isExpanded, // Allow external control over expansion - this.onExpansionChanged, // Notify when expansion changes - this.onItemSelected, // Trigger item selection when name is tapped - required this.isSelected, // Add this to initialize selection state + this.isExpanded, + this.onExpansionChanged, + this.onItemSelected, + required this.isSelected, }); @override @@ -25,7 +26,7 @@ class CustomExpansionTile extends StatefulWidget { } class CustomExpansionTileState extends State { - bool _isExpanded = false; // Local expansion state + bool _isExpanded = false; @override void initState() { @@ -36,7 +37,6 @@ class CustomExpansionTileState extends State { @override void didUpdateWidget(CustomExpansionTile oldWidget) { super.didUpdateWidget(oldWidget); - // Sync local state with external control of expansion state if (widget.isExpanded != null && widget.isExpanded != _isExpanded) { setState(() { _isExpanded = widget.isExpanded!; @@ -44,7 +44,6 @@ class CustomExpansionTileState extends State { } } - // Utility function to capitalize the first letter of the title String _capitalizeFirstLetter(String text) { if (text.isEmpty) return text; return text[0].toUpperCase() + text.substring(1); @@ -56,7 +55,6 @@ class CustomExpansionTileState extends State { children: [ Row( children: [ - // Expand/collapse icon, now wrapped in a GestureDetector for specific onTap if (widget.children != null && widget.children!.isNotEmpty) GestureDetector( onTap: () { @@ -70,38 +68,33 @@ class CustomExpansionTileState extends State { ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right, color: ColorsManager.lightGrayColor, - size: 16.0, // Adjusted size for better alignment + size: 16, ), ), - // The title text, wrapped in GestureDetector to handle selection Expanded( child: GestureDetector( onTap: () { if (widget.onItemSelected != null) { - widget.onItemSelected!(); + widget.onItemSelected!.call(); } }, child: Text( _capitalizeFirstLetter(widget.title), style: TextStyle( color: widget.isSelected - ? ColorsManager - .blackColor // Change color to black when selected - : ColorsManager - .lightGrayColor, // Gray when not selected - fontWeight: FontWeight.w400, + ? ColorsManager.blackColor + : ColorsManager.lightGrayColor, + fontWeight: + widget.isSelected ? FontWeight.w600 : FontWeight.w400, ), ), ), ), ], ), - // The expanded section (children) that shows when the tile is expanded - if (_isExpanded && - widget.children != null && - widget.children!.isNotEmpty) + if (_isExpanded && widget.children != null && widget.children!.isNotEmpty) Padding( - padding: const EdgeInsets.only(left: 24.0), // Indented children + padding: const EdgeInsets.only(left: 24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: widget.children!, diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart b/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart index 175bafc8..6376972d 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart @@ -12,6 +12,7 @@ import 'package:syncrow_web/pages/space_management_v2/modules/update_space/data/ import 'package:syncrow_web/pages/space_management_v2/modules/update_space/domain/params/update_space_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_bloc.dart'; import 'package:syncrow_web/services/api/http_service.dart'; +import 'package:syncrow_web/utils/extension/app_snack_bar.dart'; abstract final class SpaceDetailsDialogHelper { static void showCreate( @@ -140,6 +141,9 @@ abstract final class SpaceDetailsDialogHelper { Navigator.of(context).pop(); Navigator.of(context).pop(); onSuccess?.call(space); + context.showSuccessSnackbar( + '${space.spaceName} space was updated successfully', + ); } static void _onLoading(BuildContext context) { @@ -152,20 +156,7 @@ abstract final class SpaceDetailsDialogHelper { static void _onError(BuildContext context, String errorMessage) { Navigator.of(context).pop(); - showDialog( - context: context, - barrierDismissible: false, - builder: (_) => AlertDialog( - title: const Text('Error'), - content: Text(errorMessage), - actions: [ - TextButton( - onPressed: Navigator.of(context).pop, - child: const Text('OK'), - ), - ], - ), - ); + context.showFailureSnackbar(errorMessage); } static void _onCreateSuccess( @@ -176,5 +167,8 @@ abstract final class SpaceDetailsDialogHelper { Navigator.of(context).pop(); Navigator.of(context).pop(); onSuccess?.call(space); + context.showSuccessSnackbar( + '${space.spaceName} space created successfully', + ); } }