diff --git a/lib/api/services/branch_service.dart b/lib/api/services/branch_service.dart index 5aa5b68..9c0a5d1 100644 --- a/lib/api/services/branch_service.dart +++ b/lib/api/services/branch_service.dart @@ -1,47 +1,47 @@ import 'package:dio/dio.dart'; -class Branch{ -final String branch_code; -final String branch_name; -final String zone; -final String tehsil; -final String block; -final String block_code; -final String distt_name; -final String distt_code_slbc; -final String date_of_opening; -final String rbi_code_1; -final String rbi_code_2; -final String telephone_no; -final String type_of_branch; -final String rtgs_acct_no; -final String br_lattitude; -final String br_longitude; -final String pincode; -final String post_office; +class Branch { + final String branch_code; + final String branch_name; + final String zone; + final String tehsil; + final String block; + final String block_code; + final String distt_name; + final String distt_code_slbc; + final String date_of_opening; + final String rbi_code_1; + final String rbi_code_2; + final String telephone_no; + final String type_of_branch; + final String rtgs_acct_no; + final String br_lattitude; + final String br_longitude; + final String pincode; + final String post_office; -Branch({ -required this.branch_code, -required this.branch_name, -required this.zone, -required this.tehsil, -required this.block, -required this.block_code, -required this.distt_name, -required this.distt_code_slbc, -required this.date_of_opening, -required this.rbi_code_1, -required this.rbi_code_2, -required this.telephone_no, -required this.type_of_branch, -required this.rtgs_acct_no, -required this.br_lattitude, -required this.br_longitude, -required this.pincode, -required this.post_office, -}); + Branch({ + required this.branch_code, + required this.branch_name, + required this.zone, + required this.tehsil, + required this.block, + required this.block_code, + required this.distt_name, + required this.distt_code_slbc, + required this.date_of_opening, + required this.rbi_code_1, + required this.rbi_code_2, + required this.telephone_no, + required this.type_of_branch, + required this.rtgs_acct_no, + required this.br_lattitude, + required this.br_longitude, + required this.pincode, + required this.post_office, + }); -factory Branch.fromJson(Map json) { + factory Branch.fromJson(Map json) { return Branch( branch_code: json['branch_code'] ?? json['branch_code'] ?? '', branch_name: json['branch_name'] ?? json['branch_name'] ?? '', @@ -60,33 +60,32 @@ factory Branch.fromJson(Map json) { br_lattitude: json['br_lattitude'] ?? json['br_lattitude'] ?? '', br_longitude: json['br_longitude'] ?? json['br_longitude'] ?? '', pincode: json['pincode'] ?? json['pincode'] ?? '', - post_office: json['post_office'] ?? json['post_office'] ?? '', + post_office: json['post_office'] ?? json['post_office'] ?? '', ); } -static List listFromJson(List jsonList) { - final beneficiaryList = jsonList - .map((beneficiary) => Branch.fromJson(beneficiary)) - .toList(); + static List listFromJson(List jsonList) { + final beneficiaryList = + jsonList.map((beneficiary) => Branch.fromJson(beneficiary)).toList(); return beneficiaryList; } } - class Atm { - final String name; +class Atm { + final String name; - Atm({required this.name}); + Atm({required this.name}); - factory Atm.fromJson(Map json) { - return Atm( - name: json['name'] ?? '', // Assuming the API returns a 'name' field - ); - } + factory Atm.fromJson(Map json) { + return Atm( + name: json['name'] ?? '', // Assuming the API returns a 'name' field + ); + } - static List listFromJson(List jsonList) { - return jsonList.map((atm) => Atm.fromJson(atm)).toList(); - } - } + static List listFromJson(List jsonList) { + return jsonList.map((atm) => Atm.fromJson(atm)).toList(); + } +} class BranchService { final Dio _dio; @@ -113,7 +112,7 @@ class BranchService { } } - Future> fetchAtmList() async { + Future> fetchAtmList() async { try { final response = await _dio.get( "/api/atm", @@ -134,4 +133,4 @@ class BranchService { return []; } } -} \ No newline at end of file +} diff --git a/lib/di/injection.dart b/lib/di/injection.dart index 33ec60a..0e7aabc 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -74,7 +74,7 @@ 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 connectTimeout: const Duration(seconds: 60), diff --git a/lib/features/accounts/screens/account_statement_screen.dart b/lib/features/accounts/screens/account_statement_screen.dart index 7952ca4..892020e 100644 --- a/lib/features/accounts/screens/account_statement_screen.dart +++ b/lib/features/accounts/screens/account_statement_screen.dart @@ -101,7 +101,8 @@ class _AccountStatementScreen extends State { ? fromDate!.add(const Duration(days: 183)) : now; final initialToDate = toDate ?? now; - final clampedInitialToDate = initialToDate.isBefore(fromDate!) ? fromDate! : initialToDate; + final clampedInitialToDate = + initialToDate.isBefore(fromDate!) ? fromDate! : initialToDate; final picked = await showDatePicker( context: context, initialDate: clampedInitialToDate, @@ -238,8 +239,11 @@ class _AccountStatementScreen extends State { itemCount: 3, itemBuilder: (_, __) => ListTile( leading: Shimmer.fromColors( - baseColor: Theme.of(context).colorScheme.surfaceVariant, - highlightColor: Theme.of(context).colorScheme.onSurfaceVariant, + baseColor: + Theme.of(context).colorScheme.surfaceVariant, + highlightColor: Theme.of(context) + .colorScheme + .onSurfaceVariant, child: CircleAvatar( radius: 12, backgroundColor: @@ -247,8 +251,11 @@ class _AccountStatementScreen extends State { ), ), title: Shimmer.fromColors( - baseColor: Theme.of(context).colorScheme.surfaceVariant, - highlightColor: Theme.of(context).colorScheme.onSurfaceVariant, + baseColor: + Theme.of(context).colorScheme.surfaceVariant, + highlightColor: Theme.of(context) + .colorScheme + .onSurfaceVariant, child: Container( height: 10, width: 100, @@ -257,8 +264,11 @@ class _AccountStatementScreen extends State { ), ), subtitle: Shimmer.fromColors( - baseColor: Theme.of(context).colorScheme.surfaceVariant, - highlightColor: Theme.of(context).colorScheme.onSurfaceVariant, + baseColor: + Theme.of(context).colorScheme.surfaceVariant, + highlightColor: Theme.of(context) + .colorScheme + .onSurfaceVariant, child: Container( height: 8, width: 60, @@ -288,7 +298,9 @@ class _AccountStatementScreen extends State { ? Symbols.call_received : Symbols.call_made, color: tx.type == 'CR' - ? Theme.of(context).colorScheme.secondary + ? Theme.of(context) + .colorScheme + .secondary : Theme.of(context).colorScheme.error, ), title: Text( @@ -332,7 +344,8 @@ class _AccountStatementScreen extends State { ); }, separatorBuilder: (context, index) { - return Divider(color: Theme.of(context).dividerColor); + return Divider( + color: Theme.of(context).dividerColor); }, ), ), diff --git a/lib/features/accounts/screens/all_accounts_screen.dart b/lib/features/accounts/screens/all_accounts_screen.dart index 3413e34..ad170bd 100644 --- a/lib/features/accounts/screens/all_accounts_screen.dart +++ b/lib/features/accounts/screens/all_accounts_screen.dart @@ -46,7 +46,8 @@ class _AllAccountsScreenState extends State { itemBuilder: (context, index) { final user = widget.users[index]; return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), child: _buildAccountCard(user), ); }, diff --git a/lib/features/beneficiaries/screens/beneficiary_details_screen.dart b/lib/features/beneficiaries/screens/beneficiary_details_screen.dart index cb533e9..3a4fc0c 100644 --- a/lib/features/beneficiaries/screens/beneficiary_details_screen.dart +++ b/lib/features/beneficiaries/screens/beneficiary_details_screen.dart @@ -22,7 +22,9 @@ class BeneficiaryDetailsScreen extends StatelessWidget { _showSuccessDialog(context); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('${AppLocalizations.of(context).failedToDeleteBeneficiary} : $e')), + SnackBar( + content: Text( + '${AppLocalizations.of(context).failedToDeleteBeneficiary} : $e')), ); } } @@ -33,7 +35,8 @@ class BeneficiaryDetailsScreen extends StatelessWidget { builder: (BuildContext context) { return AlertDialog( title: Text(AppLocalizations.of(context).success), - content: Text(AppLocalizations.of(context).beneficiaryDeletedSuccessfully), + content: + Text(AppLocalizations.of(context).beneficiaryDeletedSuccessfully), actions: [ TextButton( child: Text(AppLocalizations.of(context).ok), @@ -53,8 +56,8 @@ class BeneficiaryDetailsScreen extends StatelessWidget { builder: (BuildContext context) { return AlertDialog( title: Text(AppLocalizations.of(context).deleteBeneficiary), - content: - Text(AppLocalizations.of(context).areYouSureYouWantToDeleteThisBeneficiary), + content: Text(AppLocalizations.of(context) + .areYouSureYouWantToDeleteThisBeneficiary), actions: [ TextButton( child: Text(AppLocalizations.of(context).cancel), diff --git a/lib/features/cheque/screens/cheque_management_screen.dart b/lib/features/cheque/screens/cheque_management_screen.dart index cd249bd..20ce36b 100644 --- a/lib/features/cheque/screens/cheque_management_screen.dart +++ b/lib/features/cheque/screens/cheque_management_screen.dart @@ -17,8 +17,9 @@ class _ChequeManagementScreen extends State { appBar: AppBar( title: Text( AppLocalizations.of(context).chequeManagement, - style: - TextStyle(color: Theme.of(context).textTheme.titleLarge?.color, fontWeight: FontWeight.w500), + style: TextStyle( + color: Theme.of(context).textTheme.titleLarge?.color, + fontWeight: FontWeight.w500), ), centerTitle: false, ), diff --git a/lib/features/dashboard/screens/dashboard_screen.dart b/lib/features/dashboard/screens/dashboard_screen.dart index 745e9a2..dccc9f0 100644 --- a/lib/features/dashboard/screens/dashboard_screen.dart +++ b/lib/features/dashboard/screens/dashboard_screen.dart @@ -125,143 +125,144 @@ class _DashboardScreenState extends State child: Transform.translate( offset: isSelected ? const Offset(10.0, 0.0) : Offset.zero, child: Container( - margin: const EdgeInsets.symmetric(horizontal: 2), - padding: const EdgeInsets.symmetric( - horizontal: 18, - vertical: 10, - ), - decoration: BoxDecoration( - color: const Color(0xFF01A04C), - borderRadius: BorderRadius.circular(16), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Top section with account type and number (no refresh button here) - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - getFullAccountType(user.accountType), - style: TextStyle( - color: theme.colorScheme.onPrimary, - fontSize: 16, - fontWeight: FontWeight.w700, - ), - ), - Text( - user.accountNo ?? 'N/A', - style: TextStyle( - color: theme.colorScheme.onPrimary, - fontSize: 14, - fontWeight: FontWeight.w700, - ), - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - if (isSelected) // Show logo only if card is selected - CircleAvatar( - radius: 20, - backgroundColor: Colors.white, - child: Padding( - padding: const EdgeInsets.all(2.0), - child: ClipOval( - child: Image.asset( - 'assets/images/logo.png', - width: 30, - height: 30, - fit: BoxFit.cover, - ), - ), - ), - ), - ], - ), - const Spacer(), - // Bottom section with balance and combined toggle/refresh - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (isRefreshing && isSelected) - Expanded(child: _buildBalanceShimmer()) - else + margin: const EdgeInsets.symmetric(horizontal: 2), + padding: const EdgeInsets.symmetric( + horizontal: 18, + vertical: 10, + ), + decoration: BoxDecoration( + color: const Color(0xFF01A04C), + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Top section with account type and number (no refresh button here) + Row( + children: [ Expanded( - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Row( - children: [ - Text( - "₹ ", - style: TextStyle( - color: theme.colorScheme.onPrimary, - fontSize: 40, - fontWeight: FontWeight.w700, - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + getFullAccountType(user.accountType), + style: TextStyle( + color: theme.colorScheme.onPrimary, + fontSize: 16, + fontWeight: FontWeight.w700, ), - Text( - isCardVisible - ? user.currentBalance ?? '0.00' - : '*****', - style: TextStyle( - color: theme.colorScheme.onPrimary, - fontSize: 40, - fontWeight: FontWeight.w700, - ), + ), + Text( + user.accountNo ?? 'N/A', + style: TextStyle( + color: theme.colorScheme.onPrimary, + fontSize: 14, + fontWeight: FontWeight.w700, ), - ], - ), + overflow: TextOverflow.ellipsis, + ), + ], ), ), - const SizedBox(width: 10), // A steady space - if (isSelected) // Only show toggle for selected card - InkWell( - onTap: () async { - if (isRefreshing) return; // Prevent taps while refreshing - final accountNo = user.accountNo; - if (accountNo == null) return; + if (isSelected) // Show logo only if card is selected + CircleAvatar( + radius: 20, + backgroundColor: Colors.white, + child: Padding( + padding: const EdgeInsets.all(2.0), + child: ClipOval( + child: Image.asset( + 'assets/images/logo.png', + width: 30, + height: 30, + fit: BoxFit.cover, + ), + ), + ), + ), + ], + ), + const Spacer(), + // Bottom section with balance and combined toggle/refresh + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (isRefreshing && isSelected) + Expanded(child: _buildBalanceShimmer()) + else + Expanded( + child: FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.centerLeft, + child: Row( + children: [ + Text( + "₹ ", + style: TextStyle( + color: theme.colorScheme.onPrimary, + fontSize: 40, + fontWeight: FontWeight.w700, + ), + ), + Text( + isCardVisible + ? user.currentBalance ?? '0.00' + : '*****', + style: TextStyle( + color: theme.colorScheme.onPrimary, + fontSize: 40, + fontWeight: FontWeight.w700, + ), + ), + ], + ), + ), + ), + const SizedBox(width: 10), // A steady space + if (isSelected) // Only show toggle for selected card + InkWell( + onTap: () async { + if (isRefreshing) + return; // Prevent taps while refreshing + final accountNo = user.accountNo; + if (accountNo == null) return; - final bool currentVisibility = - _visibilityMap[accountNo] ?? false; + final bool currentVisibility = + _visibilityMap[accountNo] ?? false; - if (!currentVisibility) { - // If hidden, refresh data and then show the balance - await _refreshAccountData(context); - if (mounted) { + if (!currentVisibility) { + // If hidden, refresh data and then show the balance + await _refreshAccountData(context); + if (mounted) { + setState(() { + _visibilityMap[accountNo] = true; + }); + } + } else { + // If visible, just hide it setState(() { - _visibilityMap[accountNo] = true; + _visibilityMap[accountNo] = false; }); } - } else { - // If visible, just hide it - setState(() { - _visibilityMap[accountNo] = false; - }); - } - }, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Icon( - isCardVisible - ? Symbols.visibility_lock - : Symbols.visibility, - color: theme.scaffoldBackgroundColor, - weight: 800, + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + isCardVisible + ? Symbols.visibility_lock + : Symbols.visibility, + color: theme.scaffoldBackgroundColor, + weight: 800, + ), ), ), - ), - ], - ), - const Spacer(), - ], + ], + ), + const Spacer(), + ], + ), ), ), - ), ); } @@ -325,8 +326,7 @@ class _DashboardScreenState extends State return Shimmer.fromColors( baseColor: theme.colorScheme.primary, highlightColor: theme.colorScheme.onPrimary, - child: Container( - height: 36, color: theme.scaffoldBackgroundColor), + child: Container(height: 36, color: theme.scaffoldBackgroundColor), ); } @@ -445,8 +445,8 @@ class _DashboardScreenState extends State onTap: () { final authState = context.read().state; String mobileNumberToPass = ''; - String customerNo =''; - String customerName = ''; + String customerNo = ''; + String customerName = ''; if (authState is Authenticated) { if (selectedAccountIndex >= 0 && selectedAccountIndex < authState.users.length) { @@ -454,7 +454,7 @@ class _DashboardScreenState extends State authState.users[selectedAccountIndex].mobileNo ?? ''; customerNo = authState.users[selectedAccountIndex].cifNumber ?? ''; - customerName= + customerName = authState.users[selectedAccountIndex].name ?? ''; } } @@ -462,8 +462,10 @@ class _DashboardScreenState extends State Navigator.push( context, MaterialPageRoute( - builder: (context) => - ProfileScreen(mobileNumber: mobileNumberToPass, customerNo: customerNo, customerName: customerName), + builder: (context) => ProfileScreen( + mobileNumber: mobileNumberToPass, + customerNo: customerNo, + customerName: customerName), ), ); }, @@ -535,25 +537,31 @@ class _DashboardScreenState extends State // Account Info Cards ClipRect( - child: SizedBox( // This SizedBox defines the height for the Stack + child: SizedBox( + // This SizedBox defines the height for the Stack height: 160, child: Stack( children: [ // PageView part, painted underneath Padding( - padding: const EdgeInsets.only(left: 48.0), // Space for tab (40) + gap (8) - child: SizedBox( // Keep SizedBox for PageView height + padding: const EdgeInsets.only( + left: 48.0), // Space for tab (40) + gap (8) + child: SizedBox( + // Keep SizedBox for PageView height height: 160, child: PageView.builder( controller: _pageController, itemCount: users.length, - clipBehavior: Clip.none, // Keep this to show adjacent cards + clipBehavior: Clip + .none, // Keep this to show adjacent cards padEnds: false, onPageChanged: (int newIndex) async { - if (newIndex == selectedAccountIndex) return; + if (newIndex == selectedAccountIndex) + return; // Hide the balance of the old card when scrolling away - final oldAccountNo = users[selectedAccountIndex].accountNo; + final oldAccountNo = + users[selectedAccountIndex].accountNo; if (oldAccountNo != null) { _visibilityMap[oldAccountNo] = false; } @@ -561,15 +569,17 @@ class _DashboardScreenState extends State setState(() { selectedAccountIndex = newIndex; }); - + await _loadTransactions( users[newIndex].accountNo!, ); }, itemBuilder: (context, index) { final user = users[index]; - final isSelected = index == selectedAccountIndex; - return _buildAccountCard(user, isSelected); + final isSelected = + index == selectedAccountIndex; + return _buildAccountCard( + user, isSelected); }, ), ), @@ -715,7 +725,6 @@ class _DashboardScreenState extends State ), ], ), - ], ), ), @@ -777,9 +786,7 @@ class _DashboardScreenState extends State Icon( icon, size: 30, - color: disable - ? theme.disabledColor - : theme.colorScheme.primary, + color: disable ? theme.disabledColor : theme.colorScheme.primary, ), const SizedBox(height: 4), Text( @@ -788,9 +795,8 @@ class _DashboardScreenState extends State style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, fontSize: 12, - color: disable - ? theme.disabledColor - : theme.colorScheme.onSurface, + color: + disable ? theme.disabledColor : theme.colorScheme.onSurface, ), ), ], @@ -799,4 +805,3 @@ class _DashboardScreenState extends State ); } } - diff --git a/lib/features/enquiry/screens/enquiry_screen.dart b/lib/features/enquiry/screens/enquiry_screen.dart index 4f98e86..113e0cf 100644 --- a/lib/features/enquiry/screens/enquiry_screen.dart +++ b/lib/features/enquiry/screens/enquiry_screen.dart @@ -68,8 +68,10 @@ class _EnquiryScreen extends State { GestureDetector( onTap: () => _launchPhoneNumber(phone), child: Text(phone, - style: - TextStyle(color: Theme.of(context).colorScheme.primary)), // Changed color for visibility + style: TextStyle( + color: Theme.of(context) + .colorScheme + .primary)), // Changed color for visibility ), ], ); @@ -91,14 +93,16 @@ class _EnquiryScreen extends State { children: [ const SizedBox(height: 20), GestureDetector( - onTap: () => _launchUrl("https://kccbhp.bank.in/complaint-form/"), + onTap: () => + _launchUrl("https://kccbhp.bank.in/complaint-form/"), child: Row(mainAxisSize: MainAxisSize.min, children: [ Text( "Complaint Form", style: TextStyle( fontSize: 17, color: Theme.of(context).colorScheme.primary, - decoration: TextDecoration.underline, // Added underline for link clarity + decoration: TextDecoration + .underline, // Added underline for link clarity decorationColor: Theme.of(context).colorScheme.primary, ), @@ -165,4 +169,4 @@ class _EnquiryScreen extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart b/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart index 0189fd2..abb5b0e 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart @@ -492,7 +492,8 @@ class _FundTransferAmountScreenState extends State { }, ), const SizedBox(height: 8), - if (_isLoadingLimit) Text(AppLocalizations.of(context).fetchingDailyLimit), + if (_isLoadingLimit) + Text(AppLocalizations.of(context).fetchingDailyLimit), if (!_isLoadingLimit && _limit != null) Text( 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', diff --git a/lib/features/fund_transfer/screens/fund_transfer_screen.dart b/lib/features/fund_transfer/screens/fund_transfer_screen.dart index ecf20a8..e34fe78 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_screen.dart @@ -148,7 +148,8 @@ class FundTransferManagementTile extends StatelessWidget { ), elevation: 4, // Add some elevation for better visual separation child: InkWell( - onTap: disable ? null : onTap, // Disable InkWell if the tile is disabled + onTap: + disable ? null : onTap, // Disable InkWell if the tile is disabled borderRadius: BorderRadius.circular(12.0), child: Padding( padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 16.0), diff --git a/lib/features/profile/profile_screen.dart b/lib/features/profile/profile_screen.dart index 2641a37..b131c52 100644 --- a/lib/features/profile/profile_screen.dart +++ b/lib/features/profile/profile_screen.dart @@ -17,7 +17,11 @@ class ProfileScreen extends StatefulWidget { final String mobileNumber; final String customerNo; final String customerName; - const ProfileScreen({super.key, required this.mobileNumber, required this.customerNo, required this.customerName}); + const ProfileScreen( + {super.key, + required this.mobileNumber, + required this.customerNo, + required this.customerName}); @override State createState() => _ProfileScreenState(); @@ -306,283 +310,283 @@ class _ProfileScreenState extends State { // ); // } @override -Widget build(BuildContext context) { - final loc = AppLocalizations.of(context); - final theme = Theme.of(context); - final isDarkMode = theme.brightness == Brightness.dark; + Widget build(BuildContext context) { + final loc = AppLocalizations.of(context); + final theme = Theme.of(context); + final isDarkMode = theme.brightness == Brightness.dark; - return Scaffold( - appBar: AppBar( - 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, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: theme.colorScheme.surface, - image: const DecorationImage( - image: AssetImage('assets/images/logo.png'), - fit: BoxFit.cover, + return Scaffold( + appBar: AppBar( + 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, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: theme.colorScheme.surface, + image: const DecorationImage( + image: AssetImage('assets/images/logo.png'), + 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. - widget.customerName, - 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. + 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: 4), + Text( + widget.customerNo, + style: theme.textTheme.bodyMedium?.copyWith( + color: theme.colorScheme.onSurface + .withOpacity(0.7), + ), ), - ), - ], + ], + ), ), - ), - // 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, - ), - ), - ], - ), - ), - ), - - 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, - ), - ), - ); - }, - ), - _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), + // 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, + ), ), ], ), - ); + ), + ), - if (shouldExit == true) { - if (Platform.isAndroid) { - SystemNavigator.pop(); + 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, + ), + ), + ); + }, + ), + _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); } - exit(0); - } - }, - ), - _SectionTile( - leadingIcon: Icons.logout, - title: loc.deregister, - trailChevron: false, - onTap: () async { - final shouldLogout = await showDialog( - context: context, - builder: (_) => const LogoutDialog(), - ); + }, + ), + _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); - } - }, - ), + if (shouldLogout == true) { + await _handleLogout(context); + } + }, + ), - const SizedBox(height: 24), - ], - ), + 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, + // ===== 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, + ), ), ), ), ), ), - ), - ], - ), - ); -} + ], + ), + ); + } } class _SectionTile extends StatelessWidget { @@ -611,8 +615,7 @@ class _SectionTile extends StatelessWidget { ? Icon(Icons.chevron_right, color: theme.colorScheme.onSurface) : null, onTap: onTap, - contentPadding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), diff --git a/lib/features/profile/security_settings_screen.dart b/lib/features/profile/security_settings_screen.dart index fc0420d..5e194cf 100644 --- a/lib/features/profile/security_settings_screen.dart +++ b/lib/features/profile/security_settings_screen.dart @@ -57,7 +57,8 @@ class SecuritySettingsScreen extends StatelessWidget { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(loc.mpinChangedSuccessfully), - backgroundColor: Theme.of(context).colorScheme.secondary, + backgroundColor: + Theme.of(context).colorScheme.secondary, ), ); } diff --git a/lib/features/quick_pay/screens/quick_pay_screen.dart b/lib/features/quick_pay/screens/quick_pay_screen.dart index 6c90739..6f62db0 100644 --- a/lib/features/quick_pay/screens/quick_pay_screen.dart +++ b/lib/features/quick_pay/screens/quick_pay_screen.dart @@ -108,7 +108,8 @@ class QuickPayManagementTile extends StatelessWidget { ), elevation: 4, // Add some elevation for better visual separation child: InkWell( - onTap: disable ? null : onTap, // Disable InkWell if the tile is disabled + onTap: + disable ? null : onTap, // Disable InkWell if the tile is disabled borderRadius: BorderRadius.circular(12.0), child: Padding( padding: const EdgeInsets.symmetric(vertical: 36.0, horizontal: 16.0), diff --git a/lib/features/service/screens/atm_locator_screen.dart b/lib/features/service/screens/atm_locator_screen.dart index 8019c2d..9e2d70d 100644 --- a/lib/features/service/screens/atm_locator_screen.dart +++ b/lib/features/service/screens/atm_locator_screen.dart @@ -15,10 +15,12 @@ class ATMLocatorScreen extends StatefulWidget { class _ATMLocatorScreenState extends State { final TextEditingController _searchController = TextEditingController(); - var service = getIt(); // Added: Instance of BranchService for API calls + var service = + getIt(); // Added: Instance of BranchService for API calls bool _isLoading = true; // State variable to manage loading status List _allAtms = []; // Changed: List to hold all fetched Atm objects - List _filteredAtms = []; // Changed: List to hold filtered Atm objects for display + List _filteredAtms = + []; // Changed: List to hold filtered Atm objects for display @override void initState() { @@ -28,7 +30,8 @@ class _ATMLocatorScreenState extends State { /// Fetches the list of ATMs from the API using BranchService. Future _loadAtms() async { - final data = await service.fetchAtmList(); // Call the new fetchAtmList method + final data = + await service.fetchAtmList(); // Call the new fetchAtmList method setState(() { _allAtms = data; // Update the list of all ATMs _filteredAtms = data; // Initialize filtered list with all ATMs @@ -37,14 +40,18 @@ class _ATMLocatorScreenState extends State { } /// Filters the list of ATMs based on the search query. - void _filterAtms(String query) { // Changed: Renamed from _filterLocations + void _filterAtms(String query) { + // Changed: Renamed from _filterLocations setState(() { if (query.isEmpty) { _filteredAtms = _allAtms; // If query is empty, show all ATMs } else { - _filteredAtms = _allAtms.where((atm) { // Changed: Filter based on Atm object + _filteredAtms = _allAtms.where((atm) { + // Changed: Filter based on Atm object final lowerQuery = query.toLowerCase(); - return atm.name.toLowerCase().contains(lowerQuery); // Filter by atm.name + return atm.name + .toLowerCase() + .contains(lowerQuery); // Filter by atm.name }).toList(); } }); @@ -64,7 +71,8 @@ class _ATMLocatorScreenState extends State { padding: const EdgeInsets.all(12.0), child: TextField( controller: _searchController, - onChanged: _filterAtms, // Updated: Call _filterAtms on text change + onChanged: + _filterAtms, // Updated: Call _filterAtms on text change decoration: InputDecoration( hintText: "Name/Address", // Hint text for the search bar prefixIcon: const Icon(Icons.search), // Search icon @@ -81,12 +89,16 @@ class _ATMLocatorScreenState extends State { ? _buildShimmerList() // Display shimmer while loading : _filteredAtms.isEmpty ? const Center( - child: Text("No matching ATMs found")) // Message if no ATMs found + child: Text( + "No matching ATMs found")) // Message if no ATMs found : ListView.builder( - itemCount: _filteredAtms.length, // Number of items in the filtered list + itemCount: _filteredAtms + .length, // Number of items in the filtered list itemBuilder: (context, index) { - final atm = _filteredAtms[index]; // Get the current Atm object - return _buildAtmItem(atm); // Build the ATM list item + final atm = _filteredAtms[ + index]; // Get the current Atm object + return _buildAtmItem( + atm); // Build the ATM list item }, ), ), @@ -111,9 +123,9 @@ class _ATMLocatorScreenState extends State { ); } - /// Helper widget to build a single ATM list item. - Widget _buildAtmItem(Atm atm) { // Changed: Takes an Atm object + Widget _buildAtmItem(Atm atm) { + // Changed: Takes an Atm object return Card( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), child: ListTile( diff --git a/lib/features/service/screens/branch_details_screen.dart b/lib/features/service/screens/branch_details_screen.dart index 824531e..bb9b51b 100644 --- a/lib/features/service/screens/branch_details_screen.dart +++ b/lib/features/service/screens/branch_details_screen.dart @@ -1,107 +1,109 @@ - import 'package:flutter/material.dart'; - import 'package:kmobile/api/services/branch_service.dart'; - import 'package:url_launcher/url_launcher.dart'; +import 'package:flutter/material.dart'; +import 'package:kmobile/api/services/branch_service.dart'; +import 'package:url_launcher/url_launcher.dart'; - class BranchDetailsScreen extends StatelessWidget { - final Branch branch; +class BranchDetailsScreen extends StatelessWidget { + final Branch branch; - const BranchDetailsScreen({super.key, required this.branch}); + const BranchDetailsScreen({super.key, required this.branch}); - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(branch.branch_name), - ), - body: Stack( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildDetailRow(context, "Branch Name", branch.branch_name), - _buildDetailRow(context, "Branch Code", branch.branch_code), - _buildDetailRow(context, "Zone", branch.zone), - _buildDetailRow(context, "Tehsil", branch.tehsil), - _buildDetailRow(context, "Block", branch.block), - _buildDetailRow(context, "District", branch.distt_name), - _buildDetailRow(context, "Pincode", branch.pincode), - // _buildDetailRow(context, "Post Office", branch.post_office), - // _buildDetailRow(context, "Date of Opening", branch.date_of_opening), - // _buildDetailRow(context, "Branch Type", branch.type_of_branch), - _buildDetailRow(context, "Telephone No.", branch.telephone_no), - // _buildDetailRow("RTGS Account No.", branch.rtgs_acct_no), - // _buildDetailRow("RBI Code 1", branch.rbi_code_1), - // _buildDetailRow("RBI Code 2", branch.rbi_code_2), - // _buildDetailRow("Latitude", branch.br_lattitude), - // _buildDetailRow("Longitude", branch.br_longitude), - ], - ), - ), - 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 - ), - ), - ), - ), - ), - ], - ), - ); - } + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(branch.branch_name), + ), + body: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildDetailRow(context, "Branch Name", branch.branch_name), + _buildDetailRow(context, "Branch Code", branch.branch_code), + _buildDetailRow(context, "Zone", branch.zone), + _buildDetailRow(context, "Tehsil", branch.tehsil), + _buildDetailRow(context, "Block", branch.block), + _buildDetailRow(context, "District", branch.distt_name), + _buildDetailRow(context, "Pincode", branch.pincode), + // _buildDetailRow(context, "Post Office", branch.post_office), + // _buildDetailRow(context, "Date of Opening", branch.date_of_opening), + // _buildDetailRow(context, "Branch Type", branch.type_of_branch), + _buildDetailRow(context, "Telephone No.", branch.telephone_no), + // _buildDetailRow("RTGS Account No.", branch.rtgs_acct_no), + // _buildDetailRow("RBI Code 1", branch.rbi_code_1), + // _buildDetailRow("RBI Code 2", branch.rbi_code_2), + // _buildDetailRow("Latitude", branch.br_lattitude), + // _buildDetailRow("Longitude", branch.br_longitude), + ], + ), + ), + 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 + ), + ), + ), + ), + ), + ], + ), + ); + } - Widget _buildDetailRow(BuildContext context, String label, String value) { - final theme = Theme.of(context); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - label, - style: TextStyle( - fontSize: 14, - color: theme.textTheme.bodySmall?.color, - ), - ), - const SizedBox(height: 4), - label == "Telephone No." - ? InkWell( - onTap: () => _launchUrl('tel:$value'), - child: Text( - value, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: theme.colorScheme.primary, // Indicate it's clickable - decoration: TextDecoration.underline, - ), - ), - ) - : Text( - value, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - Divider(height: 16, color: theme.dividerColor), - ], - ), - ); - } - Future _launchUrl(String urlString) async { - final Uri url = Uri.parse(urlString); - if (!await launchUrl(url)) { - throw 'Could not launch $urlString'; - } - } - } + Widget _buildDetailRow(BuildContext context, String label, String value) { + final theme = Theme.of(context); + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: TextStyle( + fontSize: 14, + color: theme.textTheme.bodySmall?.color, + ), + ), + const SizedBox(height: 4), + label == "Telephone No." + ? InkWell( + onTap: () => _launchUrl('tel:$value'), + child: Text( + value, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: + theme.colorScheme.primary, // Indicate it's clickable + decoration: TextDecoration.underline, + ), + ), + ) + : Text( + value, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + Divider(height: 16, color: theme.dividerColor), + ], + ), + ); + } + + Future _launchUrl(String urlString) async { + final Uri url = Uri.parse(urlString); + if (!await launchUrl(url)) { + throw 'Could not launch $urlString'; + } + } +} diff --git a/lib/features/service/screens/branch_locator_screen.dart b/lib/features/service/screens/branch_locator_screen.dart index fe4ebc4..12124fd 100644 --- a/lib/features/service/screens/branch_locator_screen.dart +++ b/lib/features/service/screens/branch_locator_screen.dart @@ -7,7 +7,6 @@ import 'package:kmobile/di/injection.dart'; import 'package:shimmer/shimmer.dart'; import 'package:kmobile/features/service/screens/branch_details_screen.dart'; - class BranchLocatorScreen extends StatefulWidget { const BranchLocatorScreen({super.key}); @@ -15,52 +14,51 @@ class BranchLocatorScreen extends StatefulWidget { State createState() => _BranchLocatorScreenState(); } - class _BranchLocatorScreenState extends State { - final TextEditingController _searchController = TextEditingController(); - var service = getIt(); - bool _isLoading = true; - List _allBranches = []; - List _filteredBranches = []; +class _BranchLocatorScreenState extends State { + final TextEditingController _searchController = TextEditingController(); + var service = getIt(); + bool _isLoading = true; + List _allBranches = []; + List _filteredBranches = []; - @override + @override void initState() { super.initState(); // _fetchAndSetLocations(); _loadBranches(); } - Future _loadBranches() async { - final data = await service.fetchBranchList(); - setState(() { - _allBranches = data; - _filteredBranches = data; - _isLoading = false; - }); - } + Future _loadBranches() async { + final data = await service.fetchBranchList(); + setState(() { + _allBranches = data; + _filteredBranches = data; + _isLoading = false; + }); + } void _filterBranches(String query) { - setState(() { - if (query.isEmpty) { - _filteredBranches = _allBranches; - } else { - _filteredBranches = _allBranches.where((branch) { - final lowerQuery = query.toLowerCase(); - return branch.branch_name.toLowerCase().contains(lowerQuery); - }).toList(); - } - }); - } + setState(() { + if (query.isEmpty) { + _filteredBranches = _allBranches; + } else { + _filteredBranches = _allBranches.where((branch) { + final lowerQuery = query.toLowerCase(); + return branch.branch_name.toLowerCase().contains(lowerQuery); + }).toList(); + } + }); + } - - @override + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "Branch Locator", style: Theme.of(context).textTheme.titleLarge?.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), + color: Theme.of(context).colorScheme.onSurface, + ), ), ), body: Stack( @@ -88,11 +86,13 @@ class BranchLocatorScreen extends StatefulWidget { ? _buildShimmerList() // Changed to shimmer : _filteredBranches.isEmpty ? const Center( - child: Text("No matching branches found")) // Updated tex + child: Text( + "No matching branches found")) // Updated tex : ListView.builder( itemCount: _filteredBranches.length, itemBuilder: (context, index) { - final branch = _filteredBranches[index]; // Changed to + final branch = + _filteredBranches[index]; // Changed to return _buildBranchItem(branch); // Updated }, ), @@ -132,7 +132,7 @@ class BranchLocatorScreen extends StatefulWidget { } // Helper widget to build a single branch item - + Widget _buildBranchItem(Branch branch) { return Card( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), @@ -155,7 +155,6 @@ class BranchLocatorScreen extends StatefulWidget { ); } - // Shimmer loading list Widget _buildShimmerList() { return ListView.builder( diff --git a/lib/features/service/screens/faqs_screen.dart b/lib/features/service/screens/faqs_screen.dart index 6e7e679..303bab0 100644 --- a/lib/features/service/screens/faqs_screen.dart +++ b/lib/features/service/screens/faqs_screen.dart @@ -110,4 +110,4 @@ class _FaqsScreenState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/features/service/screens/quick_links_screen.dart b/lib/features/service/screens/quick_links_screen.dart index 47c3209..92bb482 100644 --- a/lib/features/service/screens/quick_links_screen.dart +++ b/lib/features/service/screens/quick_links_screen.dart @@ -1,113 +1,113 @@ -// +// - import 'package:flutter/material.dart'; - import 'package:kmobile/l10n/app_localizations.dart'; - import 'package:url_launcher/url_launcher.dart'; +import 'package:flutter/material.dart'; +import 'package:kmobile/l10n/app_localizations.dart'; +import 'package:url_launcher/url_launcher.dart'; - // Data model for a single Quick Link item - class QuickLink { - final String title; - final String url; - // The icon is no longer used in the UI but is kept in the model for potential future use. - final IconData icon; +// Data model for a single Quick Link item +class QuickLink { + final String title; + final String url; + // The icon is no longer used in the UI but is kept in the model for potential future use. + final IconData icon; - QuickLink({required this.title, required this.url, required this.icon}); - } + QuickLink({required this.title, required this.url, required this.icon}); +} - class QuickLinksScreen extends StatefulWidget { - const QuickLinksScreen({super.key}); +class QuickLinksScreen extends StatefulWidget { + const QuickLinksScreen({super.key}); - @override - State createState() => _QuickLinksScreenState(); - } + @override + State createState() => _QuickLinksScreenState(); +} - class _QuickLinksScreenState extends State { - // List of Quick Links - final List _quickLinks = [ - QuickLink( - title: "National Bank of Agriculture & Rural Development", - url: "http://www.nabard.org/", - icon: Icons.account_balance), - QuickLink( - title: "Reserve Bank of India", - url: "http://www.rbi.org.in/home.aspx", - icon: Icons.account_balance_wallet), - QuickLink( - title: "Indian Institute of Banking & Finance", - url: "http://www.iibf.org.in/", - icon: Icons.school), - QuickLink( - title: "Indian Bank Association", - url: "http://www.iba.org.in/", - icon: Icons.group_work), - QuickLink( - title: "Ministry of Finance", - url: "http://www.finmin.nic.in/", - icon: Icons.business), - QuickLink( - title: "Securities Exchange Board of India", - url: "http://www.sebi.gov.in/", - icon: Icons.show_chart), - QuickLink( - title: "Insurance Regulatory & Development Authority", - url: "https://www.irdai.gov.in/", - icon: Icons.shield_outlined), - ]; +class _QuickLinksScreenState extends State { + // List of Quick Links + final List _quickLinks = [ + QuickLink( + title: "National Bank of Agriculture & Rural Development", + url: "http://www.nabard.org/", + icon: Icons.account_balance), + QuickLink( + title: "Reserve Bank of India", + url: "http://www.rbi.org.in/home.aspx", + icon: Icons.account_balance_wallet), + QuickLink( + title: "Indian Institute of Banking & Finance", + url: "http://www.iibf.org.in/", + icon: Icons.school), + QuickLink( + title: "Indian Bank Association", + url: "http://www.iba.org.in/", + icon: Icons.group_work), + QuickLink( + title: "Ministry of Finance", + url: "http://www.finmin.nic.in/", + icon: Icons.business), + QuickLink( + title: "Securities Exchange Board of India", + url: "http://www.sebi.gov.in/", + icon: Icons.show_chart), + QuickLink( + title: "Insurance Regulatory & Development Authority", + url: "https://www.irdai.gov.in/", + icon: Icons.shield_outlined), + ]; - // Function to launch a URL - Future _launchURL(String url, BuildContext context) async { - final Uri uri = Uri.parse(url); - if (await canLaunchUrl(uri)) { - await launchUrl(uri, mode: LaunchMode.externalApplication); - } else { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Could not launch $url')), - ); - } - } + // Function to launch a URL + Future _launchURL(String url, BuildContext context) async { + final Uri uri = Uri.parse(url); + if (await canLaunchUrl(uri)) { + await launchUrl(uri, mode: LaunchMode.externalApplication); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Could not launch $url')), + ); + } + } - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(AppLocalizations.of(context).quickLinks), - ), - body: Stack( - children: [ - // Background logo - IgnorePointer( - child: Center( - child: Opacity( - opacity: 0.07, - child: ClipOval( - child: Image.asset( - 'assets/images/logo.png', - width: 200, - height: 200, - ), - ), - ), - ), - ), - // UPDATED: List of Quick Links - ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 8.0), - itemCount: _quickLinks.length, - itemBuilder: (context, index) { - final link = _quickLinks[index]; - return Card( - margin: - const EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0), - child: ListTile( - title: Text(link.title), - trailing: const Icon(Icons.open_in_new, size: 20), - onTap: () => _launchURL(link.url, context), - ), - ); - }, - ), - ], - ), - ); - } - } \ No newline at end of file + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context).quickLinks), + ), + body: Stack( + children: [ + // Background logo + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.07, + child: ClipOval( + child: Image.asset( + 'assets/images/logo.png', + width: 200, + height: 200, + ), + ), + ), + ), + ), + // UPDATED: List of Quick Links + ListView.builder( + padding: const EdgeInsets.symmetric(vertical: 8.0), + itemCount: _quickLinks.length, + itemBuilder: (context, index) { + final link = _quickLinks[index]; + return Card( + margin: + const EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0), + child: ListTile( + title: Text(link.title), + trailing: const Icon(Icons.open_in_new, size: 20), + onTap: () => _launchURL(link.url, context), + ), + ); + }, + ), + ], + ), + ); + } +} diff --git a/lib/features/service/screens/service_screen.dart b/lib/features/service/screens/service_screen.dart index a700783..251ef9e 100644 --- a/lib/features/service/screens/service_screen.dart +++ b/lib/features/service/screens/service_screen.dart @@ -52,7 +52,8 @@ class _ServiceScreen extends State { label: AppLocalizations.of(context).faq, onTap: () { Navigator.of(context).push( - MaterialPageRoute(builder: (context) => const FaqsScreen()), + MaterialPageRoute( + builder: (context) => const FaqsScreen()), ); }, disabled: false, @@ -120,7 +121,8 @@ class ServiceManagementTile extends StatelessWidget { ), elevation: 4, // Add some elevation for better visual separation child: InkWell( - onTap: disabled ? null : onTap, // Disable InkWell if the tile is disabled + onTap: + disabled ? null : onTap, // Disable InkWell if the tile is disabled borderRadius: BorderRadius.circular(12.0), child: Padding( padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 16.0), @@ -130,7 +132,8 @@ class ServiceManagementTile extends StatelessWidget { Icon( icon, size: 48, // Make icon larger - color: disabled ? theme.disabledColor : theme.colorScheme.primary, + color: + disabled ? theme.disabledColor : theme.colorScheme.primary, ), const SizedBox(height: 12), Text( @@ -138,7 +141,9 @@ class ServiceManagementTile extends StatelessWidget { textAlign: TextAlign.center, style: theme.textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, - color: disabled ? theme.disabledColor : theme.colorScheme.onSurface, + color: disabled + ? theme.disabledColor + : theme.colorScheme.onSurface, ), ), ],