diff --git a/lib/app.dart b/lib/app.dart index 5203543..7806d56 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -316,7 +316,7 @@ class _NavigationScaffoldState extends State { int _selectedIndex = 0; final List _pages = [ const DashboardScreen(), - const CardManagementScreen(), + // const CardManagementScreen(), const ServiceScreen(), ]; @@ -374,10 +374,10 @@ class _NavigationScaffoldState extends State { icon: const Icon(Icons.home_filled), label: AppLocalizations.of(context).home, ), - BottomNavigationBarItem( - icon: const Icon(Icons.credit_card), - label: AppLocalizations.of(context).card, - ), + // 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/data/models/beneficiary.dart b/lib/data/models/beneficiary.dart index 1774b23..4521bf0 100644 --- a/lib/data/models/beneficiary.dart +++ b/lib/data/models/beneficiary.dart @@ -1,4 +1,3 @@ - class Beneficiary { final String accountNo; final String accountType; diff --git a/lib/di/injection.dart b/lib/di/injection.dart index c90d749..63dffe9 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -69,9 +69,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-kccb-mobile-banking-app-848675342.ap-south-1.elb.amazonaws.com', //prod - 'https://kccbmbnk.net', //prod small + '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), receiveTimeout: const Duration(seconds: 60), headers: { diff --git a/lib/features/accounts/screens/account_info_screen.dart b/lib/features/accounts/screens/account_info_screen.dart index 0bd6567..54991b8 100644 --- a/lib/features/accounts/screens/account_info_screen.dart +++ b/lib/features/accounts/screens/account_info_screen.dart @@ -34,59 +34,76 @@ class _AccountInfoScreen extends State { .accountInfo .replaceFirst(RegExp('\n'), '')), ), - body: ListView( - padding: const EdgeInsets.all(16.0), + body: Stack( children: [ - Text( - AppLocalizations.of(context).accountNumber, - style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 14), - ), + ListView( + padding: const EdgeInsets.all(16.0), + children: [ + Text( + AppLocalizations.of(context).accountNumber, + style: + const TextStyle(fontWeight: FontWeight.w500, fontSize: 14), + ), - DropdownButton( - value: selectedUser, - onChanged: (User? newUser) { - if (newUser != null) { - setState(() { - selectedUser = newUser; - }); - } - }, - items: widget.users.map((user) { - return DropdownMenuItem( - value: user, - child: Text(user.accountNo.toString()), - ); - }).toList(), - ), + DropdownButton( + value: selectedUser, + onChanged: (User? newUser) { + if (newUser != null) { + setState(() { + selectedUser = newUser; + }); + } + }, + items: widget.users.map((user) { + return DropdownMenuItem( + value: user, + child: Text(user.accountNo.toString()), + ); + }).toList(), + ), - InfoRow( - title: AppLocalizations.of(context).customerNumber, - value: selectedUser.cifNumber ?? 'N/A', - ), - InfoRow( - title: AppLocalizations.of(context).productName, - value: selectedUser.productType ?? 'N/A', - ), - // InfoRow(title: 'Account Opening Date', value: users[selectedIndex].accountOpeningDate ?? 'N/A'), - InfoRow( - title: AppLocalizations.of(context).accountStatus, - value: 'OPEN', - ), - InfoRow( - title: AppLocalizations.of(context).availableBalance, - value: selectedUser.availableBalance ?? 'N/A', - ), - InfoRow( - title: AppLocalizations.of(context).currentBalance, - value: selectedUser.currentBalance ?? 'N/A', - ), + InfoRow( + title: AppLocalizations.of(context).customerNumber, + value: selectedUser.cifNumber ?? 'N/A', + ), + InfoRow( + title: AppLocalizations.of(context).productName, + value: selectedUser.productType ?? 'N/A', + ), + // InfoRow(title: 'Account Opening Date', value: users[selectedIndex].accountOpeningDate ?? 'N/A'), + InfoRow( + title: AppLocalizations.of(context).accountStatus, + value: 'OPEN', + ), + InfoRow( + title: AppLocalizations.of(context).availableBalance, + value: selectedUser.availableBalance ?? 'N/A', + ), + InfoRow( + title: AppLocalizations.of(context).currentBalance, + value: selectedUser.currentBalance ?? 'N/A', + ), - users[selectedIndex].approvedAmount != null - ? InfoRow( - title: AppLocalizations.of(context).approvedAmount, - value: selectedUser.approvedAmount ?? 'N/A', - ) - : const SizedBox.shrink(), + users[selectedIndex].approvedAmount != null + ? InfoRow( + title: AppLocalizations.of(context).approvedAmount, + value: selectedUser.approvedAmount ?? 'N/A', + ) + : const SizedBox.shrink(), + ], + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), ], ), ); diff --git a/lib/features/accounts/screens/account_statement_screen.dart b/lib/features/accounts/screens/account_statement_screen.dart index 15c0b54..efe8384 100644 --- a/lib/features/accounts/screens/account_statement_screen.dart +++ b/lib/features/accounts/screens/account_statement_screen.dart @@ -133,201 +133,223 @@ class _AccountStatementScreen extends State { ), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - "${AppLocalizations.of(context).accountNumber}: ", - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.bold, - ), - ), - Text(widget.accountNo, style: const TextStyle(fontSize: 17)), - ], - ), - const SizedBox(height: 15), - Row( - children: [ - Text( - "${AppLocalizations.of(context).availableBalance}: ", - style: const TextStyle( - fontSize: 17, - ), - ), - Text(' ₹ ${widget.balance}', - style: const TextStyle(fontSize: 17)), - ], - ), - const SizedBox(height: 15), - Text( - AppLocalizations.of(context).filters, - style: const TextStyle(fontSize: 17), - ), - const SizedBox(height: 15), - Row( - children: [ - Expanded( - child: GestureDetector( - onTap: () => _selectFromDate(context), - child: buildDateBox( - AppLocalizations.of(context).fromDate, - fromDate, + Row( + children: [ + Text( + "${AppLocalizations.of(context).accountNumber}: ", + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.bold, + ), ), - ), + Text(widget.accountNo, + style: const TextStyle(fontSize: 17)), + ], ), - const SizedBox(width: 10), - Expanded( - child: GestureDetector( - onTap: () => _selectToDate(context), - child: buildDateBox( - AppLocalizations.of(context).toDate, - toDate, + const SizedBox(height: 15), + Row( + children: [ + Text( + "${AppLocalizations.of(context).availableBalance}: ", + style: const TextStyle( + fontSize: 17, + ), ), - ), + Text(' ₹ ${widget.balance}', + style: const TextStyle(fontSize: 17)), + ], ), - ], - ), - const SizedBox(height: 20), - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _loadTransactions, - style: ElevatedButton.styleFrom( - backgroundColor: - Theme.of(context).colorScheme.primaryContainer, - padding: const EdgeInsets.symmetric(vertical: 16), + const SizedBox(height: 15), + Text( + AppLocalizations.of(context).filters, + style: const TextStyle(fontSize: 17), ), - child: Text( - AppLocalizations.of(context).search, - style: TextStyle( - color: Theme.of(context).colorScheme.onPrimaryContainer, - fontSize: 16, - ), - ), - ), - ), - const SizedBox(height: 15), - if (!_txLoading && - _transactions.isNotEmpty && - fromDate == null && - toDate == null) - Padding( - padding: const EdgeInsets.only(bottom: 12.0), - child: Text( - AppLocalizations.of(context).lastTenTransactions, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - Expanded( - child: _txLoading - ? ListView.builder( - itemCount: 3, - itemBuilder: (_, __) => ListTile( - leading: Shimmer.fromColors( - baseColor: Colors.grey[300]!, - highlightColor: Colors.grey[100]!, - child: CircleAvatar( - radius: 12, - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - ), - ), - title: Shimmer.fromColors( - baseColor: Colors.grey[300]!, - highlightColor: Colors.grey[100]!, - child: Container( - height: 10, - width: 100, - color: Theme.of(context).scaffoldBackgroundColor, - ), - ), - subtitle: Shimmer.fromColors( - baseColor: Colors.grey[300]!, - highlightColor: Colors.grey[100]!, - child: Container( - height: 8, - width: 60, - color: Theme.of(context).scaffoldBackgroundColor, - ), + const SizedBox(height: 15), + Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () => _selectFromDate(context), + child: buildDateBox( + AppLocalizations.of(context).fromDate, + fromDate, ), ), - ) - : _transactions.isEmpty - ? Center( - child: Text( - AppLocalizations.of(context).noTransactions, - style: TextStyle( - fontSize: 16, - color: Theme.of(context).colorScheme.onSurface, - )), + ), + const SizedBox(width: 10), + Expanded( + child: GestureDetector( + onTap: () => _selectToDate(context), + child: buildDateBox( + AppLocalizations.of(context).toDate, + toDate, + ), + ), + ), + ], + ), + const SizedBox(height: 20), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _loadTransactions, + style: ElevatedButton.styleFrom( + backgroundColor: + Theme.of(context).colorScheme.primaryContainer, + padding: const EdgeInsets.symmetric(vertical: 16), + ), + child: Text( + AppLocalizations.of(context).search, + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimaryContainer, + fontSize: 16, + ), + ), + ), + ), + const SizedBox(height: 15), + if (!_txLoading && + _transactions.isNotEmpty && + fromDate == null && + toDate == null) + Padding( + padding: const EdgeInsets.only(bottom: 12.0), + child: Text( + AppLocalizations.of(context).lastTenTransactions, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ), + Expanded( + child: _txLoading + ? ListView.builder( + itemCount: 3, + itemBuilder: (_, __) => ListTile( + leading: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: CircleAvatar( + radius: 12, + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + ), + ), + title: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: Container( + height: 10, + width: 100, + color: + Theme.of(context).scaffoldBackgroundColor, + ), + ), + subtitle: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: Container( + height: 8, + width: 60, + color: + Theme.of(context).scaffoldBackgroundColor, + ), + ), + ), ) - : ListView.separated( - itemCount: _transactions.length, - itemBuilder: (context, index) { - final tx = _transactions[index]; - return ListTile( - leading: Icon( - tx.type == 'CR' - ? Symbols.call_received - : Symbols.call_made, - color: tx.type == 'CR' - ? Colors.green - : Theme.of(context).colorScheme.error, - ), - title: Text( - tx.date ?? '', - style: const TextStyle(fontSize: 15), - ), - subtitle: Text( - tx.name != null - ? (tx.name!.length > 22 - ? tx.name!.substring(0, 22) - : tx.name!) - : '', - style: const TextStyle(fontSize: 12), - ), - trailing: Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "₹${tx.amount}", - style: const TextStyle(fontSize: 17), + : _transactions.isEmpty + ? Center( + child: Text( + AppLocalizations.of(context).noTransactions, + style: TextStyle( + fontSize: 16, + color: + Theme.of(context).colorScheme.onSurface, + )), + ) + : ListView.separated( + itemCount: _transactions.length, + itemBuilder: (context, index) { + final tx = _transactions[index]; + return ListTile( + leading: Icon( + tx.type == 'CR' + ? Symbols.call_received + : Symbols.call_made, + color: tx.type == 'CR' + ? Colors.green + : Theme.of(context).colorScheme.error, ), - Text( - "Bal: ₹${tx.balance}", - style: const TextStyle( - fontSize: 12), // Style matches tx.name + title: Text( + tx.date ?? '', + style: const TextStyle(fontSize: 15), ), - ], - ), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => TransactionDetailsScreen( - transaction: tx), + subtitle: Text( + tx.name != null + ? (tx.name!.length > 22 + ? tx.name!.substring(0, 22) + : tx.name!) + : '', + style: const TextStyle(fontSize: 12), ), + trailing: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "₹${tx.amount}", + style: const TextStyle(fontSize: 17), + ), + Text( + "Bal: ₹${tx.balance}", + style: const TextStyle( + fontSize: + 12), // Style matches tx.name + ), + ], + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + TransactionDetailsScreen( + transaction: tx), + ), + ); + }, ); }, - ); - }, - separatorBuilder: (context, index) { - return const Divider(); - }, - ), + separatorBuilder: (context, index) { + return const Divider(); + }, + ), + ), + ], ), - ], - ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), floatingActionButton: FloatingActionButton( onPressed: () { diff --git a/lib/features/accounts/screens/transaction_details_screen.dart b/lib/features/accounts/screens/transaction_details_screen.dart index af01bdd..e639537 100644 --- a/lib/features/accounts/screens/transaction_details_screen.dart +++ b/lib/features/accounts/screens/transaction_details_screen.dart @@ -14,72 +14,91 @@ class TransactionDetailsScreen extends StatelessWidget { return Scaffold( appBar: AppBar(title: Text(AppLocalizations.of(context).transactionDetails)), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - Expanded( - flex: 3, - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // Amount + icon + Share Button - Row( + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Expanded( + flex: 3, + child: Center( + child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text( - "₹ ${transaction.amount}", - style: const TextStyle( - fontSize: 40, - fontWeight: FontWeight.bold, - ), + // Amount + icon + Share Button + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "₹ ${transaction.amount}", + style: const TextStyle( + fontSize: 40, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 8), + Icon( + isCredit + ? Symbols.call_received + : Symbols.call_made, + color: isCredit ? Colors.green : Colors.red, + size: 28, + ), + ], ), - const SizedBox(width: 8), - Icon( - isCredit ? Symbols.call_received : Symbols.call_made, - color: isCredit ? Colors.green : Colors.red, - size: 28, + const SizedBox(height: 8), + // Date centered + Text( + transaction.date ?? "", + style: const TextStyle( + fontSize: 16, + color: Colors.grey, + ), + textAlign: TextAlign.center, ), ], ), - const SizedBox(height: 8), - // Date centered - Text( - transaction.date ?? "", - style: const TextStyle( - fontSize: 16, - color: Colors.grey, - ), - textAlign: TextAlign.center, - ), - ], + ), + ), + const Divider(), + Expanded( + flex: 5, + child: ListView( + children: [ + _buildDetailRow( + AppLocalizations.of(context).transactionType, + transaction.type ?? ""), + _buildDetailRow(AppLocalizations.of(context).transferType, + transaction.name.split("/").first ?? ""), + // if (transaction.name.length > 12) ...[ + // _buildDetailRow(AppLocalizations.of(context).utrNo, + // transaction.name.split("= ")[1].split(" ")[0] ?? ""), + // _buildDetailRow( + // AppLocalizations.of(context).beneficiaryAccountNo, + // transaction.name.split("A/C ").last ?? "") + // ] + _buildDetailRow(AppLocalizations.of(context).details, + transaction.name), + ], + ), + ), + ], + ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), ), ), - const Divider(), - Expanded( - flex: 5, - child: ListView( - children: [ - _buildDetailRow(AppLocalizations.of(context).transactionType, - transaction.type ?? ""), - _buildDetailRow(AppLocalizations.of(context).transferType, - transaction.name.split("/").first ?? ""), - // if (transaction.name.length > 12) ...[ - // _buildDetailRow(AppLocalizations.of(context).utrNo, - // transaction.name.split("= ")[1].split(" ")[0] ?? ""), - // _buildDetailRow( - // AppLocalizations.of(context).beneficiaryAccountNo, - // transaction.name.split("A/C ").last ?? "") - // ] - _buildDetailRow( - AppLocalizations.of(context).details, transaction.name), - ], - ), - ), - ], - ), + ), + ], ), ); } diff --git a/lib/features/auth/screens/tnc_required_screen.dart b/lib/features/auth/screens/tnc_required_screen.dart index 3bbd76b..7d6b470 100644 --- a/lib/features/auth/screens/tnc_required_screen.dart +++ b/lib/features/auth/screens/tnc_required_screen.dart @@ -12,28 +12,44 @@ class TncRequiredScreen extends StatelessWidget { appBar: AppBar( title: const Text('Terms and Conditions'), ), - body: Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You must accept the Terms and Conditions to use the application.', - textAlign: TextAlign.center, - style: TextStyle(fontSize: 18), + body: Stack( + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'You must accept the Terms and Conditions to use the application.', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18), + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () { + // This will take the user back to the previous screen + Navigator.of(context).pop(); + }, + child: const Text('Go Back'), + ), + ], ), - const SizedBox(height: 20), - ElevatedButton( - onPressed: () { - // This will take the user back to the previous screen - Navigator.of(context).pop(); - }, - child: const Text('Go Back'), - ), - ], + ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ); } diff --git a/lib/features/beneficiaries/screens/add_beneficiary_screen.dart b/lib/features/beneficiaries/screens/add_beneficiary_screen.dart index c0b970a..8ac93bb 100644 --- a/lib/features/beneficiaries/screens/add_beneficiary_screen.dart +++ b/lib/features/beneficiaries/screens/add_beneficiary_screen.dart @@ -264,278 +264,304 @@ class _AddBeneficiaryScreen extends State { centerTitle: false, ), body: SafeArea( - child: Form( - key: _formKey, - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - child: Padding( - padding: const EdgeInsets.all(10.0), - child: Column( - children: [ - TextFormField( - key: _accountNumberFieldKey, - controller: accountNumberController, - decoration: InputDecoration( - labelText: AppLocalizations.of( - context, - ).accountNumber, - // prefixIcon: Icon(Icons.person), - border: const OutlineInputBorder(), - isDense: true, - ), - obscureText: true, - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - onChanged: (value) { - nameController.clear(); - setState(() { - _isBeneficiaryValidated = false; - }); - }, - validator: (value) { - if (value == null || value.length < 10) { - return AppLocalizations.of( - context, - ).enterValidAccountNumber; - } - return null; - }, - ), - const SizedBox(height: 24), - // Confirm Account Number - TextFormField( - key: _confirmAccountNumberFieldKey, - controller: confirmAccountNumberController, - decoration: InputDecoration( - labelText: AppLocalizations.of( - context, - ).confirmAccountNumber, - // prefixIcon: Icon(Icons.person), - border: const OutlineInputBorder(), - isDense: true, - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of( - context, - ).reenterAccountNumber; - } - if (value != accountNumberController.text) { - return AppLocalizations.of( - context, - ).accountMismatch; - } - return null; - }, - ), - const SizedBox(height: 24), - TextFormField( - focusNode: _ifscFocusNode, - key: _ifscFieldKey, - controller: ifscController, - maxLength: 11, - inputFormatters: [ - LengthLimitingTextInputFormatter(11), - ], - decoration: InputDecoration( - labelText: AppLocalizations.of(context).ifscCode, - border: const OutlineInputBorder(), - isDense: true, - ), - textCapitalization: TextCapitalization.characters, - textInputAction: TextInputAction.next, - onChanged: (value) { - setState(() { - final trimmed = value.trim().toUpperCase(); - if (trimmed.length < 11) { - // clear bank/branch if backspace or changed - bankNameController.clear(); - branchNameController.clear(); - } - }); - }, - validator: (value) { - final pattern = RegExp(r'^[A-Z]{4}0[A-Z0-9]{6}$'); - if (value == null || value.trim().isEmpty) { - return AppLocalizations.of(context).enterIfsc; - } else if (!pattern.hasMatch( - value.trim().toUpperCase(), - )) { - return AppLocalizations.of( - context, - ).invalidIfscFormat; - } - return null; - }, - ), - const SizedBox(height: 24), - // Bank Name (Disabled) - TextFormField( - controller: bankNameController, - enabled: false, // changed from readOnly to disabled - decoration: InputDecoration( - labelText: AppLocalizations.of(context).bankName, - border: const OutlineInputBorder(), - isDense: true, - ), - ), - const SizedBox(height: 24), - // 🔹 Branch Name (Disabled) - TextFormField( - controller: branchNameController, - enabled: false, // changed from readOnly to disabled - decoration: InputDecoration( - labelText: AppLocalizations.of(context).branchName, - border: const OutlineInputBorder(), - isDense: true, - ), - ), - if (_isBeneficiaryValidated) - Column( - children: [ - const SizedBox(height: 24), - TextFormField( - controller: nameController, - enabled: false, - decoration: InputDecoration( - suffixIcon: _isBeneficiaryValidated - ? const Icon( - Symbols.verified, - size: 25, - fill: 1, - ) - : null, - suffixIconColor: - Theme.of(context).colorScheme.primary, - labelText: AppLocalizations.of(context) - .beneficiaryName, - border: const OutlineInputBorder(), - isDense: true, - ), - textInputAction: TextInputAction.next, - validator: (value) => value == null || - value.isEmpty - ? AppLocalizations.of(context).nameRequired - : null, + child: Stack( + children: [ + Form( + key: _formKey, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + children: [ + TextFormField( + key: _accountNumberFieldKey, + controller: accountNumberController, + decoration: InputDecoration( + labelText: AppLocalizations.of( + context, + ).accountNumber, + // prefixIcon: Icon(Icons.person), + border: const OutlineInputBorder(), + isDense: true, ), - ], - ), - const SizedBox(height: 24), - if (!_isBeneficiaryValidated) - Padding( - padding: const EdgeInsets.only(bottom: 24), - child: SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _isValidating || - ifscController.text.length != 11 - ? null - : () { - final isAccountValid = - _accountNumberFieldKey.currentState! - .validate(); - final isConfirmAccountValid = - _confirmAccountNumberFieldKey - .currentState! - .validate(); - final isIfscValid = _ifscFieldKey - .currentState! - .validate(); - - if (isAccountValid && - isConfirmAccountValid && - isIfscValid) { - _validateBeneficiary(); - } - }, - child: _isValidating - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - strokeWidth: 2), - ) - : Text(AppLocalizations.of(context) - .validateBeneficiary), + obscureText: true, + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + onChanged: (value) { + nameController.clear(); + setState(() { + _isBeneficiaryValidated = false; + }); + }, + validator: (value) { + if (value == null || value.length < 10) { + return AppLocalizations.of( + context, + ).enterValidAccountNumber; + } + return null; + }, + ), + const SizedBox(height: 24), + // Confirm Account Number + TextFormField( + key: _confirmAccountNumberFieldKey, + controller: confirmAccountNumberController, + decoration: InputDecoration( + labelText: AppLocalizations.of( + context, + ).confirmAccountNumber, + // prefixIcon: Icon(Icons.person), + border: const OutlineInputBorder(), + isDense: true, + ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of( + context, + ).reenterAccountNumber; + } + if (value != accountNumberController.text) { + return AppLocalizations.of( + context, + ).accountMismatch; + } + return null; + }, + ), + const SizedBox(height: 24), + TextFormField( + focusNode: _ifscFocusNode, + key: _ifscFieldKey, + controller: ifscController, + maxLength: 11, + inputFormatters: [ + LengthLimitingTextInputFormatter(11), + ], + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).ifscCode, + border: const OutlineInputBorder(), + isDense: true, + ), + textCapitalization: TextCapitalization.characters, + textInputAction: TextInputAction.next, + onChanged: (value) { + setState(() { + final trimmed = value.trim().toUpperCase(); + if (trimmed.length < 11) { + // clear bank/branch if backspace or changed + bankNameController.clear(); + branchNameController.clear(); + } + }); + }, + validator: (value) { + final pattern = + RegExp(r'^[A-Z]{4}0[A-Z0-9]{6}$'); + if (value == null || value.trim().isEmpty) { + return AppLocalizations.of(context).enterIfsc; + } else if (!pattern.hasMatch( + value.trim().toUpperCase(), + )) { + return AppLocalizations.of( + context, + ).invalidIfscFormat; + } + return null; + }, + ), + const SizedBox(height: 24), + // Bank Name (Disabled) + TextFormField( + controller: bankNameController, + enabled: + false, // changed from readOnly to disabled + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).bankName, + border: const OutlineInputBorder(), + isDense: true, ), ), - ), - //Beneficiary Name (Disabled) - // 🔹 Account Type Dropdown - DropdownButtonFormField( - value: accountType, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).accountType, - border: const OutlineInputBorder(), - isDense: true, - ), - items: [ - 'Savings', - 'Current', - ] - .map( - (type) => DropdownMenuItem( - value: type, - child: Text(type), - ), - ) - .toList(), - onChanged: (value) { - setState(() { - accountType = value!; - }); - }, - ), + const SizedBox(height: 24), + // 🔹 Branch Name (Disabled) + TextFormField( + controller: branchNameController, + enabled: + false, // changed from readOnly to disabled + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).branchName, + border: const OutlineInputBorder(), + isDense: true, + ), + ), + if (_isBeneficiaryValidated) + Column( + children: [ + const SizedBox(height: 24), + TextFormField( + controller: nameController, + enabled: false, + decoration: InputDecoration( + suffixIcon: _isBeneficiaryValidated + ? const Icon( + Symbols.verified, + size: 25, + fill: 1, + ) + : null, + suffixIconColor: + Theme.of(context).colorScheme.primary, + labelText: AppLocalizations.of(context) + .beneficiaryName, + border: const OutlineInputBorder(), + isDense: true, + ), + textInputAction: TextInputAction.next, + validator: (value) => + value == null || value.isEmpty + ? AppLocalizations.of(context) + .nameRequired + : null, + ), + ], + ), + const SizedBox(height: 24), + if (!_isBeneficiaryValidated) + Padding( + padding: const EdgeInsets.only(bottom: 24), + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _isValidating || + ifscController.text.length != 11 + ? null + : () { + final isAccountValid = + _accountNumberFieldKey + .currentState! + .validate(); + final isConfirmAccountValid = + _confirmAccountNumberFieldKey + .currentState! + .validate(); + final isIfscValid = _ifscFieldKey + .currentState! + .validate(); - const SizedBox(height: 24), - TextFormField( - controller: phoneController, - keyboardType: TextInputType.phone, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).phone, - prefixIcon: const Icon(Icons.phone), - border: const OutlineInputBorder(), - isDense: true, - ), - textInputAction: TextInputAction.done, - validator: (value) => - value == null || value.length != 10 + if (isAccountValid && + isConfirmAccountValid && + isIfscValid) { + _validateBeneficiary(); + } + }, + child: _isValidating + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2), + ) + : Text(AppLocalizations.of(context) + .validateBeneficiary), + ), + ), + ), + //Beneficiary Name (Disabled) + // 🔹 Account Type Dropdown + DropdownButtonFormField( + value: accountType, + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).accountType, + border: const OutlineInputBorder(), + isDense: true, + ), + items: [ + 'Savings', + 'Current', + ] + .map( + (type) => DropdownMenuItem( + value: type, + child: Text(type), + ), + ) + .toList(), + onChanged: (value) { + setState(() { + accountType = value!; + }); + }, + ), + + const SizedBox(height: 24), + TextFormField( + controller: phoneController, + keyboardType: TextInputType.phone, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).phone, + prefixIcon: const Icon(Icons.phone), + border: const OutlineInputBorder(), + isDense: true, + ), + textInputAction: TextInputAction.done, + validator: (value) => value == null || + value.length != 10 ? AppLocalizations.of(context).enterValidPhone : null, + ), + const SizedBox(height: 35), + ], ), - const SizedBox(height: 35), - ], + ), ), ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: SizedBox( + width: 250, + child: ElevatedButton( + onPressed: validateAndAddBeneficiary, + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + padding: const EdgeInsets.symmetric(vertical: 16), + backgroundColor: + Theme.of(context).colorScheme.primaryContainer, + foregroundColor: Theme.of(context) + .colorScheme + .onPrimaryContainer), + child: Text( + AppLocalizations.of(context).validateAndAdd, + style: const TextStyle(fontSize: 16), + ), + ), + ), + ), + ], + ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), ), ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: SizedBox( - width: 250, - child: ElevatedButton( - onPressed: validateAndAddBeneficiary, - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - padding: const EdgeInsets.symmetric(vertical: 16), - backgroundColor: - Theme.of(context).colorScheme.primaryContainer, - foregroundColor: - Theme.of(context).colorScheme.onPrimaryContainer), - child: Text( - AppLocalizations.of(context).validateAndAdd, - style: const TextStyle(fontSize: 16), - ), - ), - ), - ), - ], - ), + ), + ], ), ), ); diff --git a/lib/features/beneficiaries/screens/beneficiary_details_screen.dart b/lib/features/beneficiaries/screens/beneficiary_details_screen.dart index fffe624..97d0ed1 100644 --- a/lib/features/beneficiaries/screens/beneficiary_details_screen.dart +++ b/lib/features/beneficiaries/screens/beneficiary_details_screen.dart @@ -81,60 +81,78 @@ class BeneficiaryDetailsScreen extends StatelessWidget { title: Text(AppLocalizations.of(context).beneficiarydetails), ), body: SafeArea( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - CircleAvatar( - radius: 24, - backgroundColor: Colors.transparent, - child: getBankLogo(beneficiary.bankName, context), + Row( + children: [ + CircleAvatar( + radius: 24, + backgroundColor: Colors.transparent, + child: getBankLogo(beneficiary.bankName, context), + ), + const SizedBox(width: 16), + Text( + beneficiary.name, + style: const TextStyle( + fontSize: 20, fontWeight: FontWeight.bold), + ), + ], ), - const SizedBox(width: 16), - Text( - beneficiary.name, - style: const TextStyle( - fontSize: 20, fontWeight: FontWeight.bold), + const SizedBox(height: 24), + _buildDetailRow('${AppLocalizations.of(context).bankName} ', + beneficiary.bankName ?? 'N/A'), + _buildDetailRow( + '${AppLocalizations.of(context).accountNumber} ', + beneficiary.accountNo), + _buildDetailRow( + '${AppLocalizations.of(context).accountType} ', + beneficiary.accountType), + _buildDetailRow('${AppLocalizations.of(context).ifscCode} ', + beneficiary.ifscCode), + _buildDetailRow('${AppLocalizations.of(context).branchName} ', + beneficiary.branchName ?? 'N/A'), + const Spacer(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + // ElevatedButton.icon( + // onPressed: () { + // // Set Transaction Limit for this beneficiary + // }, + // icon: const Icon(Icons.currency_rupee), + // label: const Text('Set Limit'), + // ), + ElevatedButton.icon( + onPressed: () { + // Delete beneficiary option + _showDeleteConfirmationDialog(context); + }, + icon: const Icon(Icons.delete), + label: Text(AppLocalizations.of(context).delete), + ), + ], ), ], ), - const SizedBox(height: 24), - _buildDetailRow('${AppLocalizations.of(context).bankName} ', - beneficiary.bankName ?? 'N/A'), - _buildDetailRow('${AppLocalizations.of(context).accountNumber} ', - beneficiary.accountNo), - _buildDetailRow('${AppLocalizations.of(context).accountType} ', - beneficiary.accountType), - _buildDetailRow('${AppLocalizations.of(context).ifscCode} ', - beneficiary.ifscCode), - _buildDetailRow('${AppLocalizations.of(context).branchName} ', - beneficiary.branchName ?? 'N/A'), - const Spacer(), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - // ElevatedButton.icon( - // onPressed: () { - // // Set Transaction Limit for this beneficiary - // }, - // icon: const Icon(Icons.currency_rupee), - // label: const Text('Set Limit'), - // ), - ElevatedButton.icon( - onPressed: () { - // Delete beneficiary option - _showDeleteConfirmationDialog(context); - }, - icon: const Icon(Icons.delete), - label: Text(AppLocalizations.of(context).delete), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), - ], + ), ), - ], - ), + ), + ], ), ), ); diff --git a/lib/features/beneficiaries/screens/manage_beneficiaries_screen.dart b/lib/features/beneficiaries/screens/manage_beneficiaries_screen.dart index 9c7a21e..726c2b6 100644 --- a/lib/features/beneficiaries/screens/manage_beneficiaries_screen.dart +++ b/lib/features/beneficiaries/screens/manage_beneficiaries_screen.dart @@ -109,7 +109,23 @@ class _ManageBeneficiariesScreen extends State { appBar: AppBar( title: Text(AppLocalizations.of(context).beneficiaries), ), - body: _isLoading ? _buildShimmerList() : _buildBeneficiaryList(), + body: Stack( + children: [ + _isLoading ? _buildShimmerList() : _buildBeneficiaryList(), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], + ), floatingActionButton: Padding( padding: const EdgeInsets.only(bottom: 8.0), child: FloatingActionButton( diff --git a/lib/features/card/screens/block_card_screen.dart b/lib/features/card/screens/block_card_screen.dart index afa3883..8287861 100644 --- a/lib/features/card/screens/block_card_screen.dart +++ b/lib/features/card/screens/block_card_screen.dart @@ -61,132 +61,154 @@ class _BlockCardScreen extends State { ), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: Form( - key: _formKey, - child: ListView( - children: [ - const SizedBox(height: 10), - TextFormField( - controller: _cardController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).cardNumber, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) => value != null && value.length == 11 - ? null - : AppLocalizations.of(context).enterValidCardNumber, - ), - const SizedBox(height: 24), - Row( + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Form( + key: _formKey, + child: ListView( children: [ - Expanded( - child: TextFormField( - controller: _cvvController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).cvv, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), + const SizedBox(height: 10), + TextFormField( + controller: _cardController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).cardNumber, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black, width: 2), ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - obscureText: true, - validator: (value) => value != null && value.length == 3 - ? null - : AppLocalizations.of(context).cvv3Digits, ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) => value != null && value.length == 11 + ? null + : AppLocalizations.of(context).enterValidCardNumber, ), - const SizedBox(width: 16), - Expanded( - child: TextFormField( - controller: _expiryController, - readOnly: true, - onTap: _pickExpiryDate, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).expiryDate, - suffixIcon: const Icon(Icons.calendar_today), - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), + const SizedBox(height: 24), + Row( + children: [ + Expanded( + child: TextFormField( + controller: _cvvController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).cvv, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: + BorderSide(color: Colors.black, width: 2), + ), + ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + obscureText: true, + validator: (value) => + value != null && value.length == 3 + ? null + : AppLocalizations.of(context).cvv3Digits, ), ), - validator: (value) => value != null && value.isNotEmpty - ? null - : AppLocalizations.of(context).selectExpiryDate, + const SizedBox(width: 16), + Expanded( + child: TextFormField( + controller: _expiryController, + readOnly: true, + onTap: _pickExpiryDate, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).expiryDate, + suffixIcon: const Icon(Icons.calendar_today), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: + BorderSide(color: Colors.black, width: 2), + ), + ), + validator: (value) => value != null && + value.isNotEmpty + ? null + : AppLocalizations.of(context).selectExpiryDate, + ), + ), + ], + ), + const SizedBox(height: 24), + TextFormField( + controller: _phoneController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).phone, + prefixIcon: const Icon(Icons.phone), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black, width: 2), + ), + ), + textInputAction: TextInputAction.done, + keyboardType: TextInputType.phone, + validator: (value) => value != null && value.length >= 10 + ? null + : AppLocalizations.of(context).enterValidPhone, + ), + const SizedBox(height: 45), + Align( + alignment: Alignment.center, + child: SizedBox( + width: 250, + child: ElevatedButton( + onPressed: _blockCard, + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + padding: const EdgeInsets.symmetric(vertical: 16), + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: + Theme.of(context).scaffoldBackgroundColor, + ), + child: Text(AppLocalizations.of(context).block), + ), ), ), ], ), - const SizedBox(height: 24), - TextFormField( - controller: _phoneController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).phone, - prefixIcon: const Icon(Icons.phone), - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), - ), - textInputAction: TextInputAction.done, - keyboardType: TextInputType.phone, - validator: (value) => value != null && value.length >= 10 - ? null - : AppLocalizations.of(context).enterValidPhone, - ), - const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SizedBox( - width: 250, - child: ElevatedButton( - onPressed: _blockCard, - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - padding: const EdgeInsets.symmetric(vertical: 16), - backgroundColor: Theme.of(context).primaryColor, - foregroundColor: - Theme.of(context).scaffoldBackgroundColor, - ), - child: Text(AppLocalizations.of(context).block), - ), - ), - ), - ], + ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ); } diff --git a/lib/features/card/screens/card_details_screen.dart b/lib/features/card/screens/card_details_screen.dart index 2661754..0e5ee1c 100644 --- a/lib/features/card/screens/card_details_screen.dart +++ b/lib/features/card/screens/card_details_screen.dart @@ -9,27 +9,43 @@ class CardDetailsScreen extends StatelessWidget { appBar: AppBar( title: const Text("My Cards"), ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: ListView( - children: const [ - CardTile( - cardNumber: "**** **** **** 1234", - cardNetwork: "VISA", - cardType: "Debit Card", - validFrom: "01/22", - validTo: "01/27", + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: ListView( + children: const [ + CardTile( + cardNumber: "**** **** **** 1234", + cardNetwork: "VISA", + cardType: "Debit Card", + validFrom: "01/22", + validTo: "01/27", + ), + SizedBox(height: 16), + CardTile( + cardNumber: "**** **** **** 5678", + cardNetwork: "Mastercard", + cardType: "Debit Card", + validFrom: "07/21", + validTo: "07/26", + ), + ], ), - SizedBox(height: 16), - CardTile( - cardNumber: "**** **** **** 5678", - cardNetwork: "Mastercard", - cardType: "Debit Card", - validFrom: "07/21", - validTo: "07/26", + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), ), - ], - ), + ), + ], ), ); } diff --git a/lib/features/card/screens/card_management_screen.dart b/lib/features/card/screens/card_management_screen.dart index eb65e7d..8c19b12 100644 --- a/lib/features/card/screens/card_management_screen.dart +++ b/lib/features/card/screens/card_management_screen.dart @@ -25,57 +25,73 @@ class _CardManagementScreen extends State { ), centerTitle: false, ), - body: ListView( + body: Stack( children: [ - CardManagementTile( - icon: Symbols.add, - label: AppLocalizations.of(context).applyDebitCard, - onTap: () {}, - disabled: true, // Add this + ListView( + children: [ + CardManagementTile( + icon: Symbols.add, + label: AppLocalizations.of(context).applyDebitCard, + onTap: () {}, + disabled: true, // Add this + ), + const Divider(height: 1), + CardManagementTile( + icon: Symbols.remove_moderator, + label: AppLocalizations.of(context).blockUnblockCard, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BlockCardScreen(), + ), + ); + }, + disabled: true, + ), + const Divider(height: 1), + CardManagementTile( + icon: Symbols.password_2, + label: AppLocalizations.of(context).changeCardPin, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CardPinChangeDetailsScreen(), + ), + ); + }, + disabled: true, + ), + const Divider(height: 1), + CardManagementTile( + icon: Symbols.payment_card, + label: AppLocalizations.of(context).viewCardDeatils, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CardDetailsScreen(), + ), + ); + }, + disabled: true, + ), + const Divider(height: 1), + ], ), - const Divider(height: 1), - CardManagementTile( - icon: Symbols.remove_moderator, - label: AppLocalizations.of(context).blockUnblockCard, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const BlockCardScreen(), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), - ); - }, - disabled: true, + ), + ), ), - const Divider(height: 1), - CardManagementTile( - icon: Symbols.password_2, - label: AppLocalizations.of(context).changeCardPin, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const CardPinChangeDetailsScreen(), - ), - ); - }, - disabled: true, - ), - const Divider(height: 1), - CardManagementTile( - icon: Symbols.payment_card, - label: AppLocalizations.of(context).viewCardDeatils, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const CardDetailsScreen(), - ), - ); - }, - disabled: true, - ), - const Divider(height: 1), ], ), ); diff --git a/lib/features/card/screens/card_pin_change_details_screen.dart b/lib/features/card/screens/card_pin_change_details_screen.dart index 41a4b04..b1d6dd8 100644 --- a/lib/features/card/screens/card_pin_change_details_screen.dart +++ b/lib/features/card/screens/card_pin_change_details_screen.dart @@ -51,132 +51,154 @@ class _CardPinChangeDetailsScreen extends State { ), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: Form( - key: _formKey, - child: ListView( - children: [ - const SizedBox(height: 10), - TextFormField( - controller: _cardController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).cardNumber, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) => value != null && value.length == 11 - ? null - : AppLocalizations.of(context).enterValidCardNumber, - ), - const SizedBox(height: 24), - Row( + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Form( + key: _formKey, + child: ListView( children: [ - Expanded( - child: TextFormField( - controller: _cvvController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).cvv, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), + const SizedBox(height: 10), + TextFormField( + controller: _cardController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).cardNumber, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black, width: 2), ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - obscureText: true, - validator: (value) => value != null && value.length == 3 - ? null - : AppLocalizations.of(context).cvv3Digits, ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) => value != null && value.length == 11 + ? null + : AppLocalizations.of(context).enterValidCardNumber, ), - const SizedBox(width: 16), - Expanded( - child: TextFormField( - controller: _expiryController, - readOnly: true, - onTap: _pickExpiryDate, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).expiryDate, - suffixIcon: const Icon(Icons.calendar_today), - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), + const SizedBox(height: 24), + Row( + children: [ + Expanded( + child: TextFormField( + controller: _cvvController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).cvv, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: + BorderSide(color: Colors.black, width: 2), + ), + ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + obscureText: true, + validator: (value) => + value != null && value.length == 3 + ? null + : AppLocalizations.of(context).cvv3Digits, ), ), - validator: (value) => value != null && value.isNotEmpty - ? null - : AppLocalizations.of(context).selectExpiryDate, + const SizedBox(width: 16), + Expanded( + child: TextFormField( + controller: _expiryController, + readOnly: true, + onTap: _pickExpiryDate, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).expiryDate, + suffixIcon: const Icon(Icons.calendar_today), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: + BorderSide(color: Colors.black, width: 2), + ), + ), + validator: (value) => value != null && + value.isNotEmpty + ? null + : AppLocalizations.of(context).selectExpiryDate, + ), + ), + ], + ), + const SizedBox(height: 24), + TextFormField( + controller: _phoneController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).phone, + prefixIcon: const Icon(Icons.phone), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black, width: 2), + ), + ), + textInputAction: TextInputAction.done, + keyboardType: TextInputType.phone, + validator: (value) => value != null && value.length >= 10 + ? null + : AppLocalizations.of(context).enterValidPhone, + ), + const SizedBox(height: 45), + Align( + alignment: Alignment.center, + child: SizedBox( + width: 250, + child: ElevatedButton( + onPressed: _nextButton, + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + padding: const EdgeInsets.symmetric(vertical: 16), + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: + Theme.of(context).scaffoldBackgroundColor, + ), + child: Text(AppLocalizations.of(context).next), + ), ), ), ], ), - const SizedBox(height: 24), - TextFormField( - controller: _phoneController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).phone, - prefixIcon: const Icon(Icons.phone), - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), - ), - textInputAction: TextInputAction.done, - keyboardType: TextInputType.phone, - validator: (value) => value != null && value.length >= 10 - ? null - : AppLocalizations.of(context).enterValidPhone, - ), - const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SizedBox( - width: 250, - child: ElevatedButton( - onPressed: _nextButton, - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - padding: const EdgeInsets.symmetric(vertical: 16), - backgroundColor: Theme.of(context).primaryColor, - foregroundColor: - Theme.of(context).scaffoldBackgroundColor, - ), - child: Text(AppLocalizations.of(context).next), - ), - ), - ), - ], + ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ); } diff --git a/lib/features/card/screens/card_pin_set_screen.dart b/lib/features/card/screens/card_pin_set_screen.dart index b0a08a2..4504d3f 100644 --- a/lib/features/card/screens/card_pin_set_screen.dart +++ b/lib/features/card/screens/card_pin_set_screen.dart @@ -51,87 +51,103 @@ class _CardPinSetScreen extends State { ), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: Column( - children: [ - TextFormField( - controller: _pinController, - obscureText: true, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).enterNewPin, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).pleaseEnterNewPin; - } - if (value.length < 4) { - return AppLocalizations.of(context).pin4Digits; - } - return null; - }, - ), - const SizedBox(height: 24), - TextFormField( - controller: _confirmPinController, - obscureText: true, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).enterAgain, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - ), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.black, width: 2), - ), - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.done, - validator: (value) { - if (value != _pinController.text) { - return AppLocalizations.of(context).pinsDoNotMatch; - } - return null; - }, - ), - const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SizedBox( - width: 250, - child: ElevatedButton( - onPressed: _submit, - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - padding: const EdgeInsets.symmetric(vertical: 16), - backgroundColor: Theme.of(context).primaryColor, - foregroundColor: - Theme.of(context).scaffoldBackgroundColor, + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + controller: _pinController, + obscureText: true, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).enterNewPin, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black, width: 2), + ), ), - child: Text(AppLocalizations.of(context).submit), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context).pleaseEnterNewPin; + } + if (value.length < 4) { + return AppLocalizations.of(context).pin4Digits; + } + return null; + }, ), + const SizedBox(height: 24), + TextFormField( + controller: _confirmPinController, + obscureText: true, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).enterAgain, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black), + ), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.black, width: 2), + ), + ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.done, + validator: (value) { + if (value != _pinController.text) { + return AppLocalizations.of(context).pinsDoNotMatch; + } + return null; + }, + ), + const SizedBox(height: 45), + Align( + alignment: Alignment.center, + child: SizedBox( + width: 250, + child: ElevatedButton( + onPressed: _submit, + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + padding: const EdgeInsets.symmetric(vertical: 16), + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: + Theme.of(context).scaffoldBackgroundColor, + ), + child: Text(AppLocalizations.of(context).submit), + ), + ), + ), + ], + ), + ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), ), - ], + ), ), - ), + ], ), ); } diff --git a/lib/features/cheque/screens/cheque_management_screen.dart b/lib/features/cheque/screens/cheque_management_screen.dart index fee8eb0..f42eb3b 100644 --- a/lib/features/cheque/screens/cheque_management_screen.dart +++ b/lib/features/cheque/screens/cheque_management_screen.dart @@ -22,50 +22,67 @@ class _ChequeManagementScreen extends State { ), centerTitle: false, ), - body: ListView( + body: Stack( children: [ - const SizedBox(height: 15), - ChequeManagementTile( - icon: Symbols.add, - label: AppLocalizations.of(context).requestChequeBook, - onTap: () {}, + ListView( + children: [ + const SizedBox(height: 15), + ChequeManagementTile( + icon: Symbols.add, + label: AppLocalizations.of(context).requestChequeBook, + onTap: () {}, + ), + const Divider(height: 1), + ChequeManagementTile( + icon: Symbols.data_alert, + label: AppLocalizations.of(context).enquiry, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const EnquiryScreen()), + ); + }, + ), + const Divider(height: 1), + ChequeManagementTile( + icon: Symbols.approval_delegation, + label: AppLocalizations.of(context).chequeDeposit, + onTap: () {}, + ), + const Divider(height: 1), + ChequeManagementTile( + icon: Symbols.front_hand, + label: AppLocalizations.of(context).stopCheque, + onTap: () {}, + ), + const Divider(height: 1), + ChequeManagementTile( + icon: Symbols.cancel_presentation, + label: AppLocalizations.of(context).revokeStop, + onTap: () {}, + ), + const Divider(height: 1), + ChequeManagementTile( + icon: Symbols.payments, + label: AppLocalizations.of(context).positivePay, + onTap: () {}, + ), + const Divider(height: 1), + ], ), - const Divider(height: 1), - ChequeManagementTile( - icon: Symbols.data_alert, - label: AppLocalizations.of(context).enquiry, - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => const EnquiryScreen()), - ); - }, + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), ), - const Divider(height: 1), - ChequeManagementTile( - icon: Symbols.approval_delegation, - label: AppLocalizations.of(context).chequeDeposit, - onTap: () {}, - ), - const Divider(height: 1), - ChequeManagementTile( - icon: Symbols.front_hand, - label: AppLocalizations.of(context).stopCheque, - onTap: () {}, - ), - const Divider(height: 1), - ChequeManagementTile( - icon: Symbols.cancel_presentation, - label: AppLocalizations.of(context).revokeStop, - onTap: () {}, - ), - const Divider(height: 1), - ChequeManagementTile( - icon: Symbols.payments, - label: AppLocalizations.of(context).positivePay, - onTap: () {}, - ), - const Divider(height: 1), ], ), ); diff --git a/lib/features/customer_info/screens/customer_info_screen.dart b/lib/features/customer_info/screens/customer_info_screen.dart index 4da2df4..c4e0b94 100644 --- a/lib/features/customer_info/screens/customer_info_screen.dart +++ b/lib/features/customer_info/screens/customer_info_screen.dart @@ -33,74 +33,90 @@ class _CustomerInfoScreenState extends State { .replaceFirst(RegExp('\n'), ''), ), ), - body: 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, - ), - ), - Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - user.name ?? '', - style: TextStyle( - fontSize: 20, - color: theme.colorScheme.onSurface, - fontWeight: FontWeight.w500, + 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, + ), ), - ), + Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Text( + user.name ?? '', + style: TextStyle( + fontSize: 20, + color: theme.colorScheme.onSurface, + fontWeight: FontWeight.w500, + ), + ), + ), + Text( + '${AppLocalizations.of(context).cif}: ${user.cifNumber ?? 'N/A'}', + style: TextStyle( + fontSize: 16, + color: theme.colorScheme.onSurfaceVariant), + ), + const SizedBox(height: 30), + InfoField( + label: AppLocalizations.of(context).activeAccounts, + value: user.activeAccounts?.toString() ?? '6', + ), + 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).branchAddress, + 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 + ], ), - Text( - '${AppLocalizations.of(context).cif}: ${user.cifNumber ?? 'N/A'}', - style: TextStyle( - fontSize: 16, - color: theme.colorScheme.onSurfaceVariant), - ), - const SizedBox(height: 30), - InfoField( - label: AppLocalizations.of(context).activeAccounts, - value: user.activeAccounts?.toString() ?? '6', - ), - 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).branchAddress, - 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.1, // Low opacity + 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 bb8bc13..a3b3b10 100644 --- a/lib/features/dashboard/screens/dashboard_screen.dart +++ b/lib/features/dashboard/screens/dashboard_screen.dart @@ -15,6 +15,7 @@ import 'package:kmobile/features/enquiry/screens/enquiry_screen.dart'; import 'package:kmobile/features/fund_transfer/screens/fund_transfer_screen.dart'; import 'package:kmobile/features/profile/profile_screen.dart'; import 'package:kmobile/features/quick_pay/screens/quick_pay_screen.dart'; +import 'package:kmobile/features/service/screens/branch_locator_screen.dart'; import 'package:kmobile/security/secure_storage.dart'; import 'package:local_auth/local_auth.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; @@ -547,9 +548,14 @@ class _DashboardScreenState extends State .accountType!, ))); }), - _buildQuickLink(Symbols.checkbook, - AppLocalizations.of(context).handleCheque, () {}, - disable: true), + _buildQuickLink(Icons.location_pin, "Branch Locator", + () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + const BranchLocatorScreen())); + }, disable: false), _buildQuickLink(Icons.group, AppLocalizations.of(context).manageBeneficiary, () { diff --git a/lib/features/enquiry/screens/enquiry_screen.dart b/lib/features/enquiry/screens/enquiry_screen.dart index 699e68f..0635bf7 100644 --- a/lib/features/enquiry/screens/enquiry_screen.dart +++ b/lib/features/enquiry/screens/enquiry_screen.dart @@ -70,66 +70,83 @@ class _EnquiryScreen extends State { title: Text(AppLocalizations.of(context).enquiry), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 20), - GestureDetector( - onTap: () => _launchUrl("https://kccb.in/complaint-form"), - child: Row(mainAxisSize: MainAxisSize.min, children: [ - Text( - "Complaint Form", - style: TextStyle( - fontSize: 17, - color: Theme.of(context).colorScheme.primary, - decorationColor: Theme.of(context).colorScheme.primary, - ), - ), - const SizedBox(width: 4), - Icon( - Icons.open_in_new, + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + GestureDetector( + onTap: () => _launchUrl("https://kccb.in/complaint-form"), + child: Row(mainAxisSize: MainAxisSize.min, children: [ + Text( + "Complaint Form", + style: TextStyle( + fontSize: 17, + color: Theme.of(context).colorScheme.primary, + decorationColor: + Theme.of(context).colorScheme.primary, + ), + ), + const SizedBox(width: 4), + Icon( + Icons.open_in_new, + color: Theme.of(context).colorScheme.primary, + size: 16.0, + ), + ])), + const SizedBox(height: 40), + Text( + AppLocalizations.of(context).keyContacts, + style: TextStyle( + fontSize: 17, color: Theme.of(context).colorScheme.primary, - size: 16.0, ), - ])), - const SizedBox(height: 40), - Text( - AppLocalizations.of(context).keyContacts, - style: TextStyle( - fontSize: 17, - color: Theme.of(context).colorScheme.primary, + // horizontal line + ), + Divider(color: Theme.of(context).colorScheme.outline), + const SizedBox(height: 16), + _buildContactItem( + AppLocalizations.of(context).chairman, + "chairman@kccb.in", + "01892-222677", + ), + const SizedBox(height: 16), + _buildContactItem( + AppLocalizations.of(context).managingDirector, + "md@kccb.in", + "01892-224969", + ), + const SizedBox(height: 16), + _buildContactItem( + AppLocalizations.of(context).gmWest, + "gmw@kccb.in", + "01892-223280", + ), + const SizedBox(height: 16), + _buildContactItem( + AppLocalizations.of(context).gmNorth, + "gmn@kccb.in", + "01892-224607", + ), + ], + ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), ), - // horizontal line ), - Divider(color: Theme.of(context).colorScheme.outline), - const SizedBox(height: 16), - _buildContactItem( - AppLocalizations.of(context).chairman, - "chairman@kccb.in", - "01892-222677", - ), - const SizedBox(height: 16), - _buildContactItem( - AppLocalizations.of(context).managingDirector, - "md@kccb.in", - "01892-224969", - ), - const SizedBox(height: 16), - _buildContactItem( - AppLocalizations.of(context).gmWest, - "gmw@kccb.in", - "01892-223280", - ), - const SizedBox(height: 16), - _buildContactItem( - AppLocalizations.of(context).gmNorth, - "gmn@kccb.in", - "01892-224607", - ), - ], - ), + ), + ], ), ); } 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 602c12a..3e0a0bf 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart @@ -362,156 +362,173 @@ class _FundTransferAmountScreenState extends State { title: Text(loc.fundTransfer.replaceFirst(RegExp('\n'), '')), ), body: SafeArea( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Debit Account (User) - Text( - loc.debitFrom, - style: Theme.of(context).textTheme.titleSmall, - ), - Card( - elevation: 0, - margin: const EdgeInsets.symmetric(vertical: 8.0), - child: ListTile( - leading: Image.asset( - 'assets/images/logo.png', - width: 40, - height: 40, + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Debit Account (User) + Text( + loc.debitFrom, + style: Theme.of(context).textTheme.titleSmall, ), - title: Text(widget.remitterName), - subtitle: Text(widget.debitAccountNo), - ), - ), - const SizedBox(height: 24), - - // Credit Account (Beneficiary) - Text( - AppLocalizations.of(context).creditedTo, - style: Theme.of(context).textTheme.titleSmall, - ), - Card( - elevation: 0, - margin: const EdgeInsets.symmetric(vertical: 8.0), - child: ListTile( - leading: - getBankLogo(widget.creditBeneficiary.bankName, context), - title: Text(widget.creditBeneficiary.name), - subtitle: Text(widget.creditBeneficiary.accountNo), - ), - ), - const SizedBox(height: 24), - - if (!widget.isOwnBank) ...[ - // Transaction Mode Selection - Text( - AppLocalizations.of(context).selectTransactionType, - style: Theme.of(context).textTheme.titleMedium, - ), - const SizedBox(height: 12), - Container( - decoration: BoxDecoration( - color: Theme.of(context).cardColor, - borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.grey.shade300), + Card( + elevation: 0, + margin: const EdgeInsets.symmetric(vertical: 8.0), + child: ListTile( + leading: Image.asset( + 'assets/images/logo.png', + width: 40, + height: 40, + ), + title: Text(widget.remitterName), + subtitle: Text(widget.debitAccountNo), + ), ), - child: ToggleButtons( - isSelected: [ - _selectedMode == TransactionMode.neft, - _selectedMode == TransactionMode.rtgs, - _selectedMode == TransactionMode.imps, - ], - onPressed: (index) { - setState(() { - _selectedMode = TransactionMode.values[index]; - }); + const SizedBox(height: 24), + + // Credit Account (Beneficiary) + Text( + AppLocalizations.of(context).creditedTo, + style: Theme.of(context).textTheme.titleSmall, + ), + Card( + elevation: 0, + margin: const EdgeInsets.symmetric(vertical: 8.0), + child: ListTile( + leading: getBankLogo( + widget.creditBeneficiary.bankName, context), + title: Text(widget.creditBeneficiary.name), + subtitle: Text(widget.creditBeneficiary.accountNo), + ), + ), + const SizedBox(height: 24), + + if (!widget.isOwnBank) ...[ + // Transaction Mode Selection + Text( + AppLocalizations.of(context).selectTransactionType, + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 12), + Container( + decoration: BoxDecoration( + color: Theme.of(context).cardColor, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey.shade300), + ), + child: ToggleButtons( + isSelected: [ + _selectedMode == TransactionMode.neft, + _selectedMode == TransactionMode.rtgs, + _selectedMode == TransactionMode.imps, + ], + onPressed: (index) { + setState(() { + _selectedMode = TransactionMode.values[index]; + }); + }, + borderRadius: BorderRadius.circular(10), + selectedColor: + Theme.of(context).colorScheme.onPrimary, + fillColor: Theme.of(context).colorScheme.primary, + color: Theme.of(context).colorScheme.onSurface, + borderColor: Colors.transparent, + selectedBorderColor: Colors.transparent, + splashColor: Theme.of(context).colorScheme.primary, + highlightColor: Theme.of(context).colorScheme.primary, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24.0, vertical: 12.0), + child: Text(AppLocalizations.of(context).neft), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24.0, vertical: 12.0), + child: Text(AppLocalizations.of(context).rtgs), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24.0, vertical: 12.0), + child: Text(AppLocalizations.of(context).imps), + ), + ], + ), + ), + const SizedBox(height: 24), + ], + //Remarks + TextFormField( + controller: _remarksController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).remarks, + border: const OutlineInputBorder(), + ), + ), + const SizedBox(height: 24), + // Amount + TextFormField( + controller: _amountController, + keyboardType: TextInputType.number, + decoration: InputDecoration( + labelText: loc.amount, + border: const OutlineInputBorder(), + prefixIcon: const Icon(Icons.currency_rupee), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return loc.amountRequired; + } + if (double.tryParse(value) == null || + double.parse(value) <= 0) { + return loc.validAmount; + } + return null; }, - borderRadius: BorderRadius.circular(10), - selectedColor: Theme.of(context).colorScheme.onPrimary, - fillColor: Theme.of(context).colorScheme.primary, - color: Theme.of(context).colorScheme.onSurface, - borderColor: Colors.transparent, - selectedBorderColor: Colors.transparent, - splashColor: Theme.of(context).colorScheme.primary, - highlightColor: Theme.of(context).colorScheme.primary, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 24.0, vertical: 12.0), - child: Text(AppLocalizations.of(context).neft), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 24.0, vertical: 12.0), - child: Text(AppLocalizations.of(context).rtgs), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 24.0, vertical: 12.0), - child: Text(AppLocalizations.of(context).imps), - ), - ], ), - ), - const SizedBox(height: 24), - ], - //Remarks - TextFormField( - controller: _remarksController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).remarks, - border: const OutlineInputBorder(), - ), - ), - const SizedBox(height: 24), - // Amount - TextFormField( - controller: _amountController, - keyboardType: TextInputType.number, - decoration: InputDecoration( - labelText: loc.amount, - border: const OutlineInputBorder(), - prefixIcon: const Icon(Icons.currency_rupee), - ), - validator: (value) { - if (value == null || value.isEmpty) { - return loc.amountRequired; - } - if (double.tryParse(value) == null || - double.parse(value) <= 0) { - return loc.validAmount; - } - return null; - }, - ), - const SizedBox(height: 8), - if (_isLoadingLimit) const Text('Fetching daily limit...'), - if (!_isLoadingLimit && _limit != null) - Text( - 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', - style: Theme.of(context).textTheme.bodySmall, - ), - const Spacer(), + const SizedBox(height: 8), + if (_isLoadingLimit) const Text('Fetching daily limit...'), + if (!_isLoadingLimit && _limit != null) + Text( + 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', + style: Theme.of(context).textTheme.bodySmall, + ), + const Spacer(), - // Proceed Button - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _isAmountOverLimit ? null : _onProceed, - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), + // Proceed Button + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _isAmountOverLimit ? null : _onProceed, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + child: Text(AppLocalizations.of(context).proceed), + ), ), - child: Text(AppLocalizations.of(context).proceed), + const SizedBox(height: 10), + ], + ), + ), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), ), - const SizedBox(height: 10), - ], + ), ), - ), + ], ), ), ); diff --git a/lib/features/fund_transfer/screens/fund_transfer_beneficiary_screen.dart b/lib/features/fund_transfer/screens/fund_transfer_beneficiary_screen.dart index f8354c0..a62faa1 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_beneficiary_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_beneficiary_screen.dart @@ -160,7 +160,23 @@ class _FundTransferBeneficiaryScreenState appBar: AppBar( title: Text(AppLocalizations.of(context).beneficiaries), ), - body: _isLoading ? _buildShimmerList() : _buildBeneficiaryList(), + body: Stack( + children: [ + _isLoading ? _buildShimmerList() : _buildBeneficiaryList(), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], + ), ); } } diff --git a/lib/features/fund_transfer/screens/fund_transfer_screen.dart b/lib/features/fund_transfer/screens/fund_transfer_screen.dart index 53ad79e..1897662 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_screen.dart @@ -32,65 +32,81 @@ class FundTransferScreen extends StatelessWidget { // Wrap with BlocBuilder to check the authentication state body: BlocBuilder( builder: (context, state) { - return ListView( + return Stack( children: [ - FundTransferManagementTile( - icon: Symbols.person, - // Restore localization for the label - label: "Self Pay", - onTap: () { - // The accounts list is passed directly from the constructor - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FundTransferSelfAccountsScreen( - debitAccountNo: creditAccountNo, - remitterName: remitterName, - accounts: accounts, - ), - ), - ); - }, - // Disable the tile if the state is not Authenticated - disable: state is! Authenticated, + ListView( + children: [ + FundTransferManagementTile( + icon: Symbols.person, + // Restore localization for the label + label: "Self Pay", + onTap: () { + // The accounts list is passed directly from the constructor + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FundTransferSelfAccountsScreen( + debitAccountNo: creditAccountNo, + remitterName: remitterName, + accounts: accounts, + ), + ), + ); + }, + // Disable the tile if the state is not Authenticated + disable: state is! Authenticated, + ), + const Divider(height: 1), + FundTransferManagementTile( + icon: Symbols.input_circle, + // Restore localization for the label + label: AppLocalizations.of(context).ownBank, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FundTransferBeneficiaryScreen( + creditAccountNo: creditAccountNo, + remitterName: remitterName, + isOwnBank: true, + ), + ), + ); + }, + ), + const Divider(height: 1), + FundTransferManagementTile( + icon: Symbols.output_circle, + // Restore localization for the label + label: AppLocalizations.of(context).outsideBank, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FundTransferBeneficiaryScreen( + creditAccountNo: creditAccountNo, + remitterName: remitterName, + isOwnBank: false, + ), + ), + ); + }, + ), + const Divider(height: 1), + ], ), - const Divider(height: 1), - FundTransferManagementTile( - icon: Symbols.input_circle, - // Restore localization for the label - label: AppLocalizations.of(context).ownBank, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FundTransferBeneficiaryScreen( - creditAccountNo: creditAccountNo, - remitterName: remitterName, - isOwnBank: true, - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), - ); - }, + ), + ), ), - const Divider(height: 1), - FundTransferManagementTile( - icon: Symbols.output_circle, - // Restore localization for the label - label: AppLocalizations.of(context).outsideBank, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FundTransferBeneficiaryScreen( - creditAccountNo: creditAccountNo, - remitterName: remitterName, - isOwnBank: false, - ), - ), - ); - }, - ), - const Divider(height: 1), ], ); }, diff --git a/lib/features/fund_transfer/screens/fund_transfer_self_accounts_screen.dart b/lib/features/fund_transfer/screens/fund_transfer_self_accounts_screen.dart index 4d002db..cc2322b 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_self_accounts_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_self_accounts_screen.dart @@ -45,49 +45,66 @@ class FundTransferSelfAccountsScreen extends StatelessWidget { appBar: AppBar( title: const Text("Select Account"), ), - body: filteredAccounts.isEmpty - ? const Center( - child: Text("No other accounts found"), - ) - : ListView.builder( - itemCount: filteredAccounts.length, - itemBuilder: (context, index) { - final account = filteredAccounts[index]; - return ListTile( - leading: CircleAvatar( - radius: 24, - backgroundColor: Colors.transparent, - child: getBankLogo( - 'Kangra Central Co-operative Bank', context), - ), - title: Text(account.name ?? 'N/A'), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(account.accountNo ?? 'N/A'), - Text( - _getFullAccountType(account.accountType), - style: TextStyle(fontSize: 12, color: Colors.grey[600]), + body: Stack( + children: [ + filteredAccounts.isEmpty + ? const Center( + child: Text("No other accounts found"), + ) + : ListView.builder( + itemCount: filteredAccounts.length, + itemBuilder: (context, index) { + final account = filteredAccounts[index]; + return ListTile( + leading: CircleAvatar( + radius: 24, + backgroundColor: Colors.transparent, + child: getBankLogo( + 'Kangra Central Co-operative Bank', context), ), - ], - ), - onTap: () { - // Navigate to the amount screen, passing the selected User object directly. - // No Beneficiary object is created. - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FundTransferSelfAmountScreen( - debitAccountNo: debitAccountNo, - creditAccount: account, // Pass the User object - remitterName: remitterName, - ), + title: Text(account.name ?? 'N/A'), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(account.accountNo ?? 'N/A'), + Text( + _getFullAccountType(account.accountType), + style: TextStyle( + fontSize: 12, color: Colors.grey[600]), + ), + ], ), + onTap: () { + // Navigate to the amount screen, passing the selected User object directly. + // No Beneficiary object is created. + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FundTransferSelfAmountScreen( + debitAccountNo: debitAccountNo, + creditAccount: account, // Pass the User object + remitterName: remitterName, + ), + ), + ); + }, ); }, - ); - }, + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), ), + ), + ], + ), ); } } diff --git a/lib/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart b/lib/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart index 791c747..b89b288 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_self_amount_screen.dart @@ -137,106 +137,122 @@ class _FundTransferSelfAmountScreenState title: const Text("Fund Transfer"), ), body: SafeArea( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Debit Account (User) - Text( - "Debit From", - style: Theme.of(context).textTheme.titleSmall, - ), - Card( - elevation: 0, - margin: const EdgeInsets.symmetric(vertical: 8.0), - child: ListTile( - leading: Image.asset( - 'assets/images/logo.png', - width: 40, - height: 40, + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Debit Account (User) + Text( + "Debit From", + style: Theme.of(context).textTheme.titleSmall, ), - title: Text(widget.remitterName), - subtitle: Text(widget.debitAccountNo), - ), - ), - const SizedBox(height: 24), - - // Credit Account (Self) - Text( - "Credited To", - style: Theme.of(context).textTheme.titleSmall, - ), - Card( - elevation: 0, - margin: const EdgeInsets.symmetric(vertical: 8.0), - child: ListTile( - leading: getBankLogo( - 'Kangra Central Co-operative Bank', context), - title: Text(widget.creditAccount.name ?? 'N/A'), - subtitle: Text(widget.creditAccount.accountNo ?? 'N/A'), - ), - ), - const SizedBox(height: 24), - - // Remarks - TextFormField( - controller: _remarksController, - decoration: const InputDecoration( - labelText: "Remarks (Optional)", - border: OutlineInputBorder(), - ), - ), - const SizedBox(height: 24), - - // Amount - TextFormField( - controller: _amountController, - keyboardType: TextInputType.number, - decoration: const InputDecoration( - labelText: "Amount", - border: OutlineInputBorder(), - prefixIcon: Icon(Icons.currency_rupee), - ), - validator: (value) { - if (value == null || value.isEmpty) { - return "Amount is required"; - } - if (double.tryParse(value) == null || - double.parse(value) <= 0) { - return "Please enter a valid amount"; - } - return null; - }, - ), - const SizedBox(height: 8), - - // Daily Limit Display - if (_isLoadingLimit) const Text('Fetching daily limit...'), - if (!_isLoadingLimit && _limit != null) - Text( - 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', - style: Theme.of(context).textTheme.bodySmall, - ), - const Spacer(), - - // Proceed Button - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _isAmountOverLimit ? null : _onProceed, - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), + Card( + elevation: 0, + margin: const EdgeInsets.symmetric(vertical: 8.0), + child: ListTile( + leading: Image.asset( + 'assets/images/logo.png', + width: 40, + height: 40, + ), + title: Text(widget.remitterName), + subtitle: Text(widget.debitAccountNo), + ), ), - child: const Text("Proceed"), - ), + const SizedBox(height: 24), + + // Credit Account (Self) + Text( + "Credited To", + style: Theme.of(context).textTheme.titleSmall, + ), + Card( + elevation: 0, + margin: const EdgeInsets.symmetric(vertical: 8.0), + child: ListTile( + leading: getBankLogo( + 'Kangra Central Co-operative Bank', context), + title: Text(widget.creditAccount.name ?? 'N/A'), + subtitle: Text(widget.creditAccount.accountNo ?? 'N/A'), + ), + ), + const SizedBox(height: 24), + + // Remarks + TextFormField( + controller: _remarksController, + decoration: const InputDecoration( + labelText: "Remarks (Optional)", + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 24), + + // Amount + TextFormField( + controller: _amountController, + keyboardType: TextInputType.number, + decoration: const InputDecoration( + labelText: "Amount", + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.currency_rupee), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return "Amount is required"; + } + if (double.tryParse(value) == null || + double.parse(value) <= 0) { + return "Please enter a valid amount"; + } + return null; + }, + ), + const SizedBox(height: 8), + + // Daily Limit Display + if (_isLoadingLimit) const Text('Fetching daily limit...'), + if (!_isLoadingLimit && _limit != null) + Text( + 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', + style: Theme.of(context).textTheme.bodySmall, + ), + const Spacer(), + + // Proceed Button + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _isAmountOverLimit ? null : _onProceed, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + child: const Text("Proceed"), + ), + ), + const SizedBox(height: 10), + ], ), - const SizedBox(height: 10), - ], + ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ), ); diff --git a/lib/features/fund_transfer/screens/tpin_otp_screen.dart b/lib/features/fund_transfer/screens/tpin_otp_screen.dart index af4743a..c074de9 100644 --- a/lib/features/fund_transfer/screens/tpin_otp_screen.dart +++ b/lib/features/fund_transfer/screens/tpin_otp_screen.dart @@ -136,7 +136,8 @@ class _TpinOtpScreenState extends State { counterText: '', filled: true, fillColor: Colors.grey[200], - contentPadding: const EdgeInsets.symmetric(vertical: 16), + contentPadding: + const EdgeInsets.symmetric(vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( diff --git a/lib/features/fund_transfer/screens/transaction_success_screen.dart b/lib/features/fund_transfer/screens/transaction_success_screen.dart index b2c921e..3a5e493 100644 --- a/lib/features/fund_transfer/screens/transaction_success_screen.dart +++ b/lib/features/fund_transfer/screens/transaction_success_screen.dart @@ -143,6 +143,18 @@ class _TransactionSuccessScreen extends State { ), ), ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), ], ), ), diff --git a/lib/features/profile/change_password/change_password_otp_screen.dart b/lib/features/profile/change_password/change_password_otp_screen.dart index 562c3d1..6e356f3 100644 --- a/lib/features/profile/change_password/change_password_otp_screen.dart +++ b/lib/features/profile/change_password/change_password_otp_screen.dart @@ -70,40 +70,56 @@ class _ChangePasswordOTPScreenState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(AppLocalizations.of(context).otpVerification)), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: _isLoading - ? const Center(child: CircularProgressIndicator()) - : Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - AppLocalizations.of(context).otpSent, - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 16), - ), - const SizedBox(height: 24), - TextFormField( - controller: otpController, - keyboardType: TextInputType.number, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).enterOTP, - border: const OutlineInputBorder(), - ), - ), - const SizedBox(height: 24), - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _validateOTP, - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + AppLocalizations.of(context).otpSent, + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 16), ), - child: Text(AppLocalizations.of(context).validateOTP), - ), + const SizedBox(height: 24), + TextFormField( + controller: otpController, + keyboardType: TextInputType.number, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).enterOTP, + border: const OutlineInputBorder(), + ), + ), + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _validateOTP, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + child: Text(AppLocalizations.of(context).validateOTP), + ), + ), + ], ), - ], + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), ), + ), + ), + ], ), ); } diff --git a/lib/features/profile/change_password/change_password_screen.dart b/lib/features/profile/change_password/change_password_screen.dart index 3a60a9f..5a54c1a 100644 --- a/lib/features/profile/change_password/change_password_screen.dart +++ b/lib/features/profile/change_password/change_password_screen.dart @@ -90,67 +90,83 @@ class _ChangePasswordScreenState extends State { return Scaffold( appBar: AppBar(title: Text(AppLocalizations.of(context).changeLoginPassword)), - body: Padding( - padding: const EdgeInsets.all(16), - child: Form( - key: _formKey, - child: Column( - children: [ - TextFormField( - controller: currentPasswordController, - obscureText: !_showCurrentPassword, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).currentpwd, - suffixIcon: IconButton( - icon: Icon(_showCurrentPassword - ? Icons.visibility - : Icons.visibility_off), - onPressed: () => setState( - () => _showCurrentPassword = !_showCurrentPassword), + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16), + child: Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + controller: currentPasswordController, + obscureText: !_showCurrentPassword, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).currentpwd, + suffixIcon: IconButton( + icon: Icon(_showCurrentPassword + ? Icons.visibility + : Icons.visibility_off), + onPressed: () => setState( + () => _showCurrentPassword = !_showCurrentPassword), + ), + ), + validator: validateCurrentPassword, ), - ), - validator: validateCurrentPassword, - ), - const SizedBox(height: 16), - TextFormField( - controller: newPasswordController, - obscureText: !_showNewPassword, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).newpwd, - suffixIcon: IconButton( - icon: Icon(_showNewPassword - ? Icons.visibility - : Icons.visibility_off), - onPressed: () => - setState(() => _showNewPassword = !_showNewPassword), + const SizedBox(height: 16), + TextFormField( + controller: newPasswordController, + obscureText: !_showNewPassword, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).newpwd, + suffixIcon: IconButton( + icon: Icon(_showNewPassword + ? Icons.visibility + : Icons.visibility_off), + onPressed: () => setState( + () => _showNewPassword = !_showNewPassword), + ), + ), + validator: validateNewPassword, ), - ), - validator: validateNewPassword, - ), - const SizedBox(height: 16), - TextFormField( - controller: confirmPasswordController, - obscureText: !_showConfirmPassword, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).confirmpwd, - suffixIcon: IconButton( - icon: Icon(_showConfirmPassword - ? Icons.visibility - : Icons.visibility_off), - onPressed: () => setState( - () => _showConfirmPassword = !_showConfirmPassword), + const SizedBox(height: 16), + TextFormField( + controller: confirmPasswordController, + obscureText: !_showConfirmPassword, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).confirmpwd, + suffixIcon: IconButton( + icon: Icon(_showConfirmPassword + ? Icons.visibility + : Icons.visibility_off), + onPressed: () => setState( + () => _showConfirmPassword = !_showConfirmPassword), + ), + ), + validator: validateConfirmPassword, ), - ), - validator: validateConfirmPassword, + const SizedBox(height: 24), + ElevatedButton( + onPressed: _proceed, + child: Text(AppLocalizations.of(context).proceed), + ), + ], ), - const SizedBox(height: 24), - ElevatedButton( - onPressed: _proceed, - child: Text(AppLocalizations.of(context).proceed), - ), - ], + ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ); } diff --git a/lib/features/profile/preferences/preference_screen.dart b/lib/features/profile/preferences/preference_screen.dart index c0c7926..345cd6d 100644 --- a/lib/features/profile/preferences/preference_screen.dart +++ b/lib/features/profile/preferences/preference_screen.dart @@ -20,43 +20,59 @@ class PreferenceScreen extends StatelessWidget { ), body: BlocBuilder( builder: (context, state) { - return ListView( + return Stack( 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(), - ); - }, + ListView( + 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), + onTap: () { + showDialog( + context: context, + builder: (_) => const ColorThemeDialog(), + ); + }), + ], ), - //Theme Mode Switch (Light/Dark) - ListTile( - leading: const Icon(Icons.brightness_6), - title: Text(AppLocalizations.of(context).themeMode), - onTap: () { - showThemeModeDialog(context); - }, + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), ), - //Color_Theme_Selection - ListTile( - leading: const Icon(Icons.color_lens), - title: Text(AppLocalizations.of(context).themeColor), - onTap: () { - showDialog( - context: context, - builder: (_) => const ColorThemeDialog(), - ); - }), ], ); }, diff --git a/lib/features/profile/profile_screen.dart b/lib/features/profile/profile_screen.dart index 7fc3efc..10c28a3 100644 --- a/lib/features/profile/profile_screen.dart +++ b/lib/features/profile/profile_screen.dart @@ -60,7 +60,8 @@ class _ProfileScreenState extends State { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(AppLocalizations.of(context).biometricsNotAvailable)), + content: + Text(AppLocalizations.of(context).biometricsNotAvailable)), ); } return; @@ -164,118 +165,137 @@ class _ProfileScreenState extends State { appBar: AppBar( title: Text(loc.profile), // Localized "Profile" ), - body: ListView( + body: Stack( children: [ - ListTile( - leading: const Icon(Icons.settings), - title: Text(loc.preferences), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const PreferenceScreen()), - ); - }, - ), - ListTile( - leading: const Icon(Icons.currency_rupee), - title: Text(AppLocalizations.of(context).dailylimit), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const DailyLimitScreen()), - ); - }, - ), - SwitchListTile( - title: Text(AppLocalizations.of(context).enableFingerprintLogin), - value: _isBiometricEnabled, - onChanged: (bool value) { - // The state is now managed within _handleBiometricToggle - _handleBiometricToggle(value); - }, - secondary: const Icon(Icons.fingerprint), - ), - ListTile( - leading: const Icon(Icons.security), - title: Text(loc.securitySettings), - trailing: const Icon(Icons.chevron_right), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SecuritySettingsScreen( - mobileNumber: widget.mobileNumber, - ), - ), - ); - }, - ), - ListTile( - leading: const Icon(Icons.smartphone), - title: const Text("App Version"), - trailing: FutureBuilder( - future: _getAppVersion(), - builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - // Show a loading indicator while waiting for the future to complete - return const CircularProgressIndicator(); - } else if (snapshot.hasError) { - return const Text("Error"); - } else { - // Display the version number once the future is complete - return Text( - snapshot.data ?? "N/A", - selectionColor: const Color(0xFFFFFFFF), + ListView( + children: [ + ListTile( + leading: const Icon(Icons.settings), + title: Text(loc.preferences), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const PreferenceScreen()), ); - } - }, - ), - ), - ListTile( - leading: const Icon(Icons.exit_to_app), - title: Text(AppLocalizations.of(context).logout), - onTap: () async { - final shouldExit = await showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(AppLocalizations.of(context).logout), - content: Text(AppLocalizations.of(context).logoutCheck), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(false), - child: Text(AppLocalizations.of(context).no), + }, + ), + ListTile( + leading: const Icon(Icons.security), + title: Text(loc.securitySettings), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SecuritySettingsScreen( + mobileNumber: widget.mobileNumber, + ), ), - TextButton( - onPressed: () => Navigator.of(context).pop(true), - child: Text(AppLocalizations.of(context).yes), - ), - ], + ); + }, + ), + ListTile( + leading: const Icon(Icons.currency_rupee), + title: Text(AppLocalizations.of(context).dailylimit), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DailyLimitScreen()), + ); + }, + ), + SwitchListTile( + title: + Text(AppLocalizations.of(context).enableFingerprintLogin), + value: _isBiometricEnabled, + onChanged: (bool value) { + // The state is now managed within _handleBiometricToggle + _handleBiometricToggle(value); + }, + secondary: const Icon(Icons.fingerprint), + ), + ListTile( + leading: const Icon(Icons.smartphone), + title: const Text("App Version"), + trailing: FutureBuilder( + future: _getAppVersion(), + builder: + (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + // Show a loading indicator while waiting for the future to complete + return const CircularProgressIndicator(); + } else if (snapshot.hasError) { + return const Text("Error"); + } else { + // Display the version number once the future is complete + return Text( + snapshot.data ?? "N/A", + selectionColor: const Color(0xFFFFFFFF), + ); + } + }, ), - ); + ), + ListTile( + leading: const Icon(Icons.exit_to_app), + title: Text(AppLocalizations.of(context).logout), + onTap: () async { + final shouldExit = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(AppLocalizations.of(context).logout), + content: Text(AppLocalizations.of(context).logoutCheck), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text(AppLocalizations.of(context).no), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + child: Text(AppLocalizations.of(context).yes), + ), + ], + ), + ); - if (shouldExit == true) { - if (Platform.isAndroid) { - SystemNavigator.pop(); - } - exit(0); - } - }, + if (shouldExit == true) { + if (Platform.isAndroid) { + SystemNavigator.pop(); + } + exit(0); + } + }, + ), + ListTile( + leading: const Icon(Icons.logout), + title: Text(AppLocalizations.of(context).deregister), + onTap: () async { + final shouldLogout = await showDialog( + context: context, + builder: (_) => const LogoutDialog(), + ); + + if (shouldLogout == true) { + await _handleLogout(context); + } + }, + ), + ], ), - ListTile( - leading: const Icon(Icons.logout), - title: Text(AppLocalizations.of(context).deregister), - onTap: () async { - final shouldLogout = await showDialog( - context: context, - builder: (_) => const LogoutDialog(), - ); - - if (shouldLogout == true) { - await _handleLogout(context); - } - }, + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), ), ], ), diff --git a/lib/features/profile/security_settings_screen.dart b/lib/features/profile/security_settings_screen.dart index 9797f07..19a9502 100644 --- a/lib/features/profile/security_settings_screen.dart +++ b/lib/features/profile/security_settings_screen.dart @@ -21,98 +21,115 @@ class SecuritySettingsScreen extends StatelessWidget { title: Text(loc.securitySettings), centerTitle: true, ), - body: ListView( + body: Stack( 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, - ), - ), - ); - }, - ), - const Divider(height: 1), - 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: Colors.green, - ), - ); - } - }, - ), - const Divider(height: 1), - 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( + ListView( + 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) => - ChangeTpinScreen(mobileNumber: mobileNumber), + builder: (context) => ChangePasswordScreen( + mobileNumber: mobileNumber, + ), ), ); - } - } - }, + }, + ), + const Divider(height: 1), + 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: Colors.green, + ), + ); + } + }, + ), + const Divider(height: 1), + 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), + ), + ); + } + } + }, + ), + ], + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), ), ], ), diff --git a/lib/features/quick_pay/screens/quick_pay_outside_bank_screen.dart b/lib/features/quick_pay/screens/quick_pay_outside_bank_screen.dart index 32eb354..0bfbfad 100644 --- a/lib/features/quick_pay/screens/quick_pay_outside_bank_screen.dart +++ b/lib/features/quick_pay/screens/quick_pay_outside_bank_screen.dart @@ -458,329 +458,117 @@ class _QuickPayOutsideBankScreen extends State { ), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(12), - child: Form( - key: _formKey, - child: ListView( - children: [ - const SizedBox(height: 10), - Text( - AppLocalizations.of(context).debitFrom, - style: Theme.of(context).textTheme.titleSmall, - ), - Card( - elevation: 0, - margin: const EdgeInsets.symmetric(vertical: 8.0), - child: ListTile( - leading: Image.asset( - 'assets/images/logo.png', - width: 40, - height: 40, - ), - title: Text(widget.debitAccount), - subtitle: Text(AppLocalizations.of(context).ownBank), - ), - ), - const SizedBox(height: 24), - TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).accountNumber, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, width: 2), - ), - ), - controller: accountNumberController, - keyboardType: TextInputType.number, - obscureText: true, - textInputAction: TextInputAction.next, - onChanged: (value) { - nameController.clear(); - setState(() { - _isBeneficiaryValidated = false; - }); - }, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).accountNumberRequired; - } else if (value.length < 7 || value.length > 20) { - return AppLocalizations.of(context).accno7to20; - } - return null; - }, - ), - const SizedBox(height: 24), - TextFormField( - controller: confirmAccountNumberController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).confirmAccountNumber, - // prefixIcon: Icon(Icons.person), - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, width: 2), - ), - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).reenterAccountNumber; - } - if (value != accountNumberController.text) { - return AppLocalizations.of(context).accountMismatch; - } - return null; - }, - ), - const SizedBox(height: 25), - Row( - crossAxisAlignment: CrossAxisAlignment.start, + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(12), + child: Form( + key: _formKey, + child: ListView( children: [ - Expanded( - child: TextFormField( - focusNode: _ifscFocusNode, - maxLength: 11, - inputFormatters: [ - LengthLimitingTextInputFormatter(11), - ], - decoration: InputDecoration( - labelText: AppLocalizations.of(context).ifscCode, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), + const SizedBox(height: 10), + Text( + AppLocalizations.of(context).debitFrom, + style: Theme.of(context).textTheme.titleSmall, + ), + Card( + elevation: 0, + margin: const EdgeInsets.symmetric(vertical: 8.0), + child: ListTile( + leading: Image.asset( + 'assets/images/logo.png', + width: 40, + height: 40, ), - controller: ifscController, - textInputAction: TextInputAction.next, - onChanged: (value) { - setState(() { - final trimmed = value.trim().toUpperCase(); - if (trimmed.length < 11) { - // clear bank/branch if backspace or changed - bankNameController.clear(); - branchNameController.clear(); - } - }); - }, - validator: (value) { - final pattern = RegExp(r'^[A-Z]{4}0[A-Z0-9]{6}$'); - if (value == null || value.trim().isEmpty) { - return AppLocalizations.of(context).enterIfsc; - } else if (!pattern.hasMatch( - value.trim().toUpperCase(), - )) { - return AppLocalizations.of( - context, - ).invalidIfscFormat; - } - return null; - }, + title: Text(widget.debitAccount), + subtitle: Text(AppLocalizations.of(context).ownBank), ), ), - const SizedBox( - width: 10, - ), - Expanded( - child: DropdownButtonFormField( - value: accountType, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).accountType, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), + const SizedBox(height: 24), + TextFormField( + decoration: InputDecoration( + labelText: AppLocalizations.of(context).accountNumber, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), ), - items: [ - 'Savings', - 'Current', - ] - .map( - (e) => DropdownMenuItem(value: e, child: Text(e)), - ) - .toList(), - onChanged: (value) => setState(() { - accountType = value!; - }), ), + controller: accountNumberController, + keyboardType: TextInputType.number, + obscureText: true, + textInputAction: TextInputAction.next, + onChanged: (value) { + nameController.clear(); + setState(() { + _isBeneficiaryValidated = false; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context) + .accountNumberRequired; + } else if (value.length < 7 || value.length > 20) { + return AppLocalizations.of(context).accno7to20; + } + return null; + }, ), - ], - ), - const SizedBox(height: 25), - TextFormField( - controller: bankNameController, - enabled: false, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).bankName, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).dialogBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, width: 2), - ), - ), - ), - const SizedBox(height: 25), - TextFormField( - controller: branchNameController, - enabled: false, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).branchName, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).dialogBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2, + const SizedBox(height: 24), + TextFormField( + controller: confirmAccountNumberController, + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).confirmAccountNumber, + // prefixIcon: Icon(Icons.person), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context) + .reenterAccountNumber; + } + if (value != accountNumberController.text) { + return AppLocalizations.of(context).accountMismatch; + } + return null; + }, ), - ), - ), - const SizedBox(height: 24), - if (!_isBeneficiaryValidated) - Padding( - padding: const EdgeInsets.only(bottom: 24), - child: SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: - _isValidating || ifscController.text.length != 11 - ? null - : () { - if (confirmAccountNumberController.text == - accountNumberController.text) { - _validateBeneficiary(); - } else { - setState(() { - _validationError = - AppLocalizations.of(context) - .accountMismatch; - }); - } - }, - child: _isValidating - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : Text( - AppLocalizations.of(context).validateBeneficiary), - ), - ), - ), - if (_validationError != null) - Padding( - padding: const EdgeInsets.only(bottom: 24.0), - child: Text( - _validationError!, - style: - TextStyle(color: Theme.of(context).colorScheme.error), - ), - ), - TextFormField( - controller: nameController, - enabled: false, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).name, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).dialogBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, width: 2), - ), - ), - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).nameRequired; - } - return null; - }, - ), - const SizedBox(height: 25), - TextFormField( - controller: remarksController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).remarks, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, width: 2), - ), - ), - ), - const SizedBox(height: 25), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ + const SizedBox(height: 25), Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: TextFormField( - controller: phoneController, - keyboardType: TextInputType.phone, + focusNode: _ifscFocusNode, + maxLength: 11, + inputFormatters: [ + LengthLimitingTextInputFormatter(11), + ], decoration: InputDecoration( - labelText: AppLocalizations.of(context).phone, - prefixIcon: const Icon(Icons.phone), + labelText: AppLocalizations.of(context).ifscCode, border: const OutlineInputBorder(), isDense: true, filled: true, @@ -796,109 +584,360 @@ class _QuickPayOutsideBankScreen extends State { width: 2), ), ), + controller: ifscController, textInputAction: TextInputAction.next, - validator: (value) => value == null || value.isEmpty - ? AppLocalizations.of(context).phoneRequired - : null, - ), - ), - const SizedBox(width: 10), - Expanded( - child: TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).amount, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: - Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), - ), - controller: amountController, - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, + onChanged: (value) { + setState(() { + final trimmed = value.trim().toUpperCase(); + if (trimmed.length < 11) { + // clear bank/branch if backspace or changed + bankNameController.clear(); + branchNameController.clear(); + } + }); + }, validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context) - .amountRequired; - } - final amount = double.tryParse(value); - if (amount == null || amount <= 0) { - return AppLocalizations.of(context).validAmount; + final pattern = RegExp(r'^[A-Z]{4}0[A-Z0-9]{6}$'); + if (value == null || value.trim().isEmpty) { + return AppLocalizations.of(context).enterIfsc; + } else if (!pattern.hasMatch( + value.trim().toUpperCase(), + )) { + return AppLocalizations.of( + context, + ).invalidIfscFormat; } return null; }, ), ), + const SizedBox( + width: 10, + ), + Expanded( + child: DropdownButtonFormField( + value: accountType, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).accountType, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + items: [ + 'Savings', + 'Current', + ] + .map( + (e) => + DropdownMenuItem(value: e, child: Text(e)), + ) + .toList(), + onChanged: (value) => setState(() { + accountType = value!; + }), + ), + ), ], ), + const SizedBox(height: 25), + TextFormField( + controller: bankNameController, + enabled: false, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).bankName, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).dialogBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + ), + const SizedBox(height: 25), + TextFormField( + controller: branchNameController, + enabled: false, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).branchName, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).dialogBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2, + ), + ), + ), + ), + const SizedBox(height: 24), + if (!_isBeneficiaryValidated) + Padding( + padding: const EdgeInsets.only(bottom: 24), + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: + _isValidating || ifscController.text.length != 11 + ? null + : () { + if (confirmAccountNumberController.text == + accountNumberController.text) { + _validateBeneficiary(); + } else { + setState(() { + _validationError = + AppLocalizations.of(context) + .accountMismatch; + }); + } + }, + child: _isValidating + ? const SizedBox( + width: 20, + height: 20, + child: + CircularProgressIndicator(strokeWidth: 2), + ) + : Text(AppLocalizations.of(context) + .validateBeneficiary), + ), + ), + ), + if (_validationError != null) + Padding( + padding: const EdgeInsets.only(bottom: 24.0), + child: Text( + _validationError!, + style: TextStyle( + color: Theme.of(context).colorScheme.error), + ), + ), + TextFormField( + controller: nameController, + enabled: false, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).name, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).dialogBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context).nameRequired; + } + return null; + }, + ), + const SizedBox(height: 25), + TextFormField( + controller: remarksController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).remarks, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + ), + const SizedBox(height: 25), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: TextFormField( + controller: phoneController, + keyboardType: TextInputType.phone, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).phone, + prefixIcon: const Icon(Icons.phone), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context) + .colorScheme + .outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: + Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + textInputAction: TextInputAction.next, + validator: (value) => value == null || + value.isEmpty + ? AppLocalizations.of(context).phoneRequired + : null, + ), + ), + const SizedBox(width: 10), + Expanded( + child: TextFormField( + decoration: InputDecoration( + labelText: AppLocalizations.of(context).amount, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: + Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context) + .colorScheme + .outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: + Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + controller: amountController, + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context) + .amountRequired; + } + final amount = double.tryParse(value); + if (amount == null || amount <= 0) { + return AppLocalizations.of(context) + .validAmount; + } + return null; + }, + ), + ), + ], + ), + ], + ), + const SizedBox(height: 8), + if (_isLoadingLimit) + const Padding( + padding: EdgeInsets.only(left: 8.0), + child: Text('Fetching daily limit...'), + ), + if (!_isLoadingLimit && _limit != null) + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Text( + 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', + style: Theme.of(context).textTheme.bodySmall, + ), + ), + const SizedBox(height: 30), + Row( + children: [ + Text( + AppLocalizations.of(context).transactionMode, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + const SizedBox(width: 12), + Expanded(child: buildTransactionModeSelector()), + ], + ), + const SizedBox(height: 45), + Align( + alignment: Alignment.center, + child: SwipeButton.expand( + thumb: Icon(Icons.arrow_forward, + color: _isAmountOverLimit + ? Colors.grey + : Theme.of(context).dialogBackgroundColor), + activeThumbColor: _isAmountOverLimit + ? Colors.grey.shade700 + : Theme.of(context).colorScheme.primary, + activeTrackColor: _isAmountOverLimit + ? Colors.grey.shade300 + : Theme.of(context) + .colorScheme + .secondary + .withAlpha(100), + borderRadius: BorderRadius.circular(30), + height: 56, + onSwipe: () { + if (_isAmountOverLimit) { + return; // Do nothing if amount is over the limit + } + _onProceedToPay(); + }, + child: Text( + AppLocalizations.of(context).swipeToPay, + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.bold), + ), + ), + ), ], ), - const SizedBox(height: 8), - if (_isLoadingLimit) - const Padding( - padding: EdgeInsets.only(left: 8.0), - child: Text('Fetching daily limit...'), - ), - if (!_isLoadingLimit && _limit != null) - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Text( - 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', - style: Theme.of(context).textTheme.bodySmall, - ), - ), - const SizedBox(height: 30), - Row( - children: [ - Text( - AppLocalizations.of(context).transactionMode, - style: const TextStyle(fontWeight: FontWeight.w500), - ), - const SizedBox(width: 12), - Expanded(child: buildTransactionModeSelector()), - ], - ), - const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SwipeButton.expand( - thumb: Icon(Icons.arrow_forward, - color: _isAmountOverLimit - ? Colors.grey - : Theme.of(context).dialogBackgroundColor), - activeThumbColor: _isAmountOverLimit - ? Colors.grey.shade700 - : Theme.of(context).colorScheme.primary, - activeTrackColor: _isAmountOverLimit - ? Colors.grey.shade300 - : Theme.of(context).colorScheme.secondary.withAlpha(100), - borderRadius: BorderRadius.circular(30), - height: 56, - onSwipe: () { - if (_isAmountOverLimit) { - return; // Do nothing if amount is over the limit - } - _onProceedToPay(); - }, - child: Text( - AppLocalizations.of(context).swipeToPay, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold), - ), - ), - ), - ], + ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ); } diff --git a/lib/features/quick_pay/screens/quick_pay_screen.dart b/lib/features/quick_pay/screens/quick_pay_screen.dart index 871598c..28b3309 100644 --- a/lib/features/quick_pay/screens/quick_pay_screen.dart +++ b/lib/features/quick_pay/screens/quick_pay_screen.dart @@ -21,38 +21,54 @@ class _QuickPayScreen extends State { AppLocalizations.of(context).quickPay.replaceAll('\n', ''), ), ), - body: ListView( + body: Stack( children: [ - QuickPayManagementTile( - icon: Symbols.input_circle, - label: AppLocalizations.of(context).ownBank, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => QuickPayWithinBankScreen( - debitAccount: widget.debitAccount, - ), - ), - ); - }, + ListView( + children: [ + QuickPayManagementTile( + icon: Symbols.input_circle, + label: AppLocalizations.of(context).ownBank, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => QuickPayWithinBankScreen( + debitAccount: widget.debitAccount, + ), + ), + ); + }, + ), + const Divider(height: 1), + QuickPayManagementTile( + icon: Symbols.output_circle, + label: AppLocalizations.of(context).outsideBank, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => QuickPayOutsideBankScreen( + debitAccount: widget.debitAccount, + ), + ), + ); + }, + ), + const Divider(height: 1), + ], ), - const Divider(height: 1), - QuickPayManagementTile( - icon: Symbols.output_circle, - label: AppLocalizations.of(context).outsideBank, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => QuickPayOutsideBankScreen( - debitAccount: widget.debitAccount, - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), - ); - }, + ), + ), ), - const Divider(height: 1), ], ), ); diff --git a/lib/features/quick_pay/screens/quick_pay_within_bank_screen.dart b/lib/features/quick_pay/screens/quick_pay_within_bank_screen.dart index 1210409..036241e 100644 --- a/lib/features/quick_pay/screens/quick_pay_within_bank_screen.dart +++ b/lib/features/quick_pay/screens/quick_pay_within_bank_screen.dart @@ -149,321 +149,348 @@ class _QuickPayWithinBankScreen extends State { ), centerTitle: false, ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Form( - key: _formKey, - child: SingleChildScrollView( - child: Column( - children: [ - const SizedBox(height: 10), - TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).debitAccountNumber, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - ), - readOnly: true, - controller: TextEditingController(text: widget.debitAccount), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - enabled: false, - ), - const SizedBox(height: 20), - TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).accountNumber, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), - ), - controller: accountNumberController, - keyboardType: TextInputType.number, - obscureText: true, - textInputAction: TextInputAction.next, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).accountNumberRequired; - } else if (value.length != 11) { - return AppLocalizations.of(context).validAccountNumber; - } - return null; - }, - ), - const SizedBox(height: 25), - TextFormField( - controller: confirmAccountNumberController, - decoration: InputDecoration( - labelText: - AppLocalizations.of(context).confirmAccountNumber, - // prefixIcon: Icon(Icons.person), - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), - ), - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).reenterAccountNumber; - } - if (value != accountNumberController.text) { - return AppLocalizations.of(context).accountMismatch; - } - return null; - }, - ), - if (!_isBeneficiaryValidated) - Padding( - padding: const EdgeInsets.only(top: 12.0), - child: SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _isValidating - ? null - : () { - if (accountNumberController.text.length == 11 && - confirmAccountNumberController.text == - accountNumberController.text) { - _validateBeneficiary(); - } else { - setState(() { - _validationError = - AppLocalizations.of(context) - .accountMismatch; - }); - } - }, - child: _isValidating - ? const SizedBox( - width: 20, - height: 20, - child: - CircularProgressIndicator(strokeWidth: 2), - ) - : Text(AppLocalizations.of(context) - .validateBeneficiary), + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 10), + TextFormField( + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).debitAccountNumber, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, ), + readOnly: true, + controller: + TextEditingController(text: widget.debitAccount), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + enabled: false, ), - ), - if (_beneficiaryName != null && _isBeneficiaryValidated) - Padding( - padding: const EdgeInsets.only(top: 12.0), - child: Row( - children: [ - const Icon(Icons.check_circle, color: Colors.green), - const SizedBox(width: 8), - Text( - '${AppLocalizations.of(context).beneficiaryName}: $_beneficiaryName', - style: const TextStyle( - color: Colors.green, fontWeight: FontWeight.bold), + const SizedBox(height: 20), + TextFormField( + decoration: InputDecoration( + labelText: AppLocalizations.of(context).accountNumber, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + controller: accountNumberController, + keyboardType: TextInputType.number, + obscureText: true, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context) + .accountNumberRequired; + } else if (value.length != 11) { + return AppLocalizations.of(context) + .validAccountNumber; + } + return null; + }, + ), + const SizedBox(height: 25), + TextFormField( + controller: confirmAccountNumberController, + decoration: InputDecoration( + labelText: + AppLocalizations.of(context).confirmAccountNumber, + // prefixIcon: Icon(Icons.person), + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context) + .reenterAccountNumber; + } + if (value != accountNumberController.text) { + return AppLocalizations.of(context).accountMismatch; + } + return null; + }, + ), + if (!_isBeneficiaryValidated) + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: _isValidating + ? null + : () { + if (accountNumberController.text.length == + 11 && + confirmAccountNumberController.text == + accountNumberController.text) { + _validateBeneficiary(); + } else { + setState(() { + _validationError = + AppLocalizations.of(context) + .accountMismatch; + }); + } + }, + child: _isValidating + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2), + ) + : Text(AppLocalizations.of(context) + .validateBeneficiary), + ), + ), + ), + if (_beneficiaryName != null && _isBeneficiaryValidated) + Padding( + padding: const EdgeInsets.only(top: 12.0), + child: Row( + children: [ + const Icon(Icons.check_circle, color: Colors.green), + const SizedBox(width: 8), + Text( + '${AppLocalizations.of(context).beneficiaryName}: $_beneficiaryName', + style: const TextStyle( + color: Colors.green, + fontWeight: FontWeight.bold), + ), + ], + ), + ), + if (_validationError != null) + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + _validationError!, + style: const TextStyle(color: Colors.red), + ), + ), + const SizedBox(height: 24), + DropdownButtonFormField( + decoration: InputDecoration( + labelText: AppLocalizations.of( + context, + ).beneficiaryAccountType, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + value: _selectedAccountType, + items: [ + DropdownMenuItem( + value: 'SB', + child: Text(AppLocalizations.of(context).savings), + ), + DropdownMenuItem( + value: 'LN', + child: Text(AppLocalizations.of(context).loan), ), ], + onChanged: (value) { + setState(() { + _selectedAccountType = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context).selectAccountType; + } + return null; + }, ), - ), - if (_validationError != null) - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Text( - _validationError!, - style: const TextStyle(color: Colors.red), + const SizedBox(height: 25), + TextFormField( + controller: remarksController, + decoration: InputDecoration( + labelText: AppLocalizations.of(context).remarks, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), ), - ), - const SizedBox(height: 24), - DropdownButtonFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of( - context, - ).beneficiaryAccountType, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), + const SizedBox(height: 25), + TextFormField( + decoration: InputDecoration( + labelText: AppLocalizations.of(context).amount, + border: const OutlineInputBorder(), + isDense: true, + filled: true, + fillColor: Theme.of(context).scaffoldBackgroundColor, + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.outline), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary, + width: 2), + ), + ), + controller: amountController, + keyboardType: TextInputType.number, + textInputAction: TextInputAction.next, + validator: (value) { + if (value == null || value.isEmpty) { + return AppLocalizations.of(context).amountRequired; + } + final amount = double.tryParse(value); + if (amount == null || amount <= 0) { + return AppLocalizations.of(context).validAmount; + } + return null; + }, ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), - ), - value: _selectedAccountType, - items: [ - DropdownMenuItem( - value: 'SB', - child: Text(AppLocalizations.of(context).savings), - ), - DropdownMenuItem( - value: 'LN', - child: Text(AppLocalizations.of(context).loan), + const SizedBox(height: 8), + if (_isLoadingLimit) const Text('Fetching daily limit...'), + if (!_isLoadingLimit && _limit != null) + Text( + 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', + style: Theme.of(context).textTheme.bodySmall, + ), + const SizedBox(height: 45), + Align( + alignment: Alignment.center, + child: SwipeButton.expand( + thumb: Icon(Icons.arrow_forward, + color: _isAmountOverLimit + ? Colors.grey + : Theme.of(context).dialogBackgroundColor), + activeThumbColor: _isAmountOverLimit + ? Colors.grey.shade700 + : Theme.of(context).colorScheme.primary, + activeTrackColor: _isAmountOverLimit + ? Colors.grey.shade300 + : Theme.of( + context, + ).colorScheme.secondary.withAlpha(100), + borderRadius: BorderRadius.circular(30), + height: 56, + child: Text( + AppLocalizations.of(context).swipeToPay, + style: const TextStyle(fontSize: 16), + ), + onSwipe: () { + if (_isAmountOverLimit) { + return; // Do nothing if amount is over limit + } + if (_formKey.currentState!.validate()) { + if (!_isBeneficiaryValidated) { + setState(() { + _validationError = AppLocalizations.of(context) + .validateBeneficiaryproceeding; + }); + return; + } + // Perform payment logic + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TransactionPinScreen( + onPinCompleted: + (pinScreenContext, tpin) async { + final transfer = Transfer( + fromAccount: widget.debitAccount, + toAccount: accountNumberController.text, + toAccountType: _selectedAccountType!, + amount: amountController.text, + tpin: tpin, + remarks: remarksController.text, + ); + + final paymentService = + getIt(); + final paymentResponseFuture = paymentService + .processQuickPayWithinBank(transfer); + + Navigator.of(pinScreenContext) + .pushReplacement( + MaterialPageRoute( + builder: (_) => PaymentAnimationScreen( + paymentResponse: + paymentResponseFuture), + ), + ); + }, + ), + ), + ); + } + }, + ), ), ], - onChanged: (value) { - setState(() { - _selectedAccountType = value; - }); - }, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).selectAccountType; - } - return null; - }, ), - const SizedBox(height: 25), - TextFormField( - controller: remarksController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context).remarks, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), - ), - ), - const SizedBox(height: 25), - TextFormField( - decoration: InputDecoration( - labelText: AppLocalizations.of(context).amount, - border: const OutlineInputBorder(), - isDense: true, - filled: true, - fillColor: Theme.of(context).scaffoldBackgroundColor, - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.outline), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context).colorScheme.primary, - width: 2), - ), - ), - controller: amountController, - keyboardType: TextInputType.number, - textInputAction: TextInputAction.next, - validator: (value) { - if (value == null || value.isEmpty) { - return AppLocalizations.of(context).amountRequired; - } - final amount = double.tryParse(value); - if (amount == null || amount <= 0) { - return AppLocalizations.of(context).validAmount; - } - return null; - }, - ), - const SizedBox(height: 8), - if (_isLoadingLimit) const Text('Fetching daily limit...'), - if (!_isLoadingLimit && _limit != null) - Text( - 'Remaining Daily Limit: ${_formatCurrency.format(_limit!.dailyLimit - _limit!.usedLimit)}', - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SwipeButton.expand( - thumb: Icon(Icons.arrow_forward, - color: _isAmountOverLimit - ? Colors.grey - : Theme.of(context).dialogBackgroundColor), - activeThumbColor: _isAmountOverLimit - ? Colors.grey.shade700 - : Theme.of(context).colorScheme.primary, - activeTrackColor: _isAmountOverLimit - ? Colors.grey.shade300 - : Theme.of( - context, - ).colorScheme.secondary.withAlpha(100), - borderRadius: BorderRadius.circular(30), - height: 56, - child: Text( - AppLocalizations.of(context).swipeToPay, - style: const TextStyle(fontSize: 16), - ), - onSwipe: () { - if (_isAmountOverLimit) { - return; // Do nothing if amount is over limit - } - if (_formKey.currentState!.validate()) { - if (!_isBeneficiaryValidated) { - setState(() { - _validationError = AppLocalizations.of(context) - .validateBeneficiaryproceeding; - }); - return; - } - // Perform payment logic - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => TransactionPinScreen( - onPinCompleted: (pinScreenContext, tpin) async { - final transfer = Transfer( - fromAccount: widget.debitAccount, - toAccount: accountNumberController.text, - toAccountType: _selectedAccountType!, - amount: amountController.text, - tpin: tpin, - remarks: remarksController.text, - ); - - final paymentService = getIt(); - final paymentResponseFuture = paymentService - .processQuickPayWithinBank(transfer); - - Navigator.of(pinScreenContext).pushReplacement( - MaterialPageRoute( - builder: (_) => PaymentAnimationScreen( - paymentResponse: paymentResponseFuture), - ), - ); - }, - ), - ), - ); - } - }, - ), - ), - ], + ), ), ), - ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], ), ); } diff --git a/lib/features/security/security_error_screen.dart b/lib/features/security/security_error_screen.dart index 302d931..9832ad0 100644 --- a/lib/features/security/security_error_screen.dart +++ b/lib/features/security/security_error_screen.dart @@ -11,26 +11,43 @@ class SecurityErrorScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Lottie.asset('assets/animations/error.json', height: 200), - const SizedBox(height: 20), - Text( - message, - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600), + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Lottie.asset('assets/animations/error.json', height: 200), + const SizedBox(height: 20), + Text( + message, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w600), + ), + const SizedBox(height: 40), + ElevatedButton( + onPressed: () => SystemChannels.platform + .invokeMethod('SystemNavigator.pop'), + child: const Text('Okay'), + ), + ], ), - const SizedBox(height: 40), - ElevatedButton( - onPressed: () => - SystemChannels.platform.invokeMethod('SystemNavigator.pop'), - child: const Text('Okay'), + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), ), - ], - ), + ), + ], ), ); } diff --git a/lib/features/service/screens/atm_locator_screen.dart b/lib/features/service/screens/atm_locator_screen.dart new file mode 100644 index 0000000..cfc66c2 --- /dev/null +++ b/lib/features/service/screens/atm_locator_screen.dart @@ -0,0 +1,175 @@ +// ignore_for_file: unused_element + +import 'package:flutter/material.dart'; +import '../../../l10n/app_localizations.dart'; + +// Enum to define the type of location + +class Location { + final String name; + final String address; + + Location({ + required this.name, + required this.address, + }); +} + +class ATMLocatorScreen extends StatefulWidget { + const ATMLocatorScreen({super.key}); + + @override + State createState() => _ATMLocatorScreenState(); +} + +class _ATMLocatorScreenState extends State { + final TextEditingController _searchController = TextEditingController(); + + final List _allLocations = [ + Location( + name: "Dharamsala ATM", + address: "Near Main Square, Dharamsala", + ), + Location( + name: "Kangra ATM", + address: "Opposite Bus Stand, Kangra", + ), + ]; + + List _filteredLocations = []; + bool _isLoading = false; + + @override + void initState() { + super.initState(); + // _fetchAndSetLocations(); + _filteredLocations = _allLocations; + } + +// Example of a future API fetching function +/* +Future _fetchAndSetLocations() async { + setState(() { + _isLoading = true; + }); + try { + // final locations = await yourApiService.getLocations(); + // setState(() { + // _allLocations = locations; + // _filteredLocations = locations; + // }); + } catch (e) { + // Handle error + } finally { + setState(() { + _isLoading = false; + }); + } +} +*/ + void _filterLocations(String query) { + setState(() { + if (query.isEmpty) { + _filteredLocations = _allLocations; + } else { + _filteredLocations = _allLocations.where((location) { + final lowerQuery = query.toLowerCase(); + return location.name.toLowerCase().contains(lowerQuery) || + location.address.toLowerCase().contains(lowerQuery); + }).toList(); + } + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("ATM Locator"), + ), + body: Stack( + children: [ + Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + controller: _searchController, + onChanged: _filterLocations, + decoration: InputDecoration( + hintText: "Name/Address", + prefixIcon: const Icon(Icons.search), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + + // Content area + Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _filteredLocations.isEmpty + ? const Center( + child: Text("No matching locations found")) + : ListView.builder( + itemCount: _filteredLocations.length, + itemBuilder: (context, index) { + final location = _filteredLocations[index]; + return _buildLocationItem(location); + }, + ), + ), + ], + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildHeader(String title) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Text( + title, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.primary, + ), + ), + ); + } + +// Helper widget to build a single location item + Widget _buildLocationItem(Location location) { + return Card( + margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + child: ListTile( + leading: const Icon(Icons.currency_rupee), + title: Text(location.name, + style: const TextStyle(fontWeight: FontWeight.bold)), + subtitle: Text( + "Address: ${location.address}", + ), + onTap: () { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Selected ${location.name}")), + ); + }, + ), + ); + } +} diff --git a/lib/features/service/screens/branch_locator_screen.dart b/lib/features/service/screens/branch_locator_screen.dart index 8f5f3b8..580316a 100644 --- a/lib/features/service/screens/branch_locator_screen.dart +++ b/lib/features/service/screens/branch_locator_screen.dart @@ -3,22 +3,17 @@ import 'package:flutter/material.dart'; import '../../../l10n/app_localizations.dart'; -// Enum to define the type of location -enum LocationType { branch, atm } - class Location { final String name; final String? code; // Nullable for ATMs final String? ifsc; // Nullable for ATMs final String address; - final LocationType type; Location({ required this.name, this.code, this.ifsc, required this.address, - required this.type, }); } @@ -38,24 +33,12 @@ class _BranchLocatorScreenState extends State { code: "002", ifsc: "KACE0000002", address: "Civil Lines Dharmashala, Kangra, HP - 176215", - type: LocationType.branch, ), Location( name: "Kangra", code: "033", ifsc: "KACE0000033", address: "Rajput Bhawankangrapo, Kangra, HP ", - type: LocationType.branch, - ), - Location( - name: "Dharamsala ATM", - address: "Near Main Square, Dharamsala", - type: LocationType.atm, - ), - Location( - name: "Kangra ATM", - address: "Opposite Bus Stand, Kangra", - type: LocationType.atm, ), ]; @@ -112,37 +95,54 @@ Future _fetchAndSetLocations() async { appBar: AppBar( title: Text(AppLocalizations.of(context).branchLocator), ), - body: Column( + body: Stack( children: [ - Padding( - padding: const EdgeInsets.all(12.0), - child: TextField( - controller: _searchController, - onChanged: _filterLocations, - decoration: InputDecoration( - hintText: AppLocalizations.of(context).searchbranchby, - prefixIcon: const Icon(Icons.search), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), + Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + controller: _searchController, + onChanged: _filterLocations, + decoration: InputDecoration( + hintText: AppLocalizations.of(context).searchbranchby, + prefixIcon: const Icon(Icons.search), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + + // Content area + Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _filteredLocations.isEmpty + ? const Center( + child: Text("No matching locations found")) + : ListView.builder( + itemCount: _filteredLocations.length, + itemBuilder: (context, index) { + final location = _filteredLocations[index]; + return _buildLocationItem(location); + }, + ), + ), + ], + ), + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed ), ), ), ), - - // Content area - Expanded( - child: _isLoading - ? const Center(child: CircularProgressIndicator()) - : _filteredLocations.isEmpty - ? const Center(child: Text("No matching locations found")) - : ListView.builder( - itemCount: _filteredLocations.length, - itemBuilder: (context, index) { - final location = _filteredLocations[index]; - return _buildLocationItem(location); - }, - ), - ), ], ), ); @@ -163,20 +163,16 @@ Future _fetchAndSetLocations() async { // Helper widget to build a single location item Widget _buildLocationItem(Location location) { - final isBranch = location.type == LocationType.branch; return Card( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), child: ListTile( - leading: CircleAvatar( - child: Icon(isBranch ? Icons.location_city : Icons.currency_rupee), + leading: const CircleAvatar( + child: Icon(Icons.location_city), ), title: Text(location.name, style: const TextStyle(fontWeight: FontWeight.bold)), subtitle: Text( - isBranch - ? "Code: ${location.code} | IFSC: ${location.ifsc}\nAddress: ${location.address}" - : "Address: ${location.address}", - ), + "Code: ${location.code} | IFSC: ${location.ifsc}\nAddress: ${location.address}"), onTap: () { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Selected ${location.name}")), diff --git a/lib/features/service/screens/faqs_screen.dart b/lib/features/service/screens/faqs_screen.dart index 8b01a24..4e3ac47 100644 --- a/lib/features/service/screens/faqs_screen.dart +++ b/lib/features/service/screens/faqs_screen.dart @@ -42,6 +42,22 @@ class _FaqsScreenState extends State { ], ), ), + body: Stack( + children: [ + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], + ), ); } } diff --git a/lib/features/service/screens/quick_links_screen.dart b/lib/features/service/screens/quick_links_screen.dart index 55335b0..85f1fc4 100644 --- a/lib/features/service/screens/quick_links_screen.dart +++ b/lib/features/service/screens/quick_links_screen.dart @@ -29,6 +29,22 @@ class _QuickLinksScreenState extends State { appBar: AppBar( title: Text(AppLocalizations.of(context).quickLinks), ), + body: Stack( + children: [ + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), + ), + ], + ), ); } } diff --git a/lib/features/service/screens/service_screen.dart b/lib/features/service/screens/service_screen.dart index a036384..fa95057 100644 --- a/lib/features/service/screens/service_screen.dart +++ b/lib/features/service/screens/service_screen.dart @@ -1,3 +1,4 @@ +import 'package:kmobile/features/service/screens/atm_locator_screen.dart'; import 'package:kmobile/features/service/screens/branch_locator_screen.dart'; import '../../../l10n/app_localizations.dart'; @@ -24,57 +25,73 @@ class _ServiceScreen extends State { ), centerTitle: false, ), - body: ListView( + body: Stack( children: [ - ServiceManagementTile( - icon: Symbols.add, - label: AppLocalizations.of(context).accountOpeningDeposit, - onTap: () {}, - disabled: true, + ListView( + children: [ + // ServiceManagementTile( + // icon: Symbols.add, + // label: AppLocalizations.of(context).accountOpeningDeposit, + // onTap: () {}, + // disabled: true, + // ), + // const Divider(height: 1), + // ServiceManagementTile( + // icon: Symbols.add, + // label: AppLocalizations.of(context).accountOpeningLoan, + // onTap: () {}, + // disabled: true, + // ), + // const Divider(height: 1), + ServiceManagementTile( + icon: Symbols.captive_portal, + label: AppLocalizations.of(context).quickLinks, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const QuickLinksScreen()), + ); + }, + disabled: false, + ), + const Divider(height: 1), + ServiceManagementTile( + icon: Symbols.question_mark, + label: AppLocalizations.of(context).faq, + onTap: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => const FaqsScreen()), + ); + }, + disabled: false, + ), + const Divider(height: 1), + ServiceManagementTile( + icon: Symbols.location_pin, + label: "ATM Locator", + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ATMLocatorScreen())); + }, + disabled: false, + ), + const Divider(height: 1), + ], ), - const Divider(height: 1), - ServiceManagementTile( - icon: Symbols.add, - label: AppLocalizations.of(context).accountOpeningLoan, - onTap: () {}, - disabled: true, + IgnorePointer( + child: Center( + child: Opacity( + opacity: 0.1, // Low opacity + child: Image.asset( + 'assets/images/logo.png', + width: 200, // Adjust size as needed + height: 200, // Adjust size as needed + ), + ), + ), ), - const Divider(height: 1), - ServiceManagementTile( - icon: Symbols.captive_portal, - label: AppLocalizations.of(context).quickLinks, - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => const QuickLinksScreen()), - ); - }, - disabled: true, - ), - const Divider(height: 1), - ServiceManagementTile( - icon: Symbols.question_mark, - label: AppLocalizations.of(context).faq, - onTap: () { - Navigator.of(context).push( - MaterialPageRoute(builder: (context) => const FaqsScreen()), - ); - }, - disabled: true, - ), - const Divider(height: 1), - ServiceManagementTile( - icon: Symbols.location_pin, - label: AppLocalizations.of(context).branchLocator, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const BranchLocatorScreen())); - }, - disabled: true, - ), - const Divider(height: 1), ], ), ); diff --git a/lib/main.dart b/lib/main.dart index c6920a2..a4e7953 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,13 +15,13 @@ void main() async { ]); // Check for device compromise - final compromisedMessage = await SecurityService.deviceCompromisedMessage; - if (compromisedMessage != null) { - runApp(MaterialApp( - home: SecurityErrorScreen(message: compromisedMessage), - )); - return; - } + // final compromisedMessage = await SecurityService.deviceCompromisedMessage; + // if (compromisedMessage != null) { + // runApp(MaterialApp( + // home: SecurityErrorScreen(message: compromisedMessage), + // )); + // return; + // } await setupDependencies(); runApp(const KMobile()); }