1)User Login api Integrate
2)Forgot Password api Integrate 3)Change Password api Integrate and ChangePassword UI Create
This commit is contained in:
parent
37e8ebbe30
commit
7aa59ca145
@ -2,7 +2,7 @@ import 'package:cheminova/screens/splash_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
void main() {
|
||||
void main()async{
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const GetMaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
home: SplashScreen(),
|
||||
);
|
||||
}
|
||||
|
181
lib/screens/authentication/change_password_screen.dart
Normal file
181
lib/screens/authentication/change_password_screen.dart
Normal file
@ -0,0 +1,181 @@
|
||||
import 'package:cheminova/widgets/custom_button.dart';
|
||||
import 'package:cheminova/widgets/input_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../utils/show_snackbar.dart';
|
||||
import 'controller/auth_controller.dart';
|
||||
|
||||
|
||||
class ChangePasswordScreen extends StatefulWidget {
|
||||
const ChangePasswordScreen({super.key});
|
||||
|
||||
@override
|
||||
State<ChangePasswordScreen> createState() => _ChangePasswordScreenState();
|
||||
}
|
||||
|
||||
class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
|
||||
final authController = Get.put(AuthController());
|
||||
|
||||
|
||||
void dispose() {
|
||||
authController.currentpassController.dispose();
|
||||
authController.newpassController.dispose();
|
||||
authController.confirmpassController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void validateAndChangePassword() async {
|
||||
String oldPassword = authController.currentpassController.text.trim();
|
||||
String newPassword = authController.newpassController.text.trim();
|
||||
String confirmPassword = authController.confirmpassController.text.trim();
|
||||
|
||||
if (newPassword.isEmpty || confirmPassword.isEmpty || oldPassword.isEmpty) {
|
||||
showSnackbar('All fields are required');
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword.length < 8) {
|
||||
showSnackbar('Password must be at least 8 characters long');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RegExp(r'[!@#$%^&*(),.?":{}|<>]').hasMatch(newPassword)) {
|
||||
showSnackbar('Password must contain at least one special character');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (newPassword != confirmPassword) {
|
||||
showSnackbar('New Password and Confirm Password do not match');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
authController.changePassword();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
extendBodyBehindAppBar: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
|
||||
elevation: 0,
|
||||
leading: GestureDetector(
|
||||
onTap: () => Get.back(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: SvgPicture.asset('assets/svg/menu.svg')),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
GestureDetector(
|
||||
onTap: () => Get.back(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SvgPicture.asset('assets/svg/back_arrow.svg'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: AssetImage(
|
||||
'assets/images/image_1.png',
|
||||
),
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(50.0),
|
||||
bottomRight: Radius.circular(50.0),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
width: Get.width,
|
||||
height: Get.height * 0.7,
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Card(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 24),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(19),
|
||||
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||
),
|
||||
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
|
||||
Container(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'Change Password',
|
||||
style: GoogleFonts.getFont(
|
||||
'Roboto',
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 30,
|
||||
height: 1.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
InputField(
|
||||
hintText: "Current Password",
|
||||
labelText: "Current Password",
|
||||
controller: authController.currentpassController,
|
||||
obscureText: true,
|
||||
keyboardType: TextInputType.text,
|
||||
),
|
||||
|
||||
const SizedBox(height: 15),
|
||||
InputField(
|
||||
hintText: "New Password",
|
||||
labelText: "New Password",
|
||||
obscureText: true,
|
||||
controller: authController.newpassController,
|
||||
keyboardType: TextInputType.text,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
InputField(
|
||||
hintText: "Confirm Password",
|
||||
labelText: "Confirm Password",
|
||||
obscureText: true,
|
||||
controller: authController.confirmpassController,
|
||||
keyboardType: TextInputType.text,
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
CustomButton(
|
||||
text: "RESET PASSWORD",
|
||||
onPressed: () async {
|
||||
|
||||
validateAndChangePassword();
|
||||
|
||||
},
|
||||
isLoading: authController.isLoading.value,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ import 'package:cheminova/screens/authentication/controller/auth_service.dart';
|
||||
import 'package:cheminova/screens/home_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class AuthController extends GetxController {
|
||||
final authService = AuthService();
|
||||
@ -9,6 +10,10 @@ class AuthController extends GetxController {
|
||||
TextEditingController emailController = TextEditingController();
|
||||
TextEditingController passwordController = TextEditingController();
|
||||
TextEditingController phoneController = TextEditingController();
|
||||
TextEditingController currentpassController = TextEditingController();
|
||||
TextEditingController newpassController = TextEditingController();
|
||||
TextEditingController confirmpassController = TextEditingController();
|
||||
|
||||
RxBool isLoading = false.obs;
|
||||
|
||||
Future<void> login() async {
|
||||
@ -23,4 +28,53 @@ class AuthController extends GetxController {
|
||||
Get.offAll(() => const HomeScreen());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> forgotpass() async{
|
||||
isLoading.value = true;
|
||||
final response = await authService.forgotPassword(
|
||||
{
|
||||
'email': emailController.text,
|
||||
}
|
||||
);
|
||||
isLoading.value = false;
|
||||
update();
|
||||
if(response != null){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> changePassword() async {
|
||||
isLoading.value = true;
|
||||
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String? token = prefs.getString('token');
|
||||
|
||||
if (token != null) {
|
||||
final response = await authService.changePassword(
|
||||
{
|
||||
'oldPassword': currentpassController.text,
|
||||
'newPassword': newpassController.text,
|
||||
'confirmPassword': confirmpassController.text,
|
||||
},
|
||||
token: token, // Pass the token here
|
||||
);
|
||||
print("tokemn ,$token");
|
||||
isLoading.value = false;
|
||||
update();
|
||||
|
||||
if (response != null) {
|
||||
|
||||
Get.snackbar('Success', 'Password changed successfully');
|
||||
} else {
|
||||
|
||||
Get.snackbar('Error', 'Failed to change password');
|
||||
}
|
||||
} else {
|
||||
isLoading.value = false;
|
||||
update();
|
||||
Get.snackbar('Error', 'Token not found. Please login again.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ class AuthService {
|
||||
Future<Map<String, dynamic>?> login(Map<String, dynamic> data) async {
|
||||
try {
|
||||
final response = await commonApiService<Map<String, dynamic>>(
|
||||
url: '/api/territorymanager/login',
|
||||
url: '/api/v1/user/login/',
|
||||
method: 'POST',
|
||||
body: data,
|
||||
fromJson: (json) => json, // Simply return the JSON map as is
|
||||
@ -16,4 +16,41 @@ class AuthService {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Future<Map<String, dynamic>?> forgotPassword(Map<String, dynamic> data) async {
|
||||
try {
|
||||
final response = await commonApiService<Map<String, dynamic>>(
|
||||
url: '/api/v1/user/password/forgot',
|
||||
method: 'POST',
|
||||
body: data,
|
||||
fromJson: (json) => json, // Simply return the JSON map as is
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
showSnackbar(e.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Future<Map<String, dynamic>?> changePassword(Map<String, dynamic> data, {required String token}) async {
|
||||
try {
|
||||
final response = await commonApiService<Map<String, dynamic>>(
|
||||
url: '/api/v1/user/password/update',
|
||||
method: 'PUT',
|
||||
body: data,
|
||||
fromJson: (json) => json, // Simply return the JSON map as is
|
||||
additionalHeaders: { // Pass the token here
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
showSnackbar(e.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import 'package:flutter_svg/svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'controller/auth_controller.dart';
|
||||
|
||||
class ForgetPasswordScreen extends StatefulWidget {
|
||||
const ForgetPasswordScreen({super.key});
|
||||
|
||||
@ -15,6 +17,7 @@ class ForgetPasswordScreen extends StatefulWidget {
|
||||
class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
|
||||
final userNameController = TextEditingController();
|
||||
final passwordController = TextEditingController();
|
||||
final authController = Get.put(AuthController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -125,7 +128,11 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
CustomButton(text: "Send", onPressed: () {}),
|
||||
CustomButton(text: "Send",
|
||||
|
||||
onPressed: () => authController.forgotpass(),
|
||||
isLoading: authController.isLoading.value,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -11,6 +11,7 @@ Future<BodyType?> commonApiService<BodyType>({
|
||||
Map<String, dynamic> body = const {},
|
||||
File? imageFile,
|
||||
bool isformData = true,
|
||||
Map<String, String>? additionalHeaders,
|
||||
required BodyType Function(Map<String, dynamic>) fromJson,
|
||||
}) async {
|
||||
try {
|
||||
@ -31,6 +32,9 @@ Future<BodyType?> commonApiService<BodyType>({
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
|
||||
if (additionalHeaders != null) {
|
||||
headers.addAll(additionalHeaders);
|
||||
}
|
||||
Options options = Options(headers: headers);
|
||||
|
||||
FormData formData = FormData.fromMap(body);
|
||||
@ -60,7 +64,7 @@ Future<BodyType?> commonApiService<BodyType>({
|
||||
|
||||
print("response of $url : $response");
|
||||
|
||||
if (url == "/api/territorymanager/login" &&
|
||||
if (url == "/api/v1/user/login/" &&
|
||||
response.data['token'] != null) {
|
||||
prefs.setString('token', response.data['token']);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:cheminova/controller/home_controller.dart';
|
||||
import 'package:cheminova/screens/authentication/change_password_screen.dart';
|
||||
import 'package:cheminova/screens/authentication/login_screen.dart';
|
||||
import 'package:cheminova/screens/home_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -64,7 +65,9 @@ class _MyDrawerState extends State<MyDrawer> {
|
||||
ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: const Text('Change Password'),
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Get.to(ChangePasswordScreen());
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.exit_to_app),
|
||||
|
Loading…
Reference in New Issue
Block a user