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 SelectionFullScreenDialog extends StatefulWidget { final List? items; final T? selectedItem; // Now nullable final T? disableItem; // Now nullable final String title; final bool showCancel; final SelectionBuilderString builderString; final Function(T?) onSelect; const SelectionFullScreenDialog({Key? key, this.items, this.selectedItem, this.disableItem, this.title = "", required this.builderString, this.showCancel = false, required this.onSelect}) : 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), actions: [ if (widget.showCancel) AnimatedContainer( height: 24, duration: const Duration(milliseconds: 250), margin: const EdgeInsets.only(right: 16), decoration: BoxDecoration(color: _selectedValue != null ? 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 != null ? () { Navigator.pop(context); widget.onSelect(null); } : 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: RadioListTile( // Specify type for RadioListTile value: filteredList![index], dense: true, contentPadding: const EdgeInsets.only(left: 16, right: 16), groupValue: _selectedValue, activeColor: AppColor.iconColor(context), hoverColor: Colors.transparent, onChanged: isDisabledItem ? null : (value) { _selectedValue = value; searchFocusNode.unfocus(); setState(() {}); }, title: Text( widget.builderString(filteredList![index]).cleanupWhitespace.capitalizeFirstOfEach ?? "", style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: isDisabledItem ? AppColor.neutral20 : null), ), ), ); }), ), 8.height, if (_selectedValue != null) FooterActionButton.footerContainer( context: context, child: AppFilledButton( label: context.translation.select, maxWidth: true, onPressed: () { Navigator.pop(context); widget.onSelect(_selectedValue); }, )), ], ), ); } }