vista de administrador

This commit is contained in:
Soka_jplr 2024-05-26 13:06:55 -06:00
parent 41b16210f2
commit f50deaf29d
5 changed files with 325 additions and 191 deletions

View File

@ -4,16 +4,19 @@ import Mensaje from '../Model/Mensaje.js'; // Asegúrate de tener la ruta correc
import DAORegistro from './DAORegistro.js'; import DAORegistro from './DAORegistro.js';
class DAO { class DAO {
static async dameAlumnos() {
static async matriculas() {
const conexion = new Conexion(); const conexion = new Conexion();
const conexionEstablecida = await conexion.conectar(); const conexionEstablecida = await conexion.conectar();
try { try {
const sql = `SELECT id, nombre, apellido, matricula FROM usuario`; const sql = `SELECT id, matricula FROM usuario where inscrito = 1`;
const [rows] = await conexionEstablecida.query(sql); const [rows] = await conexionEstablecida.query(sql);
const resultado = rows.map(row => new Usuario(row.id, row.nombre, row.apellido, row.matricula)); const resultado = rows.map(row => {
return { id: row.id, matricula: row.matricula };
});
return resultado; return resultado;
} catch (error) { } catch (error) {
console.error(error); console.error(error); s
return []; return [];
} finally { } finally {
conexion.cerrarConexion(); conexion.cerrarConexion();
@ -155,6 +158,61 @@ class DAO {
} }
return usuario; return usuario;
} }
static async editarAlumnoInscrito(data) {
const conexion = new Conexion();
const conexionEstablecida = await conexion.conectar();
try {
const sql = `UPDATE usuario SET inscrito = ? WHERE id = ?`;
const [result] = await conexionEstablecida.query(sql, [
1, data.idUsuario
]);
return result.affectedRows > 0;
} catch (error) {
} finally {
conexion.cerrarConexion();
}
}
static async traeTodosLosDatosUsuario(id) {
const conexion = new Conexion();
const conexionEstablecida = await conexion.conectar();
let usuario = null;
try {
const sql = `SELECT U.id,U.nombre,U.apellido,matricula,correo,nacionalidad,tipoSangre,fecha_nacimiento,curp,inscrito, T.nombre as tutorNombre, T.apellido as tutorApellido, T.numeroDeTelefono,C.nombre as carreraNombre FROM usuario U, tutor T, carrera C where C.id= U.idCarrera and U.id = T.idUsuario and inscrito =1 and U.id =?;`;
const [rows] = await conexionEstablecida.query(sql, [id]);
if (rows.length > 0) {
const row = rows[0];
// Convertir la fecha al formato "yyyy-MM-dd"
const fechaNacimiento = new Date(row.fecha_nacimiento);
const formattedDate = fechaNacimiento.toISOString().split('T')[0]; // "yyyy-MM-dd"
usuario = {
id: row.id,
nombre: row.nombre,
apellido: row.apellido,
matricula: row.matricula,
correo: row.correo,
nacionalidad: row.nacionalidad,
tipoSangre: row.tipoSangre,
fecha_nacimiento: formattedDate,
curp: row.curp,
inscrito: row.inscrito,
tutorNombre: row.tutorNombre,
tutorApellido: row.tutorApellido,
numeroDeTelefono: row.numeroDeTelefono,
carreraNombre: row.carreraNombre
}
}
} catch (error) {
console.error(error);
} finally {
conexion.cerrarConexion();
}
return usuario;
}
} }
export default DAO; export default DAO;

View File

@ -1,5 +1,6 @@
import express from 'express'; import express from 'express';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
import cors from 'cors';
import DAO from './Controller/DAO.js'; // Importa tus controladores DAO import DAO from './Controller/DAO.js'; // Importa tus controladores DAO
import DAOTutor from './Controller/DAOTutor.js'; import DAOTutor from './Controller/DAOTutor.js';
import DAOCarreras from './Controller/DAOCarrera.js'; import DAOCarreras from './Controller/DAOCarrera.js';
@ -31,18 +32,18 @@ const fileUpload = multer({
app.use(bodyParser.json()); app.use(bodyParser.json());
// Configuración de CORS // Configuración de CORS
app.use((req, res, next) => { app.use(cors({
res.header("Access-Control-Allow-Origin", "http://localhost:5173"); origin: 'http://localhost:5173', // Especifica el origen permitido
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); allowedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'],
res.header("Access-Control-Allow-Credentials", "true"); credentials: true
next(); }));
}); app.use(express.static(path.join(__dirname,'ActasNacimiento')))
// Rutas // Rutas
app.get("/todosLosAlumnos", async (req, res) => { app.get("/matriculas", async (req, res) => {
try { try {
const alumnos = await DAO.dameAlumnos(); const alumnos = await DAO.matriculas();
res.json(alumnos); res.json(alumnos);
} catch (error) { } catch (error) {
res.status(500).json({ error: error.message }); res.status(500).json({ error: error.message });
@ -159,9 +160,14 @@ app.post("/agregarDocumentoAN", fileUpload, async (req, res) => {
const guardado = await DAODocumento.agregarDocumento(data, file); const guardado = await DAODocumento.agregarDocumento(data, file);
if (guardado) { if (guardado) {
res.json({ message: "Archivo guardado correctamente" }); const cambiar = await DAO.editarAlumnoInscrito(data);
if (cambiar) {
res.json({ message: true });
} else {
res.json({ message: false });
}
} else { } else {
res.json({ message: "No se pudo guardar el archivo" }); res.json({ message: false });
} }
} catch (error) { } catch (error) {
res.status(500).json({ error: error.message }); res.status(500).json({ error: error.message });
@ -178,3 +184,13 @@ app.use((err, req, res, next) => {
app.listen(port, () => { app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`); console.log(`App listening at http://localhost:${port}`);
}); });
app.post("/traerTodosDatosAlumno", async (req, res) => {
try {
const usuario = req.body;
const datos = await DAO.traeTodosLosDatosUsuario(usuario.id);
res.json(datos);
} catch (error) {
res.status(500).json({ error: error.message });
}
});

View File

@ -18,7 +18,8 @@ const Inscripcion = () => {
tipoSangre: "", tipoSangre: "",
fecha_nacimiento: "", fecha_nacimiento: "",
curp: "", curp: "",
idCarrera: 0 idCarrera: 0,
inscrito:0
}); });
const [tutor, setTutor] = useState({ const [tutor, setTutor] = useState({
@ -53,7 +54,8 @@ const Inscripcion = () => {
tipoSangre: resUsuario.data.tipoSangre || "", tipoSangre: resUsuario.data.tipoSangre || "",
fecha_nacimiento: resUsuario.data.fecha_nacimiento || "", fecha_nacimiento: resUsuario.data.fecha_nacimiento || "",
curp: resUsuario.data.curp || "", curp: resUsuario.data.curp || "",
idCarrera: resUsuario.data.idCarrera || 0 idCarrera: resUsuario.data.idCarrera || 0,
inscrito: resUsuario.data.inscrito || 0
})); }));
} else { } else {
console.log('Error: No hay usuario'); console.log('Error: No hay usuario');
@ -157,155 +159,162 @@ const Inscripcion = () => {
formData.append('titulo', `${usuario.matricula}_ActaN`); formData.append('titulo', `${usuario.matricula}_ActaN`);
formData.append('archivo', actaN.archivo); formData.append('archivo', actaN.archivo);
formData.append('idUsuario', usuario.id); formData.append('idUsuario', usuario.id);
fetch('http://localhost:3000/agregarDocumentoAN',{ const reqs = await axios.post('/agregarDocumentoAN', formData,{
method: 'POST', headers: {
body: formData 'Content-Type': 'multipart/form-data',
}).then(res=>res.text()) },
.then(res => console.log(res)) });
.catch(err=>{ if (reqs){
console.error(err) window.location.reload();
}) }
setActaN(null)
} catch (error) { } catch (error) {
console.error('Error al subir los datos:', error); console.error('Error al subir los datos:', error);
//window.location.reload();
} }
}; };
return ( return (
<div className='container'> <>
<div className='nbn'> {usuario.inscrito !== 1 ? (
<form onSubmit={subir}> <div className='container'>
<div className="mb-4"> <div className='nbn'>
<h5>Datos Personales</h5> <form onSubmit={subir}>
<DivInput <div className="mb-4">
type="text" <h5>Datos Personales</h5>
name="nombre" <DivInput
value={usuario.nombre} type="text"
className="form-control mb-3" name="nombre"
placeholder="Nombre" value={usuario.nombre}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="Nombre"
/> required
<DivInput handleChange={handleInputChange}
type="text" />
name="apellido" <DivInput
value={usuario.apellido} type="text"
className="form-control mb-3" name="apellido"
placeholder="Apellido" value={usuario.apellido}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="Apellido"
/> required
<DivInput handleChange={handleInputChange}
type="email" />
name="correo" <DivInput
value={usuario.correo} type="email"
className="form-control mb-3" name="correo"
placeholder="Correo Electrónico" value={usuario.correo}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="Correo Electrónico"
/> required
<DivInput handleChange={handleInputChange}
type="text" />
name="nacionalidad" <DivInput
value={usuario.nacionalidad} type="text"
className="form-control mb-3" name="nacionalidad"
placeholder="Nacionalidad" value={usuario.nacionalidad}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="Nacionalidad"
/> required
<DivInput handleChange={handleInputChange}
type="text" />
name="tipoSangre" <DivInput
value={usuario.tipoSangre} type="text"
className="form-control mb-3" name="tipoSangre"
placeholder="Tipo de Sangre" value={usuario.tipoSangre}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="Tipo de Sangre"
/> required
<h6>Fecha de Nacimiento</h6> handleChange={handleInputChange}
<DivInput />
type="date" <h6>Fecha de Nacimiento</h6>
name="fecha_nacimiento" <DivInput
value={usuario.fecha_nacimiento} type="date"
className="form-control mb-3" name="fecha_nacimiento"
placeholder="Fecha de Nacimiento" value={usuario.fecha_nacimiento}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="Fecha de Nacimiento"
/> required
<DivInput handleChange={handleInputChange}
type="text" />
name="curp" <DivInput
value={usuario.curp} type="text"
className="form-control mb-3" name="curp"
placeholder="CURP" value={usuario.curp}
required className="form-control mb-3"
handleChange={handleInputChange} placeholder="CURP"
/> required
handleChange={handleInputChange}
/>
</div>
<div className="mb-4">
<h5>Datos del Tutor</h5>
<DivInput
type="text"
name="nombre"
value={tutor.nombre}
className="form-control mb-3"
placeholder="Nombre"
required
handleChange={handleTutorInputChange}
/>
<DivInput
type="text"
name="apellido"
value={tutor.apellido}
className="form-control mb-3"
placeholder="Apellidos"
required
handleChange={handleTutorInputChange}
/>
<DivInput
type="tel"
name="numeroDeTelefono"
value={tutor.numeroDeTelefono}
className="form-control mb-3"
placeholder="Número de Teléfono"
required
handleChange={handleTutorInputChange}
/>
</div>
<div className="mb-4">
<h5>Carrera</h5>
<select
id="carreraSelect"
className="form-control"
value={carreraSeleccionada}
onChange={handleCarreraChange}
>
<option value="" disabled>Selecciona una carrera</option>
{carrera.map((carrera) => (
<option key={carrera.id} value={carrera.id}>
{carrera.nombre}
</option>
))}
</select>
</div>
<div className="mb-4">
<h5>Documentación</h5>
<h6>Acta De Nacimiento</h6>
<input
type="file"
name="archivo"
className="form-control mb-3"
accept=".pdf"
placeholder="Acta de Nacimiento"
required
onChange={handleFileChange}
/>
</div>
<button type="submit" className="btn btn-primary">Enviar Inscripción</button>
</form>
</div> </div>
<div className="mb-4"> </div>
<h5>Datos del Tutor</h5> ) : (
<DivInput <div className="d-flex justify-content-center align-items-center vh-100">
type="text" <div className="p-5 text-center bg-light border rounded shadow">
name="nombre" Inscripción en Proceso, Validando los datos por favor revisa esta página dentro de una semana
value={tutor.nombre} </div>
className="form-control mb-3" </div>
placeholder="Nombre" )}
required </>
handleChange={handleTutorInputChange}
/>
<DivInput
type="text"
name="apellido"
value={tutor.apellido}
className="form-control mb-3"
placeholder="Apellidos"
required
handleChange={handleTutorInputChange}
/>
<DivInput
type="tel"
name="numeroDeTelefono"
value={tutor.numeroDeTelefono}
className="form-control mb-3"
placeholder="Número de Teléfono"
required
handleChange={handleTutorInputChange}
/>
</div>
<div className="mb-4">
<h5>Carrera</h5>
<select
id="carreraSelect"
className="form-control"
value={carreraSeleccionada}
onChange={handleCarreraChange}
>
<option value="" disabled>Selecciona una carrera</option>
{carrera.map((carrera) => (
<option key={carrera.id} value={carrera.id}>
{carrera.nombre}
</option>
))}
</select>
</div>
<div className="mb-4">
<h5>Documentación</h5>
<h6>Acta De Nacimiento</h6>
<input
type="file"
name="archivo"
className="form-control mb-3"
accept=".pdf"
placeholder="Acta de Nacimiento"
required
onChange={handleFileChange}
/>
</div>
<button type="submit" className="btn btn-primary">Enviar Inscripción</button>
</form>
</div>
</div>
); );
}; };

View File

@ -1,47 +1,100 @@
import React, { useState } from 'react'; import axios from 'axios';
import React, { useState, useEffect } from 'react';
const ValidacionAdm = () => { const ValidacionAdm = () => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [alumno, setAlumno] = useState({});
const [matriculas, setMatriculas] = useState([]);
const [currentMatriculaIndex, setCurrentMatriculaIndex] = useState(0);
const handleLoad = () => { useEffect(() => {
setLoading(false); const fetchData = async () => {
try {
const resMatriculas = await axios.get('http://localhost:3000/matriculas');
if (resMatriculas.status === 200 && resMatriculas.data.length > 0) {
setMatriculas(resMatriculas.data);
await fetchAlumnoData(resMatriculas.data[0].id);
}
} catch (error) {
console.log(error);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
const fetchAlumnoData = async (id) => {
try {
const resAlumno = await axios.post('http://localhost:3000/traerTodosDatosAlumno', { id: parseInt(id, 10) });
if (resAlumno.status === 200) {
setAlumno(resAlumno.data);
}
} catch (error) {
console.log(error);
}
}; };
const handlePreviousMatricula = () => {
if (currentMatriculaIndex > 0) {
const newIndex = currentMatriculaIndex - 1;
setCurrentMatriculaIndex(newIndex);
fetchAlumnoData(matriculas[newIndex].id);
}
};
const handleNextMatricula = () => {
if (currentMatriculaIndex < matriculas.length - 1) {
const newIndex = currentMatriculaIndex + 1;
setCurrentMatriculaIndex(newIndex);
fetchAlumnoData(matriculas[newIndex].id);
}
};
if (loading) {
return <div>Loading...</div>;
}
return ( return (
<div className="container mt-4"> <div className="container mt-4">
<h1 className="text-center mb-4">Validacion Administrativa</h1> <h1 className="text-center mb-4">Validación Administrativa</h1>
<div className="input-group mb-3 justify-content-center"> <div className="input-group mb-3 justify-content-center">
<div className="input-group-prepend"> <div className="input-group-prepend">
<button className="btn btn-sm p-0 border-0" type="button"> <button className="btn btn-sm p-0 border-0" type="button" onClick={handlePreviousMatricula}>
<img src="left-arrow.png" alt="Icono de flecha izquierda" style={{ width: '20px', height: '20px' }} /> <img src="left-arrow.png" alt="Icono de flecha izquierda" style={{ width: '20px', height: '20px' }} />
</button> </button>
</div> </div>
<input type="text" className="form-control form-control-sm text-center" style={{ maxWidth: '250px' }} placeholder="Aqui aparece la matricula" /> <input
type="text"
className="form-control form-control-sm text-center"
style={{ maxWidth: '250px' }}
placeholder="Aqui aparece la matricula"
value={matriculas[currentMatriculaIndex].matricula}
readOnly
/>
<div className="input-group-append"> <div className="input-group-append">
<button className="btn btn-sm p-0 border-0" type="button"> <button className="btn btn-sm p-0 border-0" type="button" onClick={handleNextMatricula}>
<img src="right-arrow.png" alt="Icono de flecha derecha" style={{ width: '20px', height: '20px' }} /> <img src="right-arrow.png" alt="Icono de flecha derecha" style={{ width: '20px', height: '20px' }} />
</button> </button>
</div> </div>
</div> </div>
<div className="card mb-4"> <div className="card mb-4">
<div className="card-body"> <div className="card-body">
<h2 className="card-title">Datos del Alumno</h2> <h2 className="card-title">Datos del Alumno</h2>
<div className="row"> <div className="row">
<div className="col-md-6"> <div className="col-md-6">
<p className="card-text"><strong>Nombre:</strong> { } </p> <p className="card-text"><strong>Nombre:</strong> {alumno.nombre}</p>
<p className="card-text"><strong>Apellido:</strong>{ } </p> <p className="card-text"><strong>Apellido:</strong> {alumno.apellido}</p>
<p className="card-text"><strong>Matricula:</strong> { }</p> <p className="card-text"><strong>Matricula:</strong> {alumno.matricula}</p>
<p className="card-text"><strong>Correo:</strong>{ } </p> <p className="card-text"><strong>Correo:</strong> {alumno.correo}</p>
<p className="card-text"><strong>Nacionalidad:</strong>{ } </p> <p className="card-text"><strong>Nacionalidad:</strong> {alumno.nacionalidad}</p>
<p className="card-text"><strong>Tipo de sangre:</strong>{ } </p> <p className="card-text"><strong>Tipo de sangre:</strong> {alumno.tipoSangre}</p>
<p className="card-text"><strong>Fecha de nacimiento:</strong>{ } </p> <p className="card-text"><strong>Fecha de nacimiento:</strong> {alumno.fecha_nacimiento}</p>
<p className="card-text"><strong>CURP:</strong>{ } </p> <p className="card-text"><strong>CURP:</strong> {alumno.curp}</p>
<p className="card-text"><strong>Carrera:</strong>{ } </p> <p className="card-text"><strong>Carrera:</strong> {alumno.carreraNombre}</p>
</div> </div>
</div> </div>
</div> </div>
@ -52,9 +105,9 @@ const ValidacionAdm = () => {
<h2 className="card-title">Datos del Tutor</h2> <h2 className="card-title">Datos del Tutor</h2>
<div className="row"> <div className="row">
<div className="col-md-6"> <div className="col-md-6">
<p className="card-text"><strong>Nombre:</strong> { } </p> <p className="card-text"><strong>Nombre:</strong> {alumno.tutorNombre}</p>
<p className="card-text"><strong>Apellido:</strong>{ } </p> <p className="card-text"><strong>Apellido:</strong> {alumno.tutorApellido}</p>
<p className="card-text"><strong>Teléfono:</strong>{ }</p> <p className="card-text"><strong>Teléfono:</strong> {alumno.numeroDeTelefono}</p>
</div> </div>
</div> </div>
</div> </div>
@ -62,35 +115,33 @@ const ValidacionAdm = () => {
<div className="card mb-4"> <div className="card mb-4">
<div className="card-body"> <div className="card-body">
<h2 className="card-title">Documentos de Alumno</h2> <h2 className="card-title">Documentos del Alumno</h2>
<div className="pdf-container mb-4"> <div className="pdf-container mb-4">
<p className="card-text"><strong>Acta de Nacimiento:</strong> </p> <p className="card-text"><strong>Acta de Nacimiento:</strong></p>
<embed src={"mapa_curri_TC.pdf"} type="application/pdf" width="100%" height="300px" onLoad={handleLoad} /> <embed src={'http://localhost:3000/'+alumno.matricula+'_ActaN.pdf'} type="application/pdf" width="100%" height="300px" />
<div className="d-flex justify-content-center mt-3"> <div className="d-flex justify-content-center mt-3">
<button className="btn btn-primary btn-sm me-1">Aceptar Documentos</button> <button className="btn btn-primary btn-sm me-1">Aceptar Documentos</button>
<button className="btn btn-primary btn-sm ms-1">Rechazar Documentos</button> <button className="btn btn-primary btn-sm ms-1">Rechazar Documentos</button>
</div> </div>
</div> </div>
<div className="pdf-container mb-4"> <div className="pdf-container mb-4">
<p className="card-text"><strong>Constancia de estudios :</strong> </p> <p className="card-text"><strong>Constancia de estudios:</strong></p>
<embed src={"mapa_curri_TC.pdf"} type="application/pdf" width="100%" height="300px" onLoad={handleLoad} /> <embed src={alumno.constanciaEstudios} type="application/pdf" width="100%" height="300px" />
<div className="d-flex justify-content-center mt-3"> <div className="d-flex justify-content-center mt-3">
<button className="btn btn-primary btn-sm me-1">Aceptar Documentos</button> <button className="btn btn-primary btn-sm me-1">Aceptar Documentos</button>
<button className="btn btn-primary btn-sm ms-1">Rechazar Documentos</button> <button className="btn btn-primary btn-sm ms-1">Rechazar Documentos</button>
</div> </div>
</div> </div>
<div className="pdf-container mb-4"> <div className="pdf-container mb-4">
<p className="card-text"><strong>Fotografia:</strong> </p> <p className="card-text"><strong>Fotografía:</strong></p>
<embed src={"mapa_curri_TC.pdf"} type="application/pdf" width="100%" height="300px" onLoad={handleLoad} /> <embed src={alumno.fotografia} type="application/pdf" width="100%" height="300px" />
<div className="d-flex justify-content-center mt-3"> <div className="d-flex justify-content-center mt-3">
<button className="btn btn-primary btn-sm me-1">Aceptar Documentos</button> <button className="btn btn-primary btn-sm me-1">Aceptar Documentos</button>
<button className="btn btn-primary btn-sm ms-1">Rechazar Documentos</button> <button className="btn btn-primary btn-sm ms-1">Rechazar Documentos</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
); );
}; };