From 74b77ce84ea7b90e1b75d14e88d37beea3884197 Mon Sep 17 00:00:00 2001 From: Elliot Axel Noriega Date: Mon, 5 Aug 2024 21:35:53 -0600 Subject: [PATCH 1/3] Cambio de componentes distribuidos por url; register, login --- cosiap_frontend/src/App.jsx | 9 +++--- .../src/components/users/AuthPage.jsx | 32 ------------------- .../src/components/users/Login/Login.jsx | 17 +++++++--- .../components/users/Login/LoginInputCURP.jsx | 2 +- .../users/Login/LoginInputPassword.jsx | 2 +- .../components/users/Register/Register.jsx | 20 +++++++++--- 6 files changed, 35 insertions(+), 47 deletions(-) delete mode 100644 cosiap_frontend/src/components/users/AuthPage.jsx diff --git a/cosiap_frontend/src/App.jsx b/cosiap_frontend/src/App.jsx index 0ad6f47..aca4efd 100644 --- a/cosiap_frontend/src/App.jsx +++ b/cosiap_frontend/src/App.jsx @@ -4,8 +4,8 @@ import {Autenticador} from "@/components/common/utility/Autenticador"; import {LoginRequiredRoutes} from "@/components/common/utility/LoginRequiredRoutes" import "./App.css"; import PageLoader from '@/components/common/ui/PageLoader'; - -import { AuthPage } from "./components/users/AuthPage"; +import { Login } from './components/users/Login/Login'; +import Register from './components/users/Register/Register'; import Inicio from "./components/users/Inicio"; import { useState } from 'react'; @@ -28,8 +28,9 @@ function App() { {/* Rutas publicas */} - } /> - } /> + } /> + } /> + } /> {/* Rutas protegidas */} }> diff --git a/cosiap_frontend/src/components/users/AuthPage.jsx b/cosiap_frontend/src/components/users/AuthPage.jsx deleted file mode 100644 index 5a1913d..0000000 --- a/cosiap_frontend/src/components/users/AuthPage.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import LayoutBaseAuthenticator from '@/components/common/layouts/LayoutBaseAuthenticator'; -import { Login } from "./Login/Login"; -import Register from './Register/Register'; -import { useState } from 'react'; - -export function AuthPage( {setViewPageLoader} ) { - const [component, setComponent] = useState('Login') - - const renderPage = () => { - switch (component) { - case 'Login': - return ; - case 'Register': - return ; - // case 'resetPassword': - // return ; - default: - return ; - } - } - - return ( - <> - - - {renderPage()} - - - ); -} \ No newline at end of file diff --git a/cosiap_frontend/src/components/users/Login/Login.jsx b/cosiap_frontend/src/components/users/Login/Login.jsx index b59eea0..a142106 100644 --- a/cosiap_frontend/src/components/users/Login/Login.jsx +++ b/cosiap_frontend/src/components/users/Login/Login.jsx @@ -1,9 +1,18 @@ +import LayoutBaseAuthenticator from '@/components/common/layouts/LayoutBaseAuthenticator'; +import { useNavigate } from "react-router-dom"; import { LoginForm } from './LoginForm'; -export function Login( {setComponent, setViewPageLoader} ) { + +export function Login( {setViewPageLoader} ) { + const navigate = useNavigate(); + + function navigateRegister(){ + navigate('register'); + } + return ( - <> +

¿Haz olvidado tu contraseña? @@ -11,9 +20,9 @@ export function Login( {setComponent, setViewPageLoader} ) {

¿Aun no tienes cuenta?

-

setComponent('Register')}> +

Registrate

- +
); } \ No newline at end of file diff --git a/cosiap_frontend/src/components/users/Login/LoginInputCURP.jsx b/cosiap_frontend/src/components/users/Login/LoginInputCURP.jsx index c5ffafa..fa3dbe8 100644 --- a/cosiap_frontend/src/components/users/Login/LoginInputCURP.jsx +++ b/cosiap_frontend/src/components/users/Login/LoginInputCURP.jsx @@ -9,7 +9,7 @@ export const LoginInputCURP = ({ name, type, placeholder, className, register, e name={name} type={type} placeholder={placeholder} - className={`customInputsButtons block w-full rounded-tr-2xl bg-[#F6F2F2] border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-[var(--principal-f)] placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-[var(--principal-mf)] sm:text-sm sm:leading-6 ${className}`} + className={`customInputsButtons block w-full rounded-tr-2xl bg-[var(--pagina-fondo)] border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-[var(--principal-f)] placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-[var(--principal-mf)] sm:text-sm sm:leading-6 ${className}`} register={register} errors={errors} /> diff --git a/cosiap_frontend/src/components/users/Login/LoginInputPassword.jsx b/cosiap_frontend/src/components/users/Login/LoginInputPassword.jsx index 1daaa4a..5254f66 100644 --- a/cosiap_frontend/src/components/users/Login/LoginInputPassword.jsx +++ b/cosiap_frontend/src/components/users/Login/LoginInputPassword.jsx @@ -9,7 +9,7 @@ export const LoginInputPassword = ({ name, placeholder, className, register, er id={name} name={name} placeholder={placeholder} - className={`customInputsButtons block w-full rounded-tr-2xl bg-[#F6F2F2] border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-[var(--principal-f)] placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-[var(--principal-mf)] sm:text-sm sm:leading-6 ${className}`} + className={`customInputsButtons block w-full rounded-tr-2xl bg-[var(--pagina-fondo)] border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-[var(--principal-f)] placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-[var(--principal-mf)] sm:text-sm sm:leading-6 ${className}`} register={register} errors={errors} /> diff --git a/cosiap_frontend/src/components/users/Register/Register.jsx b/cosiap_frontend/src/components/users/Register/Register.jsx index e343e9a..14e6c93 100644 --- a/cosiap_frontend/src/components/users/Register/Register.jsx +++ b/cosiap_frontend/src/components/users/Register/Register.jsx @@ -1,15 +1,25 @@ +import LayoutBaseAuthenticator from '@/components/common/layouts/LayoutBaseAuthenticator'; +import { useNavigate } from "react-router-dom"; + + import { useState } from "react"; import RegisterForm from "./RegisterForm"; -export default function Register( {setComponent, setViewPageLoader} ) { +export default function Register({setViewPageLoader} ) { const [sentEmail, setSentEmail] = useState(false); + const navigate = useNavigate(); + + function navigateLogin(){ + navigate('/authentication'); + } + return ( - <> + { !sentEmail ? ( <> -

setComponent('Login')}> +

Iniciar sesión

@@ -24,13 +34,13 @@ export default function Register( {setComponent, setViewPageLoader} ) {
-
) } - +
); } \ No newline at end of file -- GitLab From cca2a58de8595ccd8bf3bd681d8bc520cefc3a55 Mon Sep 17 00:00:00 2001 From: Elliot Axel Noriega Date: Tue, 6 Aug 2024 18:04:46 -0600 Subject: [PATCH 2/3] =?UTF-8?q?Actualizaci=C3=B3n=20de=20edpoints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cosiap_frontend/src/api.js | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/cosiap_frontend/src/api.js b/cosiap_frontend/src/api.js index f324376..7cd0b33 100644 --- a/cosiap_frontend/src/api.js +++ b/cosiap_frontend/src/api.js @@ -50,12 +50,66 @@ const api = { getById: (id) => ax.get(`api/usuarios/${id}`), update: (id, data) => ax.put(`api/usuarios/${id}`, data), delete: (id) => ax.delete(`api/usuarios/${id}`), + + verificarCorreo: (uidb64, token) => ax.get(`api/usuarios/verificar-correo/${uidb64}/${token}`), + restablecerPassoword: (data) => ax.post(`api/usuarios/restablecer-password`, data), + nuevaPassword: (uidb64, token, data) => ax.get(`api/usuarios/nueva-password/${uidb64}/${token}`, data), + + administradores: { + get: () => ax.get('api/usuarios/administradores'), + post: (data) => ax.post('api/usuarios/administradores/', data), + }, + + // Endpoints del submodulo token token: { login: (data) => ax.post('api/usuarios/token/',data), refresh: () => ax.post('api/usuarios/token/refresh/'), }, + + //Endpoints del submodulo solicitantes + solicitantes: { + get: () => ax.get('api/usuarios/solicitantes'), + post: (data) => ax.post('api/usuarios/solicitantes/', data), + getById: (id) => ax.get(`api/usuarios/solicitantes/${id}`), + update: (id, data) => ax.put(`api/usuarios/solicitantes/${id}`, data), + }, + }, + administracion: { + //Aun por declarar }, - + modalidades: { + get: () => ax.get('api/modalidades'), + post: (data) => ax.post('api/modalidades/', data), + getById: (id) => ax.get(`api/modalidades/${id}`), + update: (id, data) => ax.put(`api/modalidades/${id}`, data), + delete: (id) => ax.delete(`api/modalidades/${id}`), + monto: { + post: (data) => ax.post('api/modalidades', data), + } + }, + notificaciones: { + // Aun por declarar + }, + solicitudes: { + get: () => ax.get('api/solicitudes'), + post: (data) => ax.post('api/solicitudes/', data), + getById: (id) => ax.get(`api/solicitudes/${id}`), + update: (id, data) => ax.put(`api/solicitudes/${id}`, data), + historial: { + get: () => ax.get('api/solicitudes/historial'), + getById: (id) => ax.get(`api/solicitudes/historial/${id}`), + }, + reportes: { + get: () => ax.get('api/solicitudes/reportes'), + getById: (id) => ax.get(`api/solicitudes/reportes/${id}`), + } + }, + dynamicTables: { + get: () => ax.get('api/dynamic-tables'), + post: (data) => ax.post('api/dynamic-tables/', data), + getById: (id) => ax.get(`api/dynamic-tables/${id}`), + update: (id, data) => ax.put(`api/dynamic-tables/${id}`, data), + } }; // Exportar los endpoints de la API -- GitLab From fa53c18b3920c23088c4a9eccb30ab9626b93210 Mon Sep 17 00:00:00 2001 From: Elliot Axel Noriega Date: Tue, 6 Aug 2024 20:43:55 -0600 Subject: [PATCH 3/3] =?UTF-8?q?Separaci=C3=B3n=20de=20validaciones=20de=20?= =?UTF-8?q?formularios=20en=20un=20archivo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/FormsValidations.jsx | 46 +++++++++++++ .../src/components/users/Inicio.jsx | 68 +++++++++++++++++-- .../src/components/users/Login/LoginForm.jsx | 14 ++-- .../users/Register/RegisterForm.jsx | 21 +----- 4 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 cosiap_frontend/src/components/FormsValidations.jsx diff --git a/cosiap_frontend/src/components/FormsValidations.jsx b/cosiap_frontend/src/components/FormsValidations.jsx new file mode 100644 index 0000000..785a51a --- /dev/null +++ b/cosiap_frontend/src/components/FormsValidations.jsx @@ -0,0 +1,46 @@ +import * as Yup from "yup"; + + +// Variable de formato para validación de formato de CURP +const CURP_REGEX = /^[A-Z]{1}[AEIOU]{1}[A-Z]{2}[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[HM]{1}(AS|BC|BS|CC|CH|CL|CM|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)[B-DF-HJ-NP-TV-Z]{3}[0-9A-Z]{1}[0-9]{1}$/; + +// Validación de un campo CURP +const CURP_VALIDATION = Yup.string() + .required("La CURP es requerida") + .matches(CURP_REGEX, "Formato de CURP inválido"); + + +const PASSWORD_CREATION_VALIDATION = Yup.string() + .required("La contraseña es requerida") + .min(8, 'La contraseña debe tener al menos 8 caracteres') + .max(20, 'La contraseña no puede tener más de 20 caracteres') + .matches(/\d/, 'Debe contener al menos un número') + .matches(/[a-z]/, 'Debe contener al menos una letra minúscula') + .matches(/[A-Z]/, 'Debe contener al menos una letra mayúscula') + .matches(/[@$#¡!%*¿?&]/, 'Debe contener al menos un carácter especial') + .matches(/^\S*$/, 'La contraseña no puede contener espacios'); + +const CONFIRM_PASSWORD_VALIDATION = Yup.string() + .required("La confirmacion de la contraseña es requerida") + .oneOf([Yup.ref('password'), null], 'Las contraseñas no coinciden'); + + + + +export const LoginValidationSchema = Yup.object().shape({ + curp: CURP_VALIDATION, + password: Yup.string() + .required("La contraseña es requerida") +}); + +export const RegisterValidationSchema = Yup.object({ + nombre: Yup.string() + .required('El nombre es requerido') + .min(3, 'El nombre debe tener al menos 3 caracteres'), + curp: CURP_VALIDATION, + email: Yup.string() + .required("El correo electronico es requerido") + .email("El correo electronico no es válido"), + password: PASSWORD_CREATION_VALIDATION, + confirmar_password: CONFIRM_PASSWORD_VALIDATION +}); diff --git a/cosiap_frontend/src/components/users/Inicio.jsx b/cosiap_frontend/src/components/users/Inicio.jsx index a6d7e7b..e004bcf 100644 --- a/cosiap_frontend/src/components/users/Inicio.jsx +++ b/cosiap_frontend/src/components/users/Inicio.jsx @@ -1,7 +1,67 @@ export default function Inicio() { return ( -
-

Inicio

-
- ); + <> + + + ) } diff --git a/cosiap_frontend/src/components/users/Login/LoginForm.jsx b/cosiap_frontend/src/components/users/Login/LoginForm.jsx index d81f83c..b5b820c 100644 --- a/cosiap_frontend/src/components/users/Login/LoginForm.jsx +++ b/cosiap_frontend/src/components/users/Login/LoginForm.jsx @@ -1,6 +1,8 @@ import { useForm } from "react-hook-form"; -import * as Yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; +//Importa el objeto de validacion del formulario +import { LoginValidationSchema } from "@/components/FormsValidations"; + import api from "@/api"; // Asegúrate de importar tu instancia de API import {LoginInputCURP} from '@/components/users/Login/LoginInputCURP' import { LoginInputPassword } from "@/components/users/Login/LoginInputPassword"; @@ -9,14 +11,7 @@ import {ErrorDisplay} from '@/components/common/ui/ErrorDisplay' import { useNavigate } from "react-router-dom"; import {useAutenticacion} from "@/components/common/utility/Autenticador" -const CURP_REGEX = /^[A-Z]{1}[AEIOU]{1}[A-Z]{2}[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[HM]{1}(AS|BC|BS|CC|CH|CL|CM|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)[B-DF-HJ-NP-TV-Z]{3}[0-9A-Z]{1}[0-9]{1}$/; -const validationSchema = Yup.object({ - curp: Yup.string() - .required("Requerido") - .matches(CURP_REGEX, "CURP inválido"), - password: Yup.string().required("Requerido"), -}); export function LoginForm( {setViewPageLoader} ) { const [loginError, setLoginError] = useState('') @@ -27,10 +22,9 @@ export function LoginForm( {setViewPageLoader} ) { handleSubmit, formState: { errors, isSubmitting }, } = useForm({ - resolver: yupResolver(validationSchema), + resolver: yupResolver(LoginValidationSchema), }); - const onSubmit = async (data) => { setViewPageLoader(true) try { diff --git a/cosiap_frontend/src/components/users/Register/RegisterForm.jsx b/cosiap_frontend/src/components/users/Register/RegisterForm.jsx index 017fddf..bd51aa8 100644 --- a/cosiap_frontend/src/components/users/Register/RegisterForm.jsx +++ b/cosiap_frontend/src/components/users/Register/RegisterForm.jsx @@ -3,27 +3,10 @@ import { RegisterInputPassword } from "./RegisterInputPassword"; import { useState } from "react"; import { ErrorDisplay } from '@/components/common/ui/ErrorDisplay'; import { useForm } from "react-hook-form"; -import * as Yup from "yup"; import { yupResolver } from "@hookform/resolvers/yup"; +import { RegisterValidationSchema } from "@/components/FormsValidations"; import api from "@/api"; // Asegúrate de importar tu instancia de API -const CURP_REGEX = /^[A-Z]{1}[AEIOU]{1}[A-Z]{2}[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[HM]{1}(AS|BC|BS|CC|CH|CL|CM|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)[B-DF-HJ-NP-TV-Z]{3}[0-9A-Z]{1}[0-9]{1}$/; - -const validationSchema = Yup.object({ - nombre: Yup.string() - .required('Campo requerido'), - curp: Yup.string() - .required("Campo requerido") - .matches(CURP_REGEX, "Campo requerido"), - email: Yup.string() - .email("El email no es válido") - .required("Campo requerido"), - password: Yup.string() - .required("Campo requerido"), - confirmar_password: Yup.string() - .required("Campo requerido") - .oneOf([Yup.ref('password'), null], 'Las contraseñas no coinciden') -}); export default function RegisterForm( {setSentEmail, setViewPageLoader} ) { const [registerErrorMessage, setRegisterErrorMessage] = useState(''); @@ -32,7 +15,7 @@ export default function RegisterForm( {setSentEmail, setViewPageLoader} ) { handleSubmit, formState: { errors, isSubmitting }, } = useForm({ - resolver: yupResolver(validationSchema), + resolver: yupResolver(RegisterValidationSchema), }); const handleFormSubmission = async (data) => { -- GitLab