diff --git a/lib/api/services/beneficiary_service.dart b/lib/api/services/beneficiary_service.dart index 4610b88..52094ca 100644 --- a/lib/api/services/beneficiary_service.dart +++ b/lib/api/services/beneficiary_service.dart @@ -71,7 +71,7 @@ class BeneficiaryService { return response.data['name']; } - // Send Data for Validation + // Beneficiary Validate And ADD Future sendForValidation(Beneficiary beneficiary) async { try { final response = await _dio.post( diff --git a/lib/api/services/change_password_service.dart b/lib/api/services/change_password_service.dart index ffc91df..df0143e 100644 --- a/lib/api/services/change_password_service.dart +++ b/lib/api/services/change_password_service.dart @@ -10,7 +10,7 @@ class ChangePasswordService { }) async { final response = await _dio.post( '/api/otp/send', - queryParameters: { + data: { 'mobileNumber': mobileNumber, 'type': "CHANGE_LPWORD" }, @@ -18,6 +18,7 @@ class ChangePasswordService { if (response.statusCode != 200) { throw Exception("Invalid Mobile Number/Type"); } + print(response.toString()); return response.toString(); } @@ -28,7 +29,7 @@ class ChangePasswordService { }) async { final response = await _dio.post( '/api/otp/verify?mobileNumber=$mobileNumber', - queryParameters: { + data: { 'otp' : otp, }, ); @@ -45,7 +46,7 @@ class ChangePasswordService { }) async { final response = await _dio.post( '/api/auth/change/login_password', - queryParameters: { + data: { 'OldLPsw': OldLPsw, 'newLPsw': newLPsw, 'confirmLPsw': confirmLPsw, diff --git a/lib/di/injection.dart b/lib/di/injection.dart index 32e34f6..b651f4a 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -11,6 +11,7 @@ import 'package:kmobile/features/auth/controllers/theme_cubit.dart'; import 'package:kmobile/features/auth/controllers/theme_mode_cubit.dart'; import '../api/services/auth_service.dart'; import '../api/interceptors/auth_interceptor.dart'; +import '../api/services/change_password_service.dart'; import '../data/repositories/auth_repository.dart'; import '../features/auth/controllers/auth_cubit.dart'; import '../security/secure_storage.dart'; @@ -48,6 +49,7 @@ Future setupDependencies() async { getIt.registerSingleton(NeftService(getIt())); getIt.registerSingleton(RtgsService(getIt())); getIt.registerSingleton(ImpsService(getIt())); + getIt.registerLazySingleton(() => ChangePasswordService(getIt()),); // Add auth interceptor after repository is available getIt().interceptors.add( @@ -63,8 +65,8 @@ Dio _createDioClient() { final dio = Dio( BaseOptions( baseUrl: - 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', - //'http://localhost:8081', + //'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', + 'http://localhost:8081', // 'http://localhost:8082', connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 10), 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 c87703b..88a2566 100644 --- a/lib/features/profile/change_password/change_password_otp_screen.dart +++ b/lib/features/profile/change_password/change_password_otp_screen.dart @@ -1,15 +1,21 @@ import 'package:flutter/material.dart'; +import '../../../api/services/change_password_service.dart'; +import '../../../di/injection.dart'; +import '../../../l10n/app_localizations.dart'; + class ChangePasswordOTPScreen extends StatefulWidget { final String currentPassword; final String newPassword; final String confirmPassword; + final String mobileNumber; // ignore: use_key_in_widget_constructors const ChangePasswordOTPScreen({ required this.currentPassword, required this.newPassword, - required this.confirmPassword, + required this.confirmPassword, + required this.mobileNumber, }); @override @@ -30,20 +36,39 @@ class _ChangePasswordOTPScreenState extends State { }); }); } + final changePasswordService = getIt(); + Future _validateOTP() async { + try { + await changePasswordService.validateOtp( + otp: otpController.text, + mobileNumber: widget.mobileNumber, + ); - void _validateOTP() { - // TODO: Add validation logic later - print("Validating OTP..."); - print('Current Password: ${widget.currentPassword}'); - print('New Password: ${widget.newPassword}'); - print('Confirm Password: ${widget.confirmPassword}'); - print('Entered OTP: ${otpController.text}'); + // If OTP is valid, then change the password + await changePasswordService.validateChangePwd( + OldLPsw: widget.currentPassword, + newLPsw: widget.newPassword, + confirmLPsw: widget.confirmPassword, + ); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(AppLocalizations.of(context).pwdchangeSuccess)), + ); + + // Navigate back to profile or login + Navigator.of(context).popUntil((route) => route.isFirst); + +} catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('${AppLocalizations.of(context).failedToValidate}: $e')), + ); +} } @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text('OTP Verification')), + appBar: AppBar(title: Text(AppLocalizations.of(context).otpVerification)), body: Padding( padding: const EdgeInsets.all(16.0), child: _isLoading @@ -51,18 +76,18 @@ class _ChangePasswordOTPScreenState extends State { : Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - const Text( - 'An OTP has been sent to your registered mobile number.', + Text( + AppLocalizations.of(context).otpSent, textAlign: TextAlign.center, - style: TextStyle(fontSize: 16), + style: const TextStyle(fontSize: 16), ), const SizedBox(height: 24), TextFormField( controller: otpController, keyboardType: TextInputType.number, - decoration: const InputDecoration( - labelText: 'Enter OTP', - border: OutlineInputBorder(), + decoration: InputDecoration( + labelText: AppLocalizations.of(context).enterOTP, + border: const OutlineInputBorder(), ), ), const SizedBox(height: 24), @@ -73,7 +98,7 @@ class _ChangePasswordOTPScreenState extends State { style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), ), - child: const Text('Validate OTP'), + child: Text(AppLocalizations.of(context).validateOTP), ), ), ], diff --git a/lib/features/profile/change_password/change_password_screen.dart b/lib/features/profile/change_password/change_password_screen.dart index 2adbe49..2f5992c 100644 --- a/lib/features/profile/change_password/change_password_screen.dart +++ b/lib/features/profile/change_password/change_password_screen.dart @@ -1,6 +1,8 @@ // ignore_for_file: use_key_in_widget_constructors import 'package:flutter/material.dart'; +import '../../../api/services/change_password_service.dart'; +import '../../../di/injection.dart'; import '../../../l10n/app_localizations.dart'; import 'change_password_otp_screen.dart'; @@ -26,36 +28,43 @@ class _ChangePasswordScreenState extends State { String? validateCurrentPassword(String? value) { if (value == null || value.isEmpty) { - return 'Current password is required'; + return AppLocalizations.of(context).currentpwdrqd; } return null; } String? validateNewPassword(String? value) { if (value == null || value.isEmpty) { - return 'New password is required'; + return AppLocalizations.of(context).newpwdrqd; } if (!passwordRegex.hasMatch(value)) { - return 'At least 8 chars, upper & lower case, digit, special char'; + return AppLocalizations.of(context).pwdFormat; } if (value == currentPasswordController.text) { - return 'New password must differ from current'; + return AppLocalizations.of(context).newoldpwddiff; } return null; } String? validateConfirmPassword(String? value) { if (value == null || value.isEmpty) { - return 'Confirm new password is required'; + return AppLocalizations.of(context).confirmpwdrqd; } if (value != newPasswordController.text) { - return 'Passwords do not match'; + return AppLocalizations.of(context).pwdmismatch; } return null; } +final ChangePasswordService _changePasswordService = getIt(); +void _proceed() async { + if (_formKey.currentState!.validate()) { + + + try { + const mobileNumber = "8981274001"; // Replace with actual mobile number + await _changePasswordService.getOtp(mobileNumber: mobileNumber); + - void _proceed() { - if (_formKey.currentState!.validate()) { Navigator.push( context, MaterialPageRoute( @@ -63,11 +72,17 @@ class _ChangePasswordScreenState extends State { currentPassword: currentPasswordController.text, newPassword: newPasswordController.text, confirmPassword: confirmPasswordController.text, + mobileNumber: mobileNumber, ), ), ); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('${AppLocalizations.of(context).failedtosentOTP}: $e')), + ); } } +} @override Widget build(BuildContext context) { @@ -83,7 +98,7 @@ class _ChangePasswordScreenState extends State { controller: currentPasswordController, obscureText: !_showCurrentPassword, decoration: InputDecoration( - labelText: 'Current Password', + labelText: AppLocalizations.of(context).currentpwd, suffixIcon: IconButton( icon: Icon(_showCurrentPassword ? Icons.visibility @@ -99,7 +114,7 @@ class _ChangePasswordScreenState extends State { controller: newPasswordController, obscureText: !_showNewPassword, decoration: InputDecoration( - labelText: 'New Password', + labelText: AppLocalizations.of(context).newpwd, suffixIcon: IconButton( icon: Icon(_showNewPassword ? Icons.visibility @@ -115,7 +130,7 @@ class _ChangePasswordScreenState extends State { controller: confirmPasswordController, obscureText: !_showConfirmPassword, decoration: InputDecoration( - labelText: 'Confirm New Password', + labelText: AppLocalizations.of(context).confirmpwd, suffixIcon: IconButton( icon: Icon(_showConfirmPassword ? Icons.visibility diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index fab9255..0a203a1 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -292,5 +292,21 @@ "viewCardDeatils": "View Card Details", "logout": "Logout", "logoutCheck": "Are you sure you want to logout?", -"changeLoginPassword": "Change Login Password" +"changeLoginPassword": "Change Login Password", +"currentpwdrqd": "Current password is required", +"newpwdrqd": "New password is required", +"pwdFormat": "At least 8 characters(upper & lower case), digit, special char", +"newoldpwddiff": "New password must differ from current", +"confirmpwdrqd": "Confirm password is required", +"pwdmismatch": "Passwords do not match", +"failedtosentOTP": "Failed to send OTP", +"currentpwd": "Current Password", +"newpwd": "New Password", +"confirmpwd": "Confirm New Password", +"pwdchangeSuccess": "Password changed successfully!", +"failedToValidate": "Failed to Validate", +"otpVerification": "OTP Verification", +"otpSent": "An OTP has been sent to your registered mobile number.", +"enterOTP": "Enter OTP", +"validateOTP": "Validate OTP" } diff --git a/lib/l10n/app_hi.arb b/lib/l10n/app_hi.arb index 971d02d..0242675 100644 --- a/lib/l10n/app_hi.arb +++ b/lib/l10n/app_hi.arb @@ -293,5 +293,21 @@ "viewCardDeatils": "कार्ड विवरण देखें", "logout": "लॉग आउट", "logoutCheck": "क्या आप लॉग आउट करना चाहते हैं?", -"changeLoginPassword": "लॉगिन पासवर्ड बदलें" +"changeLoginPassword": "लॉगिन पासवर्ड बदलें", +"currentpwdrqd": "वर्तमान पासवर्ड आवश्यक है", +"newpwdrqd": "नया पासवर्ड आवश्यक है", +"pwdFormat": "कम से कम 8 अक्षर (बड़े और छोटे अक्षर), अंक, विशेष अक्षर", +"newoldpwddiff": "नया पासवर्ड वर्तमान पासवर्ड से भिन्न होना चाहिए", +"confirmpwdrqd": "पुष्टि पासवर्ड आवश्यक है", +"pwdmismatch": "सांकेतिक शब्द मेल नहीं खाते", +"failedtosentOTP": "ओटीपी भेजने में विफल", +"currentpwd": "वर्तमान पासवर्ड", +"newpwd": "नया पासवर्ड", +"confirmpwd": "नए पासवर्ड की पुष्टि करें", +"pwdchangeSuccess": "पासवर्ड सफलतापूर्वक बदला गया!", +"failedToValidate": "सत्यापित करने में विफल", +"otpVerification": "ओटीपी सत्यापन", +"otpSent": "आपके पंजीकृत मोबाइल नंबर पर एक ओटीपी भेजा गया है।", +"enterOTP": "ओटीपी दर्ज करें", +"validateOTP": "ओटीपी सत्यापित करें" }