Proceed or Swipe to pay disabled on over limit

This commit is contained in:
2025-10-31 16:51:37 +05:30
parent d86ff2c427
commit 8f8fdb70e6
3 changed files with 148 additions and 110 deletions

View File

@@ -45,6 +45,7 @@ class _FundTransferAmountScreenState extends State<FundTransferAmountScreen> {
final _limitService = getIt<LimitService>(); final _limitService = getIt<LimitService>();
Limit? _limit; Limit? _limit;
bool _isLoadingLimit = true; bool _isLoadingLimit = true;
bool _isAmountOverLimit = false;
final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: ''); final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '');
final _amountController = TextEditingController(); final _amountController = TextEditingController();
final _remarksController = TextEditingController(); final _remarksController = TextEditingController();
@@ -76,13 +77,14 @@ void initState() {
} }
// Add this method to check the amount against the limit // Add this method to check the amount against the limit
void _checkAmountLimit() { void _checkAmountLimit() {
if (_limit == null) return; if (_limit == null) return;
final amount = double.tryParse(_amountController.text) ?? 0; final amount = double.tryParse(_amountController.text) ?? 0;
final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit;
final bool isOverLimit = amount > remainingLimit;
if (amount > remainingLimit) { if (isOverLimit) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
@@ -90,7 +92,13 @@ void initState() {
), ),
); );
} }
if (_isAmountOverLimit != isOverLimit) {
setState(() {
_isAmountOverLimit = isOverLimit;
});
} }
}
@override @override
void dispose() { void dispose() {
@@ -492,13 +500,13 @@ void initState() {
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: ElevatedButton( child: ElevatedButton(
onPressed: _onProceed, onPressed: _isAmountOverLimit ? null : _onProceed,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
), ),
child: Text(AppLocalizations.of(context).proceed), child: Text(AppLocalizations.of(context).proceed),
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
), ),

View File

@@ -46,6 +46,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
final remarksController = TextEditingController(); final remarksController = TextEditingController();
final _ifscFocusNode = FocusNode(); final _ifscFocusNode = FocusNode();
final service = getIt<BeneficiaryService>(); final service = getIt<BeneficiaryService>();
bool _isAmountOverLimit = false;
late String accountType; late String accountType;
bool _isValidating = false; bool _isValidating = false;
@@ -88,13 +89,14 @@ Future<void> _loadLimit() async {
} }
// Add this method to check the amount against the limit // Add this method to check the amount against the limit
void _checkAmountLimit() { void _checkAmountLimit() {
if (_limit == null) return; if (_limit == null) return;
final amount = double.tryParse(amountController.text) ?? 0; final amount = double.tryParse(amountController.text) ?? 0;
final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit;
final bool isOverLimit = amount > remainingLimit;
if (amount > remainingLimit) { if (isOverLimit) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'),
@@ -102,7 +104,13 @@ void _checkAmountLimit() {
), ),
); );
} }
}
if (_isAmountOverLimit != isOverLimit) {
setState(() {
_isAmountOverLimit = isOverLimit;
});
}
}
void _validateIFSC() async { void _validateIFSC() async {
final ifsc = ifscController.text.trim().toUpperCase(); final ifsc = ifscController.text.trim().toUpperCase();
@@ -860,13 +868,20 @@ if (!_isLoadingLimit && _limit != null)
alignment: Alignment.center, alignment: Alignment.center,
child: SwipeButton.expand( child: SwipeButton.expand(
thumb: Icon(Icons.arrow_forward, thumb: Icon(Icons.arrow_forward,
color: Theme.of(context).dialogBackgroundColor), color: _isAmountOverLimit ? Colors.grey : Theme.of(context).dialogBackgroundColor),
activeThumbColor: Theme.of(context).colorScheme.primary, activeThumbColor: _isAmountOverLimit ? Colors.grey.shade700 :
activeTrackColor: Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.secondary.withAlpha(100), activeTrackColor: _isAmountOverLimit
? Colors.grey.shade300
: Theme.of(context).colorScheme.secondary.withAlpha(100),
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
height: 56, height: 56,
onSwipe: _onProceedToPay, onSwipe: () {
if (_isAmountOverLimit) {
return; // Do nothing if amount is over the limit
}
_onProceedToPay();
},
child: Text( child: Text(
AppLocalizations.of(context).swipeToPay, AppLocalizations.of(context).swipeToPay,
style: const TextStyle( style: const TextStyle(

View File

@@ -31,7 +31,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
final TextEditingController amountController = TextEditingController(); final TextEditingController amountController = TextEditingController();
final TextEditingController remarksController = TextEditingController(); final TextEditingController remarksController = TextEditingController();
String? _selectedAccountType; String? _selectedAccountType;
bool _isAmountOverLimit = false;
String? _beneficiaryName; String? _beneficiaryName;
bool _isValidating = false; bool _isValidating = false;
bool _isBeneficiaryValidated = false; bool _isBeneficiaryValidated = false;
@@ -43,6 +43,7 @@ final _formatCurrency = NumberFormat.currency(locale: 'en_IN', symbol: '₹');
_loadLimit(); _loadLimit();
accountNumberController.addListener(_resetBeneficiaryValidation); accountNumberController.addListener(_resetBeneficiaryValidation);
confirmAccountNumberController.addListener(_resetBeneficiaryValidation); confirmAccountNumberController.addListener(_resetBeneficiaryValidation);
amountController.addListener(_checkAmountLimit);
} }
Future<void> _loadLimit() async { Future<void> _loadLimit() async {
@@ -68,8 +69,9 @@ void _checkAmountLimit() {
final amount = double.tryParse(amountController.text) ?? 0; final amount = double.tryParse(amountController.text) ?? 0;
final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit; final remainingLimit = _limit!.dailyLimit - _limit!.usedLimit;
final bool isOverLimit = amount > remainingLimit;
if (amount > remainingLimit) { if (isOverLimit) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Amount exceeds remaining daily limit of ${_formatCurrency.format(remainingLimit)}'), 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() { void _resetBeneficiaryValidation() {
@@ -383,9 +392,12 @@ if (!_isLoadingLimit && _limit != null)
alignment: Alignment.center, alignment: Alignment.center,
child: SwipeButton.expand( child: SwipeButton.expand(
thumb: Icon(Icons.arrow_forward, thumb: Icon(Icons.arrow_forward,
color: Theme.of(context).dialogBackgroundColor), color: _isAmountOverLimit ? Colors.grey : Theme.of(context).dialogBackgroundColor),
activeThumbColor: Theme.of(context).colorScheme.primary, activeThumbColor: _isAmountOverLimit ? Colors.grey.shade700 :
activeTrackColor: Theme.of( Theme.of(context).colorScheme.primary,
activeTrackColor: _isAmountOverLimit
? Colors.grey.shade300
: Theme.of(
context, context,
).colorScheme.secondary.withAlpha(100), ).colorScheme.secondary.withAlpha(100),
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
@@ -395,6 +407,9 @@ if (!_isLoadingLimit && _limit != null)
style: const TextStyle(fontSize: 16), style: const TextStyle(fontSize: 16),
), ),
onSwipe: () { onSwipe: () {
if (_isAmountOverLimit) {
return; // Do nothing if amount is over limit
}
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
if (!_isBeneficiaryValidated) { if (!_isBeneficiaryValidated) {
setState(() { setState(() {