diff --git a/cosiap_api/cosiap_api/settings.py b/cosiap_api/cosiap_api/settings.py
index 8b3015dc827cbb070efe3d5dc500301ecfbe3358..68e6856919d39872737e0f22c40c40256587c004 100644
--- a/cosiap_api/cosiap_api/settings.py
+++ b/cosiap_api/cosiap_api/settings.py
@@ -184,8 +184,8 @@ SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SIMPLE_JWT = {
- 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
- 'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
+ 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=0.5),
+ 'REFRESH_TOKEN_LIFETIME': timedelta(minutes=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'ALGORITHM': 'HS256',
diff --git a/cosiap_api/users/views.py b/cosiap_api/users/views.py
index 8e869c8d8e2f2ed8ef730d1050bde2ae28535dc3..4252bbe4b43918cf91741e87a9495bb7148e1e5b 100644
--- a/cosiap_api/users/views.py
+++ b/cosiap_api/users/views.py
@@ -45,10 +45,8 @@ class CustomTokenObtainPairView(TokenObtainPairView):
# Eliminar el refresh token de la respuesta JSON
del response.data['refresh']
# Agregar mensaje de éxito
- response.data['message'] = {'succes':'Login successful'}
- else:
- response.data['errors'] = response.data # Mover errores a la clave 'errors'
- response.data['message'] = {'error':'Login failed'}
+ response.data['message'] = {'succes':'Login exitoso'}
+
return response
class CustomTokenRefreshView(TokenRefreshView):
diff --git a/cosiap_frontend/src/components/common/ui/ErrorDisplay.css b/cosiap_frontend/src/components/common/ui/ErrorDisplay.css
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/cosiap_frontend/src/components/common/ui/ErrorDisplay.jsx b/cosiap_frontend/src/components/common/ui/ErrorDisplay.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..ebcada877ddd525791e2a761db42e2090d3e0a50
--- /dev/null
+++ b/cosiap_frontend/src/components/common/ui/ErrorDisplay.jsx
@@ -0,0 +1,36 @@
+import PropTypes from 'prop-types';
+
+
+export const ErrorDisplay = ({ errors }) => {
+ if (!errors) return null;
+
+ return (
+
+ {renderErrors(errors)}
+
+ );
+};
+
+const renderErrors = (errors) => {
+ if (typeof errors === 'string') {
+ return {errors}
;
+ } else if (Array.isArray(errors)) {
+ return errors.map((error, index) => {error}
);
+ } else if (typeof errors === 'object' && !Array.isArray(errors)) {
+ return Object.values(errors).map((errorList, index) => (
+
+ {errorList.map((error, idx) =>
{error}
)}
+
+ ));
+ }
+};
+
+ErrorDisplay.propTypes = {
+ errors: PropTypes.oneOfType([
+ PropTypes.object,
+ PropTypes.array,
+ PropTypes.string
+ ])
+};
+
+export default ErrorDisplay;
\ No newline at end of file
diff --git a/cosiap_frontend/src/components/common/ui/ErrorDisplay.utils.js b/cosiap_frontend/src/components/common/ui/ErrorDisplay.utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..2b9ed51c6f6ecba0cfd0ac6bf391239a99ab8b66
--- /dev/null
+++ b/cosiap_frontend/src/components/common/ui/ErrorDisplay.utils.js
@@ -0,0 +1,14 @@
+export function mergeErrors(errorList) {
+ // Filtrar y eliminar elementos undefined del array
+ const filteredErrors = errorList.filter(error => error !== undefined);
+
+ return filteredErrors.reduce((acc, error) => {
+ Object.keys(error).forEach(key => {
+ if (!acc[key]) {
+ acc[key] = [];
+ }
+ acc[key] = acc[key].concat(error[key]);
+ });
+ return acc;
+ }, {});
+}
\ No newline at end of file
diff --git a/cosiap_frontend/src/components/common/ui/FormInput.jsx b/cosiap_frontend/src/components/common/ui/FormInput.jsx
index 7d397a5875d0a370476d23ec518cffc32d97c901..3ac82c14b9fbfc2c4cd73a52d3387ec9f7c0d601 100644
--- a/cosiap_frontend/src/components/common/ui/FormInput.jsx
+++ b/cosiap_frontend/src/components/common/ui/FormInput.jsx
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
+import {ErrorDisplay} from '@/components/common/ui/ErrorDisplay'
-export function FormInput({ id, name, type, placeholder, className, register, error }) {
+export function FormInput({ id, name, type, placeholder, className, register, errors }) {
return (
- {error &&
{error.message}
}
+
);
}
@@ -20,8 +21,12 @@ FormInput.propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
- placeholder: PropTypes.string.isRequired,
+ placeholder: PropTypes.string,
className: PropTypes.string,
register: PropTypes.func.isRequired,
- error: PropTypes.object,
+ errors: PropTypes.oneOfType([
+ PropTypes.object,
+ PropTypes.array,
+ PropTypes.string
+ ])
};
\ No newline at end of file
diff --git a/cosiap_frontend/src/components/users/LoginPage/LoginContainer.jsx b/cosiap_frontend/src/components/users/LoginPage/LoginContainer.jsx
index 039145b98149f690eceb6119137f518e6483a75c..c15abd263ed6150a265c98787371ec089265cc7d 100644
--- a/cosiap_frontend/src/components/users/LoginPage/LoginContainer.jsx
+++ b/cosiap_frontend/src/components/users/LoginPage/LoginContainer.jsx
@@ -5,7 +5,7 @@ export function LoginContainer() {
= 640 ? "absolute" : "relative",
diff --git a/cosiap_frontend/src/components/users/LoginPage/LoginForm.jsx b/cosiap_frontend/src/components/users/LoginPage/LoginForm.jsx
index 93ec6440bdd0d92008ec8b16bab4e3b668c0888a..a9ab1fe01e8e38b124af8a36164d9eb157d7cad5 100644
--- a/cosiap_frontend/src/components/users/LoginPage/LoginForm.jsx
+++ b/cosiap_frontend/src/components/users/LoginPage/LoginForm.jsx
@@ -3,17 +3,20 @@ import * as Yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import api from "@/api"; // Asegúrate de importar tu instancia de API
import {LoginInput} from '@/components/users/LoginPage/loginInput'
+import { useState } from "react";
+import {ErrorDisplay} from '@/components/common/ui/ErrorDisplay'
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()
- .matches(CURP_REGEX, "CURP inválida")
+ .matches(CURP_REGEX, "CURP inválido")
.required("Requerido"),
password: Yup.string().required("Requerido"),
});
export function LoginForm() {
+ const [loginError, setLoginError] = useState('')
const {
register,
handleSubmit,
@@ -21,7 +24,7 @@ export function LoginForm() {
} = useForm({
resolver: yupResolver(validationSchema),
});
-
+
const onSubmit = async (data) => {
try {
const response = await api.usuarios.token.login(data);
@@ -29,26 +32,27 @@ export function LoginForm() {
// Manejar la respuesta exitosa aquí
} catch (error) {
console.error("Login failed:", error);
- // Manejar el error aquí
+ setLoginError(error.response.data.detail)
}
};
return (