diff --git a/cosiap_api/cosiap_api/.env b/cosiap_api/cosiap_api/.env
index 1b8c473086c249755da5edce9d772d86374b1358..efd2d313abce2ad842d937242cfe1013cdaab054 100644
--- a/cosiap_api/cosiap_api/.env
+++ b/cosiap_api/cosiap_api/.env
@@ -14,8 +14,8 @@ DATABASES_DEFAULT_PORT="3306"
EMAIL_HOST="sandbox.smtp.mailtrap.io"
EMAIL_FROM="cosiap@example.com"
-EMAIL_HOST_USER="3b48193365f615"
-EMAIL_HOST_PASSWORD="37f89fc1d98f48"
+EMAIL_HOST_USER="dab27aa7ffd16a"
+EMAIL_HOST_PASSWORD="59d827a27f4eda"
EMAIL_PORT="2525"
EMAIL_USE_TLS=True
diff --git a/cosiap_api/static/css/colores.css b/cosiap_api/static/css/colores.css
index 227521458c89ea6c72a0743614bf9d3bd97a3770..0d31fc59d49f60b0aa340d144a28902766e94d5f 100644
--- a/cosiap_api/static/css/colores.css
+++ b/cosiap_api/static/css/colores.css
@@ -1,57 +1,57 @@
:root {
-/* =========================
+ /* =========================
Estilos Básicos del Sitio
========================= */
- --principal-mc: rgb(252,226,228);
- --principal-c: rgb(245,173,171);
- --principal: rgb(226,116,110);
- --principal-f: rgb(187,68,51);
- --principal-mf: rgb(120,16,5);
-
- --secundario-mc:#e0e0e0;
- --secundario-c: #c0c0c0;
- --secundario: #a0a0a0;
- --secundario-f: #808080;
- --secundario-mf:#606060;
-
- --texto-general: #676767;
- --pagina-fondo: #EEE5E5;
-
- --exito-f: #8abc94;
- --exito: #B9E2C1;
- --exito-c: #D5F5E2;
-
- --error-f: #C7564A;
- --error: #E4756F;
- --error-c: #E1B2AF;
-
- --precaucion-f: #d4bf47;
- --precaucion: #e4d26f;
- --precaucion-c: #f1e7a8;
-
- --cancelar-f: #B8A9A8;
- --cancelar: #DCCBCA;
- --cancelar-c: #E9DEDD;
-
- --informacion-f: #5b9bd5;
- --informacion: #85c1e9;
- --informacion-c: #cfe2f3;
-
- --neutral-f: #6c757d;
- --neutral: #adb5bd;
- --neutral-c: #dee2e6;
-
- --gris-principal: #b9b4b4;
- --gris-0: #f8f8f8;
- --gris-1: #efefef;
- --gris-2: #e0e0e0;
- --gris-3: #c0c0c0;
- --gris-4: #a0a0a0;
- --gris-5: #808080;
- --gris-6: #606060;
- --gris-7: #404040;
- --gris-8: #202020;
- --blanco: #FFFFFF;
- --negro: #000000;
-
-}
\ No newline at end of file
+ --principal-mc: rgb(252, 226, 228);
+ --principal-c: rgb(245, 173, 171);
+ --principal: rgb(226, 116, 110);
+ --principal-f: rgb(187, 68, 51);
+ --principal-mf: rgb(120, 16, 5);
+
+ --secundario-mc: #e0e0e0;
+ --secundario-c: #c0c0c0;
+ --secundario: #a0a0a0;
+ --secundario-f: #808080;
+ --secundario-mf: #606060;
+
+ --texto-general: #676767;
+ --pagina-fondo: #eee5e5;
+
+ --exito-f: #8abc94;
+ --exito: #b9e2c1;
+ --exito-c: #d5f5e2;
+ --exito-btn: #527f18;
+
+ --error-f: #c7564a;
+ --error: #e4756f;
+ --error-c: #e1b2af;
+
+ --precaucion-f: #d4bf47;
+ --precaucion: #e4d26f;
+ --precaucion-c: #f1e7a8;
+
+ --cancelar-f: #b8a9a8;
+ --cancelar: #dccbca;
+ --cancelar-c: #e9dedd;
+
+ --informacion-f: #5b9bd5;
+ --informacion: #85c1e9;
+ --informacion-c: #cfe2f3;
+
+ --neutral-f: #6c757d;
+ --neutral: #adb5bd;
+ --neutral-c: #dee2e6;
+
+ --gris-principal: #b9b4b4;
+ --gris-0: #f8f8f8;
+ --gris-1: #efefef;
+ --gris-2: #e0e0e0;
+ --gris-3: #c0c0c0;
+ --gris-4: #a0a0a0;
+ --gris-5: #808080;
+ --gris-6: #606060;
+ --gris-7: #404040;
+ --gris-8: #202020;
+ --blanco: #ffffff;
+ --negro: #000000;
+}
diff --git a/cosiap_frontend/src/App.jsx b/cosiap_frontend/src/App.jsx
index ce4903609fadf6b14799f082dd1ab2f9de4c4d7a..87450145e3aa1d3a6643719487a59744b131336c 100644
--- a/cosiap_frontend/src/App.jsx
+++ b/cosiap_frontend/src/App.jsx
@@ -1,93 +1,118 @@
-import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
-import {PaginaHead} from "@/components/common/utility/PaginaHead";
-import {Autenticador} from "@/components/common/utility/Autenticador";
-import { useAutenticacion } from '@/components/common/utility/Autenticador';
+import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
+import { PaginaHead } from "@/components/common/utility/PaginaHead";
+import { Autenticador } from "@/components/common/utility/Autenticador";
+import { useAutenticacion } from "@/components/common/utility/Autenticador";
-import {LoginRequiredRoute, IsAdminRequiredRoute, IsLogged} from "@/components/common/utility/LoginRequiredRoute"
+import {
+ LoginRequiredRoute,
+ IsAdminRequiredRoute,
+ IsLogged,
+} from "@/components/common/utility/LoginRequiredRoute";
import "./App.css";
-import PageLoader from '@/components/common/ui/PageLoader';
+import PageLoader from "@/components/common/ui/PageLoader";
// Importaciones de componentes de autenticacion
-import { Login } from '@/components/users/Login/Login';
-import Register from '@/components/users/Register/Register';
-import ResetPassword from '@/components/users/Password/ResetPassword';
-import NoAutorizado from '@/components/users/NoAutorizado';
-import PageNotFound from '@/components/users/PageNotFound';
+import { Login } from "@/components/users/Login/Login";
+import Register from "@/components/users/Register/Register";
+import ResetPassword from "@/components/users/Password/ResetPassword";
+import NoAutorizado from "@/components/users/NoAutorizado";
+import PageNotFound from "@/components/users/PageNotFound";
import Inicio from "@/components/Inicio";
-import { useState } from 'react';
+import { useState } from "react";
// Importaciones de layoutsBase
-import LayoutBaseAuthenticator from '@/components/common/layouts/LayoutBaseAuthenticator';
-import LayoutBaseNavigation from '@/components/common/layouts/LayoutBaseNavigation';
-
-
-
+import LayoutBaseAuthenticator from "@/components/common/layouts/LayoutBaseAuthenticator";
+import LayoutBaseNavigation from "@/components/common/layouts/LayoutBaseNavigation";
+import Modalidades from "@/components/modalidades/Modalidades";
function App() {
const [viewPageLoader, setViewPageLoader] = useState(false);
- return (
+ return (
- Sistema de apoyos COZCyT
-
-
+ Sistema de apoyos COZCyT
+
+
- {
- viewPageLoader &&
- }
-
+ {viewPageLoader && }
+
-
-
+
);
}
-function RoutesApp( {setViewPageLoader} ){
- const {token, isAdmin} = useAutenticacion();
- console.log(token)
+function RoutesApp({ setViewPageLoader }) {
+ const { token } = useAutenticacion();
+
return (
- } />
+
+ }
+ />
{/* Rutas públicas */}
- {/* Componente del layout */}
- }>
+ {/* Componente del layout */}
+ }>
}>
- {/* Componentes hijos del layout autenticador */}
- } />
- } />
- } />
+ {/* Componentes hijos del layout autenticador */}
+ }
+ />
+ }
+ />
+ }
+ />
-
- {/* Rutas protegidas */}
+
+ {/* Rutas protegidas */}
}>
- {/* Componentes del layout de navegación */}
+ {/* Componentes del layout de navegación */}
}>
{/* Componentes hijos del layout autenticador */}
-
+
{/* Cualquier usuario puede acceder a estas url */}
} />
- } />
+ }
+ />
} />
} />
} />
} />
{/* Solo administradores pueden acceder a estas url */}
- }>
+
+ }
+ >
} />
} />
-
+
} />
} />
-
);
}
-export default App;
\ No newline at end of file
+export default App;
diff --git a/cosiap_frontend/src/assets/iconsImg/Money.svg b/cosiap_frontend/src/assets/iconsImg/Money.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7ca3d6b5c393609fd8b6db169fcd7acbcf1848d6
--- /dev/null
+++ b/cosiap_frontend/src/assets/iconsImg/Money.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/cosiap_frontend/src/assets/modalidad.png b/cosiap_frontend/src/assets/modalidad.png
new file mode 100644
index 0000000000000000000000000000000000000000..61360d679964322b3a6ba500136d3373e363a247
Binary files /dev/null and b/cosiap_frontend/src/assets/modalidad.png differ
diff --git a/cosiap_frontend/src/components/common/utility/DocumentInput.jsx b/cosiap_frontend/src/components/common/utility/DocumentInput.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..e364644ac0d8f6783fc38f024a0f4a8e174e1e62
--- /dev/null
+++ b/cosiap_frontend/src/components/common/utility/DocumentInput.jsx
@@ -0,0 +1,22 @@
+export default function DocumentInput({ title, description, children }) {
+ return (
+ <>
+
+
+ {/* (Título del documento) */}
+ {title}
+
+
+
+ {/* (Descripción del documento) */}
+ {description}
+
+
+
+ {/* Contenedores extra */}
+ {children}
+
+
+ >
+ );
+}
diff --git a/cosiap_frontend/src/components/common/utility/HeaderSection.jsx b/cosiap_frontend/src/components/common/utility/HeaderSection.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..a372cca7cd14117220c68f2673c4d2f371e2ea86
--- /dev/null
+++ b/cosiap_frontend/src/components/common/utility/HeaderSection.jsx
@@ -0,0 +1,13 @@
+export default function HeaderSection({ title }) {
+ return (
+
+ );
+}
diff --git a/cosiap_frontend/src/components/common/utility/InputFile.jsx b/cosiap_frontend/src/components/common/utility/InputFile.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..daf4db1d150682b53fedb1860e4a92dbf37adb99
--- /dev/null
+++ b/cosiap_frontend/src/components/common/utility/InputFile.jsx
@@ -0,0 +1,15 @@
+export default function InputFile({ titleBtn, descBtn }) {
+ return (
+
+ );
+}
diff --git a/cosiap_frontend/src/components/common/utility/InputMonto.jsx b/cosiap_frontend/src/components/common/utility/InputMonto.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..4c61b9f3401937997129d00014be85e79a171f83
--- /dev/null
+++ b/cosiap_frontend/src/components/common/utility/InputMonto.jsx
@@ -0,0 +1,21 @@
+export default function InputMonto() {
+ return (
+
+
+
+
+
+
+ MXN
+
+
+ );
+}
\ No newline at end of file
diff --git a/cosiap_frontend/src/components/common/utility/MainContainer.jsx b/cosiap_frontend/src/components/common/utility/MainContainer.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..4774e03649a642d9089827224c6d4b5b9ec6e51a
--- /dev/null
+++ b/cosiap_frontend/src/components/common/utility/MainContainer.jsx
@@ -0,0 +1,17 @@
+export default function MainContainer({ title, children }) {
+ return (
+ <>
+
+
+
+ {title}
+
+
+
+ {children}
+
+ >
+ );
+}
diff --git a/cosiap_frontend/src/components/common/utility/StatusDocument.jsx b/cosiap_frontend/src/components/common/utility/StatusDocument.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..19784a6b784b3738719adf8f1374c15681a27fd4
--- /dev/null
+++ b/cosiap_frontend/src/components/common/utility/StatusDocument.jsx
@@ -0,0 +1,12 @@
+export default function StatusDocument({ title, description }) {
+ return (
+
+
+ {title}
+
+
+ {description}
+
+
+ );
+}
diff --git a/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx b/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..318e22a176f50d4c08000b9d01b988c19690f8ab
--- /dev/null
+++ b/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx
@@ -0,0 +1,67 @@
+/* eslint-disable react/jsx-no-comment-textnodes */
+// import { useNavigate } from "react-router-dom";
+import { ModalidadCard } from "@/components/modalidades/ModalidadCard";
+import api from "@/api";
+import { useState, useEffect } from "react";
+import MainContainer from "@/components/common/utility/MainContainer";
+
+export default function ListaModalidades({
+ setViewPageLoader,
+ handleModalidadDetail,
+}) {
+ const [modalidades, setModalidades] = useState([]);
+
+ const obtenerModalidades = async () => {
+ setViewPageLoader(true);
+
+ try {
+ const response = await api.modalidades.get();
+ console.log("Modalidades extraidas");
+ console.log(response.data.data);
+ setModalidades(response.data.data);
+ } catch (error) {
+ console.log("No fueron extraidas");
+ }
+ setViewPageLoader(false);
+ };
+
+ useEffect(() => {
+ obtenerModalidades();
+ }, []);
+
+ return (
+
+
+ {/** Tarjetas para mostrar modalidades disponibles */}
+ {modalidades.length > 0 ? (
+ modalidades.map((item) => {
+ return (
+
+
+
+
+
+
+ );
+ })
+ ) : (
+
+ No hay modalidades disponibles
+
+ )}
+
+
+ );
+}
diff --git a/cosiap_frontend/src/components/modalidades/Modalidad.jsx b/cosiap_frontend/src/components/modalidades/Modalidad.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..988ae4dfa40ab2dce5eaa0a588a80576a77b6d73
--- /dev/null
+++ b/cosiap_frontend/src/components/modalidades/Modalidad.jsx
@@ -0,0 +1,145 @@
+import DocumentInput from "@/components/common/utility/DocumentInput";
+import HeaderSection from "@/components/common/utility/HeaderSection";
+import StatusDocument from "@/components/common/utility/StatusDocument";
+import InputMonto from "@/components/common/utility/InputMonto";
+import InputFile from "@/components/common/utility/InputFile";
+import api from "@/api";
+import { useEffect, useState } from "react";
+
+// eslint-disable-next-line react-refresh/only-export-components
+export { useNavigate } from "react-router-dom";
+
+export default function Modalidad({ id, setViewPageLoader }) {
+ const [modalidad, setModalidad] = useState();
+
+ const obtenerModalidad = async () => {
+ setViewPageLoader(true);
+ try {
+ const response = await api.modalidades.getById(Number(id));
+ setModalidad(response.data.data);
+ console.log("Modalidad extraída con éxito", response);
+ console.log(response.data);
+ } catch (error) {
+ console.error("Modalidad no extraída", error);
+ }
+ setViewPageLoader(false);
+ };
+
+ useEffect(() => {
+ obtenerModalidad();
+ }, [id]);
+
+ /* Función para mostrar el monto_maximo en formato de pesos MXN */
+ const formatCurrency = (amount) => {
+ return new Intl.NumberFormat("es-MX", {
+ style: "currency",
+ currency: "MXN",
+ }).format(amount);
+ };
+
+ return (
+ modalidad && (
+
+
+
+
+
+
+
+
+ Modalidad:
+
+
+
+ {modalidad.nombre}
+
+
+
+
+ {modalidad.descripcion}
+
+
+
+
+ {formatCurrency(modalidad.monto_maximo)}
+
+
+
+
+
+
+
+
+
+
+ {/* Campos para subir documentación. */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ );
+}
diff --git a/cosiap_frontend/src/components/modalidades/ModalidadCard.jsx b/cosiap_frontend/src/components/modalidades/ModalidadCard.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..b9d4fd2b18a157ee621fd9e28351cb2949b20f53
--- /dev/null
+++ b/cosiap_frontend/src/components/modalidades/ModalidadCard.jsx
@@ -0,0 +1,60 @@
+export function ModalidadCard({ title, description, monto, image, children }) {
+ /* Formatear monto con separadores de miles */
+ const formatCurrency = (amount) => {
+ return new Intl.NumberFormat("es-MX", {
+ style: "currency",
+ currency: "MXN",
+ }).format(amount);
+ };
+
+ return (
+
+
+
+
+ {`http://localhost:8000${image}`}
+
+
+
+
+
+
+ {/* (NOMBRE DE LA MODALIDAD) */}
+ {title}
+
+
+
+
+
+
+ {/* (Descripción de la modalidad) */}
+ {description}
+
+
+
+
+
{formatCurrency(monto)}
+
+ {children}
+
+
+
+ );
+}
diff --git a/cosiap_frontend/src/components/modalidades/Modalidades.jsx b/cosiap_frontend/src/components/modalidades/Modalidades.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..767dbc57eef3556e5480b6e17077209a08a64dc4
--- /dev/null
+++ b/cosiap_frontend/src/components/modalidades/Modalidades.jsx
@@ -0,0 +1,29 @@
+import ListaModalidades from "@/components/modalidades/ListaModalidades";
+import { useState } from "react";
+import Modalidad from "@/components/modalidades/Modalidad";
+
+export default function Modalidades({ setViewPageLoader }) {
+ const [viewModalidades, setViewModalidades] = useState(true);
+ const [viewModalidadDetail, setViewModalidadDetail] = useState(false);
+ const [selectedId, setSelectedId] = useState(null);
+
+ const handleModalidadDetail = (id) => {
+ setViewModalidades(false);
+ setViewModalidadDetail(true);
+ setSelectedId(id);
+ };
+
+ return (
+ <>
+ {viewModalidades && (
+
+ )}
+ {viewModalidadDetail && selectedId && (
+
+ )}
+ >
+ );
+}