first commit
This commit is contained in:
@@ -0,0 +1,477 @@
|
||||
"use client";
|
||||
import { useSessionStore, useSessionTokenStore } from "@store/Sesion.Store";
|
||||
import { ApiError } from "@models/Server.Error.model";
|
||||
import { ISession } from "@models/Session.model";
|
||||
import EvangelizeBanner from "@components/EvangelizeBanner/EvangelizeBanner";
|
||||
import {
|
||||
login,
|
||||
loginAndVerificate,
|
||||
recoveryAccountWithCode,
|
||||
sendRecoveryCode,
|
||||
} from "@services/Session.Login";
|
||||
import Checkbox from "@mui/material/Checkbox";
|
||||
import Textbox from "@components/Textbox/Textbox";
|
||||
import Button from "@components/Button/Button";
|
||||
import ButtonGoogle from "./LoginGoogle";
|
||||
import { GoogleOAuthProvider } from "@react-oauth/google";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import * as Yup from "yup";
|
||||
import { useAlert } from "@store/Alert.Store";
|
||||
import Link from "next/link";
|
||||
import AnimatedContainer from "@components/AnimatedConainer/AnimatedContainer";
|
||||
import { LOGIN_ACTIONS, useLoginActionStore } from "@core/Store/LoginAction.Store";
|
||||
import HeaderConfProvider from "../../HeaderConfProvider/HeaderConfProvider";
|
||||
import { EVENT_TYPES, useEventHandlerStore } from "@core/Store/EventHandler.Store";
|
||||
import { ScrollToTop } from "@core/app/components/ScrollTop";
|
||||
import { useNavigation } from "@core/app/hooks/goto";
|
||||
|
||||
interface LoginProps {
|
||||
verification?: boolean;
|
||||
recovery?: boolean;
|
||||
recoveryCode?: boolean;
|
||||
}
|
||||
export default function Login(props: LoginProps) {
|
||||
const { verification = false, recovery = false, recoveryCode = false } = props;
|
||||
const router = useRouter();
|
||||
const loginAction = useLoginActionStore();
|
||||
const SessionInfo = useSessionStore();
|
||||
const SessionToken = useSessionTokenStore();
|
||||
const alert = useAlert();
|
||||
const eventHandler = useEventHandlerStore();
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [verificationCode, setVerificationCode] = useState("");
|
||||
const [checkReadTerms, setCheckReadTerms] = useState(false);
|
||||
|
||||
const clientId = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || "";
|
||||
|
||||
const { goTo } = useNavigation();
|
||||
|
||||
const createSession = (userSession: ISession, msg: string) => {
|
||||
SessionInfo.setUser(userSession);
|
||||
SessionToken.setToken(userSession.userToken);
|
||||
SessionInfo.setLoginState("success");
|
||||
alert.showSuccess(msg);
|
||||
};
|
||||
|
||||
const manageLoginActions = () => {
|
||||
const toUrl = process.env.NEXT_PUBLIC_DEFAULT_PATH_AFTER_LOGIN || "/";
|
||||
if (loginAction.action !== LOGIN_ACTIONS.NONE) {
|
||||
goTo(loginAction.url);
|
||||
loginAction.clear();
|
||||
} else {
|
||||
if (SessionInfo.subscription && SessionInfo.subscription.plan) {
|
||||
goTo("/landing/dashboard");
|
||||
return;
|
||||
}
|
||||
|
||||
goTo(toUrl);
|
||||
}
|
||||
};
|
||||
|
||||
const clearSession = (msg: string) => {
|
||||
SessionInfo.clear();
|
||||
SessionToken.setToken("");
|
||||
alert.showError(msg);
|
||||
SessionInfo.setLoginState("error");
|
||||
};
|
||||
|
||||
const verificateLogin = () => {
|
||||
const schema = Yup.object().shape({
|
||||
verificationCode: Yup.string()
|
||||
.length(6, "El código de verificacion debe tener 6 digitos")
|
||||
.required("El código de verificacion es obligatorio."),
|
||||
password: Yup.string()
|
||||
.min(8, "La contraseña debe tener al menos 8 caracteres.")
|
||||
.required("El campo de contraseña es obligatorio."),
|
||||
email: Yup.string()
|
||||
.email("Debe ingresar un correo electrónico válido.")
|
||||
.required("El campo de correo electrónico es obligatorio."),
|
||||
});
|
||||
|
||||
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
||||
schema
|
||||
.validate({ email, password, verificationCode }, { abortEarly: true, strict: true })
|
||||
.then(() => {
|
||||
SessionInfo.setLoginState("started");
|
||||
loginAndVerificate(email, password, verificationCode)
|
||||
.then((userSession: ISession) => {
|
||||
createSession(
|
||||
userSession,
|
||||
"Registro compleatado. Bienvenido a turnosXpress."
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
clearSession(error.format());
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
const e = error as Yup.ValidationError;
|
||||
clearSession("Ha ocurrido un error. Por favor intentelo nuevamente. " + e.message);
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
};
|
||||
|
||||
const sendRecoveryMail = () => {
|
||||
const schema = Yup.object().shape({
|
||||
email: Yup.string()
|
||||
.email("Debe ingresar un correo electrónico válido.")
|
||||
.required("El campo de correo electrónico es obligatorio."),
|
||||
});
|
||||
|
||||
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
||||
schema
|
||||
.validate({ email }, { abortEarly: true, strict: true })
|
||||
.then(() => {
|
||||
SessionInfo.setLoginState("started");
|
||||
sendRecoveryCode(email)
|
||||
.then(() => {
|
||||
alert.showSuccess(
|
||||
"Se ha enviado un correo de recuperación a la cuenta indicada."
|
||||
);
|
||||
setTimeout(() => {
|
||||
router.push("/landing/recover-account/verify");
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
clearSession(error.format());
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
const e = error as Yup.ValidationError;
|
||||
clearSession(e.message);
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
};
|
||||
|
||||
const recoveryAccount = () => {
|
||||
const schema = Yup.object().shape({
|
||||
email: Yup.string()
|
||||
.email("Debe ingresar un correo electrónico válido.")
|
||||
.required("El campo de correo electrónico es obligatorio."),
|
||||
verificationCode: Yup.string()
|
||||
.length(6, "El código de verificación debe tener 6 digitos")
|
||||
.required("El código de verificacion es obligatorio."),
|
||||
password: Yup.string()
|
||||
.min(8, "La contraseña debe tener al menos 8 caracteres.")
|
||||
.required("El campo de contraseña es obligatorio."),
|
||||
});
|
||||
|
||||
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
||||
schema
|
||||
.validate({ email, verificationCode, password }, { abortEarly: true, strict: true })
|
||||
.then(() => {
|
||||
recoveryAccountWithCode(email, password, verificationCode)
|
||||
.then(() => {
|
||||
alert.showSuccess("Se ha cambiado la contraseña de la cuenta indicada.");
|
||||
setTimeout(() => {
|
||||
goTo("/landing/login");
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
clearSession(error.format());
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
const e = error as Yup.ValidationError;
|
||||
clearSession(e.message);
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
};
|
||||
|
||||
const iniciarSesion = () => {
|
||||
const schema = Yup.object().shape({
|
||||
email: Yup.string()
|
||||
.email("Debe ingresar un correo electrónico válido.")
|
||||
.required("El campo de correo electrónico es obligatorio."),
|
||||
password: Yup.string()
|
||||
.min(8, "La contraseña debe tener al menos 8 caracteres.")
|
||||
.required("El campo de contraseña es obligatorio."),
|
||||
});
|
||||
|
||||
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
||||
|
||||
schema
|
||||
.validate({ email, password }, { abortEarly: false })
|
||||
.then(() => {
|
||||
SessionInfo.setLoginState("started");
|
||||
login(email, password)
|
||||
.then((userSession: ISession) => {
|
||||
createSession(userSession, "Has iniciado sesión correctamente!");
|
||||
})
|
||||
.catch((error: ApiError) => {
|
||||
clearSession(error.format());
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
let errorDesc = "";
|
||||
if (error instanceof Yup.ValidationError) {
|
||||
const e: Yup.ValidationError = error as Yup.ValidationError;
|
||||
errorDesc = e.errors.reduce((prev, curr) => prev + " " + curr, "");
|
||||
} else {
|
||||
errorDesc = "Ha ocurrido un error. Por favor intentelo nuevamente.";
|
||||
}
|
||||
clearSession(errorDesc);
|
||||
})
|
||||
.finally(() => {
|
||||
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (SessionInfo.loged) {
|
||||
manageLoginActions();
|
||||
}
|
||||
}, [SessionInfo.loged]);
|
||||
|
||||
return (
|
||||
<AnimatedContainer
|
||||
color="#aeaeae"
|
||||
minSize={150}
|
||||
maxSize={500}
|
||||
items={10}
|
||||
style={{
|
||||
minHeight: "100vh",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
background:
|
||||
"linear-gradient(180deg, var(--wine-darkest) 0%, var(--wine-dark) 100%)",
|
||||
}}
|
||||
>
|
||||
<ScrollToTop />
|
||||
<div className="homeCentered">
|
||||
<HeaderConfProvider />
|
||||
<GoogleOAuthProvider clientId={clientId}>
|
||||
<div
|
||||
style={{
|
||||
paddingLeft: "20px",
|
||||
paddingRight: "20px",
|
||||
translate: "0px -30px",
|
||||
}}
|
||||
>
|
||||
<div className="card">
|
||||
<div
|
||||
style={{
|
||||
textAlign: "center",
|
||||
paddingBottom: "30px",
|
||||
paddingTop: "20px",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
{verification && (
|
||||
<>
|
||||
<h1 className="homeTitleHeader">Finalizar registro</h1>
|
||||
<p>
|
||||
Hemos enviado un correo electronico a tu cuenta con el
|
||||
código de verificación para completar el registro.{" "}
|
||||
<strong>Por favor revisa tu bandeja de entrada.</strong>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
{recovery && (
|
||||
<>
|
||||
<h1 className="homeTitleHeader">Reestablecer clave</h1>
|
||||
<p>
|
||||
Te enviaremos un correo electrónico a la dirección
|
||||
registrada con tu cuenta. Asegúrate de proporcionarnos
|
||||
el mismo correo con el que te registraste.{" "}
|
||||
<strong>
|
||||
Revisa tu bandeja de entrada y, si no lo encuentras,
|
||||
también la carpeta de spam. Luego, sigue las
|
||||
instrucciones.
|
||||
</strong>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
{recoveryCode && (
|
||||
<>
|
||||
<h1 className="homeTitleHeader">Recuperar el acceso</h1>
|
||||
<p>
|
||||
Hemos enviado un correo electrónico a tu cuenta con el
|
||||
código de verificación para completar el proceso de
|
||||
recuperación.{" "}
|
||||
<strong>
|
||||
Ingresa tu email, la nueva clave y el código de
|
||||
verificación que te enviamos.
|
||||
</strong>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
{!verification && !recovery && !recoveryCode && (
|
||||
<h1 className="homeTitleHeader">Ingresar</h1>
|
||||
)}
|
||||
<Textbox
|
||||
name="name"
|
||||
placeholder="Email"
|
||||
type="text"
|
||||
value={email}
|
||||
width="100%"
|
||||
onChange={(e) => {
|
||||
setEmail(e.target.value);
|
||||
}}
|
||||
onKeyUp={(e) => {
|
||||
if (!verification && !recovery && !recoveryCode) {
|
||||
if (e.key === "Enter") {
|
||||
document.getElementById("password")?.focus();
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{!recovery && (
|
||||
<Textbox
|
||||
name="password"
|
||||
placeholder="Clave"
|
||||
type="password"
|
||||
value={password}
|
||||
width="100%"
|
||||
onChange={(e) => {
|
||||
setPassword(e.target.value);
|
||||
}}
|
||||
onKeyUp={(e) => {
|
||||
if (!verification && !recovery && !recoveryCode) {
|
||||
if (e.key === "Enter") {
|
||||
iniciarSesion();
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{(verification || recoveryCode) && (
|
||||
<Textbox
|
||||
placeholder="Código de verificaion"
|
||||
type="text"
|
||||
value={verificationCode}
|
||||
width="100%"
|
||||
onChange={(e) => {
|
||||
setVerificationCode(e.target.value);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{verification && (
|
||||
<Button
|
||||
name="btnLogin"
|
||||
text="Verificar"
|
||||
width="100%"
|
||||
onClick={verificateLogin}
|
||||
style={{ marginTop: "20px" }}
|
||||
type="submit"
|
||||
/>
|
||||
)}
|
||||
|
||||
{recovery && (
|
||||
<Button
|
||||
name="btnLogin"
|
||||
text="Enviar email"
|
||||
width="100%"
|
||||
onClick={sendRecoveryMail}
|
||||
style={{ marginTop: "20px" }}
|
||||
type="submit"
|
||||
/>
|
||||
)}
|
||||
|
||||
{recoveryCode && (
|
||||
<Button
|
||||
name="btnLogin"
|
||||
text="Cambiar clave"
|
||||
width="100%"
|
||||
onClick={recoveryAccount}
|
||||
style={{ marginTop: "20px" }}
|
||||
type="submit"
|
||||
/>
|
||||
)}
|
||||
|
||||
{!verification && !recovery && !recoveryCode && (
|
||||
<Button
|
||||
name="btnLogin"
|
||||
text="Ingresar"
|
||||
width="100%"
|
||||
onClick={iniciarSesion}
|
||||
style={{ marginTop: "20px" }}
|
||||
type="submit"
|
||||
/>
|
||||
)}
|
||||
|
||||
{!verification && !recovery && !recoveryCode && (
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "flex-start",
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
checked={checkReadTerms}
|
||||
onClick={() => setCheckReadTerms(!checkReadTerms)}
|
||||
/>
|
||||
<div style={{ marginTop: "8px" }}>
|
||||
Declaro que acepto los siguientes
|
||||
<Link href="/landing/terms">
|
||||
Términos y condiciones
|
||||
</Link>{" "}
|
||||
y{" "}
|
||||
<Link href="/landing/privacy">
|
||||
Políticas de privacidad
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<ButtonGoogle termsReaded={checkReadTerms} />
|
||||
</div>
|
||||
)}
|
||||
{!recoveryCode && (
|
||||
<p style={{ marginTop: "20px" }}>
|
||||
No tienes una cuenta?
|
||||
<Link href="/landing/signup">Registrate!</Link>
|
||||
</p>
|
||||
)}
|
||||
|
||||
{!recovery && !recoveryCode && (
|
||||
<Link
|
||||
href="/landing/recover-account"
|
||||
style={{ display: "block", marginTop: "10px" }}
|
||||
>
|
||||
Olvide mi clave!
|
||||
</Link>
|
||||
)}
|
||||
{recovery && !recoveryCode && (
|
||||
<Link
|
||||
href="/landing/recover-account/verify"
|
||||
style={{ display: "block", marginTop: "10px" }}
|
||||
>
|
||||
Ya tengo el código de verificación!
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GoogleOAuthProvider>
|
||||
</div>
|
||||
<EvangelizeBanner variant="popup" delay={4000} />
|
||||
</AnimatedContainer>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user