mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-08-25 01:12:28 +00:00
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.
This commit is contained in:
@ -5,19 +5,20 @@ class CustomExpansionTile extends StatefulWidget {
|
|||||||
final String title;
|
final String title;
|
||||||
final List<Widget>? children;
|
final List<Widget>? children;
|
||||||
final bool initiallyExpanded;
|
final bool initiallyExpanded;
|
||||||
final bool isSelected; // Add this to track selection
|
final bool isSelected;
|
||||||
final bool? isExpanded; // External control over expansion
|
final bool? isExpanded;
|
||||||
final ValueChanged<bool>? onExpansionChanged; // Notify when expansion changes
|
final ValueChanged<bool>? onExpansionChanged;
|
||||||
final VoidCallback? onItemSelected; // Callback for selecting the item
|
final VoidCallback? onItemSelected;
|
||||||
|
|
||||||
CustomExpansionTile({
|
const CustomExpansionTile({
|
||||||
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
this.children,
|
this.children,
|
||||||
this.initiallyExpanded = false,
|
this.initiallyExpanded = false,
|
||||||
this.isExpanded, // Allow external control over expansion
|
this.isExpanded,
|
||||||
this.onExpansionChanged, // Notify when expansion changes
|
this.onExpansionChanged,
|
||||||
this.onItemSelected, // Trigger item selection when name is tapped
|
this.onItemSelected,
|
||||||
required this.isSelected, // Add this to initialize selection state
|
required this.isSelected,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -25,7 +26,7 @@ class CustomExpansionTile extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CustomExpansionTileState extends State<CustomExpansionTile> {
|
class CustomExpansionTileState extends State<CustomExpansionTile> {
|
||||||
bool _isExpanded = false; // Local expansion state
|
bool _isExpanded = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -36,7 +37,6 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
@override
|
@override
|
||||||
void didUpdateWidget(CustomExpansionTile oldWidget) {
|
void didUpdateWidget(CustomExpansionTile oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
// Sync local state with external control of expansion state
|
|
||||||
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
|
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isExpanded = widget.isExpanded!;
|
_isExpanded = widget.isExpanded!;
|
||||||
@ -44,7 +44,6 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to capitalize the first letter of the title
|
|
||||||
String _capitalizeFirstLetter(String text) {
|
String _capitalizeFirstLetter(String text) {
|
||||||
if (text.isEmpty) return text;
|
if (text.isEmpty) return text;
|
||||||
return text[0].toUpperCase() + text.substring(1);
|
return text[0].toUpperCase() + text.substring(1);
|
||||||
@ -56,7 +55,6 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
// Expand/collapse icon, now wrapped in a GestureDetector for specific onTap
|
|
||||||
if (widget.children != null && widget.children!.isNotEmpty)
|
if (widget.children != null && widget.children!.isNotEmpty)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -70,38 +68,33 @@ class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|||||||
? Icons.keyboard_arrow_down
|
? Icons.keyboard_arrow_down
|
||||||
: Icons.keyboard_arrow_right,
|
: Icons.keyboard_arrow_right,
|
||||||
color: ColorsManager.lightGrayColor,
|
color: ColorsManager.lightGrayColor,
|
||||||
size: 16.0, // Adjusted size for better alignment
|
size: 16,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// The title text, wrapped in GestureDetector to handle selection
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (widget.onItemSelected != null) {
|
if (widget.onItemSelected != null) {
|
||||||
widget.onItemSelected!();
|
widget.onItemSelected!.call();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
_capitalizeFirstLetter(widget.title),
|
_capitalizeFirstLetter(widget.title),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: widget.isSelected
|
color: widget.isSelected
|
||||||
? ColorsManager
|
? ColorsManager.blackColor
|
||||||
.blackColor // Change color to black when selected
|
: ColorsManager.lightGrayColor,
|
||||||
: ColorsManager
|
fontWeight:
|
||||||
.lightGrayColor, // Gray when not selected
|
widget.isSelected ? FontWeight.w600 : FontWeight.w400,
|
||||||
fontWeight: 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(
|
||||||
padding: const EdgeInsets.only(left: 24.0), // Indented children
|
padding: const EdgeInsets.only(left: 24),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: widget.children!,
|
children: widget.children!,
|
||||||
|
@ -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/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/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/services/api/http_service.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/app_snack_bar.dart';
|
||||||
|
|
||||||
abstract final class SpaceDetailsDialogHelper {
|
abstract final class SpaceDetailsDialogHelper {
|
||||||
static void showCreate(
|
static void showCreate(
|
||||||
@ -140,6 +141,9 @@ abstract final class SpaceDetailsDialogHelper {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
onSuccess?.call(space);
|
onSuccess?.call(space);
|
||||||
|
context.showSuccessSnackbar(
|
||||||
|
'${space.spaceName} space was updated successfully',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _onLoading(BuildContext context) {
|
static void _onLoading(BuildContext context) {
|
||||||
@ -152,20 +156,7 @@ abstract final class SpaceDetailsDialogHelper {
|
|||||||
|
|
||||||
static void _onError(BuildContext context, String errorMessage) {
|
static void _onError(BuildContext context, String errorMessage) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
showDialog<void>(
|
context.showFailureSnackbar(errorMessage);
|
||||||
context: context,
|
|
||||||
barrierDismissible: false,
|
|
||||||
builder: (_) => AlertDialog(
|
|
||||||
title: const Text('Error'),
|
|
||||||
content: Text(errorMessage),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: Navigator.of(context).pop,
|
|
||||||
child: const Text('OK'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _onCreateSuccess(
|
static void _onCreateSuccess(
|
||||||
@ -176,5 +167,8 @@ abstract final class SpaceDetailsDialogHelper {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
onSuccess?.call(space);
|
onSuccess?.call(space);
|
||||||
|
context.showSuccessSnackbar(
|
||||||
|
'${space.spaceName} space created successfully',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user