diff --git a/lib/api/services/beneficiary_service.dart b/lib/api/services/beneficiary_service.dart index fa2308d..a018487 100644 --- a/lib/api/services/beneficiary_service.dart +++ b/lib/api/services/beneficiary_service.dart @@ -126,4 +126,27 @@ class BeneficiaryService { throw Exception('Unexpected error: ${e.toString()}'); } } + + Future updateLimit({ + required String beneficiaryAccountNo, + required String newLimit, + }) async { + log('inside update limit of beneficiary service'); + final response = await _dio.patch( + '/api/beneficiary/update-limit', + data: { + 'beneficiaryAccountNo': beneficiaryAccountNo, + 'newLimit': int.tryParse(newLimit), + }, + options: Options( + sendTimeout: const Duration(seconds: 60), + receiveTimeout: const Duration(seconds: 60), + ), + ); + if (response.statusCode != 200) { + throw Exception("INTERNAL SERVER ERROR"); + } + return response; + } + } diff --git a/lib/features/beneficiaries/screens/beneficiary_details_screen.dart b/lib/features/beneficiaries/screens/beneficiary_details_screen.dart index e592a12..0cf320c 100644 --- a/lib/features/beneficiaries/screens/beneficiary_details_screen.dart +++ b/lib/features/beneficiaries/screens/beneficiary_details_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:kmobile/data/models/beneficiary.dart'; import 'package:kmobile/di/injection.dart'; import 'package:kmobile/widgets/bank_logos.dart'; @@ -6,16 +7,39 @@ import 'package:kmobile/api/services/beneficiary_service.dart'; import '../../../l10n/app_localizations.dart'; -class BeneficiaryDetailsScreen extends StatelessWidget { +class BeneficiaryDetailsScreen extends StatefulWidget { final Beneficiary beneficiary; - BeneficiaryDetailsScreen({super.key, required this.beneficiary}); + const BeneficiaryDetailsScreen({super.key, required this.beneficiary}); + @override + State createState() => + _BeneficiaryDetailsScreenState(); +} + +class _BeneficiaryDetailsScreenState extends State { final service = getIt(); + late String _currentLimit; + final _limitController = TextEditingController(); + + @override + void initState() { + super.initState(); + _currentLimit = (widget.beneficiary.transactionLimit == null || + widget.beneficiary.transactionLimit!.isEmpty) + ? 'N/A' + : widget.beneficiary.transactionLimit!; + } + + @override + void dispose() { + _limitController.dispose(); + super.dispose(); + } void _deleteBeneficiary(BuildContext context) async { try { - await service.deleteBeneficiary(beneficiary.accountNo); + await service.deleteBeneficiary(widget.beneficiary.accountNo); if (!context.mounted) { return; } @@ -77,6 +101,73 @@ class BeneficiaryDetailsScreen extends StatelessWidget { ); } + Future _showEditLimitDialog() async { + _limitController.text = _currentLimit == 'N/A' ? '' : _currentLimit; + await showDialog( + context: context, + builder: (dialogContext) { + final localizations = AppLocalizations.of(dialogContext); + final theme = Theme.of(dialogContext); + return AlertDialog( + title: Text(localizations.editLimit), + content: TextField( + controller: _limitController, + autofocus: true, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'^\d+')), + ], + decoration: InputDecoration( + labelText: localizations.limitAmount, + prefixText: '₹', + border: const OutlineInputBorder(), + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(), + child: Text(localizations.cancel), + ), + ElevatedButton( + onPressed: () async { + final value = _limitController.text; + if (value.isEmpty || int.tryParse(value) == null) return; + + try { + await service.updateLimit( + beneficiaryAccountNo: widget.beneficiary.accountNo, + newLimit: value, + ); + if (!mounted) return; + setState(() { + _currentLimit = value; + }); + Navigator.of(dialogContext).pop(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(localizations.limitUpdatedSuccess), + behavior: SnackBarBehavior.floating, + ), + ); + } catch (e) { + Navigator.of(dialogContext).pop(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text("${localizations.error}: $e"), + behavior: SnackBarBehavior.floating, + backgroundColor: theme.colorScheme.error, + ), + ); + } + }, + child: Text(localizations.save), + ), + ], + ); + }, + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -96,11 +187,11 @@ class BeneficiaryDetailsScreen extends StatelessWidget { CircleAvatar( radius: 24, backgroundColor: Colors.transparent, - child: getBankLogo(beneficiary.bankName, context), + child: getBankLogo(widget.beneficiary.bankName, context), ), const SizedBox(width: 16), Text( - beneficiary.name, + widget.beneficiary.name, style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), @@ -108,29 +199,28 @@ class BeneficiaryDetailsScreen extends StatelessWidget { ), const SizedBox(height: 24), _buildDetailRow('${AppLocalizations.of(context).bankName} ', - beneficiary.bankName ?? 'N/A'), + widget.beneficiary.bankName ?? 'N/A'), _buildDetailRow( '${AppLocalizations.of(context).accountNumber} ', - beneficiary.accountNo), + widget.beneficiary.accountNo), _buildDetailRow( '${AppLocalizations.of(context).accountType} ', - beneficiary.accountType), + widget.beneficiary.accountType), _buildDetailRow('${AppLocalizations.of(context).ifscCode} ', - beneficiary.ifscCode), + widget.beneficiary.ifscCode), _buildDetailRow('${AppLocalizations.of(context).branchName} ', - beneficiary.branchName ?? 'N/A'), - _buildDetailRow("Beneficiary Transactional Limit", beneficiary.transactionLimit ?? 'N/A'), + widget.beneficiary.branchName ?? 'N/A'), + _buildDetailRow( + "Beneficiary Transactional Limit", _currentLimit), 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: _showEditLimitDialog, + icon: const Icon(Icons.currency_rupee), + label: Text(AppLocalizations.of(context).editLimit), + ), ElevatedButton.icon( onPressed: () { // Delete beneficiary option @@ -184,3 +274,4 @@ class BeneficiaryDetailsScreen extends StatelessWidget { ); } } + diff --git a/lib/features/yojna/screens/gov_scheme_screen.dart b/lib/features/yojna/screens/gov_scheme_screen.dart index 30340f6..84c5a33 100644 --- a/lib/features/yojna/screens/gov_scheme_screen.dart +++ b/lib/features/yojna/screens/gov_scheme_screen.dart @@ -50,24 +50,24 @@ class _GovSchemeScreenState extends State { }, ), ), - Expanded( - child: GovSchemeTile( - logoText: "APY", - label: l10n.registerForAtalPensionYojana, - subtitle: l10n.secureYourFutureAPY, - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => APYScreen( - users: widget.users, - selectedIndex: widget.selectedIndex, - ), - ), - );// Action for APY will be added later - }, - ), - ), + // Expanded( + // child: GovSchemeTile( + // logoText: "APY", + // label: l10n.registerForAtalPensionYojana, + // subtitle: l10n.secureYourFutureAPY, + // onTap: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => APYScreen( + // users: widget.users, + // selectedIndex: widget.selectedIndex, + // ), + // ), + // );// Action for APY will be added later + // }, + // ), + // ), ], ), ),