@@ -62,82 +62,104 @@ class AccountPage extends StatelessWidget {
6262 Widget _buildUserHeader (BuildContext context, User ? user, bool isAnonymous) {
6363 final l10n = AppLocalizationsX (context).l10n;
6464 final theme = Theme .of (context);
65- final textTheme = theme.textTheme;
6665 final colorScheme = theme.colorScheme;
6766
68- final avatarIcon = Icon (
69- Icons .person_outline,
70- size: AppSpacing .xxl,
71- color: colorScheme.onPrimaryContainer,
72- );
73-
74- final String displayName;
75- final Widget statusWidget;
67+ final String statusText;
68+ final String accountTypeText;
69+ final Widget actionButton;
7670
7771 if (isAnonymous) {
78- displayName = l10n.accountAnonymousUser;
79- statusWidget = Padding (
80- padding: const EdgeInsets .only (top: AppSpacing .md),
81- child: ElevatedButton .icon (
82- icon: const Icon (Icons .link_outlined),
83- label: Text (l10n.accountSignInPromptButton),
84- style: ElevatedButton .styleFrom (
85- padding: const EdgeInsets .symmetric (
86- horizontal: AppSpacing .lg,
87- vertical: AppSpacing .sm,
88- ),
89- textStyle: textTheme.labelLarge,
90- ),
91- onPressed: () {
92- // Navigate directly to the linking flow.
93- context.goNamed (Routes .accountLinkingName);
94- },
95- ),
96- );
72+ statusText = l10n.accountAnonymousUser;
73+ accountTypeText = l10n.accountGuestAccount;
74+ actionButton = _buildSignInButton (context);
9775 } else {
98- displayName = user? .email ?? l10n.accountNoNameUser;
99- statusWidget = Column (
100- mainAxisSize: MainAxisSize .min,
101- children: [
102- const SizedBox (height: AppSpacing .md),
103- OutlinedButton .icon (
104- icon: Icon (Icons .logout, color: colorScheme.error),
105- label: Text (l10n.accountSignOutTile),
106- style: OutlinedButton .styleFrom (
107- foregroundColor: colorScheme.error,
108- side: BorderSide (color: colorScheme.error.withOpacity (0.5 )),
109- padding: const EdgeInsets .symmetric (
110- horizontal: AppSpacing .lg,
111- vertical: AppSpacing .sm,
112- ),
113- textStyle: textTheme.labelLarge,
114- ),
115- onPressed: () {
116- // Dispatch sign-out event.
117- context.read <AuthenticationBloc >().add (
118- const AuthenticationSignOutRequested (),
119- );
120- },
121- ),
122- ],
123- );
76+ statusText = user? .email ?? l10n.accountNoNameUser;
77+
78+ final String roleDisplayName;
79+ switch (user? .appRole) {
80+ case AppUserRole .standardUser:
81+ roleDisplayName = l10n.accountRoleStandard;
82+ case AppUserRole .premiumUser:
83+ roleDisplayName = l10n.accountRolePremium;
84+ case AppUserRole .guestUser:
85+ roleDisplayName = l10n.accountGuestAccount;
86+ case null :
87+ roleDisplayName = '' ;
88+ }
89+ accountTypeText = roleDisplayName;
90+ actionButton = _buildSignOutButton (context);
12491 }
12592
126- return Column (
127- children: [
128- CircleAvatar (
129- radius: AppSpacing .xxl - AppSpacing .sm,
130- backgroundColor: colorScheme.primaryContainer,
131- child: avatarIcon,
132- ),
133- const SizedBox (height: AppSpacing .md),
134- Text (
135- displayName,
136- style: textTheme.headlineSmall,
137- textAlign: TextAlign .center,
93+ return Card (
94+ child: Padding (
95+ padding: const EdgeInsets .all (AppSpacing .md),
96+ child: Row (
97+ crossAxisAlignment: CrossAxisAlignment .center,
98+ children: [
99+ ClipRRect (
100+ borderRadius: BorderRadius .circular (AppSpacing .sm),
101+ child: Container (
102+ width: AppSpacing .xxl + AppSpacing .sm,
103+ height: AppSpacing .xxl + AppSpacing .sm,
104+ color: colorScheme.primaryContainer,
105+ child: Icon (
106+ Icons .person_outline,
107+ size: AppSpacing .xl,
108+ color: colorScheme.onPrimaryContainer,
109+ ),
110+ ),
111+ ),
112+ const SizedBox (width: AppSpacing .md),
113+ Expanded (
114+ child: Column (
115+ crossAxisAlignment: CrossAxisAlignment .start,
116+ children: [
117+ Text (
118+ statusText,
119+ style: theme.textTheme.titleMedium? .copyWith (
120+ fontWeight: FontWeight .bold,
121+ ),
122+ maxLines: 1 ,
123+ overflow: TextOverflow .ellipsis,
124+ ),
125+ const SizedBox (height: AppSpacing .xs),
126+ if (accountTypeText.isNotEmpty)
127+ Text (
128+ accountTypeText,
129+ style: theme.textTheme.bodySmall? .copyWith (
130+ color: colorScheme.onSurfaceVariant,
131+ ),
132+ maxLines: 1 ,
133+ overflow: TextOverflow .ellipsis,
134+ ),
135+ ],
136+ ),
137+ ),
138+ const SizedBox (width: AppSpacing .md),
139+ actionButton,
140+ ],
138141 ),
139- statusWidget,
140- ],
142+ ),
143+ );
144+ }
145+
146+ /// Builds the sign-in button for anonymous users.
147+ Widget _buildSignInButton (BuildContext context) {
148+ final l10n = AppLocalizationsX (context).l10n;
149+ return ElevatedButton (
150+ onPressed: () => context.goNamed (Routes .accountLinkingName),
151+ child: Text (l10n.accountSignInPromptButton),
152+ );
153+ }
154+
155+ /// Builds the sign-out button for authenticated users.
156+ Widget _buildSignOutButton (BuildContext context) {
157+ final l10n = AppLocalizationsX (context).l10n;
158+ return OutlinedButton (
159+ onPressed: () => context.read <AuthenticationBloc >().add (
160+ const AuthenticationSignOutRequested (),
161+ ),
162+ child: Text (l10n.accountSignOutTile),
141163 );
142164 }
143165
0 commit comments