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/models/base.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.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 MultipleSelectionFullScreenDialog extends StatefulWidget { final List? items; final List selectedItem; // Now nullable final T? disableItem; // Now nullable final String title; final bool showCancel; final SelectionBuilderString builderString; final Function(List) onSelect; const MultipleSelectionFullScreenDialog( {Key? key, this.items, this.selectedItem = const [], this.disableItem, this.title = "", required this.builderString, this.showCancel = false, required this.onSelect}) : super(key: key); @override _SelectionBottomSheetState createState() => _SelectionBottomSheetState(); } class _SelectionBottomSheetState extends State> { late List _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), actions: [ if (widget.showCancel) AnimatedContainer( height: 24, duration: const Duration(milliseconds: 250), margin: const EdgeInsets.only(right: 16), decoration: BoxDecoration(color: _selectedValue.isNotEmpty ? const Color(0xffF63939).withOpacity(.75) : Colors.grey.withOpacity(.75), borderRadius: BorderRadius.circular(30)), padding: const EdgeInsets.only(left: 4, right: 8, top: 4, bottom: 4), alignment: Alignment.center, child: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ const Icon(Icons.clear, color: Colors.white, size: 16), 4.width, const Text( "Clear", style: TextStyle(fontSize: 14, color: Colors.white, height: 1), ) ], ).onPress(_selectedValue.isNotEmpty ? () { Navigator.pop(context); widget.onSelect([]); } : null), ), ], ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SearchBar( focusNode: searchFocusNode, elevation: WidgetStateProperty.all(0), backgroundColor: WidgetStateProperty.all(context.isDark ? AppColor.neutral120 : null), leading: Icon(Icons.search, color: AppColor.iconColor(context)), textStyle: WidgetStateProperty.all( TextStyle(color: AppColor.textColor(context), fontSize: 16.0), ), hintStyle: WidgetStateProperty.all( TextStyle(color: AppColor.textColor(context), 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) { bool isDisabledItem = widget.disableItem != null && widget.disableItem?.identifier == filteredList![index].identifier; return Theme( data: Theme.of(context).copyWith( radioTheme: RadioThemeData( fillColor: MaterialStateColor.resolveWith((states) { if (states.contains(MaterialState.selected)) { return AppColor.iconColor(context); // Active color } return Colors.grey; // Inactive color }), ), ), child: CheckboxListTile( value: checkItContains(filteredList![index]), dense: true, controlAffinity: ListTileControlAffinity.leading, activeColor: AppColor.textColor(context), contentPadding: const EdgeInsets.only(left: 16, right: 16), onChanged: (value) { // if (checkItContains(filteredList![index]) ?? false) { // _selectedValue.remove(filteredList![index]); // } else { // _selectedValue.add(filteredList![index]); // } if (value == true) { _selectedValue.add(filteredList![index]); } else if (value == false) { _selectedValue.remove(filteredList![index]); } searchFocusNode.unfocus(); setState(() {}); }, title: Text( widget.builderString(filteredList![index]).cleanupWhitespace.capitalizeFirstOfEach ?? "", style: Theme.of(context).textTheme.bodyLarge, ), ), ); }), ), 8.height, if (_selectedValue.isNotEmpty) FooterActionButton.footerContainer( context: context, child: AppFilledButton( label: context.translation.select, maxWidth: true, onPressed: () { Navigator.pop(context); widget.onSelect(_selectedValue); }, )), ], ), ); } bool? checkItContains(T) { return _selectedValue.contains(T); } }