diff --git a/assets/images/ic_user.svg b/assets/images/ic_user.svg
new file mode 100644
index 000000000..1d8da314e
--- /dev/null
+++ b/assets/images/ic_user.svg
@@ -0,0 +1,5 @@
+
diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart
index a0f761fe9..fde8e9b01 100644
--- a/core/lib/presentation/resources/image_paths.dart
+++ b/core/lib/presentation/resources/image_paths.dart
@@ -260,6 +260,7 @@ class ImagePaths {
String get icInsertLink => _getImagePath('ic_insert_link.svg');
String get icRemoveLink => _getImagePath('ic_remove_link.svg');
String get icText => _getImagePath('ic_text.svg');
+ String get icUser => _getImagePath('ic_user.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
diff --git a/lib/features/manage_account/presentation/menu/settings/setting_user_info_widget.dart b/lib/features/manage_account/presentation/menu/settings/setting_user_info_widget.dart
new file mode 100644
index 000000000..07ed4c874
--- /dev/null
+++ b/lib/features/manage_account/presentation/menu/settings/setting_user_info_widget.dart
@@ -0,0 +1,100 @@
+import 'package:core/presentation/extensions/color_extension.dart';
+import 'package:core/presentation/extensions/string_extension.dart';
+import 'package:core/presentation/resources/image_paths.dart';
+import 'package:core/presentation/utils/theme_utils.dart';
+import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
+import 'package:flutter/material.dart';
+import 'package:model/extensions/oidc_user_info_extension.dart';
+import 'package:model/oidc/response/oidc_user_info.dart';
+import 'package:tmail_ui_user/features/base/widget/user_avatar_builder.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+
+typedef OnOpenCommonSetting = void Function(OidcUserInfo oidcUserInfo);
+
+class SettingUserInfoWidget extends StatelessWidget {
+ final String ownEmailAddress;
+ final String ownDisplayName;
+ final OidcUserInfo? oidcUserInfo;
+ final ImagePaths imagePaths;
+ final OnOpenCommonSetting? onOpenCommonSetting;
+
+ const SettingUserInfoWidget({
+ Key? key,
+ required this.ownEmailAddress,
+ required this.imagePaths,
+ this.ownDisplayName = '',
+ this.oidcUserInfo,
+ this.onOpenCommonSetting,
+ }) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: const EdgeInsets.all(16),
+ color: Colors.white,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Row(
+ children: [
+ UserAvatarBuilder(
+ username: ownEmailAddress.firstLetterToUpperCase,
+ size: 94,
+ textStyle: ThemeUtils.textStyleInter500().copyWith(
+ fontSize: 50,
+ height: 80 / 50,
+ letterSpacing: 0.24,
+ color: Colors.white,
+ ),
+ ),
+ const SizedBox(width: 16),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ if (ownDisplayName.isNotEmpty)
+ Text(
+ ownDisplayName,
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: ThemeUtils.textStyleInter600().copyWith(
+ fontSize: 22,
+ height: 28 / 22,
+ color: AppColor.gray424244,
+ ),
+ ),
+ Text(
+ ownEmailAddress,
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: ThemeUtils.textStyleM3BodyMedium.copyWith(
+ color: AppColor.textSecondary.withValues(alpha: 0.48),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ if (oidcUserInfo?.isWorkplaceFqdnValid == true)
+ Container(
+ constraints: const BoxConstraints(minWidth: 253),
+ height: 40,
+ margin: const EdgeInsetsDirectional.only(top: 16),
+ child: ConfirmDialogButton(
+ label: AppLocalizations.of(context).manageYourTwakeAccount,
+ backgroundColor: Colors.white,
+ textColor: AppColor.primaryMain,
+ borderColor: AppColor.primaryMain,
+ icon: imagePaths.icUser,
+ iconSize: 18,
+ onTapAction: () => onOpenCommonSetting?.call(oidcUserInfo!),
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/features/manage_account/presentation/menu/settings/settings_controller.dart b/lib/features/manage_account/presentation/menu/settings/settings_controller.dart
index 6cf0d6922..8af294c48 100644
--- a/lib/features/manage_account/presentation/menu/settings/settings_controller.dart
+++ b/lib/features/manage_account/presentation/menu/settings/settings_controller.dart
@@ -1,7 +1,10 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
+import 'package:core/utils/app_logger.dart';
+import 'package:core/utils/web_link_generator.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
+import 'package:model/oidc/response/oidc_user_info.dart';
import 'package:tmail_ui_user/features/base/mixin/contact_support_mixin.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/profile_setting/profile_setting_action_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/extensions/export_trace_log_extension.dart';
@@ -9,6 +12,7 @@ import 'package:tmail_ui_user/features/manage_account/presentation/extensions/ha
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/settings_page_level.dart';
+import 'package:tmail_ui_user/main/utils/app_utils.dart';
class SettingsController extends GetxController with ContactSupportMixin {
final manageAccountDashboardController = Get.find();
@@ -40,4 +44,13 @@ class SettingsController extends GetxController with ContactSupportMixin {
void showExportTraceLogConfirmDialog(BuildContext context) {
manageAccountDashboardController.showExportTraceLogConfirmDialog(context);
}
+
+ void goToCommonSetting(OidcUserInfo oidcUserInfo) {
+ final commonSettingUrl = WebLinkGenerator.safeGenerateWebLink(
+ workplaceFqdn: oidcUserInfo.workplaceFqdn!,
+ slug: 'settings',
+ );
+ log('$runtimeType::goToCommonSetting: CommonSettingUrl is $commonSettingUrl');
+ AppUtils.launchLink(commonSettingUrl);
+ }
}
\ No newline at end of file
diff --git a/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart b/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart
index d8de0eac7..646815f70 100644
--- a/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart
+++ b/lib/features/manage_account/presentation/menu/settings/settings_first_level_view.dart
@@ -5,6 +5,7 @@ import 'package:get/get.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget.dart';
+import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/setting_user_info_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings/settings_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/widgets/setting_first_level_tile_builder.dart';
@@ -36,25 +37,46 @@ class SettingsFirstLevelView extends GetWidget {
key: const Key('setting_menu'),
child: Column(children: [
Obx(() {
- String accountDisplayName = controller
+ String ownEmailAddress = controller
.manageAccountDashboardController
.ownEmailAddress
.value;
- if (accountDisplayName.trim().isEmpty) {
- accountDisplayName = controller
+ if (ownEmailAddress.trim().isEmpty) {
+ ownEmailAddress = controller
.manageAccountDashboardController
.sessionCurrent
?.getOwnEmailAddressOrUsername() ?? '';
}
- return UserInformationWidget(
- ownEmailAddress: accountDisplayName,
- padding: SettingsUtils.getPaddingInFirstLevel(
- context,
- controller.responsiveUtils,
- ),
- titlePadding: const EdgeInsetsDirectional.only(start: 16),
- );
+
+ if (PlatformInfo.isMobile) {
+ final ownDisplayName = controller
+ .manageAccountDashboardController
+ .sessionCurrent
+ ?.getUserDisplayName() ?? '';
+
+ final oidcUserInfo = controller
+ .manageAccountDashboardController
+ .twakeAppManager
+ .oidcUserInfo;
+
+ return SettingUserInfoWidget(
+ ownEmailAddress: ownEmailAddress,
+ ownDisplayName: ownDisplayName,
+ imagePaths: controller.imagePaths,
+ oidcUserInfo: oidcUserInfo,
+ onOpenCommonSetting: controller.goToCommonSetting,
+ );
+ } else {
+ return UserInformationWidget(
+ ownEmailAddress: ownEmailAddress,
+ padding: SettingsUtils.getPaddingInFirstLevel(
+ context,
+ controller.responsiveUtils,
+ ),
+ titlePadding: const EdgeInsetsDirectional.only(start: 16),
+ );
+ }
}),
divider,
_buildSettingItem(
diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb
index a0d8d52e1..dae6bb758 100644
--- a/lib/l10n/intl_messages.arb
+++ b/lib/l10n/intl_messages.arb
@@ -1,5 +1,5 @@
{
- "@@last_modified": "2025-11-10T12:07:59.064737",
+ "@@last_modified": "2025-11-12T23:59:36.025917",
"initializing_data": "Initializing data...",
"@initializing_data": {
"type": "text",
@@ -5111,5 +5111,11 @@
"type": "text",
"placeholders_order": [],
"placeholders": {}
+ },
+ "manageYourTwakeAccount": "Manage your Twake account",
+ "@manageYourTwakeAccount": {
+ "type": "text",
+ "placeholders_order": [],
+ "placeholders": {}
}
}
\ No newline at end of file
diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart
index 718f60a6e..241b9f9c5 100644
--- a/lib/main/localizations/app_localizations.dart
+++ b/lib/main/localizations/app_localizations.dart
@@ -5415,4 +5415,11 @@ class AppLocalizations {
name: 'apply',
);
}
+
+ String get manageYourTwakeAccount {
+ return Intl.message(
+ 'Manage your Twake account',
+ name: 'manageYourTwakeAccount',
+ );
+ }
}
diff --git a/model/lib/extensions/oidc_user_info_extension.dart b/model/lib/extensions/oidc_user_info_extension.dart
new file mode 100644
index 000000000..d5bca2925
--- /dev/null
+++ b/model/lib/extensions/oidc_user_info_extension.dart
@@ -0,0 +1,5 @@
+import 'package:model/oidc/response/oidc_user_info.dart';
+
+extension OidcUserInfoExtension on OidcUserInfo {
+ bool get isWorkplaceFqdnValid => workplaceFqdn?.trim().isNotEmpty == true;
+}
diff --git a/model/lib/model.dart b/model/lib/model.dart
index 77fd5e9a3..972f1b572 100644
--- a/model/lib/model.dart
+++ b/model/lib/model.dart
@@ -62,6 +62,7 @@ export 'extensions/utc_date_extension.dart';
export 'extensions/contact_support_capability_extension.dart';
export 'extensions/list_id_extension.dart';
export 'extensions/set_email_body_part_extension.dart';
+export 'extensions/oidc_user_info_extension.dart';
// Identity
export 'identity/identity_request_dto.dart';
export 'mailbox/expand_mode.dart';