Viewing File: /home/ubuntu/voice-assistant-frontend/src/components/Auth/LoginIndex.jsx
import React, { useEffect, useState } from "react";
import { Form, Button, Image, InputGroup, Row, Col } from "react-bootstrap";
import { Link, useNavigate } from "react-router-dom";
import { useTranslation } from "react-multi-lang";
import { useDispatch, useSelector } from "react-redux";
import { Formik, Form as FORM, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import { loginStart, registerStart } from "../../store/slices/AdminSlice";
import OTPVerificationModal from "./OtpVerificationModal.jsx";
import { ButtonLoader } from "../Helper/Loader";
import AuthSection from "./AuthSection.jsx";
import configuration from "react-global-configuration";
import SocialButton from "../Helper/SocialButton.jsx";
const LoginIndex = (props) => {
const t = useTranslation("login");
const dispatch = useDispatch();
const navigate = useNavigate();
const login = useSelector((state) => state.admin.login);
const emailVerify = useSelector(state => state.admin.emailVerify);
const [skipRender, setSkipRender] = useState(true);
const [showOTPVerifyModal, setShowOTPVerifyModal] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const loginSchema = Yup.object().shape({
email: Yup.string().email(t("email.invalid")).required(t("email.required")),
password: Yup.string()
.required(t("password.required"))
.matches(/^\S+$/, t("password.space_invalid"))
.matches(/[A-Z]/, t("password.invalid"))
.matches(/[0-9]/, t("password.number_invalid"))
.matches(/[\W_]/, t("password.special_character_invalid"))
.min(6, t("password.min_length_invalid")),
});
const handleLogin = (values) => {
dispatch(loginStart(values));
};
const togglePasswordVisibility = () => {
setShowPassword(!showPassword);
};
useEffect(() => {
if (
!skipRender &&
!login.loading &&
Object.keys(login.data).length > 0
) {
if(login.data.email_status == 0){
setShowOTPVerifyModal({
...login.data,
type: "email"
});
}
else if (login.data.tfa_status == 1)
setShowOTPVerifyModal({
...login.data,
type: "2fa"
});
else
navigate("/")
}
}, [login]);
useEffect(() => {
if (
!skipRender &&
!emailVerify.loading &&
Object.keys(emailVerify.data).length > 0
) {
navigate('/generated-voice-list')
}
setSkipRender(false);
}, [emailVerify]);
// social logins
const handleFacebookLogin = (user) => {
console.log("handleFacebookLogin", user._profile);
props.dispatch(
registerStart({
name: user._profile.name,
first_name: user._profile.firstName ? user._profile.firstName : "",
last_name: user._profile.lastName ? user._profile.lastName : "",
email: user._profile.email ? user._profile.email : "",
social_unique_id: user._profile.id,
picture: user._profile.profilePicURL,
login_by: "facebook",
})
);
};
const handleGoogleLogin = (user) => {
console.log("handleGoogleLogin", user._profile);
props.dispatch(
registerStart({
name: user._profile.name,
email: user._profile.email,
first_name: user._profile.firstName ? user._profile.firstName : "",
last_name: user._profile.lastName ? user._profile.lastName : "",
social_unique_id: user._profile.id,
picture: user._profile.profilePicURL,
login_by: "google",
})
);
};
const handleSocialLoginFailure = (err) => {
console.error(err);
};
return (
<>
<div className="auth-sec">
<div className="auth-box">
<AuthSection/>
<div className="auth-right-sec">
<div className="auth-right-box">
<Row className="justify-content-md-center">
<Col md={10}>
<Formik
initialValues={{
email: "",
password: "",
}}
validationSchema={loginSchema}
onSubmit={handleLogin}
>
{({ setFieldValue, values }) => (
<FORM className="auth-form-sec">
<div className="auth-form-card">
<h3>{t("heading")}</h3>
<div className="auth-social-link-box">
<div className="auth-social-link-card">
{configuration.get("configData.FB_CLIENT_ID") ?
<SocialButton
provider="facebook"
appId={configuration.get("configData.FB_CLIENT_ID")}
onLoginSuccess={handleFacebookLogin}
onLoginFailure={handleSocialLoginFailure}
className="auth-social-btn"
id="facebook-connect"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-brand-facebook"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="#878E96"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
stroke="none"
d="M0 0h24v24H0z"
fill="none"
/>
<path d="M7 10v4h3v7h4v-7h3l1 -4h-4v-2a1 1 0 0 1 1 -1h3v-4h-3a5 5 0 0 0 -5 5v2h-3" />
</svg>
{t("facebook_signin_heading")}
</SocialButton>
:
null
}
{configuration.get("configData.GOOGLE_CLIENT_ID") ?
<SocialButton
provider="google"
key={"google"}
appId={configuration.get("configData.GOOGLE_CLIENT_ID")}
onLoginSuccess={handleGoogleLogin}
onLoginFailure={handleSocialLoginFailure}
className="auth-social-btn"
id="google-connect"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-brand-google"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="#878E96"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
stroke="none"
d="M0 0h24v24H0z"
fill="none"
/>
<path d="M20.945 11a9 9 0 1 1 -3.284 -5.997l-2.655 2.392a5.5 5.5 0 1 0 2.119 6.605h-4.125v-3h7.945z" />
</svg>
{t("google_signin_heading")}
</SocialButton>
:
null
}
</div>
</div>
{configuration.get("configData.FB_CLIENT_ID") || configuration.get("configData.GOOGLE_CLIENT_ID") ? <div className="divider-separtor-sec">
<span>Or with</span>
</div>:null}
<InputGroup className="mb-3">
<InputGroup.Text id="basic-addon1">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-mail"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="#878E96"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z" />
<path d="M3 7l9 6l9 -6" />
</svg>
</InputGroup.Text>
<Field
className="form-control"
placeholder={t("email.placeholder")}
type="email"
autoFocus={true}
name="email"
/>
</InputGroup>
<ErrorMessage
component={"div"}
name="email"
className="errorMsg"
/>
<InputGroup className="mb-3 auth-input-group">
<InputGroup.Text>
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-lock"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="#878E96"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z" />
<path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0" />
<path d="M8 11v-4a4 4 0 1 1 8 0v4" />
</svg>
</InputGroup.Text>
<Field
className="form-control"
placeholder={t("password.placeholder")}
type={showPassword ? "text" : "password"}
name="password"
aria-label="Username"
aria-describedby="basic-addon1"
/>
<InputGroup.Text
id="basic-addon1"
className="border-right-input"
onClick={togglePasswordVisibility}
>
{!showPassword ? (<svg
xmlns="http://www.w3.org/2000/svg"
class="icon icon-tabler icon-tabler-eye"
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="#878E96"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
</svg>) : (<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-eye-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" /><path d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" /><path d="M3 3l18 18" /></svg>)
}
</InputGroup.Text>
</InputGroup>
<ErrorMessage
component={"div"}
name="password"
className="errorMsg"
/>
<div className="forgot-password-link-sec">
<Link
to="/forgot-password"
className="forgot-password-link"
>
{t("forgot")}
</Link>
</div>
<div className="auth-btn-sec">
<Button type="submit" className="default-btn" disabled={login.buttonDisable}>
{login.buttonDisable ? (
<ButtonLoader varient="black" />
) : (
t("login_btn.text")
)}
</Button>
</div>
</div>
<div className="auth-footer-sec">
<Link to="/register">{t("register")}</Link>
</div>
<div className="auth-review-sec">
<p>
{t("review")}
<Link to="/page/terms">{t("terms_condition")}</Link>
{t("and")}
<Link to="/page/privacy">{t("privacy_policy")}</Link>
</p>
</div>
</FORM>
)}
</Formik>
</Col>
</Row>
</div>
</div>
</div>
</div>
{showOTPVerifyModal ?
<OTPVerificationModal OTPVerify={showOTPVerifyModal} closeShowOTPVerify={() => setShowOTPVerifyModal(false)} setShowOTPVerifyModal={setShowOTPVerifyModal} />
: null}
</>
);
};
export default LoginIndex;
Back to Directory
File Manager