319 lines
11 KiB
Dart
319 lines
11 KiB
Dart
import 'dart:convert';
|
|||
|
|
|
||
|
|
import 'package:flutter/material.dart';
|
||
|
|
|
||
|
|
import '../../Utils/image_constant.dart';
|
||
|
|
import '../../Utils/size_utils.dart';
|
||
|
|
import '../../providers/token_manager.dart';
|
||
|
|
import '../../resources/api_constants.dart';
|
||
|
|
import 'package:http/http.dart' as http;
|
||
|
|
|
||
|
|
import '../../theme/app_style.dart';
|
||
|
|
import '../../widgets/app_bar/appbar_image.dart';
|
||
|
|
import '../../widgets/app_bar/appbar_title.dart';
|
||
|
|
import '../../widgets/app_bar/custom_app_bar.dart';
|
||
|
|
import '../../widgets/custom_button.dart';
|
||
|
|
import '../../widgets/custom_text_form_field.dart';
|
||
|
|
import '../Login Screen/login_screen.dart';
|
||
|
|
import '../LogoutService/Logoutservice.dart';
|
||
|
|
|
||
|
|
class ResetPasswordScreen extends StatelessWidget {
|
||
|
|
final String userEmail;
|
||
|
|
|
||
|
|
final Map<String, dynamic> userData;
|
||
|
|
|
||
|
|
ResetPasswordScreen({required this.userEmail,required this.userData});
|
||
|
|
|
||
|
|
@override
|
||
|
|
Widget build(BuildContext context) {
|
||
|
|
return Scaffold(
|
||
|
|
appBar:
|
||
|
|
CustomAppBar(
|
||
|
|
height: getVerticalSize(49),
|
||
|
|
leadingWidth: 40,
|
||
|
|
leading: AppbarImage(
|
||
|
|
height: getSize(24),
|
||
|
|
width: getSize(24),
|
||
|
|
svgPath: ImageConstant.imgArrowleftBlueGray900,
|
||
|
|
margin: getMargin(left: 16, top: 12, bottom: 13),
|
||
|
|
onTap: () {
|
||
|
|
Navigator.pop(context);
|
||
|
|
}),
|
||
|
|
centerTitle: true,
|
||
|
|
title: AppbarTitle(text: "Reset Password")),
|
||
|
|
body: SingleChildScrollView(
|
||
|
|
padding: EdgeInsets.all(16),
|
||
|
|
child: Column(
|
||
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
|
|
children: <Widget>[
|
||
|
|
Text(
|
||
|
|
"You're signed in as $userEmail",
|
||
|
|
style: AppStyle.txtGilroyMedium16Bluegray800
|
||
|
|
),
|
||
|
|
const SizedBox(height: 20),
|
||
|
|
ResetPasswordForm(userData: userData,userEmail: userEmail),
|
||
|
|
const SizedBox(height: 20),
|
||
|
|
GestureDetector(
|
||
|
|
onTap: () {
|
||
|
|
Navigator.pushAndRemoveUntil(
|
||
|
|
context,
|
||
|
|
MaterialPageRoute(builder: (context) => const LoginScreen()),
|
||
|
|
(route) => false, // Remove all routes from the stack
|
||
|
|
);
|
||
|
|
},
|
||
|
|
child: Text(
|
||
|
|
'Wrong account? Log in instead.',
|
||
|
|
style: AppStyle.txtGreenSemiBold16,
|
||
|
|
),
|
||
|
|
),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class ResetPasswordForm extends StatefulWidget {
|
||
|
|
final String userEmail;
|
||
|
|
|
||
|
|
final Map<String, dynamic> userData;
|
||
|
|
|
||
|
|
const ResetPasswordForm({super.key, required this.userEmail,required this.userData});
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
@override
|
||
|
|
_ResetPasswordFormState createState() => _ResetPasswordFormState();
|
||
|
|
}
|
||
|
|
|
||
|
|
class _ResetPasswordFormState extends State<ResetPasswordForm> {
|
||
|
|
final TextEditingController oldPasswordController = TextEditingController();
|
||
|
|
final TextEditingController newPasswordController = TextEditingController();
|
||
|
|
final TextEditingController reEnterNewPasswordController =
|
||
|
|
TextEditingController();
|
||
|
|
|
||
|
|
var responseMessage;
|
||
|
|
var isVisible=false;
|
||
|
|
bool issuccess = false;
|
||
|
|
|
||
|
|
bool isOldPasswordVisible = false;
|
||
|
|
bool isNewPasswordVisible = false;
|
||
|
|
bool isReEnterNewPasswordVisible = false;
|
||
|
|
|
||
|
|
bool _isPasswordValid1 = true;
|
||
|
|
void _validatePassword1(String password) {
|
||
|
|
setState(() {
|
||
|
|
_isPasswordValid1 = password.isNotEmpty;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
bool _isPasswordValid2 = true;
|
||
|
|
void _validatePassword2(String password) {
|
||
|
|
setState(() {
|
||
|
|
_isPasswordValid2 = password.isNotEmpty;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
bool _isPasswordValid3 = true;
|
||
|
|
void _validatePassword3(String password) {
|
||
|
|
setState(() {
|
||
|
|
_isPasswordValid3 = password.isNotEmpty&&password==newPasswordController.text;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
@override
|
||
|
|
Widget build(BuildContext context) {
|
||
|
|
return Column(
|
||
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
|
|
children: <Widget>[
|
||
|
|
isVisible?Text(responseMessage,style: TextStyle(
|
||
|
|
color: issuccess?Colors.green:Colors.red, // Set the text color to red
|
||
|
|
)):const Text(''),
|
||
|
|
|
||
|
|
Padding(
|
||
|
|
padding: getPadding(top: 19),
|
||
|
|
child: Text("Enter Old Password",
|
||
|
|
overflow: TextOverflow.ellipsis,
|
||
|
|
textAlign: TextAlign.left,
|
||
|
|
style:
|
||
|
|
AppStyle.txtGilroyMedium16Bluegray900)),
|
||
|
|
CustomTextFormField(
|
||
|
|
focusNode: FocusNode(),
|
||
|
|
controller: oldPasswordController,
|
||
|
|
hintText: "Enter Old Password",
|
||
|
|
margin: getMargin(top: 6),
|
||
|
|
errorText:
|
||
|
|
_isPasswordValid1 ? null : 'Please enter your old password',
|
||
|
|
padding: TextFormFieldPadding.PaddingT12,
|
||
|
|
textInputAction: TextInputAction.done,
|
||
|
|
onChanged: _validatePassword1,
|
||
|
|
validator: (value) {
|
||
|
|
if (value!.isEmpty) {
|
||
|
|
return 'Please enter your old password';
|
||
|
|
}
|
||
|
|
return null; // Return null to indicate no error
|
||
|
|
},
|
||
|
|
textInputType:TextInputType.visiblePassword,
|
||
|
|
suffix: IconButton(
|
||
|
|
icon: Icon(
|
||
|
|
isOldPasswordVisible ? Icons.visibility : Icons.visibility_off,
|
||
|
|
),
|
||
|
|
onPressed: () {
|
||
|
|
setState(() {
|
||
|
|
isOldPasswordVisible = !isOldPasswordVisible;
|
||
|
|
});
|
||
|
|
},
|
||
|
|
),
|
||
|
|
suffixConstraints: BoxConstraints(
|
||
|
|
maxHeight: getVerticalSize(44)),
|
||
|
|
isObscureText: !isOldPasswordVisible),
|
||
|
|
|
||
|
|
Padding(
|
||
|
|
padding: getPadding(top: 19),
|
||
|
|
child: Text("Enter New Password",
|
||
|
|
overflow: TextOverflow.ellipsis,
|
||
|
|
textAlign: TextAlign.left,
|
||
|
|
style:
|
||
|
|
AppStyle.txtGilroyMedium16Bluegray900)),
|
||
|
|
CustomTextFormField(
|
||
|
|
focusNode: FocusNode(),
|
||
|
|
controller: newPasswordController,
|
||
|
|
hintText: "Enter New Password",
|
||
|
|
margin: getMargin(top: 6),
|
||
|
|
padding: TextFormFieldPadding.PaddingT12,
|
||
|
|
textInputAction: TextInputAction.done,
|
||
|
|
suffix: IconButton(
|
||
|
|
icon: Icon(
|
||
|
|
isNewPasswordVisible ? Icons.visibility : Icons.visibility_off,
|
||
|
|
),
|
||
|
|
onPressed: () {
|
||
|
|
setState(() {
|
||
|
|
isNewPasswordVisible = !isNewPasswordVisible;
|
||
|
|
});
|
||
|
|
},
|
||
|
|
),
|
||
|
|
errorText:
|
||
|
|
_isPasswordValid2 ? null : 'Please enter your new password',
|
||
|
|
onChanged: _validatePassword2,
|
||
|
|
validator: (value) {
|
||
|
|
if (value!.isEmpty) {
|
||
|
|
return 'Please enter your new password';
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
},
|
||
|
|
suffixConstraints: BoxConstraints(
|
||
|
|
maxHeight: getVerticalSize(44)),
|
||
|
|
isObscureText:!isNewPasswordVisible,),
|
||
|
|
|
||
|
|
Padding(
|
||
|
|
padding: getPadding(top: 19),
|
||
|
|
child: Text("Re-Enter New Password",
|
||
|
|
overflow: TextOverflow.ellipsis,
|
||
|
|
textAlign: TextAlign.left,
|
||
|
|
style:
|
||
|
|
AppStyle.txtGilroyMedium16Bluegray900)),
|
||
|
|
CustomTextFormField(
|
||
|
|
focusNode: FocusNode(),
|
||
|
|
controller: reEnterNewPasswordController,
|
||
|
|
hintText: "Re-Enter New Password",
|
||
|
|
margin: getMargin(top: 6),
|
||
|
|
padding: TextFormFieldPadding.PaddingT12,
|
||
|
|
onChanged: _validatePassword3,
|
||
|
|
validator: (value) {
|
||
|
|
if (value!.isEmpty) {
|
||
|
|
return 'Please re-enter your new password';
|
||
|
|
}
|
||
|
|
if (value != newPasswordController.text) {
|
||
|
|
return 'Passwords do not match';
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
},
|
||
|
|
suffix: IconButton(
|
||
|
|
icon: Icon(
|
||
|
|
isReEnterNewPasswordVisible
|
||
|
|
? Icons.visibility
|
||
|
|
: Icons.visibility_off,
|
||
|
|
),
|
||
|
|
onPressed: () {
|
||
|
|
setState(() {
|
||
|
|
isReEnterNewPasswordVisible = !isReEnterNewPasswordVisible;
|
||
|
|
});
|
||
|
|
},
|
||
|
|
),
|
||
|
|
errorText:
|
||
|
|
_isPasswordValid3 ? null : 'Please re-enter your new password',
|
||
|
|
textInputAction: TextInputAction.done,
|
||
|
|
suffixConstraints: BoxConstraints(
|
||
|
|
maxHeight: getVerticalSize(44)),
|
||
|
|
isObscureText:!isReEnterNewPasswordVisible,),
|
||
|
|
|
||
|
|
CustomButton(
|
||
|
|
height: getVerticalSize(50),
|
||
|
|
text: "Continue",
|
||
|
|
margin: getMargin(top: 24, bottom: 5),
|
||
|
|
onTap: () async {
|
||
|
|
if (oldPasswordController.text.isEmpty ||
|
||
|
|
newPasswordController.text.isEmpty ||
|
||
|
|
reEnterNewPasswordController.text.isEmpty) {
|
||
|
|
print(oldPasswordController.text);
|
||
|
|
print(newPasswordController.text);
|
||
|
|
print(reEnterNewPasswordController.text);
|
||
|
|
} else {
|
||
|
|
Map<String, dynamic> passwordData = {
|
||
|
|
"userId":widget.userData['userId'],
|
||
|
|
"oldPassword": oldPasswordController.text,
|
||
|
|
"newPassword": newPasswordController.text,
|
||
|
|
"confirmPassword": reEnterNewPasswordController.text,
|
||
|
|
};
|
||
|
|
final token = await TokenManager.getToken();
|
||
|
|
final String baseUrl = ApiConstants.baseUrl;
|
||
|
|
final String apiUrl = '$baseUrl/api/reset_password';
|
||
|
|
|
||
|
|
try {
|
||
|
|
final response = await http.post(Uri.parse(apiUrl),
|
||
|
|
headers: {
|
||
|
|
'Authorization': 'Bearer $token',
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
},
|
||
|
|
body: json.encode(passwordData));
|
||
|
|
if(response.statusCode==401){
|
||
|
|
LogoutService.logout();
|
||
|
|
}
|
||
|
|
if (response.statusCode <= 209) {
|
||
|
|
setState(() {
|
||
|
|
isVisible=true;
|
||
|
|
issuccess=true;
|
||
|
|
responseMessage = "Password Changes Successfully";
|
||
|
|
});
|
||
|
|
print("success");
|
||
|
|
Navigator.pushAndRemoveUntil(
|
||
|
|
context,
|
||
|
|
MaterialPageRoute(builder: (context) => LoginScreen()),
|
||
|
|
(route) => false,
|
||
|
|
);
|
||
|
|
} else {
|
||
|
|
setState(() {
|
||
|
|
isVisible=true;
|
||
|
|
responseMessage = "Incorrect Password";
|
||
|
|
});
|
||
|
|
print(response.statusCode);
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
throw Exception('Failed to Update: $e');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
),
|
||
|
|
],
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
@override
|
||
|
|
void dispose() {
|
||
|
|
oldPasswordController.dispose();
|
||
|
|
newPasswordController.dispose();
|
||
|
|
reEnterNewPasswordController.dispose();
|
||
|
|
super.dispose();
|
||
|
|
}
|
||
|
|
}
|