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 6ddd1a6..189266d 100644 --- a/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart +++ b/lib/features/fund_transfer/screens/fund_transfer_amount_screen.dart @@ -45,6 +45,7 @@ class _FundTransferAmountScreenState extends State { final _limitService = getIt(); Limit? _limit; bool _isLoadingLimit = true; +bool _isAmountOverLimit = false; final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹'); final _amountController = TextEditingController(); final _remarksController = TextEditingController(); @@ -76,21 +77,28 @@ void initState() { } // Add this method to check the amount against the limit - void _checkAmountLimit() { - if (_limit == null) return; +void _checkAmountLimit() { + if (_limit == null) return; - final amount = double.tryParse(_amountController.text) ?? 0; - final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; + final amount = double.tryParse(_amountController.text) ?? 0; + final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; + final bool isOverLimit = amount > remainingLimit; - if (amount > remainingLimit) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), - backgroundColor: Colors.red, - ), - ); - } - } + if (isOverLimit) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), + backgroundColor: Colors.red, + ), + ); + } + + if (_isAmountOverLimit != isOverLimit) { + setState(() { + _isAmountOverLimit = isOverLimit; + }); + } +} @override void dispose() { @@ -490,15 +498,15 @@ void initState() { // Proceed Button SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _onProceed, - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 16), - ), - child: Text(AppLocalizations.of(context).proceed), - ), - ), + width: double.infinity, + child: ElevatedButton( + onPressed: _isAmountOverLimit ? null : _onProceed, + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + child: Text(AppLocalizations.of(context).proceed), + ), +), const SizedBox(height: 10), ], ), 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 808365e..81bdc94 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 @@ -46,6 +46,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹'); final remarksController = TextEditingController(); final _ifscFocusNode = FocusNode(); final service = getIt(); + bool _isAmountOverLimit = false; late String accountType; bool _isValidating = false; @@ -88,21 +89,28 @@ Future _loadLimit() async { } // Add this method to check the amount against the limit -void _checkAmountLimit() { - if (_limit == null) return; + void _checkAmountLimit() { + if (_limit == null) return; - final amount = double.tryParse(amountController.text) ?? 0; - final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; + final amount = double.tryParse(amountController.text) ?? 0; + final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; + final bool isOverLimit = amount > remainingLimit; - if (amount > remainingLimit) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), - backgroundColor: Colors.red, - ), - ); - } -} + if (isOverLimit) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), + backgroundColor: Colors.red, + ), + ); + } + + if (_isAmountOverLimit != isOverLimit) { + setState(() { + _isAmountOverLimit = isOverLimit; + }); + } + } void _validateIFSC() async { final ifsc = ifscController.text.trim().toUpperCase(); @@ -856,24 +864,31 @@ if (!_isLoadingLimit && _limit != null) ], ), const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SwipeButton.expand( - thumb: Icon(Icons.arrow_forward, - color: Theme.of(context).dialogBackgroundColor), - activeThumbColor: Theme.of(context).colorScheme.primary, - activeTrackColor: - Theme.of(context).colorScheme.secondary.withAlpha(100), - borderRadius: BorderRadius.circular(30), - height: 56, - onSwipe: _onProceedToPay, - child: Text( - AppLocalizations.of(context).swipeToPay, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold), - ), - ), - ), + 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), + ), + ), + ), ], ), ), 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 3c3b14c..11982c9 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 @@ -31,7 +31,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹'); final TextEditingController amountController = TextEditingController(); final TextEditingController remarksController = TextEditingController(); String? _selectedAccountType; - + bool _isAmountOverLimit = false; String? _beneficiaryName; bool _isValidating = false; bool _isBeneficiaryValidated = false; @@ -43,6 +43,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹'); _loadLimit(); accountNumberController.addListener(_resetBeneficiaryValidation); confirmAccountNumberController.addListener(_resetBeneficiaryValidation); + amountController.addListener(_checkAmountLimit); } Future _loadLimit() async { @@ -68,8 +69,9 @@ void _checkAmountLimit() { final amount = double.tryParse(amountController.text) ?? 0; final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; + final bool isOverLimit = amount > remainingLimit; - if (amount > remainingLimit) { + if (isOverLimit) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), @@ -77,6 +79,13 @@ void _checkAmountLimit() { ), ); } + + // Update state only if it changes to avoid unnecessary rebuilds + if (_isAmountOverLimit != isOverLimit) { + setState(() { + _isAmountOverLimit = isOverLimit; + }); + } } void _resetBeneficiaryValidation() { @@ -379,63 +388,69 @@ if (!_isLoadingLimit && _limit != null) style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 45), - Align( - alignment: Alignment.center, - child: SwipeButton.expand( - thumb: Icon(Icons.arrow_forward, - color: Theme.of(context).dialogBackgroundColor), - activeThumbColor: Theme.of(context).colorScheme.primary, - activeTrackColor: 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 (_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, - ); + 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); + final paymentService = getIt(); + final paymentResponseFuture = paymentService + .processQuickPayWithinBank(transfer); - Navigator.of(pinScreenContext).pushReplacement( - MaterialPageRoute( - builder: (_) => PaymentAnimationScreen( - paymentResponse: paymentResponseFuture), - ), - ); - }, - ), - ), - ); - } - }, - ), - ), + Navigator.of(pinScreenContext).pushReplacement( + MaterialPageRoute( + builder: (_) => PaymentAnimationScreen( + paymentResponse: paymentResponseFuture), + ), + ); + }, + ), + ), + ); + } + }, + ), + ), ], ), ),