import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart'; import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; class SearchEmployeeBottomSheet extends StatefulWidget { int? notificationID; String title, apiMode; List? actionHistoryList; Function(ReplacementList) onSelectEmployee; bool fromChat; SearchEmployeeBottomSheet({ required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, required this.onSelectEmployee, required this.fromChat, }); @override State createState() => _SearchEmployeeBottomSheetState(); } class _SearchEmployeeBottomSheetState extends State { TextEditingController username = TextEditingController(); String searchText = ""; List? optionsList = [ LocaleKeys.fullName.tr(), LocaleKeys.username.tr(), LocaleKeys.endDate.tr(), ]; List? favUsersList; List? replacementList; List? favouriteUserList; List? nonFavouriteUserList; // Chat Items List? chatUsersList = []; int _selectedSearchIndex = 0; void fetchUserByInput({bool isNeedLoading = true}) async { try { Utils.showLoading(context); replacementList = await WorkListApiClient().searchUserByInput( userName: _selectedSearchIndex == 0 ? searchText : "", userId: _selectedSearchIndex == 1 ? searchText : "", email: _selectedSearchIndex == 2 ? searchText : "", ); favouriteUserList = replacementList?.where((element) => element.isFavorite ?? false).toList(); nonFavouriteUserList = replacementList?.where((element) => !(element.isFavorite ?? false)).toList(); Utils.hideLoading(context); setState(() {}); } catch (e) { Utils.hideLoading(context); Utils.handleException(e, context, null); } if (isNeedLoading) Utils.hideLoading(context); setState(() {}); return null; } void fetchChatUser({bool isNeedLoading = true}) async { try { Utils.showLoading(context); chatUsersList = await ChatProviderModel().getChatMemberFromSearch(searchText, int.parse(AppState().chatDetails!.response!.id.toString())); Utils.hideLoading(context); setState(() {}); } catch (e) { Utils.hideLoading(context); Utils.handleException(e, context, null); } if (isNeedLoading) Utils.hideLoading(context); setState(() {}); return null; } @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, height: MediaQuery.of(context).size.height - 100, child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ widget.title.toText24(isBold: true), 21.height, "Search".toText16(), 11.height, Row( children: [ radioOption("Name", 0, _selectedSearchIndex), radioOption("User Name", 1, _selectedSearchIndex), radioOption("Email", 2, _selectedSearchIndex), ], ), 14.height, Row( children: [ DynamicTextFieldWidget( "Search", "Search By Username", inputAction: TextInputAction.done, suffixIconData: Icons.search, onChange: (text) { searchText = text; setState(() {}); }, ).expanded, IconButton( constraints: const BoxConstraints(), onPressed: () async { await SystemChannels.textInput.invokeMethod('TextInput.hide'); widget.fromChat ? fetchChatUser() : fetchUserByInput(); }, icon: const Icon(Icons.search), ) ], ), if (replacementList != null) replacementList!.isEmpty ? Utils.getNoDataWidget(context).expanded : ListView( physics: const BouncingScrollPhysics(), padding: EdgeInsets.only(top: 21, bottom: 8), children: [ if (favouriteUserList?.isNotEmpty ?? false) ...[ "Favorites".toText16(), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (cxt, index) => employeeItemView(favouriteUserList![index]), separatorBuilder: (cxt, index) => Container( height: 1, color: MyColors.borderE3Color, ), itemCount: favouriteUserList?.length ?? 0), 12.height, ], if (nonFavouriteUserList?.isNotEmpty ?? false) ...[ "Related".toText16(), 12.height, ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (cxt, index) => employeeItemView(nonFavouriteUserList![index]), separatorBuilder: (cxt, index) => Container( height: 1, color: MyColors.borderE3Color, ), itemCount: nonFavouriteUserList?.length ?? 0), ] ], ).expanded, if (widget.fromChat) if (chatUsersList != null && widget.fromChat) chatUsersList!.isEmpty ? Column( children: [ 20.height, Utils.getNoDataWidget(context), ], ) : ListView( physics: const BouncingScrollPhysics(), padding: const EdgeInsets.only( top: 15, ), children: [ ListView.separated( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (BuildContext cxt, int index) { return SizedBox( height: 55, child: ListTile( leading: Stack( children: [ SvgPicture.asset( "assets/images/user.svg", height: 48, width: 48, ), Positioned( right: 5, bottom: 1, child: Container( width: 10, height: 10, decoration: BoxDecoration( color: chatUsersList![index].userStatus == 1 ? MyColors.green2DColor : Colors.red, borderRadius: const BorderRadius.all( Radius.circular(10), ), ), ), ) ], ), title: (chatUsersList![index].userName ?? "").toText14(color: MyColors.darkTextColor), minVerticalPadding: 0, onTap: () { Navigator.pop(context); Navigator.pushNamed( context, AppRoutes.chatDetailed, arguments: {"targetUser": chatUsersList![index], "isNewChat": true}, ); }, ), ); }, separatorBuilder: (BuildContext context, int index) => const Padding( padding: EdgeInsets.only(right: 10, left: 70, bottom: 0, top: 0), child: Divider( color: Color(0xFFE5E5E5), ), ), itemCount: chatUsersList?.length ?? 0, ), 12.height, ], ).expanded, ], ).paddingOnly(left: 21, right: 21, bottom: 0, top: 21).expanded, Container(width: double.infinity, height: 1, color: MyColors.lightGreyEFColor), DefaultButton( LocaleKeys.cancel.tr(), () { Navigator.pop(context); }, textColor: MyColors.grey3AColor, colors: const [ Color(0xffE6E6E6), Color(0xffE6E6E6), ], ).insideContainer ], ), ); } Widget employeeItemView(ReplacementList replacement) { return InkWell( onTap: () { Navigator.pop(context); widget.onSelectEmployee(replacement); }, child: SizedBox( height: 50, child: Row( children: [ CircularAvatar( url: replacement.employeeImage ?? "", height: 30, width: 30, isImageBase64: true, ), 16.width, Expanded( child: (replacement.employeeDisplayName ?? "").toText12(), ), Icon(Icons.star, size: 16, color: replacement.isFavorite! ? MyColors.yellowFavColor : MyColors.borderCEColor), ], ), ), ); } Widget radioOption(String title, int value, int groupValue) { return Row( children: [ Container( width: 24, height: 24, decoration: BoxDecoration( color: Colors.transparent, border: Border.all(color: MyColors.borderColor, width: 1), borderRadius: const BorderRadius.all( Radius.circular(100), ), ), padding: const EdgeInsets.all(4), child: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( color: value == groupValue ? MyColors.grey3AColor : Colors.transparent, borderRadius: const BorderRadius.all( Radius.circular(100), ), ), ), ), 9.width, title.toText12(color: MyColors.grey57Color) ], ).onPress(() { _selectedSearchIndex = value; setState(() {}); }).expanded; } }