Nuevos estilos y se agrego la vista de alumno
This commit is contained in:
+122
-27
@@ -1,27 +1,107 @@
|
||||
"use client"
|
||||
import { axiosInstance } from "@/api/config";
|
||||
import BarraProgreso from "@/components/alumno/barra-progreso";
|
||||
import CompletarDatosPersonales from "@/components/alumno/completar-datos-personales";
|
||||
import NavCues from "@/components/alumno/cuestionario/nav-cues";
|
||||
import InformacinoServicio from "@/components/alumno/informacion-servicio";
|
||||
import MensajeAlumno from "@/components/alumno/mensajes-alumno";
|
||||
import PreTermino from "@/components/alumno/pre-termino";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface InfoAlumnoExtendido extends InfoAlumno {
|
||||
Usuario: { usuario: string, nombre: string},
|
||||
}
|
||||
|
||||
interface Usuario {
|
||||
usuario: string,
|
||||
nombre: string,
|
||||
}
|
||||
|
||||
interface InfoAlumno{
|
||||
idServicio: number,
|
||||
creditos: string,
|
||||
correo: string,
|
||||
telefono: string,
|
||||
direccion: string,
|
||||
fechaInicio: string,
|
||||
fechaFin: string,
|
||||
fechaLiberacion: string,
|
||||
informeGlobal: string, // Falta ajustar el tipo de datos
|
||||
programaInterno: string,
|
||||
profesor: string,
|
||||
//createdAt: Date,
|
||||
idCuestionarioAlumno: number,
|
||||
idCuestionarioAlumno2: number,
|
||||
Carrera: Carrera,
|
||||
Status: Status,
|
||||
Programa: Programa,
|
||||
}
|
||||
|
||||
interface Carrera {
|
||||
idCarrera: number,
|
||||
carrera: string,
|
||||
}
|
||||
|
||||
interface Status {
|
||||
idStatus: number,
|
||||
status: string,
|
||||
}
|
||||
|
||||
interface Programa {
|
||||
idPrograma: number,
|
||||
institucion: string,
|
||||
dependencia: string,
|
||||
programa: string,
|
||||
clavePrograma: string,
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const [data, setData] = useState<InfoAlumnoExtendido>();
|
||||
|
||||
const tokenAlumno = localStorage.getItem('token')
|
||||
|
||||
const handleInfo = async () => {
|
||||
const idUsuario = localStorage.getItem('idUsuario');
|
||||
const usuario = localStorage.getItem('usuario');
|
||||
const nombre = localStorage.getItem('nombre');
|
||||
|
||||
console.log('entro para hacer el fetch')
|
||||
console.log('Este es el id del usuario', idUsuario)
|
||||
|
||||
try {
|
||||
const inf = await axiosInstance.get(`/servicio/alumno?idUsuario=${idUsuario}`)
|
||||
|
||||
const Usuario = {
|
||||
usuario, nombre,
|
||||
}
|
||||
|
||||
console.log("Esta es la inforamcion que trae el back", inf);
|
||||
|
||||
const combinado: InfoAlumnoExtendido = { ...inf.data, Usuario };
|
||||
console.log('Esta es la info combinada', combinado)
|
||||
|
||||
setData(combinado);
|
||||
console.log("Este es la infromacion combinada", data);
|
||||
} catch (error) {
|
||||
console.log("Error al hacer la peticion ", error)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
handleInfo();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<BarraProgreso idStatus={5}/>
|
||||
<CompletarDatosPersonales
|
||||
idServicio={123}
|
||||
alumno={{ token: { headers: { Authorization: "Bearer ..." } }, tokenArchivo: { headers: { Authorization: "Bearer ..." } } }}
|
||||
imprimirMensaje={(msg) => console.log(msg)}
|
||||
imprimirWarning={(msg, callback) => { if (confirm(msg)) callback(); }}
|
||||
imprimirError={(err) => console.error(err)}
|
||||
obtenerServicio={() => console.log("obtener servicio")}
|
||||
updateIsLoading={(loading) => console.log("loading", loading)}
|
||||
/>
|
||||
{ data?.Status.idStatus && (
|
||||
<BarraProgreso idStatus={data?.Status.idStatus}/>
|
||||
)}
|
||||
|
||||
<InformacinoServicio
|
||||
servicio={{
|
||||
<div className="my-5">
|
||||
<MensajeAlumno Status={{ idStatus: 2 }} />
|
||||
</div>
|
||||
|
||||
{/* servicio={{
|
||||
Programa: {
|
||||
institucion: "UNAM",
|
||||
dependencia: "Académicos",
|
||||
@@ -35,25 +115,40 @@ export default function Home() {
|
||||
fechaInicio: new Date().toISOString(),
|
||||
fechaFin: new Date().toISOString(),
|
||||
createdAt: new Date().toISOString(),
|
||||
}}
|
||||
/>
|
||||
}} */}
|
||||
|
||||
{ data && (
|
||||
<InformacinoServicio
|
||||
servicio={data}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MensajeAlumno Status={{ idStatus: 2 }} />
|
||||
{ data?.Status.idStatus === 2 && (
|
||||
<CompletarDatosPersonales
|
||||
idServicio={123}
|
||||
alumno={{ token: { headers: { Authorization: "Bearer ..." } }, tokenArchivo: { headers: { Authorization: "Bearer ..." } } }}
|
||||
imprimirMensaje={(msg) => console.log(msg)}
|
||||
imprimirWarning={(msg, callback) => { if (confirm(msg)) callback(); }}
|
||||
imprimirError={(err) => console.error(err)}
|
||||
obtenerServicio={() => console.log("obtener servicio")}
|
||||
updateIsLoading={(loading) => console.log("loading", loading)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<PreTermino
|
||||
alumno={{ tokenArchivo: "token123" }}
|
||||
servicio={{ idServicio: 123, informeGlobal: undefined }}
|
||||
imprimirMensaje={(msg) => console.log(msg)}
|
||||
imprimirWarning={(msg, callback) => {
|
||||
if (confirm(msg)) callback();
|
||||
}}
|
||||
imprimirError={(err) => console.error(err)}
|
||||
obtenerServicio={() => console.log("obtener servicio")}
|
||||
updateIsLoading={(loading) => console.log("loading", loading)}
|
||||
/>
|
||||
{ data?.Status.idStatus !== undefined && data?.Status.idStatus >= 4 && (
|
||||
<PreTermino
|
||||
alumno={{ tokenArchivo: "token123" }}
|
||||
servicio={data}
|
||||
imprimirMensaje={(msg) => console.log(msg)}
|
||||
imprimirWarning={(msg, callback) => {
|
||||
if (confirm(msg)) callback();
|
||||
}}
|
||||
imprimirError={(err) => console.error(err)}
|
||||
obtenerServicio={() => console.log("obtener servicio")}
|
||||
updateIsLoading={(loading) => console.log("loading", loading)}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { FaUserPlus, FaUserCheck, FaUser, FaUsers, FaUserClock, FaUserTie } from "react-icons/fa";
|
||||
|
||||
interface Props {
|
||||
idStatus: number;
|
||||
}
|
||||
|
||||
interface Step {
|
||||
label: string;
|
||||
icon: string; // Puedes usar iconos de heroicons o font-awesome
|
||||
visible: boolean;
|
||||
type?: "default" | "danger";
|
||||
}
|
||||
|
||||
export default function BarraProgreso({ idStatus }: Props) {
|
||||
const steps: Step[] = [
|
||||
{ label: "Pre Registro", icon: "account-plus", visible: idStatus < 6 },
|
||||
{ label: "Pre Registro Validado", icon: "account-clock", visible: idStatus < 6 },
|
||||
{ label: "Registro", icon: "account", visible: idStatus < 6 },
|
||||
{ label: "Pre Termino", icon: "account-details", visible: idStatus < 6 },
|
||||
{ label: "Termino", icon: "account-clock", visible: idStatus < 6 },
|
||||
{ label: "Liberacion", icon: "account-check", visible: idStatus < 6 },
|
||||
{ label: "Carta Aceptación Rechazada", icon: "file", visible: idStatus === 6, type: "danger" },
|
||||
{ label: "Carta Termino Rechazada", icon: "file", visible: idStatus === 7, type: "danger" },
|
||||
{ label: "Informe Global Rechazado", icon: "file", visible: idStatus === 8, type: "danger" },
|
||||
{ label: "Cancelado", icon: "account-cancel", visible: idStatus === 9, type: "danger" },
|
||||
const steps = [
|
||||
{ label: "Pre Registro", icon: <FaUserPlus />, id: 1 },
|
||||
{ label: "Pre Registro Validado", icon: <FaUserCheck />, id: 2 },
|
||||
{ label: "Registro", icon: <FaUser />, id: 3 },
|
||||
{ label: "Pre Termino", icon: <FaUsers />, id: 4 },
|
||||
{ label: "Termino", icon: <FaUserClock />, id: 5 },
|
||||
{ label: "Liberacion", icon: <FaUserTie />, id: 6 },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="b-steps-container mt-6 mb-5">
|
||||
<div className="b-steps">
|
||||
{steps.filter(s => s.visible).map((step, idx) => (
|
||||
<div key={idx} className={`step-item ${step.type === 'danger' ? 'is-danger' : 'is-info'}`} aria-hidden>
|
||||
<div className="step-marker">
|
||||
{/* Placeholder icon: use font-awesome or heroicons in the app */}
|
||||
<span className={`icon ${step.type === 'danger' ? 'icon-danger' : 'icon-info'}`} aria-hidden>
|
||||
<i className={`fa fa-${step.icon}`} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="step-details">
|
||||
<div className="step-title">{step.label}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="container mt-5">
|
||||
<div className="d-flex justify-content-center align-items-center position-relative">
|
||||
{steps.map((step, index) => {
|
||||
const isActive = idStatus >= step.id;
|
||||
const isCurrent = idStatus === step.id;
|
||||
|
||||
<style jsx>{`
|
||||
.b-steps { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: stretch; }
|
||||
.step-item { display: flex; align-items: center; padding: 0.6rem 0.9rem; border-radius: 6px; background: #e6f2ff; color: #0b66b2; min-width: 220px; }
|
||||
.step-item.is-info { background: #ecf8ff; color: #0b66b2; }
|
||||
.step-item.is-danger { background: #ffecec; color: #a10b0b; }
|
||||
.step-marker { display:flex; align-items:center; justify-content:center; width:40px; height:40px; border-radius:50%; margin-right:0.75rem; background: rgba(255,255,255,0.6); }
|
||||
.step-item.is-info .step-marker { background: #dff4ff; }
|
||||
.step-item.is-danger .step-marker { background: #ffdede; }
|
||||
.icon { font-size: 1.1rem; }
|
||||
.step-title { font-weight: 600; font-size: 0.95rem; }
|
||||
return (
|
||||
<div key={index} className="text-center position-relative flex-fill">
|
||||
{/* Línea de conexión */}
|
||||
{index > 0 && (
|
||||
<div
|
||||
className={`position-absolute top-50 start-0 translate-middle-y w-100 border-top ${
|
||||
isActive ? "border-primary" : "border-secondary opacity-25"
|
||||
}`}
|
||||
style={{ zIndex: 0 }}
|
||||
></div>
|
||||
)}
|
||||
|
||||
/* Mimic the Buefy rule to hide ::before/::after on danger steps */
|
||||
.b-steps .step-item.is-danger::before,
|
||||
.b-steps .step-item.is-danger::after {
|
||||
display: none !important;
|
||||
content: none !important;
|
||||
}
|
||||
{/* Círculo del paso */}
|
||||
<div
|
||||
className={`rounded-circle d-flex justify-content-center align-items-center mx-auto mb-2 border ${
|
||||
isActive
|
||||
? "bg-primary text-white border-primary"
|
||||
: isCurrent
|
||||
? "border-primary text-primary bg-white"
|
||||
: "bg-light text-secondary border-secondary opacity-75"
|
||||
}`}
|
||||
style={{
|
||||
width: "48px",
|
||||
height: "48px",
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
{step.icon}
|
||||
</div>
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.step-item { min-width: 140px; padding: 0.45rem 0.6rem; }
|
||||
.step-title { font-size: 0.85rem; }
|
||||
}
|
||||
`}</style>
|
||||
{/* Título */}
|
||||
<div
|
||||
className={`fw-semibold ${
|
||||
isActive || isCurrent ? "text-dark" : "text-secondary"
|
||||
}`}
|
||||
style={{ fontSize: "0.95rem" }}
|
||||
>
|
||||
{step.label}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import { axiosInstance } from '@/api/config';
|
||||
import { isAxiosError } from 'axios';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import moment from "moment";
|
||||
import { Col, FormGroup, FormLabel, InputGroup } from "react-bootstrap";
|
||||
import { FaRegCalendarAlt } from "react-icons/fa";
|
||||
|
||||
interface Alumno {
|
||||
token: { headers: Record<string, string> };
|
||||
@@ -74,64 +76,89 @@ export default function CompletarDatosPersonales({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-xl font-semibold">Formulario Pre-registro</h3>
|
||||
<div className="container space-y-4">
|
||||
<h2 className="text-xl fw-semibold">Formulario Pre-registro</h2>
|
||||
|
||||
{/* Fecha de nacimiento */}
|
||||
<div>
|
||||
<label className="block mb-1 font-medium">Fecha de nacimiento</label>
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel className="form-label fw-semibold">Fecha de nacimiento:</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text>
|
||||
<FaRegCalendarAlt />
|
||||
</InputGroup.Text>
|
||||
<DatePicker
|
||||
selected={nacimiento}
|
||||
onChange={(date: Date | null) => {
|
||||
if (date) setNacimiento(date);
|
||||
}}
|
||||
maxDate={maxDate}
|
||||
className="border border-gray-300 rounded px-3 py-2 form-control"
|
||||
placeholderText="Fecha de nacimiento"
|
||||
wrapperClassName="flex-grow-1"
|
||||
calendarClassName="mi-calendario"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
{/*
|
||||
<div className="mb-3">
|
||||
<label className="block mb-1 fw-semibold">Fecha de nacimiento</label>
|
||||
<DatePicker
|
||||
selected={nacimiento}
|
||||
onChange={(date: Date | null) => {
|
||||
if (date) setNacimiento(date);
|
||||
}}
|
||||
maxDate={maxDate}
|
||||
className="border border-gray-300 rounded px-3 py-2 w-full"
|
||||
className="border border-gray-300 rounded px-3 py-2 form-control"
|
||||
placeholderText="Fecha de nacimiento"
|
||||
/>
|
||||
wrapperClassName="flex-grow-1"
|
||||
calendarClassName="mi-calendario"
|
||||
/>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
{/* Teléfono */}
|
||||
<div>
|
||||
<label className="block mb-1 font-medium">Teléfono</label>
|
||||
<div className="mb-3">
|
||||
<label className="block mb-1 form-label fw-semibold mb-2">Teléfono</label>
|
||||
<input
|
||||
type="tel"
|
||||
placeholder="Teléfono"
|
||||
maxLength={10}
|
||||
value={telefono}
|
||||
onChange={(e) => setTelefono(e.target.value)}
|
||||
className="border border-gray-300 rounded px-3 py-2 w-full"
|
||||
type="tel"
|
||||
placeholder="Teléfono"
|
||||
maxLength={10}
|
||||
value={telefono}
|
||||
onChange={(e) => setTelefono(e.target.value)}
|
||||
className="border border-gray-300 rounded px-3 py-2 form-control"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Dirección */}
|
||||
<div>
|
||||
<label className="block mb-1 font-medium">Dirección</label>
|
||||
<div className="mb-3">
|
||||
<label className="block mb-1 form-label fw-semibold mb-2">Dirección</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Dirección"
|
||||
maxLength={200}
|
||||
value={direccion}
|
||||
onChange={(e) => setDireccion(e.target.value)}
|
||||
className="border border-gray-300 rounded px-3 py-2 w-full"
|
||||
type="text"
|
||||
placeholder="Dirección"
|
||||
maxLength={200}
|
||||
value={direccion}
|
||||
onChange={(e) => setDireccion(e.target.value)}
|
||||
className="border border-gray-300 rounded px-3 py-2 form-control"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Botón enviar */}
|
||||
<div className="text-center mt-4">
|
||||
<button
|
||||
disabled={!telefono || !direccion}
|
||||
onClick={() =>
|
||||
imprimirWarning(
|
||||
"¿Estas seguro(a) que tus datos son correctos?",
|
||||
terminarPreRegistro
|
||||
)
|
||||
}
|
||||
className={`px-4 py-2 rounded text-white ${
|
||||
!telefono || !direccion
|
||||
? "bg-gray-400 cursor-not-allowed"
|
||||
: "bg-green-600 hover:bg-green-700"
|
||||
}`}
|
||||
disabled={!telefono || !direccion}
|
||||
onClick={() =>
|
||||
imprimirWarning(
|
||||
"¿Estas seguro(a) que tus datos son correctos?",
|
||||
terminarPreRegistro
|
||||
)
|
||||
}
|
||||
className={`px-4 py-2 rounded text-white mb-5 ${
|
||||
!telefono || !direccion
|
||||
? "bg-gray-400 cursor-not-allowed"
|
||||
: "bg-green-600 hover:bg-green-700"
|
||||
}`}
|
||||
>
|
||||
Enviar
|
||||
</button>
|
||||
|
||||
@@ -50,116 +50,116 @@ export default function InformacinoServicio({ servicio }: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Datos del programa */}
|
||||
<div className="mb-5">
|
||||
<h4 className="is-size-4 pb-2">Datos del programa</h4>
|
||||
<div className="container">
|
||||
{/* Datos del programa */}
|
||||
<div className="mb-5">
|
||||
<h4 className="is-size-4 pb-2">Datos del programa</h4>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Institución:</label>
|
||||
<p className="input">{servicio.Programa.institucion}</p>
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Institución:</label>
|
||||
<p className="form-control">{servicio.Programa.institucion}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Dependencia:</label>
|
||||
<p className="form-control">{servicio.Programa.dependencia}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Programa:</label>
|
||||
<p className="form-control">{servicio.Programa.programa}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Clave de programa:</label>
|
||||
<p className="form-control">{servicio.Programa.clavePrograma}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Dependencia:</label>
|
||||
<p className="input">{servicio.Programa.dependencia}</p>
|
||||
</div>
|
||||
{/* Datos personales */}
|
||||
<div className="mb-5">
|
||||
<h4 className="is-size-4 pb-2">Datos personales</h4>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Programa:</label>
|
||||
<p className="input">{servicio.Programa.programa}</p>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Número de cuenta:</label>
|
||||
<p className="form-control">{servicio.Usuario.usuario}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Clave de programa:</label>
|
||||
<p className="input">{servicio.Programa.clavePrograma}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Nombre:</label>
|
||||
<p className="form-control">{servicio.Usuario.nombre}</p>
|
||||
</div>
|
||||
|
||||
{/* Datos personales */}
|
||||
<div className="mb-5">
|
||||
<h4 className="is-size-4 pb-2">Datos personales</h4>
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Carrera:</label>
|
||||
<p className="form-control">{servicio.Carrera.carrera}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Número de cuenta:</label>
|
||||
<p className="input">{servicio.Usuario.usuario}</p>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Créditos:</label>
|
||||
<p className="form-control">
|
||||
{servicio.creditos ? parseInt(servicio.creditos) : ""}
|
||||
{servicio.creditos && "%"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Nombre:</label>
|
||||
<p className="input">{servicio.Usuario.nombre}</p>
|
||||
</div>
|
||||
{servicio.telefono && (
|
||||
<div className="mb-2">
|
||||
<label className="form-label">Teléfono:</label>
|
||||
<p className="form-control">{servicio.telefono}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Carrera:</label>
|
||||
<p className="input">{servicio.Carrera.carrera}</p>
|
||||
</div>
|
||||
{servicio.direccion && (
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Dirección:</label>
|
||||
<p className="form-control">{servicio.direccion}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Créditos:</label>
|
||||
<p className="input">
|
||||
{servicio.creditos ? parseInt(servicio.creditos) : ""}
|
||||
{servicio.creditos && "%"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Email:</label>
|
||||
<p className="form-control">{servicio.correo}</p>
|
||||
</div>
|
||||
|
||||
{servicio.telefono && (
|
||||
<div className="mb-2">
|
||||
<label>Teléfono:</label>
|
||||
<p className="input">{servicio.telefono}</p>
|
||||
</div>
|
||||
)}
|
||||
{servicio.programaInterno && (
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Programa Interno:</label>
|
||||
<p className="form-control">{servicio.programaInterno}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{servicio.direccion && (
|
||||
<div className="mb-2">
|
||||
<label>Dirección:</label>
|
||||
<p className="input">{servicio.direccion}</p>
|
||||
</div>
|
||||
)}
|
||||
{servicio.profesor && (
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Profesor:</label>
|
||||
<p className="form-control">{servicio.profesor}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Email:</label>
|
||||
<p className="input">{servicio.correo}</p>
|
||||
</div>
|
||||
{servicio.createdAt && (
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Fecha de registro:</label>
|
||||
<p className="form-control">{fecha(servicio.createdAt)}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{servicio.programaInterno && (
|
||||
<div className="mb-2">
|
||||
<label>Programa Interno:</label>
|
||||
<p className="input">{servicio.programaInterno}</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Fecha de inicio:</label>
|
||||
<p className="form-control">{fecha(servicio.fechaInicio)}</p>
|
||||
</div>
|
||||
|
||||
{servicio.profesor && (
|
||||
<div className="mb-2">
|
||||
<label>Profesor:</label>
|
||||
<p className="input">{servicio.profesor}</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Fecha de término:</label>
|
||||
<p className="form-control">{fecha(servicio.fechaFin)}</p>
|
||||
</div>
|
||||
|
||||
{servicio.createdAt && (
|
||||
<div className="mb-2">
|
||||
<label>Fecha de registro:</label>
|
||||
<p className="input">{fecha(servicio.createdAt)}</p>
|
||||
{servicio.fechaLiberacion && (
|
||||
<div className="mb-2">
|
||||
<label className="form-label fw-semibold">Fecha de liberación:</label>
|
||||
<p className="form-control">{fecha(servicio.fechaLiberacion)}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Fecha de inicio:</label>
|
||||
<p className="input">{fecha(servicio.fechaInicio)}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-2">
|
||||
<label>Fecha de término:</label>
|
||||
<p className="input">{fecha(servicio.fechaFin)}</p>
|
||||
</div>
|
||||
|
||||
{servicio.fechaLiberacion && (
|
||||
<div className="mb-2">
|
||||
<label>Fecha de liberación:</label>
|
||||
<p className="input">{fecha(servicio.fechaLiberacion)}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ interface Props {
|
||||
|
||||
export default function MensajeAlumno({ Status }: Props) {
|
||||
return (
|
||||
<div className="mb-6">
|
||||
<h4 className="block is-size-4">Estimado alumno(a):</h4>
|
||||
<div className="container mb-6">
|
||||
<h4 className="block is-size-4 mb-4">Estimado alumno(a):</h4>
|
||||
|
||||
<p className="has-text-justified is-size-6">
|
||||
{Status.idStatus === 2 && (
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { axiosInstance } from "@/api/config";
|
||||
import { isAxiosError } from 'axios';
|
||||
import { Button, FormGroup, FormLabel } from "react-bootstrap";
|
||||
import { FaUpload } from "react-icons/fa";
|
||||
|
||||
interface Alumno {
|
||||
tokenArchivo: string;
|
||||
@@ -53,95 +55,139 @@ export default function PreTermino({
|
||||
formData.append("informeGlobal", file);
|
||||
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.put(`/servicio/informe_global`, formData, { headers: { "Content-Type": "multipart/form-data", Authorization: alumno.tokenArchivo } });
|
||||
imprimirMensaje(res.data.message);
|
||||
obtenerServicio();
|
||||
setFile(null);
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.put(`/servicio/informe_global`, formData, { headers: { "Content-Type": "multipart/form-data", Authorization: alumno.tokenArchivo } });
|
||||
imprimirMensaje(res.data.message);
|
||||
obtenerServicio();
|
||||
setFile(null);
|
||||
} catch (err: unknown) {
|
||||
if (isAxiosError(err)) {
|
||||
imprimirError((err.response?.data) || err.message);
|
||||
} else {
|
||||
imprimirError(err);
|
||||
}
|
||||
if (isAxiosError(err)) {
|
||||
imprimirError((err.response?.data) || err.message);
|
||||
} else {
|
||||
imprimirError(err);
|
||||
}
|
||||
} finally {
|
||||
updateIsLoading(false);
|
||||
updateIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="label">
|
||||
<div className="container">
|
||||
<h6 className="label fw-semibold">
|
||||
Cuestionario de evaluación del programa de servicio social.
|
||||
</h3>
|
||||
</h6>
|
||||
|
||||
{!servicio.idCuestionarioAlumno && !servicio.idCuestionarioAlumno2 ? (
|
||||
<div className="mb-6">
|
||||
<a
|
||||
href="/alumno/cuestionario"
|
||||
className="button is-info is-light"
|
||||
>
|
||||
<span className="icon">
|
||||
<i className="fas fa-book-open"></i>
|
||||
</span>
|
||||
<span>Cuestionario</span>
|
||||
</a>
|
||||
<div className="mb-5">
|
||||
<a
|
||||
href="/alumno/cuestionario"
|
||||
className="btn btn-outline-primary is-info is-light"
|
||||
>
|
||||
<span className="icon">
|
||||
<i className="fas fa-book-open"></i>
|
||||
</span>
|
||||
<span>Cuestionario</span>
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mb-6">
|
||||
<p className="block is-size-6">
|
||||
Cuestionario contestado{" "}
|
||||
<span className="icon has-text-success">
|
||||
<i className="fas fa-check-bold"></i>
|
||||
</span>
|
||||
</p>
|
||||
<p className="block is-size-6">
|
||||
Cuestionario contestado{" "}
|
||||
<span className="icon has-text-success">
|
||||
<i className="fas fa-check-bold"></i>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h3 className="label">
|
||||
<h6 className="label fw-semibold">
|
||||
Informe global de actividades{" "}
|
||||
{!servicio.informeGlobal && (
|
||||
<span>(en formato .PDF. No se aceptan fotos)</span>
|
||||
)}
|
||||
.
|
||||
</h3>
|
||||
</h6>
|
||||
|
||||
{/*
|
||||
Codigo anterior para el envio del archivo
|
||||
<div>
|
||||
<div className="field">
|
||||
<input
|
||||
type="file"
|
||||
accept="application/pdf"
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
setFile(e.target.files[0]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p className="is-size-6">Tamaño máximo 20MB</p>
|
||||
</div>
|
||||
|
||||
<div className="field has-text-centered my-5">
|
||||
<button
|
||||
className="button is-success"
|
||||
disabled={!file}
|
||||
onClick={() =>
|
||||
imprimirWarning(
|
||||
"¿Estas seguro(a) de querer subir este informe global?",
|
||||
enviarInformeGlobal
|
||||
)
|
||||
}
|
||||
>
|
||||
Enviar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
{!servicio.informeGlobal ? (
|
||||
<div>
|
||||
<div className="field">
|
||||
<input
|
||||
type="file"
|
||||
accept="application/pdf"
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
setFile(e.target.files[0]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p className="is-size-6">Tamaño máximo 20MB</p>
|
||||
</div>
|
||||
<div className="ph-5">
|
||||
<FormGroup>
|
||||
<div className="border p-4 text-center rounded"
|
||||
style={{ cursor: 'pointer'}}
|
||||
onClick={() => document.getElementById("fileInput")?.click()}
|
||||
>
|
||||
<FaUpload size={40} className="mb-2"/>
|
||||
<p className="mb-1">
|
||||
{file?.name || 'Arrastra aquì tu archivo o da click aquì para buscar'}
|
||||
</p>
|
||||
<p className="is-size-6">Tamaño maximo 20MB</p>
|
||||
<p className="is-size-7">Sia al momento de elegir un archivo este no se selecciona, haga click en cancelar en la ventana emergente e intente de nuevo.</p>
|
||||
</div>
|
||||
|
||||
<div className="field has-text-centered my-5">
|
||||
<button
|
||||
className="button is-success"
|
||||
disabled={!file}
|
||||
onClick={() =>
|
||||
imprimirWarning(
|
||||
"¿Estas seguro(a) de querer subir este informe global?",
|
||||
enviarInformeGlobal
|
||||
)
|
||||
}
|
||||
>
|
||||
Enviar
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
id="fileInput"
|
||||
type="file"
|
||||
accept="application/pdf"
|
||||
onChange={(e) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
setFile(e.target.files[0]);
|
||||
}
|
||||
}}
|
||||
hidden
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<div className="d-flex gap-2 justify-content-center mb-5">
|
||||
<Button
|
||||
className=""
|
||||
disabled={!file}
|
||||
onClick={() =>
|
||||
imprimirWarning(
|
||||
"¿Estas seguro(a) de querer subir este informe global?",
|
||||
enviarInformeGlobal
|
||||
)
|
||||
}
|
||||
>Enviar</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className="block is-size-6">
|
||||
Informe Global enviado.{" "}
|
||||
<span className="icon has-text-success">
|
||||
<i className="fas fa-check-bold"></i>
|
||||
</span>
|
||||
<p className="block is-size-6 mb-5">
|
||||
Informe Global enviado.{" "}
|
||||
<span className="icon has-text-success">
|
||||
<i className="fas fa-check-bold"></i>
|
||||
</span>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user