diff --git a/assets/images/profile.svg b/assets/images/profile.svg new file mode 100644 index 0000000..56de2bd Binary files /dev/null and b/assets/images/profile.svg differ diff --git a/lib/di/injection.dart b/lib/di/injection.dart index e3eba3a..d68bca6 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -74,9 +74,9 @@ Dio _createDioClient() { final dio = Dio( BaseOptions( baseUrl: - 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', //test + //'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', //test //'http://lb-kccb-mobile-banking-app-848675342.ap-south-1.elb.amazonaws.com', //prod - //'https://kccbmbnk.net', //prod small + 'https://kccbmbnk.net', //prod small connectTimeout: const Duration(seconds: 60), receiveTimeout: const Duration(seconds: 60), headers: { diff --git a/lib/features/customer_info/screens/customer_info_screen.dart b/lib/features/customer_info/screens/customer_info_screen.dart index c4ccf5c..cf3b3a7 100644 --- a/lib/features/customer_info/screens/customer_info_screen.dart +++ b/lib/features/customer_info/screens/customer_info_screen.dart @@ -33,93 +33,141 @@ class _CustomerInfoScreenState extends State { .replaceFirst(RegExp('\n'), ''), ), ), - body: Stack( - children: [ - SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: SafeArea( - child: Center( - child: Column( - children: [ - const SizedBox(height: 30), - CircleAvatar( - radius: 50, - child: SvgPicture.asset( - 'assets/images/avatar_male.svg', - width: 150, - height: 150, - fit: BoxFit.cover, + body: SafeArea( + child: Stack( + children: [ + SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide( + color: theme.colorScheme.outline.withOpacity(0.2), + width: 1, + ), + ), + child: Padding( padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + SizedBox( + width: 56, + height: 56, + child: CircleAvatar( + radius: 50, + child: SvgPicture.asset( + 'assets/images/avatar_male.svg', + fit: BoxFit.cover, + ), + ), + ), + const SizedBox(width: 12), + // Name + mobile + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + // If you want to show the user's name instead, replace below. + user.name ?? '', + style: + theme.textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 4), + Text( + user.cifNumber ?? '', + style: theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.onSurface + .withOpacity(0.7), + ), + ), + ], + ), + ), + ], ), ), - Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - user.name ?? '', - style: TextStyle( - fontSize: 20, - color: theme.colorScheme.onSurface, - fontWeight: FontWeight.w500, - ), + ), + const SizedBox(height: 16), + Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide( + color: theme.colorScheme.outline.withOpacity(0.2), + width: 1, ), ), - Text( - '${AppLocalizations.of(context).cif}: ${user.cifNumber ?? 'N/A'}', - style: TextStyle( - fontSize: 16, - color: theme.colorScheme.onSurfaceVariant), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Personal Information', + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 16), + InfoField( + label: AppLocalizations.of(context).activeAccounts, + value: user.activeAccounts?.toString() ?? 'N/A', + ), + InfoField( + label: AppLocalizations.of(context).mobileNumber, + value: user.mobileNo ?? 'N/A', + ), + InfoField( + label: AppLocalizations.of(context).dateOfBirth, + value: (user.dateOfBirth != null && + user.dateOfBirth!.length == 8) + ? '${user.dateOfBirth!.substring(0, 2)}-${user.dateOfBirth!.substring(2, 4)}-${user.dateOfBirth!.substring(4, 8)}' + : 'N/A', + ), // Replace with DOB if available + InfoField( + label: AppLocalizations.of(context).branchCode, + value: user.branchId ?? 'N/A', + ), + InfoField( + label: AppLocalizations.of(context).address, + value: user.address ?? 'N/A', + ), // Replace with Aadhar if available + InfoField( + label: AppLocalizations.of(context).primaryId, + value: _maskPrimaryId(user.primaryId), + ), + ], + ), ), - const SizedBox(height: 30), - InfoField( - label: AppLocalizations.of(context).activeAccounts, - value: user.activeAccounts?.toString() ?? 'N/A', - ), - InfoField( - label: AppLocalizations.of(context).mobileNumber, - value: user.mobileNo ?? 'N/A', - ), - InfoField( - label: AppLocalizations.of(context).dateOfBirth, - value: (user.dateOfBirth != null && - user.dateOfBirth!.length == 8) - ? '${user.dateOfBirth!.substring(0, 2)}-${user.dateOfBirth!.substring(2, 4)}-${user.dateOfBirth!.substring(4, 8)}' - : 'N/A', - ), // Replace with DOB if available - InfoField( - label: AppLocalizations.of(context).branchCode, - value: user.branchId ?? 'N/A', - ), - InfoField( - label: AppLocalizations.of(context).address, - value: user.address ?? 'N/A', - ), // Replace with Aadhar if available - InfoField( - label: AppLocalizations.of(context).primaryId, - value: _maskPrimaryId(user.primaryId), - ), // Replace with PAN if available - ], + ), + ], + ), + ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.07, // Reduced opacity + child: ClipOval( + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), ), ), ), ), - ), - IgnorePointer( - child: Center( - child: Opacity( - opacity: 0.07, // Reduced opacity - child: ClipOval( - child: Image.asset( - 'assets/images/logo.png', - width: 200, // Adjust size as needed - height: 200, // Adjust size as needed - ), - ), - ), - ), - ), - ], - ), + ], + ), + ) ); } } @@ -141,16 +189,16 @@ class InfoField extends StatelessWidget { children: [ Text( label, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w500, - color: theme.colorScheme.onSurfaceVariant, + style: theme.textTheme.bodySmall?.copyWith( + color: theme.colorScheme.onSurface.withOpacity(0.6), ), ), - const SizedBox(height: 3), + const SizedBox(height: 4), Text( - value, - style: TextStyle(fontSize: 16, color: theme.colorScheme.onSurface), + value.isEmpty ? 'N/A' : value, + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.w600, + ), ), ], ), diff --git a/lib/features/profile/preferences/preference_screen.dart b/lib/features/profile/preferences/preference_screen.dart index e852133..3204ba2 100644 --- a/lib/features/profile/preferences/preference_screen.dart +++ b/lib/features/profile/preferences/preference_screen.dart @@ -23,42 +23,50 @@ class PreferenceScreen extends StatelessWidget { return Stack( children: [ ListView( + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 12), children: [ - //Set Prefered Username - // ListTile( - // leading: const Icon(Icons.person), - // title: const Text("Set Prefered Username"), - // onTap: () { - // }), // Language Selection - ListTile( - leading: const Icon(Icons.language), - title: Text(loc.language), - onTap: () { - showDialog( - context: context, - builder: (_) => const LanguageDialog(), - ); - }, - ), - //Theme Mode Switch (Light/Dark) - ListTile( - leading: const Icon(Icons.brightness_6), - title: Text(AppLocalizations.of(context).themeMode), - onTap: () { - showThemeModeDialog(context); - }, - ), - //Color_Theme_Selection - ListTile( - leading: const Icon(Icons.color_lens), - title: Text(AppLocalizations.of(context).themeColor), + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: const Icon(Icons.language), + title: Text(loc.language), + trailing: const Icon(Icons.chevron_right), onTap: () { showDialog( context: context, - builder: (_) => const ColorThemeDialog(), + builder: (_) => const LanguageDialog(), ); - }), + }, + ), + ), + //Theme Mode Switch (Light/Dark) + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: const Icon(Icons.brightness_6), + title: Text(AppLocalizations.of(context).themeMode), + trailing: const Icon(Icons.chevron_right), + onTap: () { + showThemeModeDialog(context); + }, + ), + ), + //Color_Theme_Selection + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: const Icon(Icons.color_lens), + title: Text(AppLocalizations.of(context).themeColor), + trailing: const Icon(Icons.chevron_right), + onTap: () { + showDialog( + context: context, + builder: (_) => const ColorThemeDialog(), + ); + }), + ), ], ), IgnorePointer( diff --git a/lib/features/profile/profile_screen.dart b/lib/features/profile/profile_screen.dart index 378332a..5e08d9f 100644 --- a/lib/features/profile/profile_screen.dart +++ b/lib/features/profile/profile_screen.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:kmobile/data/repositories/auth_repository.dart'; import 'package:kmobile/features/profile/daily_transaction_limit.dart'; import 'package:kmobile/features/profile/logout_dialog.dart'; @@ -188,15 +189,14 @@ class _ProfileScreenState extends State { Container( width: 56, height: 56, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: theme.colorScheme.surface, - image: const DecorationImage( - image: AssetImage('assets/images/logo.png'), - fit: BoxFit.cover, - ), +child: CircleAvatar( + radius: 50, + child: SvgPicture.asset( + 'assets/images/avatar_male.svg', + fit: BoxFit.cover, ), ), + ), const SizedBox(width: 12), // Name + mobile Expanded( @@ -221,17 +221,6 @@ class _ProfileScreenState extends State { ], ), ), - // Edit/Profile button (optional) - TextButton.icon( - onPressed: () { - // TODO: Navigate to edit profile if required - }, - icon: const Icon(Icons.edit, size: 18), - label: const Text("Edit"), - style: TextButton.styleFrom( - foregroundColor: theme.colorScheme.onSurface, - ), - ), ], ), ), diff --git a/lib/features/profile/security_settings_screen.dart b/lib/features/profile/security_settings_screen.dart index 5e194cf..a620cc3 100644 --- a/lib/features/profile/security_settings_screen.dart +++ b/lib/features/profile/security_settings_screen.dart @@ -24,99 +24,107 @@ class SecuritySettingsScreen extends StatelessWidget { body: Stack( children: [ ListView( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), children: [ - ListTile( - leading: const Icon(Icons.lock_outline), - title: Text(loc.changeLoginPassword), - trailing: const Icon(Icons.chevron_right), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ChangePasswordScreen( - mobileNumber: mobileNumber, - ), - ), - ); - }, - ), - Divider(height: 1, color: Theme.of(context).dividerColor), - ListTile( - leading: const Icon(Icons.pin), - title: Text(loc.changeMpin), - trailing: const Icon(Icons.chevron_right), - onTap: () async { - final result = await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const ChangeMpinScreen(), - ), - ); - - if (result == true && context.mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(loc.mpinChangedSuccessfully), - backgroundColor: - Theme.of(context).colorScheme.secondary, + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: const Icon(Icons.lock_outline), + title: Text(loc.changeLoginPassword), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChangePasswordScreen( + mobileNumber: mobileNumber, + ), ), ); - } - }, + }, + ), ), - Divider(height: 1, color: Theme.of(context).dividerColor), - ListTile( - leading: const Icon(Icons.password), - title: const Text('Change TPIN'), - trailing: const Icon(Icons.chevron_right), - onTap: () async { - final authService = getIt(); - final isTpinSet = await authService.checkTpin(); + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: const Icon(Icons.pin), + title: Text(loc.changeMpin), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + final result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ChangeMpinScreen(), + ), + ); - if (!isTpinSet) { - if (context.mounted) { - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: const Text('TPIN Not Set'), - content: const Text( - 'You have not set a TPIN yet. Please set a TPIN to proceed.'), - actions: [ - TextButton( - child: const Text('Back'), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: const Text('Proceed'), - onPressed: () { - Navigator.of(context).pop(); - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - const TpinSetScreen(), - ), - ); - }, - ), - ], - ); - }, - ); - } - } else { - if (context.mounted) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => - ChangeTpinScreen(mobileNumber: mobileNumber), + if (result == true && context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(loc.mpinChangedSuccessfully), + backgroundColor: + Theme.of(context).colorScheme.secondary, ), ); } - } - }, + }, + ), + ), + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: const Icon(Icons.password), + title: const Text('Change TPIN'), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + final authService = getIt(); + final isTpinSet = await authService.checkTpin(); + + if (!isTpinSet) { + if (context.mounted) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('TPIN Not Set'), + content: const Text( + 'You have not set a TPIN yet. Please set a TPIN to proceed.'), + actions: [ + TextButton( + child: const Text('Back'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: const Text('Proceed'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const TpinSetScreen(), + ), + ); + }, + ), + ], + ); + }, + ); + } + } else { + if (context.mounted) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ChangeTpinScreen(mobileNumber: mobileNumber), + ), + ); + } + } + }, + ), ), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index bdd1e8d..194aad6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -114,6 +114,7 @@ flutter: - assets/images/yes_bank_logo.png - assets/images/uco_logo.png - assets/images/ipos_logo.png + - assets/images/profile.svg - assets/animations/rupee.json - assets/animations/error.json - assets/animations/done.json