diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index ff35fb78..fda76728 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:go_router/go_router.dart'; @@ -51,6 +52,8 @@ class HomeBloc extends Bloc { await const FlutterSecureStorage().read(key: UserModel.userUuidKey); user = await HomeApi().fetchUserInfo(uuid); add(FetchTermEvent()); + add(FetchPolicyEvent()); + emit(HomeInitial()); } catch (e) { return; @@ -61,8 +64,9 @@ class HomeBloc extends Bloc { try { emit(LoadingHome()); terms = await HomeApi().fetchTerms(); - add(FetchPolicyEvent()); - emit(PolicyAgreement()); + emit(HomeInitial()); + + // emit(PolicyAgreement()); } catch (e) { return; } @@ -72,8 +76,11 @@ class HomeBloc extends Bloc { try { emit(LoadingHome()); policy = await HomeApi().fetchPolicy(); - emit(PolicyAgreement()); + debugPrint("Fetched policy: $policy"); + // Emit a state to trigger the UI update + emit(HomeInitial()); } catch (e) { + debugPrint("Error fetching policy: $e"); return; } } diff --git a/lib/pages/home/view/home_page_web.dart b/lib/pages/home/view/home_page_web.dart index 35e39821..baf18fc2 100644 --- a/lib/pages/home/view/home_page_web.dart +++ b/lib/pages/home/view/home_page_web.dart @@ -9,103 +9,126 @@ import 'package:syncrow_web/pages/home/view/home_card.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart'; -class HomeWebPage extends StatelessWidget { +class HomeWebPage extends StatefulWidget { const HomeWebPage({super.key}); + @override + State createState() => _HomeWebPageState(); +} + +class _HomeWebPageState extends State { + // Flag to track whether the dialog is already shown. + bool _dialogShown = false; + + @override + void initState() { + super.initState(); + final homeBloc = BlocProvider.of(context); + homeBloc.add(FetchUserInfo()); + } + @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; final homeBloc = BlocProvider.of(context); return PopScope( - canPop: false, - onPopInvoked: (didPop) => false, - child: BlocConsumer( - listener: (BuildContext context, state) { - if (state is HomeInitial) { - if (homeBloc.user!.hasAcceptedWebAgreement == false) { - Future.delayed(const Duration(seconds: 2), () { - showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return AgreementAndPrivacyDialog( - terms: homeBloc.terms, - policy: homeBloc.policy, - ); - }, - ).then((v) { - if (v != null) { - homeBloc.add(ConfirmUserAgreementEvent()); - homeBloc.add(const FetchUserInfo()); - } - }); + canPop: false, + onPopInvoked: (didPop) => false, + child: BlocConsumer( + listener: (BuildContext context, state) { + print('state=$state'); + if (state is HomeInitial) { + if (homeBloc.user!.hasAcceptedWebAgreement == false && + !_dialogShown) { + _dialogShown = + true; // Set the flag to true to indicate the dialog is showing. + Future.delayed(const Duration(seconds: 1), () { + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AgreementAndPrivacyDialog( + terms: homeBloc.terms, + policy: homeBloc.policy, + ); + }, + ).then((v) { + _dialogShown = false; + if (v != null) { + homeBloc.add(ConfirmUserAgreementEvent()); + homeBloc.add(const FetchUserInfo()); + } }); - } + }); } - }, - builder: (context, state) { - return WebScaffold( - enableMenuSidebar: false, - appBarTitle: Row( + } + }, + builder: (context, state) { + return WebScaffold( + enableMenuSidebar: false, + appBarTitle: Row( + children: [ + SvgPicture.asset( + Assets.loginLogo, + width: 150, + ), + ], + ), + scaffoldBody: SizedBox( + height: size.height, + width: size.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - SvgPicture.asset( - Assets.loginLogo, - width: 150, + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: size.height * 0.1), + Text( + 'ACCESS YOUR APPS', + style: Theme.of(context) + .textTheme + .headlineLarge! + .copyWith(color: Colors.black, fontSize: 40), + ), + const SizedBox(height: 30), + Expanded( + flex: 4, + child: SizedBox( + height: size.height * 0.6, + width: size.width * 0.68, + child: GridView.builder( + itemCount: 3, // Change this count if needed. + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, // Adjust as needed. + crossAxisSpacing: 20.0, + mainAxisSpacing: 20.0, + childAspectRatio: 1.5, + ), + itemBuilder: (context, index) { + return HomeCard( + index: index, + active: homeBloc.homeItems[index].active!, + name: homeBloc.homeItems[index].title!, + img: homeBloc.homeItems[index].icon!, + onTap: () => + homeBloc.homeItems[index].onPress(context), + ); + }, + ), + ), + ), + ], ), ], ), - scaffoldBody: SizedBox( - height: size.height, - width: size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox(height: size.height * 0.1), - Text( - 'ACCESS YOUR APPS', - style: Theme.of(context) - .textTheme - .headlineLarge! - .copyWith(color: Colors.black, fontSize: 40), - ), - const SizedBox(height: 30), - Expanded( - flex: 4, - child: SizedBox( - height: size.height * 0.6, - width: size.width * 0.68, - child: GridView.builder( - itemCount: 3, //8 - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, //4 - crossAxisSpacing: 20.0, - mainAxisSpacing: 20.0, - childAspectRatio: 1.5, - ), - itemBuilder: (context, index) { - return HomeCard( - index: index, - active: homeBloc.homeItems[index].active!, - name: homeBloc.homeItems[index].title!, - img: homeBloc.homeItems[index].icon!, - onTap: () => homeBloc.homeItems[index].onPress(context), - ); - }, - ), - ), - ), - ], - ), - ], - ), - ), - ); - }, - )); + ), + ); + }, + ), + ); } } diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart index 16d6cbe6..96e49040 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/bloc/users_bloc.dart @@ -79,7 +79,7 @@ class UsersBloc extends Bloc { List updatedCommunities = []; List spacesNodes = []; - List communityIds = []; + List communityIds = []; _onLoadCommunityAndSpaces( LoadCommunityAndSpacesEvent event, Emitter emit) async { try { @@ -102,12 +102,19 @@ class UsersBloc extends Bloc { ); }).toList(), ); + originalCommunities = updatedCommunities; emit(const SpacesLoadedState()); } catch (e) { emit(ErrorState('Error loading communities and spaces: $e')); } } +// This variable holds the full original list. + List originalCommunities = []; + +// This variable holds the working list that may be filtered. + +// Build tree nodes from your data model. List _buildTreeNodes(List spaces) { return spaces.map((space) { List childNodes = @@ -123,12 +130,39 @@ class UsersBloc extends Bloc { }).toList(); } +// Optional helper method to deep clone a TreeNode. + TreeNode _cloneNode(TreeNode node) { + return TreeNode( + uuid: node.uuid, + title: node.title, + isChecked: node.isChecked, + isHighlighted: node.isHighlighted, + isExpanded: node.isExpanded, + children: node.children.map(_cloneNode).toList(), + ); + } + +// Clone an entire list of tree nodes. + List _cloneNodes(List nodes) { + return nodes.map(_cloneNode).toList(); + } + +// Your search event handler. void searchTreeNode(SearchAnode event, Emitter emit) { emit(UsersLoadingState()); + + // If the search term is empty, restore the original list. if (event.searchTerm!.isEmpty) { + // Clear any highlights on the restored copy. + updatedCommunities = _cloneNodes(originalCommunities); _clearHighlights(updatedCommunities); } else { - _searchAndHighlightNodes(updatedCommunities, event.searchTerm!); + // Start with a fresh clone of the original tree. + List freshClone = _cloneNodes(originalCommunities); + + _searchAndHighlightNodes(freshClone, event.searchTerm!); + + updatedCommunities = _filterNodes(freshClone, event.searchTerm!); } emit(ChangeStatusSteps()); } @@ -155,6 +189,91 @@ class UsersBloc extends Bloc { return anyMatch; } + List _filterNodes(List nodes, String searchTerm) { + List filteredNodes = []; + for (var node in nodes) { + bool isMatch = + node.title.toLowerCase().contains(searchTerm.toLowerCase()); + List filteredChildren = _filterNodes(node.children, searchTerm); + if (isMatch || filteredChildren.isNotEmpty) { + node.isHighlighted = isMatch; + node.children = filteredChildren; + filteredNodes.add(node); + } + } + return filteredNodes; + } + + // List _buildTreeNodes(List spaces) { + // return spaces.map((space) { + // List childNodes = + // space.children.isNotEmpty ? _buildTreeNodes(space.children) : []; + // return TreeNode( + // uuid: space.uuid!, + // title: space.name, + // isChecked: false, + // isHighlighted: false, + // isExpanded: childNodes.isNotEmpty, + // children: childNodes, + // ); + // }).toList(); + // } + + // void searchTreeNode(SearchAnode event, Emitter emit) { + // emit(UsersLoadingState()); + // if (event.searchTerm!.isEmpty) { + // _clearHighlights(updatedCommunities); + // } else { + // _searchAndHighlightNodes(updatedCommunities, event.searchTerm!); + // updatedCommunities = _filterNodes(updatedCommunities, event.searchTerm!); + // } + // emit(ChangeStatusSteps()); + // } + + // void _clearHighlights(List nodes) { + // for (var node in nodes) { + // node.isHighlighted = false; + // if (node.children.isNotEmpty) { + // _clearHighlights(node.children); + // } + // } + // } + + // bool _searchAndHighlightNodes(List nodes, String searchTerm) { + // bool anyMatch = false; + // for (var node in nodes) { + // bool isMatch = + // node.title.toLowerCase().contains(searchTerm.toLowerCase()); + // bool childMatch = _searchAndHighlightNodes(node.children, searchTerm); + // node.isHighlighted = isMatch || childMatch; + + // anyMatch = anyMatch || node.isHighlighted; + // } + // return anyMatch; + // } + + // List _filterNodes(List nodes, String searchTerm) { + // List filteredNodes = []; + // for (var node in nodes) { + // // Check if the current node's title contains the search term. + // bool isMatch = + // node.title.toLowerCase().contains(searchTerm.toLowerCase()); + + // // Recursively filter the children. + // List filteredChildren = _filterNodes(node.children, searchTerm); + + // // If the current node is a match or any of its children are, include it. + // if (isMatch || filteredChildren.isNotEmpty) { + // // Optionally, update any properties (like isHighlighted) if you still need them. + // node.isHighlighted = isMatch; + // // Replace the children with the filtered ones. + // node.children = filteredChildren; + // filteredNodes.add(node); + // } + // } + // return filteredNodes; + // } + List selectedIds = []; List getSelectedIds(List nodes) { @@ -221,7 +340,7 @@ class UsersBloc extends Bloc { lastName: lastNameController.text, phoneNumber: phoneController.text, roleUuid: roleSelected, - spaceUuids: selectedIds, + spaceUuids: selectedIds, ); if (res) { @@ -251,12 +370,11 @@ class UsersBloc extends Bloc { } } - _editInviteUser(EditInviteUsers event, Emitter emit) async { try { emit(UsersLoadingState()); List selectedIds = getSelectedIds(updatedCommunities) - .where((id) => !communityIds.contains(id)) + .where((id) => !communityIds.contains(id)) .toList(); bool res = await UserPermissionApi().editInviteUser( diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart index ec35b3fd..e4cf6107 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/add_user_dialog.dart @@ -26,126 +26,126 @@ class _AddNewUserDialogState extends State { create: (BuildContext context) => UsersBloc() ..add(const LoadCommunityAndSpacesEvent()) ..add(const RoleEvent()), - child: BlocConsumer( - listener: (context, state) {}, - builder: (context, state) { - final _blocRole = BlocProvider.of(context); + child: BlocConsumer(listener: (context, state) { + // print('88888==${state}'); + // if (state is SpacesLoadedState) { + // print('object'); + // _blocRole.add(const CheckRoleStepStatus()); + // } + }, builder: (context, state) { + final _blocRole = BlocProvider.of(context); - return Dialog( - child: Container( - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(20))), - width: 900, - child: Column( - children: [ - // Title - const Padding( - padding: EdgeInsets.all(8.0), - child: SizedBox( - child: Text( - "Add New User", - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w700, - color: ColorsManager.secondaryColor), + return Dialog( + child: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(20))), + width: 900, + child: Column( + children: [ + // Title + const Padding( + padding: EdgeInsets.all(8.0), + child: SizedBox( + child: Text( + "Add New User", + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w700, + color: ColorsManager.secondaryColor), + ), + ), + ), + const Divider(), + Expanded( + child: Row( + children: [ + Expanded( + child: Container( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildStep1Indicator(1, "Basics", _blocRole), + _buildStep2Indicator(2, "Spaces", _blocRole), + _buildStep3Indicator( + 3, "Role & Permissions", _blocRole), + ], + ), ), ), - ), - const Divider(), - Expanded( - child: Row( - children: [ - Expanded( - child: Container( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildStep1Indicator(1, "Basics", _blocRole), - _buildStep2Indicator(2, "Spaces", _blocRole), - _buildStep3Indicator( - 3, "Role & Permissions", _blocRole), - ], - ), - ), - ), - Container( - width: 1, - color: ColorsManager.grayBorder, - ), - Expanded( - flex: 2, - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 10), - Expanded( - child: _getFormContent(), - ), - const SizedBox(height: 20), - ], - ), - ), - ), - ], + Container( + width: 1, + color: ColorsManager.grayBorder, ), - ), - const Divider(), - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - InkWell( - onTap: () { - Navigator.of(context).pop(); - }, - child: const Text("Cancel"), + Expanded( + flex: 2, + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + Expanded( + child: _getFormContent(), + ), + const SizedBox(height: 20), + ], ), - InkWell( - onTap: () { - _blocRole.add(const CheckEmailEvent()); - - setState(() { - if (currentStep < 3) { - currentStep++; - if (currentStep == 2) { - _blocRole.add( - const CheckStepStatus(isEditUser: false)); - } else if (currentStep == 3) { - _blocRole - .add(const CheckSpacesStepStatus()); - } - } else { - _blocRole - .add(SendInviteUsers(context: context)); - } - }); - }, - child: Text( - currentStep < 3 ? "Next" : "Save", - style: TextStyle( - color: (_blocRole.isCompleteSpaces == false || - _blocRole.isCompleteBasics == - false || - _blocRole - .isCompleteRolePermissions == - false) && - currentStep == 3 - ? ColorsManager.grayColor - : ColorsManager.secondaryColor), - ), - ), - ], + ), ), - ), - ], + ], + ), ), - )); - })); + const Divider(), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: const Text("Cancel"), + ), + InkWell( + onTap: () { + _blocRole.add(const CheckEmailEvent()); + + setState(() { + if (currentStep < 3) { + currentStep++; + if (currentStep == 2) { + _blocRole.add( + const CheckStepStatus(isEditUser: false)); + } else if (currentStep == 3) { + _blocRole.add(const CheckSpacesStepStatus()); + } + } else { + _blocRole.add(SendInviteUsers(context: context)); + } + }); + }, + child: Text( + currentStep < 3 ? "Next" : "Save", + style: TextStyle( + color: (_blocRole.isCompleteSpaces == false || + _blocRole.isCompleteBasics == false || + _blocRole.isCompleteRolePermissions == + false) && + currentStep == 3 + ? ColorsManager.grayColor + : ColorsManager.secondaryColor), + ), + ), + ], + ), + ), + ], + ), + )); + })); } Widget _getFormContent() { @@ -236,12 +236,16 @@ class _AddNewUserDialogState extends State { return GestureDetector( onTap: () { setState(() { - currentStep = step; bloc.add(const CheckStepStatus(isEditUser: false)); + currentStep = step; + Future.delayed(const Duration(milliseconds: 500), () { + bloc.add(const CheckStepStatus(isEditUser: false)); + }); if (step3 == 3) { - bloc.add(const CheckRoleStepStatus()); + Future.delayed(const Duration(seconds: 1), () { + bloc.add(const CheckRoleStepStatus()); + }); } - }); }, child: Column( diff --git a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart index 308c6c67..fa04c051 100644 --- a/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart +++ b/lib/pages/roles_and_permission/users_page/add_user_dialog/view/basics_view.dart @@ -46,117 +46,120 @@ class BasicsView extends StatelessWidget { ), Row( children: [ - SizedBox( - width: MediaQuery.of(context).size.width * 0.18, - height: MediaQuery.of(context).size.width * 0.08, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - child: Row( - children: [ - const Text( - " * ", - style: TextStyle( - color: ColorsManager.red, - fontWeight: FontWeight.w900, - fontSize: 15, + Flexible( + child: SizedBox( + // width: MediaQuery.of(context).size.width * 0.18, + height: MediaQuery.of(context).size.width * 0.08, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + child: Row( + children: [ + const Text( + " * ", + style: TextStyle( + color: ColorsManager.red, + fontWeight: FontWeight.w900, + fontSize: 15, + ), ), - ), - Text( - 'First Name', - style: context.textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w400, - fontSize: 13, - ), - ), - ], - )), - Padding( - padding: const EdgeInsets.all(8.0), - child: TextFormField( - style: - const TextStyle(color: ColorsManager.blackColor), - // onChanged: (value) { - // Future.delayed(const Duration(milliseconds: 200), - // () { - // _blocRole.add(const ValidateBasicsStep()); - // }); - // }, - controller: _blocRole.firstNameController, - decoration: inputTextFormDeco( - hintText: "Enter first name", - ).copyWith( - hintStyle: context.textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w400, - fontSize: 12, - color: ColorsManager.textGray), - ), - validator: (value) { - if (value == null || value.isEmpty) { - return 'Enter first name'; - } - return null; - }, - ), - ), - ], - ), - ), - const SizedBox(width: 10), - SizedBox( - width: MediaQuery.of(context).size.width * 0.18, - height: MediaQuery.of(context).size.width * 0.08, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - child: Row( - children: [ - const Text( - " * ", - style: TextStyle( - color: ColorsManager.red, - fontWeight: FontWeight.w900, - fontSize: 15, - ), - ), - Text('Last Name', + Text( + 'First Name', style: context.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w400, fontSize: 13, - )), - ], - )), - Padding( - padding: const EdgeInsets.all(8.0), - child: TextFormField( - // onChanged: (value) { - // Future.delayed(const Duration(milliseconds: 200), - // () { - // _blocRole.add(ValidateBasicsStep()); - // }); - // }, - controller: _blocRole.lastNameController, - style: const TextStyle(color: Colors.black), - decoration: - inputTextFormDeco(hintText: "Enter last name") - .copyWith( - hintStyle: context - .textTheme.bodyMedium - ?.copyWith( - fontWeight: FontWeight.w400, - fontSize: 12, - color: ColorsManager.textGray)), - validator: (value) { - if (value == null || value.isEmpty) { - return 'Enter last name'; - } - return null; - }, + ), + ), + ], + )), + Padding( + padding: const EdgeInsets.all(8.0), + child: TextFormField( + style: const TextStyle( + color: ColorsManager.blackColor), + // onChanged: (value) { + // Future.delayed(const Duration(milliseconds: 200), + // () { + // _blocRole.add(const ValidateBasicsStep()); + // }); + // }, + controller: _blocRole.firstNameController, + decoration: inputTextFormDeco( + hintText: "Enter first name", + ).copyWith( + hintStyle: context.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w400, + fontSize: 12, + color: ColorsManager.textGray), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Enter first name'; + } + return null; + }, + ), ), - ), - ], + ], + ), + ), + ), + const SizedBox(width: 10), + Flexible( + child: SizedBox( + // width: MediaQuery.of(context).size.width * 0.18, + height: MediaQuery.of(context).size.width * 0.08, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + child: Row( + children: [ + const Text( + " * ", + style: TextStyle( + color: ColorsManager.red, + fontWeight: FontWeight.w900, + fontSize: 15, + ), + ), + Text('Last Name', + style: context.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w400, + fontSize: 13, + )), + ], + )), + Padding( + padding: const EdgeInsets.all(8.0), + child: TextFormField( + // onChanged: (value) { + // Future.delayed(const Duration(milliseconds: 200), + // () { + // _blocRole.add(ValidateBasicsStep()); + // }); + // }, + controller: _blocRole.lastNameController, + style: const TextStyle(color: Colors.black), + decoration: + inputTextFormDeco(hintText: "Enter last name") + .copyWith( + hintStyle: context.textTheme.bodyMedium + ?.copyWith( + fontWeight: FontWeight.w400, + fontSize: 12, + color: ColorsManager.textGray)), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Enter last name'; + } + return null; + }, + ), + ), + ], + ), ), ), ], diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart index 3d09e5b4..713b03f0 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_bloc.dart @@ -27,7 +27,16 @@ class UserTableBloc extends Bloc { int currentPage = 1; List users = []; List initialUsers = []; + + List totalUsersCount = []; String currentSortOrder = ''; + + String currentSortJopTitle = ''; + String currentSortRole = ''; + String currentSortCreatedDate = ''; + String currentSortStatus = ''; + String currentSortCreatedBy = ''; + String currentSortOrderDate = ''; List roleTypes = []; List jobTitle = []; @@ -60,6 +69,7 @@ class UserTableBloc extends Bloc { jobTitle = jobTitle.toSet().toList(); createdBy = createdBy.toSet().toList(); _handlePageChange(ChangePage(1), emit); + totalUsersCount = initialUsers; add(ChangePage(currentPage)); emit(UsersLoadedState(users: users)); } catch (e) { @@ -91,26 +101,6 @@ class UserTableBloc extends Bloc { event.userId, event.newStatus == "disabled" ? false : true); if (res == true) { add(const GetUsers()); - // users = users.map((user) { - // if (user.uuid == event.userId) { - // return RolesUserModel( - // uuid: user.uuid, - // createdAt: user.createdAt, - // email: user.email, - // firstName: user.firstName, - // lastName: user.lastName, - // roleType: user.roleType, - // status: event.newStatus, - // isEnabled: event.newStatus == "disabled" ? false : true, - // invitedBy: user.invitedBy, - // phoneNumber: user.phoneNumber, - // jobTitle: user.jobTitle, - // createdDate: user.createdDate, - // createdTime: user.createdTime, - // ); - // } - // return user; - // }).toList(); } emit(UsersLoadedState(users: users)); } catch (e) { @@ -128,7 +118,6 @@ class UserTableBloc extends Bloc { emit(UsersLoadingState()); currentSortOrder = ""; users = List.from(users); - emit(UsersLoadedState(users: users)); } else { emit(UsersLoadingState()); currentSortOrder = "Asc"; @@ -136,8 +125,12 @@ class UserTableBloc extends Bloc { .toString() .toLowerCase() .compareTo(b.firstName.toString().toLowerCase())); - emit(UsersLoadedState(users: users)); } + currentSortJopTitle = ''; + currentSortCreatedDate = ''; + currentSortStatus = ''; + currentSortCreatedBy = ''; + emit(UsersLoadedState(users: users)); } void _toggleSortUsersByNameDesc( @@ -150,13 +143,16 @@ class UserTableBloc extends Bloc { emit(UsersLoadingState()); currentSortOrder = ""; users = List.from(initialUsers); - emit(UsersLoadedState(users: users)); } else { emit(UsersLoadingState()); currentSortOrder = "Desc"; users.sort((a, b) => b.firstName!.compareTo(a.firstName!)); - emit(UsersLoadedState(users: users)); } + currentSortJopTitle = ''; + currentSortCreatedDate = ''; + currentSortStatus = ''; + currentSortCreatedBy = ''; + emit(UsersLoadedState(users: users)); } void _toggleSortUsersByDateNewestToOldest( @@ -222,6 +218,7 @@ class UserTableBloc extends Bloc { Future _searchUsers( SearchUsers event, Emitter emit) async { try { + emit(TableSearch()); final query = event.query.toLowerCase(); final filteredUsers = initialUsers.where((user) { final fullName = "${user.firstName} ${user.lastName}".toLowerCase(); @@ -250,7 +247,8 @@ class UserTableBloc extends Bloc { } void _handlePageChange(ChangePage event, Emitter emit) { - const itemsPerPage = 10; + currentPage = event.pageNumber; + const itemsPerPage = 20; final startIndex = (event.pageNumber - 1) * itemsPerPage; final endIndex = startIndex + itemsPerPage; if (startIndex >= users.length) { @@ -287,9 +285,15 @@ class UserTableBloc extends Bloc { } else if (event.sortOrder == "Desc") { currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); - } else { - currentSortOrder = ""; - } + } else {} + currentSortOrder = ""; + currentSortCreatedDate = ''; + currentSortStatus = ''; + currentSortCreatedBy = ''; + currentSortJopTitle = ''; + currentSortOrderDate = ""; + + totalUsersCount = filteredUsers; emit(UsersLoadedState(users: filteredUsers)); } @@ -311,9 +315,16 @@ class UserTableBloc extends Bloc { } else if (event.sortOrder == "Desc") { currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); - } else { - currentSortOrder = ""; - } + } else {} + currentSortOrder = ""; + currentSortCreatedDate = ''; + currentSortStatus = ''; + currentSortCreatedBy = ''; + currentSortRole = ''; + currentSortOrderDate = ""; + + totalUsersCount = filteredUsers; + emit(UsersLoadedState(users: filteredUsers)); } @@ -335,9 +346,15 @@ class UserTableBloc extends Bloc { } else if (event.sortOrder == "Desc") { currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); - } else { - currentSortOrder = ""; - } + } else {} + currentSortOrder = ''; + currentSortRole = ''; + currentSortCreatedDate = ''; + currentSortStatus = ''; + currentSortOrderDate = ""; + + totalUsersCount = filteredUsers; + emit(UsersLoadedState(users: filteredUsers)); } @@ -371,14 +388,17 @@ class UserTableBloc extends Bloc { } else if (event.sortOrder == "Desc") { currentSortOrder = "Desc"; filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!)); - } else { - currentSortOrder = ""; - } + totalUsersCount = filteredUsers; + } else {} + currentSortOrder = ''; + currentSortRole = ''; + currentSortCreatedDate = ''; + currentSortCreatedBy = ''; + currentSortOrderDate = ""; emit(UsersLoadedState(users: filteredUsers)); } - void _resetAllFilters(Emitter emit) { selectedRoles.clear(); selectedJobTitles.clear(); diff --git a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart index 62037315..ae99af3a 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/bloc/user_table_state.dart @@ -9,7 +9,10 @@ final class TableInitial extends UserTableState { @override List get props => []; } - +final class TableSearch extends UserTableState { + @override + List get props => []; +} final class RolesLoadingState extends UserTableState { @override List get props => []; diff --git a/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart b/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart index ddfe63ff..eb2c2142 100644 --- a/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart +++ b/lib/pages/roles_and_permission/users_page/users_table/view/users_page.dart @@ -129,9 +129,12 @@ class UsersPage extends StatelessWidget { child: TextFormField( controller: searchController, onChanged: (value) { - context - .read() - .add(SearchUsers(value)); + final bloc = context.read(); + bloc.add(FilterClearEvent()); + bloc.add(SearchUsers(value)); + if (value == '') { + bloc.add(ChangePage(1)); + } }, style: const TextStyle(color: Colors.black), decoration: textBoxDecoration(radios: 15)!.copyWith( @@ -222,7 +225,7 @@ class UsersPage extends StatelessWidget { list: _blocRole.jobTitle, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortOrder, + isSelected: _blocRole.currentSortJopTitle, onOkPressed: () { searchController.clear(); _blocRole.add(FilterClearEvent()); @@ -233,14 +236,14 @@ class UsersPage extends StatelessWidget { Navigator.of(context).pop(); _blocRole.add(FilterUsersByJobEvent( selectedJob: selectedItems, - sortOrder: _blocRole.currentSortOrder, + sortOrder: _blocRole.currentSortJopTitle, )); }, onSortAtoZ: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortJopTitle = v; }, onSortZtoA: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortJopTitle = v; }, ); } @@ -263,7 +266,7 @@ class UsersPage extends StatelessWidget { list: _blocRole.roleTypes, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortOrder, + isSelected: _blocRole.currentSortRole, onOkPressed: () { searchController.clear(); _blocRole.add(FilterClearEvent()); @@ -275,13 +278,13 @@ class UsersPage extends StatelessWidget { context.read().add( FilterUsersByRoleEvent( selectedRoles: selectedItems, - sortOrder: _blocRole.currentSortOrder)); + sortOrder: _blocRole.currentSortRole)); }, onSortAtoZ: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortRole = v; }, onSortZtoA: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortRole = v; }, ); } @@ -319,7 +322,7 @@ class UsersPage extends StatelessWidget { list: _blocRole.createdBy, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortOrder, + isSelected: _blocRole.currentSortCreatedBy, onOkPressed: () { searchController.clear(); _blocRole.add(FilterClearEvent()); @@ -330,13 +333,13 @@ class UsersPage extends StatelessWidget { Navigator.of(context).pop(); _blocRole.add(FilterUsersByCreatedEvent( selectedCreatedBy: selectedItems, - sortOrder: _blocRole.currentSortOrder)); + sortOrder: _blocRole.currentSortCreatedBy)); }, onSortAtoZ: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortCreatedBy = v; }, onSortZtoA: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortCreatedBy = v; }, ); } @@ -359,7 +362,7 @@ class UsersPage extends StatelessWidget { list: _blocRole.status, context: context, checkboxStates: checkboxStates, - isSelected: _blocRole.currentSortOrder, + isSelected: _blocRole.currentSortStatus, onOkPressed: () { searchController.clear(); _blocRole.add(FilterClearEvent()); @@ -370,13 +373,13 @@ class UsersPage extends StatelessWidget { Navigator.of(context).pop(); _blocRole.add(FilterUsersByDeActevateEvent( selectedActivate: selectedItems, - sortOrder: _blocRole.currentSortOrder)); + sortOrder: _blocRole.currentSortStatus)); }, onSortAtoZ: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortStatus = v; }, onSortZtoA: (v) { - _blocRole.currentSortOrder = v; + _blocRole.currentSortStatus = v; }, ); } @@ -508,12 +511,11 @@ class UsersPage extends StatelessWidget { const Icon(Icons.keyboard_double_arrow_right), firstPageIcon: const Icon(Icons.keyboard_double_arrow_left), - totalPages: (_blocRole.users.length / + totalPages: (_blocRole.totalUsersCount.length / _blocRole.itemsPerPage) .ceil(), currentPage: _blocRole.currentPage, onPageChanged: (int pageNumber) { - _blocRole.currentPage = pageNumber; context .read() .add(ChangePage(pageNumber));