From f4a306a4b23bb71abf91715651a71fd540ab815d Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 30 Jan 2026 03:59:34 +0300 Subject: [PATCH 01/11] feat: add personal info card widget --- .../accout/widget/personal_info_card.dart | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 lib/presentation/accout/widget/personal_info_card.dart diff --git a/lib/presentation/accout/widget/personal_info_card.dart b/lib/presentation/accout/widget/personal_info_card.dart new file mode 100644 index 0000000..b730a69 --- /dev/null +++ b/lib/presentation/accout/widget/personal_info_card.dart @@ -0,0 +1,81 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../../../design_system/assets/app_assets.dart'; +import '../../../design_system/theme/money_colors.dart'; +import '../../../design_system/theme/money_typography.dart'; + +Widget personalInfoCard({ + required String? image, + required String name, + required String email, +}) { + return Container( + decoration: BoxDecoration( + color: MoneyColors.light.surfaceLow, + borderRadius: BorderRadius.circular(16), + ), + padding: EdgeInsets.all(8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + updateUserAvatar(image, name), + SizedBox(width: 12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: MoneyTypography.typography.title.small.copyWith( + color: MoneyColors.light.title, + ), + ), + Text( + email, + style: MoneyTypography.typography.label.small.copyWith( + color: MoneyColors.light.body, + ), + ), + ], + ), + Spacer(), + GestureDetector( + onTap: () { + // Handle click + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: MoneyColors.light.stroke), + ), + padding: EdgeInsets.all(8), + child: SvgPicture.asset(AppAssets.icEdit, width: 16, height: 16), + ), + ), + ], + ), + ); +} + +Widget updateUserAvatar(String? imageUrl, String firstName) { + if (imageUrl != null && imageUrl.isNotEmpty) { + return Image.asset(imageUrl, height: 52, width: 52); + } else { + String initials = firstName.isNotEmpty ? firstName[0].toUpperCase() : ''; + return Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: MoneyColors.light.green, + borderRadius: BorderRadius.circular(12), + ), + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 11), + alignment: Alignment.center, + child: Text( + initials, + style: MoneyTypography.typography.title.large.copyWith( + color: MoneyColors.light.title, + ), + ), + ); + } +} From 4480a8b9f387ad828fc04a401d68279f0b516f14 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 30 Jan 2026 04:00:04 +0300 Subject: [PATCH 02/11] feat: add accountSection widget --- .../accout/widget/account_section.dart | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 lib/presentation/accout/widget/account_section.dart diff --git a/lib/presentation/accout/widget/account_section.dart b/lib/presentation/accout/widget/account_section.dart new file mode 100644 index 0000000..ee80fb3 --- /dev/null +++ b/lib/presentation/accout/widget/account_section.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../../../design_system/theme/money_colors.dart'; +import '../../../design_system/theme/money_typography.dart'; + +Widget accountSection({ + required String title, + required String iconPath, + bool showDivider = true, + VoidCallback? onTap, +}) { + return InkWell( + onTap: () { + if (onTap != null) { + onTap(); + } + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: MoneyColors.light.surfaceHigh, + borderRadius: BorderRadius.circular(12), + ), + padding: EdgeInsets.symmetric(vertical: 12, horizontal: 11), + alignment: Alignment.center, + child: SvgPicture.asset(iconPath, width: 24, height: 24), + ), + SizedBox(width: 8), + Text( + title, + style: MoneyTypography.typography.label.large.copyWith( + color: MoneyColors.light.title, + ), + ), + ], + ), + if (showDivider) + Divider(color: MoneyColors.light.stroke, thickness: 0.5), + ], + ), + ); +} From 3f37551ed2d4bbe46c5a4bbe68b240ef832ef16f Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 30 Jan 2026 04:00:39 +0300 Subject: [PATCH 03/11] feat: add settings and support icons with corresponding localization strings --- assets/icons/ic_coins.svg | 5 ++++ assets/icons/ic_currency.svg | 5 ++++ assets/icons/ic_customer_support.svg | 7 ++++++ assets/icons/ic_help.svg | 6 +++++ assets/icons/ic_settings.svg | 10 ++++++++ assets/icons/ic_sun.svg | 12 +++++++++ assets/icons/ic_translation.svg | 6 +++++ lib/core/l10n/app_ar.arb | 10 +++++++- lib/core/l10n/app_en.arb | 32 ++++++++++++++---------- lib/design_system/assets/app_assets.dart | 8 ++++++ 10 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 assets/icons/ic_coins.svg create mode 100644 assets/icons/ic_currency.svg create mode 100644 assets/icons/ic_customer_support.svg create mode 100644 assets/icons/ic_help.svg create mode 100644 assets/icons/ic_settings.svg create mode 100644 assets/icons/ic_sun.svg create mode 100644 assets/icons/ic_translation.svg diff --git a/assets/icons/ic_coins.svg b/assets/icons/ic_coins.svg new file mode 100644 index 0000000..fba439d --- /dev/null +++ b/assets/icons/ic_coins.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/ic_currency.svg b/assets/icons/ic_currency.svg new file mode 100644 index 0000000..b1409c5 --- /dev/null +++ b/assets/icons/ic_currency.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/ic_customer_support.svg b/assets/icons/ic_customer_support.svg new file mode 100644 index 0000000..8148786 --- /dev/null +++ b/assets/icons/ic_customer_support.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/ic_help.svg b/assets/icons/ic_help.svg new file mode 100644 index 0000000..0afc8a0 --- /dev/null +++ b/assets/icons/ic_help.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/ic_settings.svg b/assets/icons/ic_settings.svg new file mode 100644 index 0000000..f61d23a --- /dev/null +++ b/assets/icons/ic_settings.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/icons/ic_sun.svg b/assets/icons/ic_sun.svg new file mode 100644 index 0000000..43f429c --- /dev/null +++ b/assets/icons/ic_sun.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/icons/ic_translation.svg b/assets/icons/ic_translation.svg new file mode 100644 index 0000000..d3b2e91 --- /dev/null +++ b/assets/icons/ic_translation.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lib/core/l10n/app_ar.arb b/lib/core/l10n/app_ar.arb index 91ce8c6..7fcbd07 100644 --- a/lib/core/l10n/app_ar.arb +++ b/lib/core/l10n/app_ar.arb @@ -63,5 +63,13 @@ "auth_error_server_error": "خطأ في الخادم الداخلي. يرجى المحاولة لاحقاً", "auth_error_not_implemented": "هذه الميزة غير متوفرة على الخادم", "auth_error_default": "حدث خطأ غير متوقع. يرجى المحاولة لاحقاً", - "no_internet_connection": "لا يوجد اتصال بالانترنت" + "no_internet_connection": "لا يوجد اتصال بالانترنت", + "account": "حساب", + "manageCategories": "إدارة الفئات", + "appLanguage": "لغة التطبيق", + "appTheme": "ثيم التطبيق", + "salarySettings": "إعدادات الراتب", + "frequentlyAskedQuestion": "الأسئلة المتكررة", + "helpAndSupport": "المساعدة والدعم", + "appVersion": "اصدار التطبيق" } diff --git a/lib/core/l10n/app_en.arb b/lib/core/l10n/app_en.arb index 09c2fb0..11f1676 100644 --- a/lib/core/l10n/app_en.arb +++ b/lib/core/l10n/app_en.arb @@ -21,19 +21,18 @@ "next": "Next", "finishSetup": "Finish setup", "stepOf": "Step {current} of {total}", - "stepOfTotal": "Step {current} of {total}", - "@stepOfTotal": { - "placeholders": { - "current": {}, - "total": {} - } - }, + "stepOfTotal": "Step {current} of {total}", + "@stepOfTotal": { + "placeholders": { + "current": {}, + "total": {} + } + }, "forgetPasswordAppBarTitle": "Forget Password", "forgetPasswordTitle": "Forget your password", "forgetPasswordSubtitle": "Enter your email and we’ll send you a reset link", "forgetPasswordEmailHint": "Email", "forgetPasswordButton": "Send Reset Link", - "updatePasswordAppBarTitle": "Update Password", "updatePasswordTitle": "Enter a new password for", "updatePasswordPasswordHint": "New Password", @@ -41,11 +40,10 @@ "updatePasswordButton": "Update Password", "updatePasswordSuccessMessage": "Password updated successfully", "updatePasswordErrorMessage": "Error updating password", - "error": "Error", - "success" : "Success", - "loading" : "Loading", - "login_successfully" : "Login Successfully", + "success": "Success", + "loading": "Loading", + "login_successfully": "Login Successfully", "login_welcome_title": "Welcome again!", "login_welcome_subtitle": "Enter your credentials to access your account", "login_email_hint": "Email", @@ -75,5 +73,13 @@ "auth_error_server_error": "Internal server error. Please try again later", "auth_error_not_implemented": "This feature is not available on the server", "auth_error_default": "An unexpected error occurred. Please try again later", - "no_internet_connection": "No internet connection" + "no_internet_connection": "No internet connection", + "account": "Account", + "manageCategories": "Manage categories", + "appLanguage": "App language", + "appTheme": "App theme", + "salarySettings": "Salary settings", + "frequentlyAskedQuestion": "Frequently asked question", + "helpAndSupport": "Help & Support", + "appVersion": "App version" } \ No newline at end of file diff --git a/lib/design_system/assets/app_assets.dart b/lib/design_system/assets/app_assets.dart index 554484d..353dc86 100644 --- a/lib/design_system/assets/app_assets.dart +++ b/lib/design_system/assets/app_assets.dart @@ -52,4 +52,12 @@ class AppAssets { static const String background = "$_images/background.png"; static const String logo = "$_images/logo.png"; static const String icLoading = "$_icons/ic_loading.svg"; + static const String test = "$_images/test.png"; + static const String icCoins = "$_icons/ic_coins.svg"; + static const String icCustomerSupport = "$_icons/ic_customer_support.svg"; + static const String icHelp = "$_icons/ic_help.svg"; + static const String icSettings = "$_icons/ic_settings.svg"; + static const String icSun = "$_icons/ic_sun.svg"; + static const String icTranslation = "$_icons/ic_translation.svg"; + static const String icCurrency = "$_icons/ic_currency.svg"; } From e11c63edc08d35864d5521dba478dfa69aedb84d Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 30 Jan 2026 04:03:18 +0300 Subject: [PATCH 04/11] feat: implement account screen ui --- lib/design_system/assets/app_assets.dart | 1 - .../accout/screen/account_screen.dart | 73 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 lib/presentation/accout/screen/account_screen.dart diff --git a/lib/design_system/assets/app_assets.dart b/lib/design_system/assets/app_assets.dart index 353dc86..cf5694c 100644 --- a/lib/design_system/assets/app_assets.dart +++ b/lib/design_system/assets/app_assets.dart @@ -52,7 +52,6 @@ class AppAssets { static const String background = "$_images/background.png"; static const String logo = "$_images/logo.png"; static const String icLoading = "$_icons/ic_loading.svg"; - static const String test = "$_images/test.png"; static const String icCoins = "$_icons/ic_coins.svg"; static const String icCustomerSupport = "$_icons/ic_customer_support.svg"; static const String icHelp = "$_icons/ic_help.svg"; diff --git a/lib/presentation/accout/screen/account_screen.dart b/lib/presentation/accout/screen/account_screen.dart new file mode 100644 index 0000000..fbf5fd7 --- /dev/null +++ b/lib/presentation/accout/screen/account_screen.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; + +import '../../../core/l10n/app_localizations.dart'; +import '../../../design_system/assets/app_assets.dart'; +import '../../../design_system/theme/money_extension_context.dart'; +import '../../../design_system/widgets/app_bar.dart'; +import '../widget/account_section.dart'; +import '../widget/personal_info_card.dart'; + +class AccountScreen extends StatelessWidget { + const AccountScreen({super.key}); + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context)!; + final colors = context.colors; + final typography = context.typography; + + return Scaffold( + appBar: CustomAppBar(title: l10n.account), + body: Container( + decoration: BoxDecoration(color: colors.surface), + padding: EdgeInsets.only(top: 24, left: 16, right: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + personalInfoCard( + image: '', + name: "Xxxx", + email: "Xxxx@gmail.com", + ), + SizedBox(height: 24), + accountSection( + title: l10n.manageCategories, + iconPath: AppAssets.icSettings, + ), + accountSection( + title: l10n.appLanguage, + iconPath: AppAssets.icTranslation, + ), + accountSection(title: l10n.appTheme, iconPath: AppAssets.icSun), + accountSection( + title: l10n.currency, + iconPath: AppAssets.icCurrency, + ), + accountSection( + title: l10n.salarySettings, + iconPath: AppAssets.iconMoney, + ), + accountSection( + title: l10n.frequentlyAskedQuestion, + iconPath: AppAssets.icHelp, + ), + accountSection( + title: l10n.helpAndSupport, + iconPath: AppAssets.icCustomerSupport, + showDivider: false, + ), + Spacer(), + Container( + alignment: Alignment.bottomCenter, + padding: EdgeInsets.only(bottom: 8), + child: Text( + "${l10n.appVersion} 1.0", + style: typography.label.small.copyWith(color: colors.body), + ), + ), + ], + ), + ), + ); + } +} From 757e795003d2f862d97c549a4381223128e6474e Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 20 Feb 2026 15:44:02 +0300 Subject: [PATCH 05/11] feat: implement account state --- .../accout/cubit/account_state.dart | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lib/presentation/accout/cubit/account_state.dart diff --git a/lib/presentation/accout/cubit/account_state.dart b/lib/presentation/accout/cubit/account_state.dart new file mode 100644 index 0000000..1ef474b --- /dev/null +++ b/lib/presentation/accout/cubit/account_state.dart @@ -0,0 +1,30 @@ +import 'package:flutter/cupertino.dart'; + +import '../../../domain/entity/user.dart'; + +@immutable +sealed class AccountState { + const AccountState(); +} + +class AccountLoading extends AccountState { + final bool isLoading; + + const AccountLoading({required this.isLoading}); +} + +class AccountLoaded extends AccountState { + final User user; + + const AccountLoaded({required this.user}); + + AccountLoaded copyWith({User? user}) { + return AccountLoaded(user: user ?? this.user); + } +} + +class AccountError extends AccountState { + final String errorMessage; + + const AccountError({required this.errorMessage}); +} From b92eae4b4a0899cdc34914e42188e6c8c30a3c57 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 20 Feb 2026 15:49:44 +0300 Subject: [PATCH 06/11] feat: implement account cubit --- lib/core/di/injection.dart | 5 +++++ lib/data/repository/account_repository.dart | 12 +++++++--- lib/domain/repository/account_repository.dart | 5 ++++- .../accout/cubit/account_cubit.dart | 22 +++++++++++++++++++ 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 lib/presentation/accout/cubit/account_cubit.dart diff --git a/lib/core/di/injection.dart b/lib/core/di/injection.dart index b7f9e12..7f01cea 100644 --- a/lib/core/di/injection.dart +++ b/lib/core/di/injection.dart @@ -15,6 +15,7 @@ import '../../domain/repository/authentication_repository.dart'; import '../../domain/repository/statistics_repository.dart'; import '../../domain/repository/user_money_repository.dart'; import '../../domain/validator/authentication_validator.dart'; +import '../../presentation/accout/cubit/account_cubit.dart'; import '../../presentation/home/cubit/home_cubit.dart'; import '../../presentation/income/cubit/add_income_cubit.dart'; import '../../presentation/login/cubit/login_cubit.dart'; @@ -87,4 +88,8 @@ void initDI() { transactionRepository: getIt(), ), ); + getIt.registerFactory( + () => AccountCubit(getIt()), + ); + } diff --git a/lib/data/repository/account_repository.dart b/lib/data/repository/account_repository.dart index f99ffb1..3f6c218 100644 --- a/lib/data/repository/account_repository.dart +++ b/lib/data/repository/account_repository.dart @@ -1,4 +1,6 @@ import 'package:moneyplus/domain/entity/currency.dart'; +import 'package:moneyplus/domain/entity/user.dart'; +import 'package:supabase_flutter/supabase_flutter.dart' hide User; import '../../domain/repository/account_repository.dart'; import '../service/supabase_service.dart'; @@ -9,15 +11,19 @@ class AccountRepositoryImpl extends AccountRepository { AccountRepositoryImpl({required this.supabaseService}); @override - Future> getCurrencies() async{ - try{ + Future> getCurrencies() async { + try { final client = await supabaseService.getClient(); final response = await client.from('currencies').select(); return response.map((e) => Currency.fromJson(e)).toList(); - }catch(e){ + } catch (e) { throw Exception('Failed to fetch currencies'); } + } + @override + Future getCurrentUser() async { + throw Exception('Failed to get current user'); } } \ No newline at end of file diff --git a/lib/domain/repository/account_repository.dart b/lib/domain/repository/account_repository.dart index f11c038..55f8515 100644 --- a/lib/domain/repository/account_repository.dart +++ b/lib/domain/repository/account_repository.dart @@ -1,6 +1,9 @@ - import 'package:moneyplus/domain/entity/currency.dart'; +import 'package:moneyplus/domain/entity/user.dart'; abstract class AccountRepository { Future> getCurrencies(); + + Future getCurrentUser(); + } \ No newline at end of file diff --git a/lib/presentation/accout/cubit/account_cubit.dart b/lib/presentation/accout/cubit/account_cubit.dart new file mode 100644 index 0000000..70de477 --- /dev/null +++ b/lib/presentation/accout/cubit/account_cubit.dart @@ -0,0 +1,22 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../domain/repository/account_repository.dart'; +import 'account_state.dart'; + +class AccountCubit extends Cubit { + final AccountRepository _accountRepository; + + AccountCubit(this._accountRepository) + : super(const AccountLoading(isLoading: true)); + + Future loadUserInfo() async { + try { + emit(const AccountLoading(isLoading: true)); + final user = await _accountRepository.getCurrentUser(); + emit(AccountLoaded(user: user,)); + } catch (e) { + emit(AccountError(errorMessage: e.toString())); + } + } + +} From 522fed7cceb333402d1e902c5794b418dd912a34 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 20 Feb 2026 16:13:54 +0300 Subject: [PATCH 07/11] refactor: update user avatar initials logic to use full name and change background color --- .../accout/widget/personal_info_card.dart | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/presentation/accout/widget/personal_info_card.dart b/lib/presentation/accout/widget/personal_info_card.dart index b730a69..95d24a3 100644 --- a/lib/presentation/accout/widget/personal_info_card.dart +++ b/lib/presentation/accout/widget/personal_info_card.dart @@ -57,15 +57,23 @@ Widget personalInfoCard({ ); } -Widget updateUserAvatar(String? imageUrl, String firstName) { +Widget updateUserAvatar(String? imageUrl, String fullName) { if (imageUrl != null && imageUrl.isNotEmpty) { return Image.asset(imageUrl, height: 52, width: 52); } else { - String initials = firstName.isNotEmpty ? firstName[0].toUpperCase() : ''; + String initials = ''; + if (fullName.isNotEmpty) { + final nameParts = fullName.trim().split(' '); + if (nameParts.length >= 2) { + initials = (nameParts[0][0] + nameParts[1][0]).toUpperCase(); + } else { + initials = fullName[0].toUpperCase(); + } + } return Container( decoration: BoxDecoration( shape: BoxShape.rectangle, - color: MoneyColors.light.green, + color: MoneyColors.light.surface, borderRadius: BorderRadius.circular(12), ), padding: EdgeInsets.symmetric(vertical: 12, horizontal: 11), From ea27356cc04fe99e696897b9418ed62a60724236 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 20 Feb 2026 16:14:53 +0300 Subject: [PATCH 08/11] feat: integrate AccountCubit into AccountScreen to fetch and display user info --- .../accout/screen/account_screen.dart | 57 +++++++++++++++---- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/lib/presentation/accout/screen/account_screen.dart b/lib/presentation/accout/screen/account_screen.dart index fbf5fd7..ac15b5b 100644 --- a/lib/presentation/accout/screen/account_screen.dart +++ b/lib/presentation/accout/screen/account_screen.dart @@ -1,9 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import '../../../core/di/injection.dart'; import '../../../core/l10n/app_localizations.dart'; import '../../../design_system/assets/app_assets.dart'; import '../../../design_system/theme/money_extension_context.dart'; import '../../../design_system/widgets/app_bar.dart'; +import '../cubit/account_cubit.dart'; +import '../cubit/account_state.dart'; import '../widget/account_section.dart'; import '../widget/personal_info_card.dart'; @@ -17,19 +21,46 @@ class AccountScreen extends StatelessWidget { final typography = context.typography; return Scaffold( + backgroundColor: colors.surface, appBar: CustomAppBar(title: l10n.account), - body: Container( + body: BlocProvider( + create: (_) => getIt()..loadUserInfo(), + child: BlocConsumer( + listener: (context, state) {}, + builder: (context, state) { + return _buildBody(context, state, l10n, colors, typography); + }, + ), + ), + ); + } + + Widget _buildBody( + BuildContext context, + AccountState state, + AppLocalizations l10n, + dynamic colors, + dynamic typography, + ) { + if (state is AccountLoading) { + return const Center(child: CircularProgressIndicator()); + } + + final user = state is AccountLoaded ? state.user : null; + + return SingleChildScrollView( + child: Container( decoration: BoxDecoration(color: colors.surface), - padding: EdgeInsets.only(top: 24, left: 16, right: 16), + padding: const EdgeInsets.only(top: 24, left: 16, right: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ personalInfoCard( image: '', - name: "Xxxx", - email: "Xxxx@gmail.com", + name: user?.name ?? '', + email: user?.email ?? '', ), - SizedBox(height: 24), + const SizedBox(height: 24), accountSection( title: l10n.manageCategories, iconPath: AppAssets.icSettings, @@ -56,13 +87,15 @@ class AccountScreen extends StatelessWidget { iconPath: AppAssets.icCustomerSupport, showDivider: false, ), - Spacer(), - Container( - alignment: Alignment.bottomCenter, - padding: EdgeInsets.only(bottom: 8), - child: Text( - "${l10n.appVersion} 1.0", - style: typography.label.small.copyWith(color: colors.body), + const SizedBox(height: 24), + Align( + alignment: Alignment.center, + child: Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Text( + "${l10n.appVersion} 1.0", + style: typography.label.small.copyWith(color: colors.body), + ), ), ), ], From 241308ebfc0e54207419a272d903dee39bdb23f5 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 20 Feb 2026 16:18:23 +0300 Subject: [PATCH 09/11] feat: add account screen into main container nav bar --- lib/presentation/main_container/screen/main_screen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/presentation/main_container/screen/main_screen.dart b/lib/presentation/main_container/screen/main_screen.dart index f34afbf..d0556f3 100644 --- a/lib/presentation/main_container/screen/main_screen.dart +++ b/lib/presentation/main_container/screen/main_screen.dart @@ -1,7 +1,7 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:moneyplus/design_system/theme/money_extension_context.dart'; +import 'package:moneyplus/presentation/accout/screen/account_screen.dart'; import 'package:moneyplus/presentation/main_container/cubit/main_state.dart'; import 'package:moneyplus/presentation/transactions/screen/transactions_screen.dart'; @@ -42,7 +42,7 @@ class MainScreen extends StatelessWidget { case NavBarTab.statistics: return const TransactionsScreen(); //change to statistics case NavBarTab.account: - return const TransactionsScreen(); //change to account + return const AccountScreen(); } } } From 545707c22966be82720ff62b476728e294b32ea5 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Fri, 20 Feb 2026 17:00:06 +0300 Subject: [PATCH 10/11] refactor:update account screen UI with background asset and add app bar color --- assets/images/money_background.png | Bin 0 -> 3798 bytes lib/design_system/assets/app_assets.dart | 1 + .../accout/screen/account_screen.dart | 132 ++++++++++-------- 3 files changed, 77 insertions(+), 56 deletions(-) create mode 100644 assets/images/money_background.png diff --git a/assets/images/money_background.png b/assets/images/money_background.png new file mode 100644 index 0000000000000000000000000000000000000000..4d7594b5bbab7f64040e73f77e0ab00db7665437 GIT binary patch literal 3798 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 M07*qoM6N<$f}Q(G#sB~S literal 0 HcmV?d00001 diff --git a/lib/design_system/assets/app_assets.dart b/lib/design_system/assets/app_assets.dart index 9a8a9d9..847c3a3 100644 --- a/lib/design_system/assets/app_assets.dart +++ b/lib/design_system/assets/app_assets.dart @@ -74,4 +74,5 @@ class AppAssets { static const String icSun = "$_icons/ic_sun.svg"; static const String icTranslation = "$_icons/ic_translation.svg"; static const String icCurrency = "$_icons/ic_currency.svg"; + static const String glowBackground = "$_images/money_background.png"; } diff --git a/lib/presentation/accout/screen/account_screen.dart b/lib/presentation/accout/screen/account_screen.dart index ac15b5b..b577c99 100644 --- a/lib/presentation/accout/screen/account_screen.dart +++ b/lib/presentation/accout/screen/account_screen.dart @@ -22,7 +22,7 @@ class AccountScreen extends StatelessWidget { return Scaffold( backgroundColor: colors.surface, - appBar: CustomAppBar(title: l10n.account), + appBar: CustomAppBar(title: l10n.account,backgroundColor: colors.surfaceLow), body: BlocProvider( create: (_) => getIt()..loadUserInfo(), child: BlocConsumer( @@ -36,71 +36,91 @@ class AccountScreen extends StatelessWidget { } Widget _buildBody( - BuildContext context, - AccountState state, - AppLocalizations l10n, - dynamic colors, - dynamic typography, - ) { + BuildContext context, + AccountState state, + AppLocalizations l10n, + dynamic colors, + dynamic typography, + ) { if (state is AccountLoading) { return const Center(child: CircularProgressIndicator()); } final user = state is AccountLoaded ? state.user : null; - return SingleChildScrollView( - child: Container( - decoration: BoxDecoration(color: colors.surface), - padding: const EdgeInsets.only(top: 24, left: 16, right: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - personalInfoCard( - image: '', - name: user?.name ?? '', - email: user?.email ?? '', - ), - const SizedBox(height: 24), - accountSection( - title: l10n.manageCategories, - iconPath: AppAssets.icSettings, - ), - accountSection( - title: l10n.appLanguage, - iconPath: AppAssets.icTranslation, - ), - accountSection(title: l10n.appTheme, iconPath: AppAssets.icSun), - accountSection( - title: l10n.currency, - iconPath: AppAssets.icCurrency, - ), - accountSection( - title: l10n.salarySettings, - iconPath: AppAssets.iconMoney, - ), - accountSection( - title: l10n.frequentlyAskedQuestion, - iconPath: AppAssets.icHelp, - ), - accountSection( - title: l10n.helpAndSupport, - iconPath: AppAssets.icCustomerSupport, - showDivider: false, + return Stack( + children: [ + Positioned( + child: Align( + alignment: Alignment.bottomRight, + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.75, + height: 150, + + child: Image.asset( + AppAssets.glowBackground, + fit: BoxFit.contain, + ), ), - const SizedBox(height: 24), - Align( - alignment: Alignment.center, - child: Padding( - padding: const EdgeInsets.only(bottom: 8), - child: Text( - "${l10n.appVersion} 1.0", - style: typography.label.small.copyWith(color: colors.body), + ), + ), + + SingleChildScrollView( + child: Container( + padding: const EdgeInsets.only(top: 24, left: 16, right: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + personalInfoCard( + image: '', + name: user?.name ?? '', + email: user?.email ?? '', ), - ), + const SizedBox(height: 24), + accountSection( + title: l10n.manageCategories, + iconPath: AppAssets.icSettings, + ), + accountSection( + title: l10n.appLanguage, + iconPath: AppAssets.icTranslation, + ), + accountSection(title: l10n.appTheme, iconPath: AppAssets.icSun), + accountSection( + title: l10n.currency, + iconPath: AppAssets.icCurrency, + ), + accountSection( + title: l10n.salarySettings, + iconPath: AppAssets.iconMoney, + ), + accountSection( + title: l10n.frequentlyAskedQuestion, + iconPath: AppAssets.icHelp, + ), + accountSection( + title: l10n.helpAndSupport, + iconPath: AppAssets.icCustomerSupport, + showDivider: false, + ), + const SizedBox(height: 24), + Align( + alignment: Alignment.center, + child: Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Text( + "${l10n.appVersion} 1.0", + style: typography.label.small.copyWith( + color: colors.body, + ), + ), + ), + ), + ], ), - ], + ), ), - ), + ], ); } } From d57e0b58b9b86c00c751ebc057199813ad62d1b5 Mon Sep 17 00:00:00 2001 From: abdulazizacc Date: Sun, 22 Feb 2026 20:07:43 +0300 Subject: [PATCH 11/11] refactor: delete future/async and use then/catchError in AccountCubit --- .../accout/cubit/account_cubit.dart | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/presentation/accout/cubit/account_cubit.dart b/lib/presentation/accout/cubit/account_cubit.dart index 70de477..0ebcfdf 100644 --- a/lib/presentation/accout/cubit/account_cubit.dart +++ b/lib/presentation/accout/cubit/account_cubit.dart @@ -9,14 +9,13 @@ class AccountCubit extends Cubit { AccountCubit(this._accountRepository) : super(const AccountLoading(isLoading: true)); - Future loadUserInfo() async { - try { - emit(const AccountLoading(isLoading: true)); - final user = await _accountRepository.getCurrentUser(); - emit(AccountLoaded(user: user,)); - } catch (e) { - emit(AccountError(errorMessage: e.toString())); - } - } + void loadUserInfo() { + emit(const AccountLoading(isLoading: true)); + _accountRepository.getCurrentUser().then((user) { + emit(AccountLoaded(user: user)); + }).catchError((error) { + emit(AccountError(errorMessage: error.toString())); + }); + } }