Merge branch 'main' of http://git.wdipl.com/Siddhesh.More/optifii-admin
This commit is contained in:
@@ -10,12 +10,15 @@ import {
|
||||
import "./App.css"; // Import CSS file
|
||||
import DefaultLayout from "./Layout/DefaultLayout";
|
||||
import NotFound from "./Pages/NotFound";
|
||||
import Login from "./Pages/Login";
|
||||
import GlobalStateContext from "./Contexts/GlobalStateContext";
|
||||
import Cookies from "js-cookie";
|
||||
import NoInternetScreen from "./Pages/NoInternetScreen";
|
||||
import Welcome from "./Pages/PaymentSuccess";
|
||||
import PaymentFailed from "./Pages/PaymentFailed";
|
||||
import Login from "./Pages/Login/Login";
|
||||
import ForgotPassword from "./Pages/Login/ForgotPassword.";
|
||||
import OtpScreen from "./Pages/Login/OtpScreen";
|
||||
import ResetPassword from "./Pages/Login/ResetPassword";
|
||||
|
||||
const App = () => {
|
||||
// const { isAuthenticate } = useSelector((state) => state?.auth);
|
||||
@@ -54,6 +57,10 @@ const App = () => {
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/forgot-password" element={<ForgotPassword />} />
|
||||
<Route path="/otp-screen" element={<OtpScreen />} />
|
||||
<Route path="/otp-screen/:id" element={<OtpScreen />} />
|
||||
<Route path="/reset-password" element={<ResetPassword />} />
|
||||
<Route path="/payment-success" element={<Welcome />} />
|
||||
<Route path="/payment-failed" element={<PaymentFailed />} />
|
||||
<Route
|
||||
|
||||
277
src/Pages/Login/ForgotPassword..jsx
Normal file
277
src/Pages/Login/ForgotPassword..jsx
Normal file
@@ -0,0 +1,277 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Input01 from "../../Components/Inputs/Input01";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { loginUser } from "../../Redux/Slice/auth";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import Button01 from "../../Components/Buttons/PrimaryButton";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { TiWarning } from "react-icons/ti";
|
||||
import Loader01 from "../../Components/Loaders/Loader01";
|
||||
import Asset1 from "../../assets/loginpat.png";
|
||||
import logo from "../../assets/optifii_white.svg";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Image,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
InputRightElement,
|
||||
Text,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
||||
import Cookies from "js-cookie";
|
||||
import ToastBox from "../../Components/ToastBox";
|
||||
import { useForgotPasswordMutation, useLoginMutation } from "../../Services/token.serivce";
|
||||
import * as Yup from "yup";
|
||||
import { EmailIcon, PhoneIcon } from "@chakra-ui/icons";
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
emailAddress: Yup.string()
|
||||
.email("Invalid email address")
|
||||
.required("Email address is required"),
|
||||
});
|
||||
|
||||
|
||||
const ForgotPassword = () => {
|
||||
const [show, setShow] = useState(false);
|
||||
const handleClick = () => setShow(!show);
|
||||
const { isAuthenticate, setIsAuthenticate } = useContext(GlobalStateContext);
|
||||
const toast = useToast();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [forgotPassword] = useForgotPasswordMutation()
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticate) {
|
||||
navigate("/sponser");
|
||||
}
|
||||
}, [navigate, isAuthenticate]);
|
||||
|
||||
|
||||
|
||||
|
||||
const onSubmit = async (value) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const res = await forgotPassword(value).unwrap();
|
||||
console.log(res);
|
||||
|
||||
if (res?.statusCode === 200) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.message} />
|
||||
),
|
||||
})
|
||||
setIsLoading(false);
|
||||
localStorage?.setItem("email", value?.emailAddress)
|
||||
localStorage?.setItem('code',res?.data)
|
||||
// setIsAuthenticate(true);
|
||||
// Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
navigate(`/otp-screen/${res?.data}`);
|
||||
reset();
|
||||
}else if(res?.error){
|
||||
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.error?.message} />
|
||||
),
|
||||
})
|
||||
setIsLoading(false);
|
||||
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
if (err) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"error"} message={err?.data?.message} />
|
||||
),
|
||||
});
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// if (value.emailAddress === "admin@optifii.com" && value.password_hash === "Admin@123") {
|
||||
// return setTimeout(() => {
|
||||
// // dispatch(loginUser(true));
|
||||
// setIsAuthenticate(true);
|
||||
// setIsLoading(false);
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"success"} message={"Login Successfully"} />
|
||||
// ),
|
||||
// });
|
||||
|
||||
// Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
// navigate("/");
|
||||
// }, 2000); // 3-second delay
|
||||
// } else {
|
||||
// return setTimeout(() => {
|
||||
// // dispatch(loginUser(true));
|
||||
// setIsAuthenticate(false);
|
||||
// setIsLoading(false);
|
||||
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"error"} message={"Invalid credentials"} />
|
||||
// ),
|
||||
// });
|
||||
// reset();
|
||||
// navigate("/login");
|
||||
// }, 2000);
|
||||
// }
|
||||
};
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
resolver: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
console.log(errors);
|
||||
|
||||
|
||||
return (
|
||||
<Box
|
||||
h={"100vh"}
|
||||
w={'100%'}
|
||||
display={'flex'}
|
||||
justifyContent={'end'}
|
||||
|
||||
overflow={'hidden'}
|
||||
// bg={'#EFEFEF'}
|
||||
bgGradient="linear(to-l, #3725EA, #5E0FCD)"
|
||||
>
|
||||
|
||||
<Box position={'relative'} display={'flex'} justifyContent={'center'} alignItems={'center'} w={'55%'}>
|
||||
<Image w={48} src={logo} />
|
||||
|
||||
</Box>
|
||||
<Box
|
||||
as="form"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
w={'45%'}
|
||||
backgroundColor={'#fff'}
|
||||
p={20}
|
||||
boxShadow={'md'}
|
||||
zIndex={2}
|
||||
|
||||
display={'flex'}
|
||||
justifyContent={'center'}
|
||||
alignItems={'start'}
|
||||
flexDirection={'column'}
|
||||
position={'relative'}
|
||||
shadow={'lg'}
|
||||
>
|
||||
<Box display={'flex'} flexDirection={'column'} gap={0} mb={8}>
|
||||
<Text as={'span'} fontSize={'xl'} fontWeight={600} >
|
||||
Forgot Password
|
||||
</Text>
|
||||
<Text as={'span'} fontSize={'sm'} fontWeight={400} color={'gray.500'}>
|
||||
Enter your Email Address
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<FormControl mb={6}>
|
||||
{/* <FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
|
||||
E-mail <span className="text-danger">*</span>
|
||||
</FormLabel> */}
|
||||
|
||||
|
||||
<InputGroup size={'lg'}>
|
||||
<InputLeftElement display={'flex'} alignItems={'center'} pointerEvents='none'>
|
||||
<EmailIcon color='gray.300' />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
{...register("emailAddress")}
|
||||
focusBorderColor="purple.500"
|
||||
type="text"
|
||||
name="emailAddress"
|
||||
variant="filled"
|
||||
placeholder="Email Address"
|
||||
size="lg"
|
||||
className="web-text-medium" />
|
||||
</InputGroup>
|
||||
{errors.emailAddress && (
|
||||
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
||||
<TiWarning className="fw-bold fs-5 " /> {errors.emailAddress.message}
|
||||
</span>
|
||||
)}
|
||||
</FormControl>
|
||||
|
||||
|
||||
|
||||
<Button
|
||||
isLoading={isLoading}
|
||||
type="submit"
|
||||
className="w-100"
|
||||
color={"whitesmoke"}
|
||||
bg="#5E0FCD"
|
||||
_hover={{bg:'#5E0FCD', opacity:0.9}}
|
||||
_active={{bg:"#5E0FCD", opacity:1}}
|
||||
size="md"
|
||||
fontWeight={400}
|
||||
fontSize={'sm'}
|
||||
mb={4}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
{/* <PrimaryButton type="submit" title={'Sent OTP'} w="100%"/> */}
|
||||
|
||||
{/* <Text onClick={()=> navigate('/forgot-password')} w={'100%'} color={'gray.500'} fontSize={'sm'} textAlign={'center'} >Forgot Password</Text> */}
|
||||
|
||||
<Text
|
||||
style={{
|
||||
position: "absolute",
|
||||
left:0,
|
||||
bottom: "0%",
|
||||
fontSize: "13px",
|
||||
color: "#919191",
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
Optifii v1.0.0
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Image
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
width: 350,
|
||||
}}
|
||||
src={Asset1}
|
||||
alt="bg-img"
|
||||
/>
|
||||
|
||||
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPassword;
|
||||
@@ -1,15 +1,15 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Input01 from "../Components/Inputs/Input01";
|
||||
import Input01 from "../../Components/Inputs/Input01";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { loginUser } from "../Redux/Slice/auth";
|
||||
import { loginUser } from "../../Redux/Slice/auth";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import Button01 from "../Components/Buttons/PrimaryButton";
|
||||
import Button01 from "../../Components/Buttons/PrimaryButton";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { TiWarning } from "react-icons/ti";
|
||||
import Loader01 from "../Components/Loaders/Loader01";
|
||||
import Asset1 from "../assets/loginpat.png";
|
||||
import logo from "../assets/optifii_white.svg";
|
||||
import Loader01 from "../../Components/Loaders/Loader01";
|
||||
import Asset1 from "../../assets/loginpat.png";
|
||||
import logo from "../../assets/optifii_white.svg";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -18,19 +18,18 @@ import {
|
||||
Image,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
InputRightElement,
|
||||
Text,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import GlobalStateContext from "../Contexts/GlobalStateContext";
|
||||
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
||||
import Cookies from "js-cookie";
|
||||
import ToastBox from "../Components/ToastBox";
|
||||
import { useLoginMutation } from "../Services/token.serivce";
|
||||
|
||||
|
||||
// import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import ToastBox from "../../Components/ToastBox";
|
||||
import { useLoginMutation } from "../../Services/token.serivce";
|
||||
import * as Yup from "yup";
|
||||
import PrimaryButton from "../Components/Buttons/PrimaryButton";
|
||||
import { EmailIcon, LockIcon, UnlockIcon } from "@chakra-ui/icons";
|
||||
import { PiPassword } from "react-icons/pi";
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
@@ -62,67 +61,74 @@ const Login = () => {
|
||||
|
||||
const onSubmit = async (value) => {
|
||||
setIsLoading(true);
|
||||
// try {
|
||||
// // const res = await login(value).unwrap();
|
||||
try {
|
||||
const res = await login(value).unwrap();
|
||||
console.log(res);
|
||||
|
||||
// if (res?.statusCode === 200) {
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"success"} message={"res?.message"} />
|
||||
// ),
|
||||
// })
|
||||
// setIsLoading(false);
|
||||
// setIsAuthenticate(true);
|
||||
// Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
// navigate("/sponser");
|
||||
// reset();
|
||||
// }
|
||||
if (res?.statusCode === 200) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.message} />
|
||||
),
|
||||
})
|
||||
setIsLoading(false);
|
||||
navigate(`/otp-screen/`)
|
||||
}else if(res?.error){
|
||||
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.error?.message} />
|
||||
),
|
||||
})
|
||||
setIsLoading(false);
|
||||
|
||||
// } catch (err) {
|
||||
// if (err) {
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
if (err) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"error"} message={err?.data?.message} />
|
||||
),
|
||||
});
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// if (value.emailAddress === "admin@optifii.com" && value.password_hash === "Admin@123") {
|
||||
// return setTimeout(() => {
|
||||
// // dispatch(loginUser(true));
|
||||
// setIsAuthenticate(true);
|
||||
// setIsLoading(false);
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"error"} message={err?.data?.message} />
|
||||
// <ToastBox status={"success"} message={"Login Successfully"} />
|
||||
// ),
|
||||
// });
|
||||
|
||||
// Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
// navigate("/");
|
||||
// }, 2000); // 3-second delay
|
||||
// } else {
|
||||
// return setTimeout(() => {
|
||||
// // dispatch(loginUser(true));
|
||||
// setIsAuthenticate(false);
|
||||
// setIsLoading(false);
|
||||
// }
|
||||
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"error"} message={"Invalid credentials"} />
|
||||
// ),
|
||||
// });
|
||||
// reset();
|
||||
// navigate("/login");
|
||||
// }, 2000);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (value.emailAddress === "admin@optifii.com" && value.password_hash === "Admin@123") {
|
||||
return setTimeout(() => {
|
||||
// dispatch(loginUser(true));
|
||||
setIsAuthenticate(true);
|
||||
setIsLoading(false);
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={"Login Successfully"} />
|
||||
),
|
||||
});
|
||||
|
||||
Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
navigate("/");
|
||||
}, 2000); // 3-second delay
|
||||
} else {
|
||||
return setTimeout(() => {
|
||||
// dispatch(loginUser(true));
|
||||
setIsAuthenticate(false);
|
||||
setIsLoading(false);
|
||||
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"error"} message={"Invalid credentials"} />
|
||||
),
|
||||
});
|
||||
reset();
|
||||
navigate("/login");
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
const {
|
||||
@@ -183,6 +189,11 @@ const Login = () => {
|
||||
E-mail <span className="text-danger">*</span>
|
||||
</FormLabel> */}
|
||||
|
||||
<InputGroup size={'lg'}>
|
||||
<InputLeftElement display={'flex'} alignItems={'center'} pointerEvents='none'>
|
||||
<EmailIcon color='gray.300' />
|
||||
</InputLeftElement>
|
||||
|
||||
<Input
|
||||
{...register("emailAddress")}
|
||||
focusBorderColor="purple.500"
|
||||
@@ -193,6 +204,7 @@ const Login = () => {
|
||||
size="lg"
|
||||
className="web-text-medium"
|
||||
/>
|
||||
</InputGroup>
|
||||
{errors.emailAddress && (
|
||||
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
||||
<TiWarning className="fw-bold fs-5 " /> {errors.emailAddress.message}
|
||||
@@ -205,7 +217,12 @@ const Login = () => {
|
||||
Password <span className="text-danger">*</span>
|
||||
</FormLabel> */}
|
||||
|
||||
|
||||
|
||||
<InputGroup size="lg">
|
||||
<InputLeftElement display={'flex'} alignItems={'center'} pointerEvents='none'>
|
||||
{show? <UnlockIcon color='gray.300' />: <LockIcon color='gray.300' />}
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
{...register("password_hash")}
|
||||
className="web-text-medium"
|
||||
@@ -252,7 +269,7 @@ const Login = () => {
|
||||
</Button>
|
||||
{/* <PrimaryButton type="submit" title={'Sent OTP'} w="100%"/> */}
|
||||
|
||||
<Text w={'100%'} color={'gray.500'} fontSize={'sm'} textAlign={'center'} >Forgot Password</Text>
|
||||
<Text cursor={'pointer'} onClick={()=> navigate('/forgot-password')} w={'100%'} color={'gray.500'} fontSize={'sm'} textAlign={'center'} >Forgot Password</Text>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
254
src/Pages/Login/OtpScreen.jsx
Normal file
254
src/Pages/Login/OtpScreen.jsx
Normal file
@@ -0,0 +1,254 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import Input01 from "../../Components/Inputs/Input01";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { loginUser } from "../../Redux/Slice/auth";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import Button01 from "../../Components/Buttons/PrimaryButton";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { TiWarning } from "react-icons/ti";
|
||||
import Loader01 from "../../Components/Loaders/Loader01";
|
||||
import Asset1 from "../../assets/loginpat.png";
|
||||
import logo from "../../assets/optifii_white.svg";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
HStack,
|
||||
Image,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
InputRightElement,
|
||||
PinInput,
|
||||
PinInputField,
|
||||
Text,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
||||
import Cookies from "js-cookie";
|
||||
import ToastBox from "../../Components/ToastBox";
|
||||
import {
|
||||
useForgotPasswordMutation,
|
||||
useLoginMutation,
|
||||
useResendOtpMutation,
|
||||
useResetPasswordMutation,
|
||||
} from "../../Services/token.serivce";
|
||||
import * as Yup from "yup";
|
||||
import { EmailIcon, PhoneIcon } from "@chakra-ui/icons";
|
||||
|
||||
const OtpScreen = () => {
|
||||
const params = useParams()
|
||||
const [show, setShow] = useState(false);
|
||||
const handleClick = () => setShow(!show);
|
||||
const { isAuthenticate, setIsAuthenticate } = useContext(GlobalStateContext);
|
||||
const toast = useToast();
|
||||
|
||||
const [pin, setPin] = useState(""); // State to store pin value
|
||||
|
||||
// Handle pin change
|
||||
const handlePinChange = (value) => {
|
||||
setPin(value);
|
||||
};
|
||||
|
||||
console.log(pin);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [resendPassword] = useResendOtpMutation();
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticate) {
|
||||
navigate("/sponser");
|
||||
}
|
||||
}, [navigate, isAuthenticate]);
|
||||
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
|
||||
if (params?.id) {
|
||||
// 3-second delay before navigating to "/reset-password"
|
||||
setTimeout(() => {
|
||||
navigate("/reset-password");
|
||||
setIsLoading(false);
|
||||
}, 3000);
|
||||
} else {
|
||||
// 3-second delay before setting authentication, setting cookies, and navigating
|
||||
setTimeout(() => {
|
||||
setIsAuthenticate(true);
|
||||
setIsLoading(false);
|
||||
Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
navigate("/");
|
||||
reset();
|
||||
}, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleResendOtp = async () => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try {
|
||||
const res = await resendPassword().unwrap();
|
||||
console.log(res);
|
||||
if (res?.statusCode === 200) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.message} />
|
||||
),
|
||||
})
|
||||
|
||||
}else if(res?.error){
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.error?.message} />
|
||||
),
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
if (err) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"error"} message={err?.data?.message} />
|
||||
),
|
||||
});
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Box
|
||||
h={"100vh"}
|
||||
w={"100%"}
|
||||
display={"flex"}
|
||||
justifyContent={"end"}
|
||||
overflow={"hidden"}
|
||||
// bg={'#EFEFEF'}
|
||||
bgGradient="linear(to-l, #3725EA, #5E0FCD)"
|
||||
>
|
||||
<Box
|
||||
position={"relative"}
|
||||
display={"flex"}
|
||||
justifyContent={"center"}
|
||||
alignItems={"center"}
|
||||
w={"55%"}
|
||||
>
|
||||
<Image w={48} src={logo} />
|
||||
</Box>
|
||||
<Box
|
||||
as="form"
|
||||
onSubmit={onSubmit}
|
||||
w={"45%"}
|
||||
backgroundColor={"#fff"}
|
||||
p={20}
|
||||
boxShadow={"md"}
|
||||
zIndex={2}
|
||||
display={"flex"}
|
||||
justifyContent={"center"}
|
||||
alignItems={"start"}
|
||||
flexDirection={"column"}
|
||||
position={"relative"}
|
||||
shadow={"lg"}
|
||||
>
|
||||
<Box display={"flex"} flexDirection={"column"} gap={0} mb={8}>
|
||||
<Text as={"span"} fontSize={"xl"} fontWeight={600}>
|
||||
Forgot Password
|
||||
</Text>
|
||||
<Text as={"span"} fontSize={"sm"} fontWeight={400} color={"gray.500"}>
|
||||
Enter OTP send to {localStorage?.getItem("email")}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<FormControl mb={6}>
|
||||
|
||||
<HStack justifyContent={"center"}>
|
||||
<PinInput
|
||||
value={pin}
|
||||
onChange={handlePinChange}
|
||||
size="md"
|
||||
type="alphanumeric"
|
||||
mask
|
||||
|
||||
>
|
||||
<PinInputField mx={1} />
|
||||
<PinInputField mx={1} />
|
||||
<PinInputField mx={1} />
|
||||
<PinInputField mx={1} />
|
||||
<PinInputField mx={1} />
|
||||
<PinInputField mx={1} />
|
||||
</PinInput>
|
||||
</HStack>
|
||||
|
||||
|
||||
|
||||
<HStack mt={2} fontWeight={600} fontSize={'xs'} justify={'end'} w={'100%'}>
|
||||
{/* <Text>Resend Otp</Text> */}
|
||||
<Text onClick={handleResendOtp} cursor={'pointer'}>Resend Otp</Text>
|
||||
</HStack>
|
||||
</FormControl>
|
||||
|
||||
<Button
|
||||
isLoading={isLoading}
|
||||
type="submit"
|
||||
className="w-100"
|
||||
color={"whitesmoke"}
|
||||
bg="#5E0FCD"
|
||||
_hover={{ bg: "#5E0FCD", opacity: 0.9 }}
|
||||
_active={{ bg: "#5E0FCD", opacity: 1 }}
|
||||
size="md"
|
||||
fontWeight={400}
|
||||
fontSize={"sm"}
|
||||
mb={4}
|
||||
>
|
||||
Verify
|
||||
</Button>
|
||||
{/* <PrimaryButton type="submit" title={'Sent OTP'} w="100%"/> */}
|
||||
|
||||
{/* <Text onClick={()=> navigate('/forgot-password')} w={'100%'} color={'gray.500'} fontSize={'sm'} textAlign={'center'} >Forgot Password</Text> */}
|
||||
|
||||
<Text
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
bottom: "0%",
|
||||
fontSize: "13px",
|
||||
color: "#919191",
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
Optifii v1.0.0
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Image
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
width: 350,
|
||||
}}
|
||||
src={Asset1}
|
||||
alt="bg-img"
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default OtpScreen;
|
||||
336
src/Pages/Login/ResetPassword.jsx
Normal file
336
src/Pages/Login/ResetPassword.jsx
Normal file
@@ -0,0 +1,336 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Input01 from "../../Components/Inputs/Input01";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { loginUser } from "../../Redux/Slice/auth";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import Button01 from "../../Components/Buttons/PrimaryButton";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { TiWarning } from "react-icons/ti";
|
||||
import Loader01 from "../../Components/Loaders/Loader01";
|
||||
import Asset1 from "../../assets/loginpat.png";
|
||||
import logo from "../../assets/optifii_white.svg";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Image,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
InputRightElement,
|
||||
Text,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import GlobalStateContext from "../../Contexts/GlobalStateContext";
|
||||
import Cookies from "js-cookie";
|
||||
import ToastBox from "../../Components/ToastBox";
|
||||
import { useLoginMutation, useResetPasswordMutation } from "../../Services/token.serivce";
|
||||
import * as Yup from "yup";
|
||||
import { LockIcon, UnlockIcon } from "@chakra-ui/icons";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
password: Yup.string()
|
||||
.required("Password is required")
|
||||
.min(6, "Password must be at least 6 characters long"), // Example constraint
|
||||
|
||||
confirmPassword: Yup.string()
|
||||
.oneOf([Yup.ref('password'), null], "Passwords must match") // Match password field
|
||||
.required("Confirm Password is required"),
|
||||
});
|
||||
|
||||
const ResetPassword = () => {
|
||||
const [show, setShow] = useState(false);
|
||||
const [showConfirm, setShowConfirm] = useState(false);
|
||||
const handleClick = () => setShow(!show);
|
||||
const handleClickConfirm = () => setShowConfirm(!showConfirm);
|
||||
const { isAuthenticate, setIsAuthenticate } = useContext(GlobalStateContext);
|
||||
const toast = useToast();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [resetPassword] = useResetPasswordMutation();
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticate) {
|
||||
navigate("/sponser");
|
||||
}
|
||||
}, [navigate, isAuthenticate]);
|
||||
|
||||
const onSubmit = async (value) => {
|
||||
setIsLoading(true);
|
||||
const data = {
|
||||
...value,
|
||||
code:localStorage?.getItem('code')
|
||||
}
|
||||
|
||||
console.log(value);
|
||||
|
||||
try {
|
||||
const res = await resetPassword(data).unwrap();
|
||||
console.log(res);
|
||||
|
||||
if (res?.statusCode === 200) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.message} />
|
||||
),
|
||||
})
|
||||
setIsLoading(false);
|
||||
setIsAuthenticate(true);
|
||||
Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
// navigate("/sponser");
|
||||
// reset();
|
||||
}else if(res?.error){
|
||||
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"success"} message={res?.error?.message} />
|
||||
),
|
||||
})
|
||||
setIsLoading(false);
|
||||
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
if (err) {
|
||||
toast({
|
||||
render: () => (
|
||||
<ToastBox status={"error"} message={err?.data?.message} />
|
||||
),
|
||||
});
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// if (value.emailAddress === "admin@optifii.com" && value.password_hash === "Admin@123") {
|
||||
// return setTimeout(() => {
|
||||
// // dispatch(loginUser(true));
|
||||
// setIsAuthenticate(true);
|
||||
// setIsLoading(false);
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"success"} message={"Login Successfully"} />
|
||||
// ),
|
||||
// });
|
||||
|
||||
// Cookies.set("isAuthenticated", true, { expires: 7 });
|
||||
// navigate("/");
|
||||
// }, 2000); // 3-second delay
|
||||
// } else {
|
||||
// return setTimeout(() => {
|
||||
// // dispatch(loginUser(true));
|
||||
// setIsAuthenticate(false);
|
||||
// setIsLoading(false);
|
||||
|
||||
// toast({
|
||||
// render: () => (
|
||||
// <ToastBox status={"error"} message={"Invalid credentials"} />
|
||||
// ),
|
||||
// });
|
||||
// reset();
|
||||
// navigate("/login");
|
||||
// }, 2000);
|
||||
// }
|
||||
};
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
resolver: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
console.log(errors);
|
||||
|
||||
|
||||
return (
|
||||
<Box
|
||||
h={"100vh"}
|
||||
w={'100%'}
|
||||
display={'flex'}
|
||||
justifyContent={'end'}
|
||||
|
||||
overflow={'hidden'}
|
||||
// bg={'#EFEFEF'}
|
||||
bgGradient="linear(to-l, #3725EA, #5E0FCD)"
|
||||
>
|
||||
|
||||
<Box position={'relative'} display={'flex'} justifyContent={'center'} alignItems={'center'} w={'55%'}>
|
||||
<Image w={48} src={logo} />
|
||||
|
||||
</Box>
|
||||
<Box
|
||||
as="form"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
w={'45%'}
|
||||
backgroundColor={'#fff'}
|
||||
p={20}
|
||||
boxShadow={'md'}
|
||||
zIndex={2}
|
||||
|
||||
display={'flex'}
|
||||
justifyContent={'center'}
|
||||
alignItems={'start'}
|
||||
flexDirection={'column'}
|
||||
position={'relative'}
|
||||
shadow={'lg'}
|
||||
>
|
||||
<Box display={'flex'} flexDirection={'column'} gap={0} mb={8}>
|
||||
<Text as={'span'} fontSize={'xl'} fontWeight={600} >
|
||||
Reset Password
|
||||
</Text>
|
||||
<Text as={'span'} fontSize={'sm'} fontWeight={400} color={'gray.500'}>
|
||||
Please create a new Password
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<FormControl mb={7}>
|
||||
{/* <FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
|
||||
Password <span className="text-danger">*</span>
|
||||
</FormLabel> */}
|
||||
|
||||
<InputGroup size="lg">
|
||||
<InputLeftElement display={'flex'} alignItems={'center'} pointerEvents='none'>
|
||||
{show? <UnlockIcon color='gray.300' />: <LockIcon color='gray.300' />}
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
{...register("password")}
|
||||
className="web-text-medium"
|
||||
focusBorderColor="purple.500"
|
||||
variant="filled"
|
||||
pr="4.5rem"
|
||||
type={show ? "text" : "password"}
|
||||
placeholder="Create new password"
|
||||
/>
|
||||
<InputRightElement width="4.5rem">
|
||||
<Button
|
||||
h="1.75rem"
|
||||
size="sm"
|
||||
fontSize={"xs"}
|
||||
color={"purple.800"}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{show ? "Hide" : "Show"}
|
||||
</Button>
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
{errors.password && (
|
||||
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
||||
<TiWarning className="fw-bold fs-5 " /> {errors.password.message}
|
||||
</span>
|
||||
)}
|
||||
</FormControl>
|
||||
|
||||
|
||||
<FormControl mb={7}>
|
||||
{/* <FormLabel className="rubix-text-dark ps-1 web-text-medium fw-bold">
|
||||
Password <span className="text-danger">*</span>
|
||||
</FormLabel> */}
|
||||
|
||||
<InputGroup size="lg">
|
||||
|
||||
<InputLeftElement display={'flex'} alignItems={'center'} pointerEvents='none'>
|
||||
{showConfirm? <UnlockIcon color='gray.300' />: <LockIcon color='gray.300' />}
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
{...register("confirmPassword")}
|
||||
className="web-text-medium"
|
||||
focusBorderColor="purple.500"
|
||||
variant="filled"
|
||||
pr="4.5rem"
|
||||
type={showConfirm ? "text" : "password"}
|
||||
placeholder="Confirm new password"
|
||||
|
||||
/>
|
||||
<InputRightElement width="4.5rem">
|
||||
<Button
|
||||
h="1.75rem"
|
||||
size="sm"
|
||||
fontSize={"xs"}
|
||||
color={"purple.800"}
|
||||
onClick={handleClickConfirm}
|
||||
>
|
||||
{showConfirm ? "Hide" : "Show"}
|
||||
</Button>
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
{errors.confirmPassword && (
|
||||
<span className="text-danger web-text-small fw-bold ps-2 d-flex align-items-center gap-1 mt-1">
|
||||
<TiWarning className="fw-bold fs-5 " /> {errors.confirmPassword.message}
|
||||
</span>
|
||||
)}
|
||||
</FormControl>
|
||||
|
||||
|
||||
<Button
|
||||
isLoading={isLoading}
|
||||
type="submit"
|
||||
className="w-100"
|
||||
color={"whitesmoke"}
|
||||
bg="#5E0FCD"
|
||||
_hover={{bg:'#5E0FCD', opacity:0.9}}
|
||||
_active={{bg:"#5E0FCD", opacity:1}}
|
||||
size="md"
|
||||
fontWeight={400}
|
||||
fontSize={'sm'}
|
||||
mb={4}
|
||||
>
|
||||
Reset Password
|
||||
</Button>
|
||||
{/* <PrimaryButton type="submit" title={'Sent OTP'} w="100%"/> */}
|
||||
|
||||
{/* <Text onClick={()=> navigate('/forgot-password')} w={'100%'} color={'gray.500'} fontSize={'sm'} textAlign={'center'} >Forgot Password</Text> */}
|
||||
|
||||
<Text
|
||||
style={{
|
||||
position: "absolute",
|
||||
left:0,
|
||||
bottom: "0%",
|
||||
fontSize: "13px",
|
||||
color: "#919191",
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
zIndex: 2,
|
||||
}}
|
||||
>
|
||||
Optifii v1.0.0
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Image
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
width: 350,
|
||||
}}
|
||||
src={Asset1}
|
||||
alt="bg-img"
|
||||
/>
|
||||
|
||||
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResetPassword;
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
// Define a base query function with RTK Query
|
||||
// export const baseQuery = fetchBaseQuery({
|
||||
@@ -13,9 +14,11 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||
// });
|
||||
|
||||
// Define a base query function with token refresh logic
|
||||
|
||||
console.log(import.meta.env.VITE_BASE_URL);
|
||||
export const baseQuery = async (args, api, extraOptions) => {
|
||||
let result = await fetchBaseQuery({
|
||||
baseUrl: import.meta.env.VITE_BAS_URL,
|
||||
baseUrl: import.meta.env.VITE_BASE_URL,
|
||||
prepareHeaders: (headers) => {
|
||||
const token = localStorage.getItem("accessToken");
|
||||
if (token) {
|
||||
@@ -31,10 +34,10 @@ export const baseQuery = async (args, api, extraOptions) => {
|
||||
// if (refreshToken) {
|
||||
// try {
|
||||
// const refreshResult = await fetchBaseQuery({
|
||||
// baseUrl: import.meta.env.VITE_BAS_URL,
|
||||
// baseUrl: import.meta.env.VITE_BASE_URL,
|
||||
// })(
|
||||
// {
|
||||
// url: "/auth/user/regenerate-token",
|
||||
// url: "/regenerate-token",
|
||||
// method: "POST",
|
||||
// body: { refreshToken },
|
||||
// },
|
||||
@@ -56,7 +59,7 @@ export const baseQuery = async (args, api, extraOptions) => {
|
||||
|
||||
// // Retry the original request with the new token
|
||||
// result = await fetchBaseQuery({
|
||||
// baseUrl: import.meta.env.VITE_BAS_URL,
|
||||
// baseUrl: import.meta.env.VITE_BASE_URL,
|
||||
// prepareHeaders: (headers) => {
|
||||
// const token = localStorage.getItem("accessToken");
|
||||
// if (token) {
|
||||
@@ -105,6 +108,7 @@ export const apiSlice = createApi({
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
refreshToken: builder.mutation({
|
||||
query: (refreshToken) => ({
|
||||
url: "/auth/user/regenerate-token",
|
||||
@@ -112,7 +116,45 @@ export const apiSlice = createApi({
|
||||
body: { refreshToken },
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
forgotPassword: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: "/auth/admin/forget-password",
|
||||
method: "POST",
|
||||
body: data ,
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
|
||||
|
||||
resetPassword: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: "/auth/admin/reset-password",
|
||||
method: "POST",
|
||||
body: data ,
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
resendOtp: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: "/auth/admin/resend-otp",
|
||||
method: "POST",
|
||||
body: data ,
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useLoginMutation, useRefreshTokenMutation } = apiSlice;
|
||||
export const { useLoginMutation, useRefreshTokenMutation, useForgotPasswordMutation, useResetPasswordMutation,useResendOtpMutation } = apiSlice;
|
||||
|
||||
Reference in New Issue
Block a user