From 19d585958273a4b6513ac0b74c7e61901934269e Mon Sep 17 00:00:00 2001 From: andongyeon Date: Sat, 6 Sep 2025 23:40:33 +0900 Subject: [PATCH 1/6] fix: serialization by renaming authorities to permission --- .../groups/data/data_sources/models/create_role_model.dart | 2 +- .../modules/groups/data/data_sources/models/role_model.dart | 2 +- .../groups/data/data_sources/models/update_role_model.dart | 2 +- lib/app/modules/groups/domain/entities/authority_entity.dart | 4 ++-- lib/app/modules/groups/domain/entities/role_entity.dart | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/app/modules/groups/data/data_sources/models/create_role_model.dart b/lib/app/modules/groups/data/data_sources/models/create_role_model.dart index 00687b808..759da412d 100644 --- a/lib/app/modules/groups/data/data_sources/models/create_role_model.dart +++ b/lib/app/modules/groups/data/data_sources/models/create_role_model.dart @@ -7,7 +7,7 @@ part 'create_role_model.g.dart'; sealed class CreateRoleModel with _$CreateRoleModel { factory CreateRoleModel({ required String name, - required List authorities, + required List permissions, }) = _CreateRoleModel; factory CreateRoleModel.fromJson(Map json) => diff --git a/lib/app/modules/groups/data/data_sources/models/role_model.dart b/lib/app/modules/groups/data/data_sources/models/role_model.dart index b405230ee..165240bc5 100644 --- a/lib/app/modules/groups/data/data_sources/models/role_model.dart +++ b/lib/app/modules/groups/data/data_sources/models/role_model.dart @@ -11,7 +11,7 @@ sealed class RoleModel with _$RoleModel implements RoleEntity { required int id, required GroupMemberRole name, required String groupUuid, - required List authorities, + required List permissions, }) = _RoleModel; factory RoleModel.fromJson(Map json) => diff --git a/lib/app/modules/groups/data/data_sources/models/update_role_model.dart b/lib/app/modules/groups/data/data_sources/models/update_role_model.dart index 9809ca65f..f8ffe9595 100644 --- a/lib/app/modules/groups/data/data_sources/models/update_role_model.dart +++ b/lib/app/modules/groups/data/data_sources/models/update_role_model.dart @@ -6,7 +6,7 @@ part 'update_role_model.g.dart'; @freezed sealed class UpdateRoleModel with _$UpdateRoleModel { factory UpdateRoleModel( - List authorities, + List permissions, ) = _UpdateRoleModel; factory UpdateRoleModel.fromJson(Map json) => diff --git a/lib/app/modules/groups/domain/entities/authority_entity.dart b/lib/app/modules/groups/domain/entities/authority_entity.dart index a3a783b79..8ed722ab8 100644 --- a/lib/app/modules/groups/domain/entities/authority_entity.dart +++ b/lib/app/modules/groups/domain/entities/authority_entity.dart @@ -1,5 +1,5 @@ class AuthorityEntity { - final List authorities; + final List permissions; - AuthorityEntity({required this.authorities}); + AuthorityEntity({required this.permissions}); } diff --git a/lib/app/modules/groups/domain/entities/role_entity.dart b/lib/app/modules/groups/domain/entities/role_entity.dart index d667e5335..2fc118506 100644 --- a/lib/app/modules/groups/domain/entities/role_entity.dart +++ b/lib/app/modules/groups/domain/entities/role_entity.dart @@ -4,12 +4,12 @@ class RoleEntity { final int id; final GroupMemberRole name; final String groupUuid; - final List authorities; + final List permissions; RoleEntity({ required this.id, required this.name, required this.groupUuid, - required this.authorities, + required this.permissions, }); } From fe17df06324022d9d7f5284f90d0b3489e945479 Mon Sep 17 00:00:00 2001 From: andongyeon Date: Sun, 7 Sep 2025 05:06:33 +0900 Subject: [PATCH 2/6] feat: update translation --- assets/i18n/strings.i18n.json | 9 +++++++-- assets/i18n/strings_jp.i18n.json | 9 +++++++-- assets/i18n/strings_ko.i18n.json | 9 +++++++-- assets/i18n/strings_ru.i18n.json | 9 +++++++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/assets/i18n/strings.i18n.json b/assets/i18n/strings.i18n.json index 2ddc49d86..c73281d34 100644 --- a/assets/i18n/strings.i18n.json +++ b/assets/i18n/strings.i18n.json @@ -34,7 +34,8 @@ "profile": { "name": { "label": "Group Name", - "hint": "인포팀 (Infoteam)" + "hint": "인포팀 (Infoteam)", + "sameNameError": "Group name already exists" } }, "introduce": { @@ -87,7 +88,8 @@ "header": "Update Notion Page Link", "hintText": "Enter Notion Link", "loading": "Loading Notion...", - "error": "Failed Loading Notion Link" + "error": "Failed Loading Notion Link", + "empty": "Please enter the Notion link" }, "invite": { "header": "Generate Invite Link", @@ -106,10 +108,13 @@ "memberCard": { "role": { "role": "Role", + "president": "President", "admin": "Admin", "manager": "Manager", "member": "Member" }, + "changePresidentTitle": "Would you like to make $name a president?", + "changePresidentDescription": "Your permissions will be changed to Admin.", "banish": "Banish", "banishTitle": "Are you sure you want to banish this member?", "banishDescription": "This action cannot be undone." diff --git a/assets/i18n/strings_jp.i18n.json b/assets/i18n/strings_jp.i18n.json index 52cb3347f..74251ab14 100644 --- a/assets/i18n/strings_jp.i18n.json +++ b/assets/i18n/strings_jp.i18n.json @@ -34,7 +34,8 @@ "profile": { "name": { "label": "グループ名", - "hint": "インフォチーム (Infoteam)" + "hint": "インフォチーム (Infoteam)", + "sameNameError": "グループ名はすでに存在します" } }, "introduce": { @@ -87,7 +88,8 @@ "header": "ノーションページリンクを更新", "hintText": "ノーションリンクを入力してください", "loading": "Notionを読み込み中...", - "error": "ノーションのリンクの読み込みに失敗しました" + "error": "ノーションのリンクの読み込みに失敗しました", + "empty": "ノーションリンクを入力してください" }, "invite": { "header": "招待リンクを生成", @@ -106,10 +108,13 @@ "memberCard": { "role": { "role": "役割", + "president": "社長", "admin": "管理者", "manager": "マネージャー", "member": "メンバー" }, + "changePresidentTitle": "? $name", + "changePresidentDescription": "?", "banish": "追放", "banishTitle": "本当にこのメンバーを追放しますか?", "banishDescription": "この操作は元に戻せません。" diff --git a/assets/i18n/strings_ko.i18n.json b/assets/i18n/strings_ko.i18n.json index 020de6d20..ffe6a58ba 100644 --- a/assets/i18n/strings_ko.i18n.json +++ b/assets/i18n/strings_ko.i18n.json @@ -34,7 +34,8 @@ "profile": { "name": { "label": "그룹명", - "hint": "인포팀 (Infoteam)" + "hint": "인포팀 (Infoteam)", + "sameNameError": "그룹 이름이 이미 존재합니다" } }, "introduce": { @@ -87,7 +88,8 @@ "header": "노션 페이지 링크 변경", "hintText": "노션 링크 입력", "loading": "노션 불러오는 중...", - "error": "노션 불러오기 실패" + "error": "노션 불러오기 실패", + "empty": "노션 링크를 입력해주세요" }, "invite": { "header": "초대 링크 생성", @@ -106,10 +108,13 @@ "memberCard": { "role": { "role": "역할", + "president": "그룹장", "admin": "관리자", "manager": "매니저", "member": "멤버" }, + "changePresidentTitle": "$name님을 그룹장으로 만드시겠습니까?", + "changePresidentDescription": "당신의 권한은 관리자로 변경됩니다.", "banish": "추방", "banishTitle": "정말 이 멤버를 추방하시겠습니까?", "banishDescription": "이 작업은 되돌릴 수 없습니다." diff --git a/assets/i18n/strings_ru.i18n.json b/assets/i18n/strings_ru.i18n.json index 8735ef226..73df122fc 100644 --- a/assets/i18n/strings_ru.i18n.json +++ b/assets/i18n/strings_ru.i18n.json @@ -34,7 +34,8 @@ "profile": { "name": { "label": "Название группы", - "hint": "ИнфоТим (Infoteam)" + "hint": "ИнфоТим (Infoteam)", + "sameNameError": "Имя группы уже существует" } }, "introduce": { @@ -87,7 +88,8 @@ "header": "Обновить ссылку на страницу Notion", "hintText": "Введите ссылку на Notion", "loading": "Загрузка Notion...", - "error": "Не удалось загрузить ссылку на Notion" + "error": "Не удалось загрузить ссылку на Notion", + "empty": "Пожалуйста, введите ссылку на Notion" }, "invite": { "header": "Создать ссылку для приглашения", @@ -106,10 +108,13 @@ "memberCard": { "role": { "role": "Роль", + "president": "президент", "admin": "Администратор", "manager": "Менеджер", "member": "член" }, + "changePresidentTitle": "? $name", + "changePresidentDescription": "?", "banish": "Исключить", "banishTitle": "Вы уверены, что хотите исключить этого участника?", "banishDescription": "Это действие нельзя отменить." From ebb05fc6f40fffcf8200c2678b006f59670ad27e Mon Sep 17 00:00:00 2001 From: andongyeon Date: Sun, 7 Sep 2025 05:06:55 +0900 Subject: [PATCH 3/6] feat: add update president model --- .../models/update_president_model.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/app/modules/groups/data/data_sources/models/update_president_model.dart diff --git a/lib/app/modules/groups/data/data_sources/models/update_president_model.dart b/lib/app/modules/groups/data/data_sources/models/update_president_model.dart new file mode 100644 index 000000000..d1d61ffe9 --- /dev/null +++ b/lib/app/modules/groups/data/data_sources/models/update_president_model.dart @@ -0,0 +1,14 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'update_president_model.freezed.dart'; +part 'update_president_model.g.dart'; + +@freezed +sealed class UpdatePresidentModel with _$UpdatePresidentModel { + factory UpdatePresidentModel( + String newPresidentUuid, + ) = _UpdatePresidentModel; + + factory UpdatePresidentModel.fromJson(Map json) => + _$UpdatePresidentModelFromJson(json); +} From 1da6a96b23b6d6b4177495a42dcd43f8398b7714 Mon Sep 17 00:00:00 2001 From: andongyeon Date: Sun, 7 Sep 2025 05:08:09 +0900 Subject: [PATCH 4/6] feat: add change president api --- .../data/data_sources/remote/group_api.dart | 3 +- .../repositories/rest_group_repository.dart | 7 +++++ .../domain/repository/group_repository.dart | 4 +++ .../presentation/blocs/group_member_bloc.dart | 31 +++++++++++++++++-- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/lib/app/modules/groups/data/data_sources/remote/group_api.dart b/lib/app/modules/groups/data/data_sources/remote/group_api.dart index a46a8415c..98ec0dad7 100644 --- a/lib/app/modules/groups/data/data_sources/remote/group_api.dart +++ b/lib/app/modules/groups/data/data_sources/remote/group_api.dart @@ -13,6 +13,7 @@ import 'package:ziggle/app/modules/groups/data/data_sources/models/member_list_m import 'package:ziggle/app/modules/groups/data/data_sources/models/modify_group_model.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/models/role_list_model.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/models/role_model.dart'; +import 'package:ziggle/app/modules/groups/data/data_sources/models/update_president_model.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/models/update_role_model.dart'; part 'group_api.g.dart'; @@ -104,7 +105,7 @@ abstract class GroupApi { @PATCH('{uuid}/president') Future updatePresident( @Path('uuid') String uuid, - @Body() Map newPresidentUuid, + @Body() UpdatePresidentModel newPresidentUuid, ); @GET('{groupUuid}/role') diff --git a/lib/app/modules/groups/data/repositories/rest_group_repository.dart b/lib/app/modules/groups/data/repositories/rest_group_repository.dart index 9e896cb0a..a00d43b99 100644 --- a/lib/app/modules/groups/data/repositories/rest_group_repository.dart +++ b/lib/app/modules/groups/data/repositories/rest_group_repository.dart @@ -5,6 +5,7 @@ import 'package:rxdart/rxdart.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/models/create_group_model.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/models/group_list_model.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/models/modify_group_model.dart'; +import 'package:ziggle/app/modules/groups/data/data_sources/models/update_president_model.dart'; import 'package:ziggle/app/modules/groups/data/data_sources/remote/group_api.dart'; import 'package:ziggle/app/modules/groups/data/enums/group_member_role.dart'; import 'package:ziggle/app/modules/groups/domain/entities/authority_entity.dart'; @@ -130,6 +131,12 @@ class RestGroupRepository implements GroupRepository { return _api.deleteUserRole(uuid, targetUuid, roleId); } + @override + Future changePresident( + {required String uuid, required String targetUuid}) { + return _api.updatePresident(uuid, UpdatePresidentModel(targetUuid)); + } + @override Future createRole(String groupUuid, RoleEntity role) { // TODO: implement createRole diff --git a/lib/app/modules/groups/domain/repository/group_repository.dart b/lib/app/modules/groups/domain/repository/group_repository.dart index 7bd961a03..3e6756264 100644 --- a/lib/app/modules/groups/domain/repository/group_repository.dart +++ b/lib/app/modules/groups/domain/repository/group_repository.dart @@ -49,6 +49,10 @@ abstract class GroupRepository { required String targetUuid, required int roleId, }); + Future changePresident({ + required String uuid, + required String targetUuid, + }); Future getRoles(String groupUuid); Future createRole(String groupUuid, RoleEntity role); Future updateRole( diff --git a/lib/app/modules/groups/presentation/blocs/group_member_bloc.dart b/lib/app/modules/groups/presentation/blocs/group_member_bloc.dart index bf956b39b..5d6750cf2 100644 --- a/lib/app/modules/groups/presentation/blocs/group_member_bloc.dart +++ b/lib/app/modules/groups/presentation/blocs/group_member_bloc.dart @@ -4,21 +4,29 @@ import 'package:injectable/injectable.dart'; import 'package:ziggle/app/modules/groups/data/enums/group_member_role.dart'; import 'package:ziggle/app/modules/groups/domain/entities/member_entity.dart'; import 'package:ziggle/app/modules/groups/domain/repository/group_repository.dart'; +import 'package:ziggle/app/modules/user/data/repositories/groups_rest_auth_repository.dart'; +import 'package:ziggle/app/modules/user/data/repositories/rest_auth_repository.dart'; part 'group_member_bloc.freezed.dart'; @injectable class GroupMemberBloc extends Bloc { final GroupRepository _repository; + final RestAuthRepository _authRepository; - GroupMemberBloc(this._repository) : super(_Initial()) { + GroupMemberBloc(this._repository, + @Named.from(GroupsRestAuthRepository) this._authRepository) + : super(_Initial()) { on<_Load>((event, emit) { emit(_Loading()); }); on<_GetMembers>((event, emit) async { emit(GroupMemberState.loading()); final members = await _repository.getMembers(event.uuid); - emit(GroupMemberState.loaded(members.list)); + final group = await _repository.getGroup(event.uuid); + final myUuid = await _authRepository.info().then((u) => u.uuid); + emit( + GroupMemberState.loaded(members.list, myUuid, group.president!.uuid)); }); on<_RemoveMember>((event, emit) async { emit(GroupMemberState.loading()); @@ -47,6 +55,19 @@ class GroupMemberBloc extends Bloc { emit(GroupMemberState.success()); add(GroupMemberEvent.getMembers(event.uuid)); }); + on<_ChangePresident>((event, emit) async { + emit(GroupMemberState.loading()); + try { + await _repository.changePresident( + uuid: event.uuid, + targetUuid: event.targetUuid, + ); + } on Exception catch (e) { + emit(_Error(e.toString())); + } + emit(GroupMemberState.success()); + add(GroupMemberEvent.getMembers(event.uuid)); + }); } } @@ -58,13 +79,17 @@ class GroupMemberEvent with _$GroupMemberEvent { _RemoveMember; const factory GroupMemberEvent.grantRoleToUser(String uuid, String targetUuid, GroupMemberRole role, GroupMemberRole previousRole) = _GrantRoleToUser; + + const factory GroupMemberEvent.changePresident( + String uuid, String targetUuid) = _ChangePresident; } @freezed class GroupMemberState with _$GroupMemberState { const factory GroupMemberState.initial() = _Initial; const factory GroupMemberState.loading() = _Loading; - const factory GroupMemberState.loaded(List list) = _Loaded; + const factory GroupMemberState.loaded( + List list, String myUuid, String presidentUuid) = _Loaded; const factory GroupMemberState.success() = _Success; const factory GroupMemberState.error(String error) = _Error; } From cfad1faf0a23492d4d019c5abab40430b01fd44a Mon Sep 17 00:00:00 2001 From: andongyeon Date: Sun, 7 Sep 2025 05:08:28 +0900 Subject: [PATCH 5/6] feat: add president role --- .../groups/data/enums/group_member_role.dart | 9 +++ .../widgets/group_member_card.dart | 75 ++++++++++++++----- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/lib/app/modules/groups/data/enums/group_member_role.dart b/lib/app/modules/groups/data/enums/group_member_role.dart index 315d7bfea..3c9b91047 100644 --- a/lib/app/modules/groups/data/enums/group_member_role.dart +++ b/lib/app/modules/groups/data/enums/group_member_role.dart @@ -6,6 +6,9 @@ part 'group_member_role.g.dart'; @JsonEnum(alwaysCreate: true) enum GroupMemberRole { + @JsonValue('president') + president, + @JsonValue('admin') admin, @@ -17,6 +20,8 @@ enum GroupMemberRole { int toInt() { switch (this) { + case GroupMemberRole.president: + return 0; case GroupMemberRole.admin: return 1; case GroupMemberRole.manager: @@ -26,6 +31,8 @@ enum GroupMemberRole { } } + bool isPresident() => this == GroupMemberRole.president; + bool isAdmin() => this == GroupMemberRole.admin; bool isManager() => this == GroupMemberRole.manager; @@ -36,6 +43,8 @@ enum GroupMemberRole { extension GroupMemberRoleX on GroupMemberRole { String toLocalizedString(BuildContext context) { switch (this) { + case GroupMemberRole.president: + return context.t.group.memberCard.role.president; case GroupMemberRole.admin: return context.t.group.memberCard.role.admin; case GroupMemberRole.manager: diff --git a/lib/app/modules/groups/presentation/widgets/group_member_card.dart b/lib/app/modules/groups/presentation/widgets/group_member_card.dart index 86a5e8f21..58c47e690 100644 --- a/lib/app/modules/groups/presentation/widgets/group_member_card.dart +++ b/lib/app/modules/groups/presentation/widgets/group_member_card.dart @@ -11,6 +11,9 @@ class GroupMemberCard extends StatelessWidget { final VoidCallback? onBanish; final bool editMode; final GroupMemberRole? role; + final String uuid; + final String myUuid; + final String presidentUuid; final ValueChanged? onChanged; const GroupMemberCard.editMode({ @@ -20,6 +23,9 @@ class GroupMemberCard extends StatelessWidget { required this.role, required this.onBanish, required this.onChanged, + required this.uuid, + required this.myUuid, + required this.presidentUuid, }) : editMode = true; const GroupMemberCard.viewMode({ @@ -29,7 +35,10 @@ class GroupMemberCard extends StatelessWidget { required this.role, }) : editMode = false, onBanish = null, - onChanged = null; + onChanged = null, + uuid = "3141592", + myUuid = "1618033", + presidentUuid = "2718281"; @override Widget build(BuildContext context) { @@ -98,23 +107,55 @@ class GroupMemberCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded( - child: ZiggleSelect( - onChanged: onChanged, - value: role, - small: true, - hintText: context.t.group.memberCard.role.role, - entries: GroupMemberRole.values - .map((value) => ZiggleSelectEntry( - value: value, - label: value.toLocalizedString(context))) - .toList(), - ), + child: (uuid == presidentUuid) + ? Container( + padding: const EdgeInsets.symmetric( + vertical: 5, horizontal: 10) + + const EdgeInsets.only(left: 2), + decoration: const BoxDecoration( + border: Border.fromBorderSide( + BorderSide( + color: Palette.grayBorder, strokeAlign: 1), + ), + borderRadius: + BorderRadius.all(Radius.circular(10)), + color: Palette.grayLight, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + context.t.group.memberCard.role.president, + style: TextStyle( + color: Palette.primary, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ) + : ZiggleSelect( + onChanged: onChanged, + value: role, + small: true, + hintText: context.t.group.memberCard.role.role, + entries: (presidentUuid == myUuid + ? GroupMemberRole.values + : GroupMemberRole.values.where( + (r) => r != GroupMemberRole.president)) + .map((value) => ZiggleSelectEntry( + value: value, + label: value.toLocalizedString(context))) + .toList(), + ), ), - const SizedBox(width: 10), - ZiggleButton.small( - onPressed: onBanish, - child: Text(context.t.group.memberCard.banish), - ) + if (uuid != presidentUuid) const SizedBox(width: 10), + if (uuid != presidentUuid) + ZiggleButton.small( + onPressed: onBanish, + child: Text(context.t.group.memberCard.banish), + ) ], ), ) From 1aea88565d20dd4acd6502fc0b5a624b1d66e4bd Mon Sep 17 00:00:00 2001 From: andongyeon Date: Sun, 7 Sep 2025 05:08:40 +0900 Subject: [PATCH 6/6] feat: add change president --- .../pages/group_management_member_page.dart | 157 +++++++++++------- 1 file changed, 93 insertions(+), 64 deletions(-) diff --git a/lib/app/modules/groups/presentation/pages/group_management_member_page.dart b/lib/app/modules/groups/presentation/pages/group_management_member_page.dart index d36ed6062..21968011d 100644 --- a/lib/app/modules/groups/presentation/pages/group_management_member_page.dart +++ b/lib/app/modules/groups/presentation/pages/group_management_member_page.dart @@ -7,9 +7,12 @@ import 'package:ziggle/app/modules/common/presentation/extensions/confirm.dart'; import 'package:ziggle/app/modules/common/presentation/widgets/ziggle_app_bar.dart'; import 'package:ziggle/app/modules/common/presentation/widgets/ziggle_button.dart'; import 'package:ziggle/app/modules/core/domain/enums/page_source.dart'; +import 'package:ziggle/app/modules/groups/data/enums/group_member_role.dart'; +import 'package:ziggle/app/modules/groups/domain/repository/group_repository.dart'; import 'package:ziggle/app/modules/groups/presentation/blocs/group_management_bloc.dart'; import 'package:ziggle/app/modules/groups/presentation/blocs/group_member_bloc.dart'; import 'package:ziggle/app/modules/groups/presentation/widgets/group_member_card.dart'; +import 'package:ziggle/app/modules/user/data/repositories/rest_auth_repository.dart'; import 'package:ziggle/gen/assets.gen.dart'; import 'package:ziggle/gen/strings.g.dart'; @@ -21,75 +24,101 @@ class GroupManagementMemberPage extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider( + return BlocProvider( + lazy: false, create: (context) => sl()..add(GroupMemberEvent.getMembers(uuid)), - child: Scaffold( - appBar: ZiggleAppBar.compact( - from: PageSource.groupManagement, - backLabel: context.t.group.manage.header, - title: Text(context.t.group.manage.member.header), - ), - body: Padding( - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 18), - child: BlocBuilder( - builder: (context, state) { - return state.maybeWhen( - orElse: () => Container(), - loading: () => Center( - child: Lottie.asset(Assets.lotties.loading, - height: MediaQuery.of(context).size.width * 0.2, - width: MediaQuery.of(context).size.width * 0.2), - ), - loaded: (members) { - return Column( - children: [ - Expanded( - child: ListView.separated( - itemBuilder: (context, index) => - GroupMemberCard.editMode( - name: members[index].name, - email: members[index].email!, - role: members[index].role!, - onChanged: (e) { - context.read().add( - GroupMemberEvent.grantRoleToUser( - uuid, - members[index].uuid, - e!, - members[index].role!)); - }, - onBanish: () { - context.showDialog( - title: context.t.group.memberCard.banishTitle, - content: context - .t.group.memberCard.banishDescription, - onConfirm: (_) { - context.read().add( - GroupManagementEvent.removeMember( - uuid, members[index].uuid)); - }, - ); - }, + child: Builder(builder: (context) { + context.read().add(GroupMemberEvent.getMembers(uuid)); + return Scaffold( + appBar: ZiggleAppBar.compact( + from: PageSource.groupManagement, + backLabel: context.t.group.manage.header, + title: Text(context.t.group.manage.member.header), + ), + body: Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 18), + child: BlocBuilder( + builder: (context, state) { + return state.maybeWhen( + orElse: () => Container(), + loading: () => Center( + child: Lottie.asset(Assets.lotties.loading, + height: MediaQuery.of(context).size.width * 0.2, + width: MediaQuery.of(context).size.width * 0.2), + ), + loaded: (members, myUuid, presidentUuid) { + return Column( + children: [ + Expanded( + child: ListView.separated( + itemBuilder: (context, index) => + GroupMemberCard.editMode( + name: members[index].name, + email: members[index].email!, + role: members[index].role!, + onChanged: (e) { + if (e == GroupMemberRole.president) { + context.showDialog( + title: context.t.group.memberCard + .changePresidentTitle( + name: members[index].name), + content: context.t.group.memberCard + .changePresidentDescription, + onConfirm: (dialogContext) { + context + .read() + .add(GroupMemberEvent.changePresident( + uuid, + members[index].uuid, + )); + Navigator.of(dialogContext).pop(); + }, + ); + } else { + context.read().add( + GroupMemberEvent.grantRoleToUser( + uuid, + members[index].uuid, + e!, + members[index].role!)); + } + }, + onBanish: () { + context.showDialog( + title: context.t.group.memberCard.banishTitle, + content: context + .t.group.memberCard.banishDescription, + onConfirm: (_) { + context.read().add( + GroupManagementEvent.removeMember( + uuid, members[index].uuid)); + }, + ); + }, + uuid: members[index].uuid, + myUuid: myUuid, + presidentUuid: presidentUuid, + ), + separatorBuilder: (context, index) => + SizedBox(height: 10), + itemCount: members.length, ), - separatorBuilder: (context, index) => - SizedBox(height: 10), - itemCount: members.length, ), - ), - SizedBox(height: 30), - ZiggleButton.cta( - child: Text(context.t.group.manage.back), - onPressed: () => context.maybePop(), - ), - ], - ); - }, - ); - }, + SizedBox(height: 30), + ZiggleButton.cta( + child: Text(context.t.group.manage.back), + onPressed: () => context.maybePop(), + ), + ], + ); + }, + ); + }, + ), ), - ), - ), + ); + }), ); } }