diff --git a/lib/new_views/common_widgets/single_item_drop_down_menu.dart b/lib/new_views/common_widgets/single_item_drop_down_menu.dart index f5c4a1d5..6a5b808b 100644 --- a/lib/new_views/common_widgets/single_item_drop_down_menu.dart +++ b/lib/new_views/common_widgets/single_item_drop_down_menu.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; @@ -6,6 +7,7 @@ import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/new_views/common_widgets/app_loading_manager.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/views/widgets/bottom_sheets/selection_bottom_sheet.dart'; +import 'package:test_sa/views/widgets/fullscreen_dialogs/selection_fullscreen_dialog.dart'; import '../../models/base.dart'; import '../app_style/app_color.dart'; @@ -16,6 +18,7 @@ class SingleItemDropDownMenu exte final T? initialValue; final bool enabled; final bool showAsBottomSheet; + final bool showAsFullScreenDialog; final List? staticData; final String title; final double? height; @@ -34,6 +37,7 @@ class SingleItemDropDownMenu exte this.enabled = true, this.height, this.showAsBottomSheet = false, + this.showAsFullScreenDialog = false, this.staticData, // Provide a default empty list this.showShadow = true, this.backgroundColor, @@ -140,7 +144,7 @@ class _SingleItemDropDownMenuState( - // Specify return type - context: context, - isScrollControlled: true, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical( - top: Radius.circular(20), - ), - ), - clipBehavior: Clip.antiAliasWithSaveLayer, - builder: (BuildContext context) => SelectionBottomSheet( - // Specify generic type - items: ((X == NullableLoadingProvider) ? widget.staticData : provider?.items as List) ?? [], // Provide default empty list if null - selectedItem: _selectedItem, - title: widget.title, - builderString: (emp) => emp?.name ?? "", // Null-aware operator for emp.name - ), - ); - if (selectedT != null) { - setState(() { - _selectedItem = selectedT; - }); - widget.onSelect!(selectedT); // Non-null assertion after null check - } + ).onPress(widget.showAsFullScreenDialog + ? () { + openDialog(); } - : null), + : (widget.showAsBottomSheet + ? () async { + final selectedT = await showModalBottomSheet( + // Specify return type + context: context, + isScrollControlled: true, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + clipBehavior: Clip.antiAliasWithSaveLayer, + builder: (BuildContext context) => SelectionBottomSheet( + // Specify generic type + items: ((X == NullableLoadingProvider) ? widget.staticData : provider?.items as List) ?? [], // Provide default empty list if null + selectedItem: _selectedItem, + title: widget.title, + builderString: (emp) => emp?.name ?? "", // Null-aware operator for emp.name + ), + ); + if (selectedT != null) { + setState(() { + _selectedItem = selectedT; + }); + widget.onSelect!(selectedT); // Non-null assertion after null check + } + } + : null)), ], ), ], @@ -194,4 +202,28 @@ class _SingleItemDropDownMenuState( + // Specify generic type + items: ((X == NullableLoadingProvider) ? widget.staticData : provider?.items as List) ?? [], // Provide default empty list if null + selectedItem: _selectedItem, + title: widget.title, + builderString: (emp) => emp?.name ?? "", // Null-aware operator for emp.name + ); + + final selectedT = await pushRouter(child); + if (selectedT != null) { + setState(() { + _selectedItem = selectedT; + }); + widget.onSelect!(selectedT); // Non-null assertion after null check + } + } + + Future pushRouter(Widget child) async { + // PageRoute pRoute = !Platform.isIOS ? CupertinoPageRoute(fullscreenDialog: true, builder: (context) => child) : MaterialPageRoute(fullscreenDialog: true, builder: (context) => child); + + return await Navigator.of(context).push(CupertinoPageRoute(fullscreenDialog: true, builder: (context) => child)); + } } diff --git a/lib/views/widgets/fullscreen_dialogs/selection_fullscreen_dialog.dart b/lib/views/widgets/fullscreen_dialogs/selection_fullscreen_dialog.dart new file mode 100644 index 00000000..5cdc5429 --- /dev/null +++ b/lib/views/widgets/fullscreen_dialogs/selection_fullscreen_dialog.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; + +typedef SelectionBuilderString = String Function(dynamic); + +class SelectionFullScreenDialog extends StatefulWidget { + final List? items; + final T? selectedItem; // Now nullable + final String title; + final SelectionBuilderString builderString; + + const SelectionFullScreenDialog({Key? key, this.items, this.selectedItem, this.title = "", required this.builderString}) : super(key: key); + + @override + _SelectionBottomSheetState createState() => _SelectionBottomSheetState(); +} + +class _SelectionBottomSheetState extends State> { + T? _selectedValue; // Now nullable + + String query = ""; + + List? get filteredList => widget.items?.where((element) => widget.builderString(element).toLowerCase().contains(query.toLowerCase())).toList(); + + @override + void initState() { + _selectedValue = widget.selectedItem; + super.initState(); + } + + FocusNode searchFocusNode = FocusNode(); + + @override + void dispose() { + searchFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: widget.title.heading5(context)), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SearchBar( + focusNode: searchFocusNode, + elevation: WidgetStateProperty.all(0), + leading: const Icon(Icons.search, color: AppColor.neutral50), + textStyle: WidgetStateProperty.all( + const TextStyle(color: AppColor.neutral50, fontSize: 16.0), + ), + hintStyle: WidgetStateProperty.all( + const TextStyle(color: AppColor.neutral20, fontSize: 14.0), + ), + hintText: 'Search by name', + onChanged: (queryString) { + query = queryString; + setState(() {}); + }, + ).paddingOnly(top: 16, start: 16, end: 16, bottom: 8), + // TextField( + // onChanged: (queryString) { + // query = queryString; + // setState(() {}); + // }, + // style: const TextStyle(fontSize: 14), + // focusNode: searchFocusNode, + // decoration: InputDecoration( + // hintText: 'Search by name', + // labelText: 'Search', + // hintStyle: const TextStyle(fontSize: 14), + // focusedBorder: OutlineInputBorder( + // borderSide: BorderSide(color: AppColor.blueStatus(context), width: 2.0), + // borderRadius: const BorderRadius.all(Radius.circular(12.0)), + // ), + // enabledBorder: OutlineInputBorder( + // borderSide: BorderSide(color: AppColor.blueStatus(context), width: 1.0), + // borderRadius: const BorderRadius.all(Radius.circular(12.0)), + // ), + // contentPadding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + // ), + // ), + 8.height, + Expanded( + child: ListView.builder( + itemCount: filteredList?.length, + padding: EdgeInsets.zero, + itemBuilder: (cxt, index) => RadioListTile( + // Specify type for RadioListTile + value: filteredList![index], + dense: true, + contentPadding: const EdgeInsets.only(left: 16, right: 16), + groupValue: _selectedValue, + activeColor: Colors.black87, + hoverColor: Colors.transparent, + onChanged: (value) { + _selectedValue = value; + searchFocusNode.unfocus(); + setState(() {}); + }, + title: Text( + widget.builderString(filteredList![index]).cleanupWhitespace.capitalizeFirstOfEach ?? "", + style: Theme.of(context).textTheme.bodyLarge, + ), + ), + ), + ), + 8.height, + if (_selectedValue != null) + AppFilledButton( + label: context.translation.select, + maxWidth: true, + onPressed: () { + Navigator.pop(context, _selectedValue); + }, + ).paddingAll(16), + ], + ), + ); + } +}