From 8c7e94759a484cad77f8a45ff73dfdbec1b17828 Mon Sep 17 00:00:00 2001 From: asif Date: Mon, 1 Dec 2025 12:58:17 +0530 Subject: [PATCH] APK Build #1 --- assets/images/profile.png | Bin 0 -> 3343 bytes lib/app.dart | 7 - .../accounts/screens/account_info_screen.dart | 4 +- .../screens/account_statement_screen.dart | 66 +-- .../screens/customer_info_screen.dart | 253 +++++----- .../dashboard/screens/dashboard_screen.dart | 2 +- lib/features/profile/profile_screen.dart | 456 +++++++++--------- lib/main.dart | 2 +- pubspec.yaml | 1 + 9 files changed, 387 insertions(+), 404 deletions(-) create mode 100644 assets/images/profile.png diff --git a/assets/images/profile.png b/assets/images/profile.png new file mode 100644 index 0000000000000000000000000000000000000000..82d41fe3a643b84f0ccaabe2d9af55975f52c5cc GIT binary patch literal 3343 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 GA?m*{%~(MI literal 0 HcmV?d00001 diff --git a/lib/app.dart b/lib/app.dart index 0410684..c6b6c1a 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -12,10 +12,8 @@ import 'package:kmobile/features/auth/controllers/theme_state.dart'; import 'config/routes.dart'; import 'di/injection.dart'; import 'features/auth/controllers/auth_cubit.dart'; -import 'features/card/screens/card_management_screen.dart'; import 'features/accounts/screens/account_statement_screen.dart'; import 'package:kmobile/features/auth/controllers/auth_state.dart'; - import 'features/auth/screens/login_screen.dart'; import 'features/service/screens/service_screen.dart'; import 'features/dashboard/screens/dashboard_screen.dart'; @@ -330,7 +328,6 @@ class _NavigationScaffoldState extends State { return const Center(child: CircularProgressIndicator()); }, ), - const CardManagementScreen(), const ServiceScreen(), ]; @@ -392,10 +389,6 @@ class _NavigationScaffoldState extends State { icon: const Icon(Icons.swap_vert_sharp), label: AppLocalizations.of(context).transactions, ), - BottomNavigationBarItem( - icon: const Icon(Icons.credit_card), - label: AppLocalizations.of(context).card, - ), BottomNavigationBarItem( icon: const Icon(Icons.miscellaneous_services), label: AppLocalizations.of(context).services, diff --git a/lib/features/accounts/screens/account_info_screen.dart b/lib/features/accounts/screens/account_info_screen.dart index 9eea9f5..1628b2e 100644 --- a/lib/features/accounts/screens/account_info_screen.dart +++ b/lib/features/accounts/screens/account_info_screen.dart @@ -42,10 +42,10 @@ class _AccountInfoScreen extends State { return AppLocalizations.of(context).recurringDeposit; case 'ca': return "Current Account"; - case 'cc': + case 'cc': return "Cash Credit Account"; case 'od': - return "Overdraft Account"; + return "Overdraft Account"; default: return AppLocalizations.of(context).unknownAccount; } diff --git a/lib/features/accounts/screens/account_statement_screen.dart b/lib/features/accounts/screens/account_statement_screen.dart index d9e9a83..39ce2e1 100644 --- a/lib/features/accounts/screens/account_statement_screen.dart +++ b/lib/features/accounts/screens/account_statement_screen.dart @@ -150,36 +150,42 @@ class _AccountStatementScreen extends State { margin: const EdgeInsets.only(bottom: 10), child: Padding( padding: const EdgeInsets.all(16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context).accountNumber, - style: const TextStyle( - fontWeight: FontWeight.w500, fontSize: 17), - ), - const VerticalDivider(width: 20, thickness: 1, indent: 5, endIndent: 5, color: Colors.grey), - DropdownButton( - value: selectedUser, - onChanged: (User? newUser) { - if (newUser != null) { - setState(() { - selectedUser = newUser; - }); - _loadTransactions(); - } - }, - items: widget.users.map((user) { - return DropdownMenuItem( - value: user, - child: Text(user.accountNo.toString()), - ); - }).toList(), - underline: Container(), // Remove the underline - ), - Spacer(), - ], - ), ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context).accountNumber, + style: const TextStyle( + fontWeight: FontWeight.w500, fontSize: 17), + ), + const VerticalDivider( + width: 20, + thickness: 1, + indent: 5, + endIndent: 5, + color: Colors.grey), + DropdownButton( + value: selectedUser, + onChanged: (User? newUser) { + if (newUser != null) { + setState(() { + selectedUser = newUser; + }); + _loadTransactions(); + } + }, + items: widget.users.map((user) { + return DropdownMenuItem( + value: user, + child: Text(user.accountNo.toString()), + ); + }).toList(), + underline: Container(), // Remove the underline + ), + Spacer(), + ], + ), + ), ), Card( margin: const EdgeInsets.only(bottom: 10), diff --git a/lib/features/customer_info/screens/customer_info_screen.dart b/lib/features/customer_info/screens/customer_info_screen.dart index cf3b3a7..b5631ff 100644 --- a/lib/features/customer_info/screens/customer_info_screen.dart +++ b/lib/features/customer_info/screens/customer_info_screen.dart @@ -26,149 +26,152 @@ class _CustomerInfoScreenState extends State { Widget build(BuildContext context) { final theme = Theme.of(context); return Scaffold( - appBar: AppBar( - title: Text( - AppLocalizations.of(context) - .customerInfo - .replaceFirst(RegExp('\n'), ''), + appBar: AppBar( + title: Text( + AppLocalizations.of(context) + .customerInfo + .replaceFirst(RegExp('\n'), ''), + ), ), - ), - 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, + 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(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), + const SizedBox(height: 4), + Text( + user.cifNumber ?? '', + style: + theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.onSurface + .withOpacity(0.7), + ), ), - ), - ], + ], + ), ), - ), - ], + ], + ), ), ), - ), - const SizedBox(height: 16), - Card( - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - side: BorderSide( - color: theme.colorScheme.outline.withOpacity(0.2), - width: 1, + const SizedBox(height: 16), + 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: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Personal Information', - style: theme.textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, + 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: 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), + ), + ], + ), ), ), - ), - ], + ], + ), ), ), - ), - 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 + ), ), ), ), ), - ), - ], - ), - ) - ); + ], + ), + )); } } diff --git a/lib/features/dashboard/screens/dashboard_screen.dart b/lib/features/dashboard/screens/dashboard_screen.dart index 95d1990..095ee73 100644 --- a/lib/features/dashboard/screens/dashboard_screen.dart +++ b/lib/features/dashboard/screens/dashboard_screen.dart @@ -337,7 +337,7 @@ class _DashboardScreenState extends State case 'cc': return "Cash Credit Account"; case 'od': - return "Overdraft Account"; + return "Overdraft Account"; default: return AppLocalizations.of(context).unknownAccount; } diff --git a/lib/features/profile/profile_screen.dart b/lib/features/profile/profile_screen.dart index 5e08d9f..3bee767 100644 --- a/lib/features/profile/profile_screen.dart +++ b/lib/features/profile/profile_screen.dart @@ -174,260 +174,240 @@ class _ProfileScreenState extends State { title: Text(loc.profile), elevation: 0, ), - body: Stack( - children: [ - ListView( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - children: [ - // ===== Profile Header ===== - Card( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Row( - children: [ - // Avatar - Container( - 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, + body: Stack( + children: [ + ListView( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + children: [ + // ===== Profile Header ===== + Card( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( children: [ - Text( - // If you want to show the user's name instead, replace below. - widget.customerName, - style: theme.textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.w600, + // Avatar + Container( + width: 56, + height: 56, + child: CircleAvatar( + radius: 50, + child: SvgPicture.asset( + 'assets/images/avatar_male.svg', + fit: BoxFit.cover, + ), ), ), - const SizedBox(height: 4), - Text( - widget.customerNo, - style: theme.textTheme.bodyMedium?.copyWith( - color: theme.colorScheme.onSurface - .withOpacity(0.7), + 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. + widget.customerName, + style: theme.textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 4), + Text( + widget.customerNo, + style: theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.onSurface + .withOpacity(0.7), + ), + ), + ], ), ), ], ), ), - ], - ), - ), - ), - - const SizedBox(height: 16), - - // ===== Section: Settings ===== - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text( - "Settings", - style: theme.textTheme.labelLarge?.copyWith( - fontWeight: FontWeight.w600, - letterSpacing: 0.2, - ), - ), - ), - const SizedBox(height: 8), - - _SectionTile( - leadingIcon: Icons.settings, - title: loc.preferences, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const PreferenceScreen(), ), - ); - }, - ), - _SectionTile( - leadingIcon: Icons.security, - title: loc.securitySettings, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SecuritySettingsScreen( - mobileNumber: widget.mobileNumber, + + const SizedBox(height: 16), + + // ===== Section: Settings ===== + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + "Settings", + style: theme.textTheme.labelLarge?.copyWith( + fontWeight: FontWeight.w600, + letterSpacing: 0.2, + ), ), ), - ); - }, - ), - _SectionTile( - leadingIcon: Icons.currency_rupee, - title: loc.dailylimit, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const DailyLimitScreen(), - ), - ); - }, - ), - Card( - child: SwitchListTile( - title: Text(loc.enableFingerprintLogin), - value: _isBiometricEnabled, - onChanged: (bool value) { - _handleBiometricToggle(value); - }, - secondary: const Icon(Icons.fingerprint), - contentPadding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - ), - ), - - const SizedBox(height: 16), - const Divider(height: 24), - - // ===== Section: Security & App ===== - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text( - loc.appVersion, - style: theme.textTheme.labelLarge?.copyWith( - fontWeight: FontWeight.w600, - letterSpacing: 0.2, - ), - ), - ), - const SizedBox(height: 8), - - // Fingerprint toggle inside a styled container - Card( - child: ListTile( - leading: const Icon(Icons.smartphone), - title: Text(loc.appVersion), - trailing: FutureBuilder( - future: _getAppVersion(), - builder: - (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator(strokeWidth: 2), + const SizedBox(height: 8), + + _SectionTile( + leadingIcon: Icons.settings, + title: loc.preferences, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const PreferenceScreen(), + ), ); - } else if (snapshot.hasError) { - return Text(loc.error); - } else { - return Text( - snapshot.data ?? "N/A", + }, + ), + _SectionTile( + leadingIcon: Icons.security, + title: loc.securitySettings, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SecuritySettingsScreen( + mobileNumber: widget.mobileNumber, + ), + ), ); - } - }, - ), - contentPadding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - ), - ), - - const SizedBox(height: 16), - const Divider(height: 24), - - // ===== Section: Actions ===== - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text( - "Exit", - style: theme.textTheme.labelLarge?.copyWith( - fontWeight: FontWeight.w600, - letterSpacing: 0.2, - ), - ), - ), - const SizedBox(height: 8), - - _SectionTile( - leadingIcon: Icons.exit_to_app, - title: loc.logout, - trailChevron: false, // action tile, no chevron - onTap: () async { - final shouldExit = await showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(loc.logout), - content: Text(loc.logoutCheck), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(false), - child: Text(loc.no), - ), - TextButton( - onPressed: () => Navigator.of(context).pop(true), - child: Text(loc.yes), - ), - ], + }, ), - ); - - if (shouldExit == true) { - if (Platform.isAndroid) { - SystemNavigator.pop(); - } - exit(0); - } - }, - ), - _SectionTile( - leadingIcon: Icons.logout, - title: loc.deregister, - trailChevron: false, - onTap: () async { - final shouldLogout = await showDialog( - context: context, - builder: (_) => const LogoutDialog(), - ); - - if (shouldLogout == true) { - await _handleLogout(context); - } - }, - ), - - const SizedBox(height: 24), - ], - ), - - // ===== Watermark (kept subtle, no theme change) ===== - IgnorePointer( - child: Positioned.fill( - child: Center( - child: Opacity( - opacity: 0.06, - child: ClipOval( - child: Image.asset( - 'assets/images/logo.png', - width: 200, - height: 200, - filterQuality: FilterQuality.medium, + _SectionTile( + leadingIcon: Icons.currency_rupee, + title: loc.dailylimit, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DailyLimitScreen(), + ), + ); + }, ), - ), + Card( + child: SwitchListTile( + title: Text(loc.enableFingerprintLogin), + value: _isBiometricEnabled, + onChanged: (bool value) { + _handleBiometricToggle(value); + }, + secondary: const Icon(Icons.fingerprint), + contentPadding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + ), + ), + + const SizedBox(height: 16), + const Divider(height: 24), + + // ===== Section: Security & App ===== + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + loc.appVersion, + style: theme.textTheme.labelLarge?.copyWith( + fontWeight: FontWeight.w600, + letterSpacing: 0.2, + ), + ), + ), + const SizedBox(height: 8), + + // Fingerprint toggle inside a styled container + Card( + child: ListTile( + leading: const Icon(Icons.smartphone), + title: Text(loc.appVersion), + trailing: FutureBuilder( + future: _getAppVersion(), + builder: + (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const SizedBox( + width: 18, + height: 18, + child: CircularProgressIndicator(strokeWidth: 2), + ); + } else if (snapshot.hasError) { + return Text(loc.error); + } else { + return Text( + snapshot.data ?? "N/A", + ); + } + }, + ), + contentPadding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + ), + ), + + const SizedBox(height: 16), + const Divider(height: 24), + + // ===== Section: Actions ===== + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + "Exit", + style: theme.textTheme.labelLarge?.copyWith( + fontWeight: FontWeight.w600, + letterSpacing: 0.2, + ), + ), + ), + const SizedBox(height: 8), + + _SectionTile( + leadingIcon: Icons.exit_to_app, + title: loc.logout, + trailChevron: false, // action tile, no chevron + onTap: () async { + final shouldExit = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(loc.logout), + content: Text(loc.logoutCheck), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text(loc.no), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + child: Text(loc.yes), + ), + ], + ), + ); + + if (shouldExit == true) { + if (Platform.isAndroid) { + SystemNavigator.pop(); + } + exit(0); + } + }, + ), + _SectionTile( + leadingIcon: Icons.logout, + title: loc.deregister, + trailChevron: false, + onTap: () async { + final shouldLogout = await showDialog( + context: context, + builder: (_) => const LogoutDialog(), + ); + + if (shouldLogout == true) { + await _handleLogout(context); + } + }, + ), + + const SizedBox(height: 24), + ], ), - ), - ), - ), - ], - ), - ); + ], + ), ); } } diff --git a/lib/main.dart b/lib/main.dart index b73e538..a4e7953 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,7 +15,7 @@ void main() async { ]); // Check for device compromise - //final compromisedMessage = await SecurityService.deviceCompromisedMessage; + // final compromisedMessage = await SecurityService.deviceCompromisedMessage; // if (compromisedMessage != null) { // runApp(MaterialApp( // home: SecurityErrorScreen(message: compromisedMessage), diff --git a/pubspec.yaml b/pubspec.yaml index 194aad6..f013478 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -115,6 +115,7 @@ flutter: - assets/images/uco_logo.png - assets/images/ipos_logo.png - assets/images/profile.svg + - assets/images/profile.png - assets/animations/rupee.json - assets/animations/error.json - assets/animations/done.json