Se agregarn vistas faltantes al proyecto. Queda pendiente funcionaildades de API
This commit is contained in:
1 parent
eed3b45de3
commit
a2fbd4b675
17 files changed
+7222
-100
No files matched your search
@@ -0,0 +1,47 @@
|
|||||||
|
Proyecto Web/Web (solo archivos .aspx)
|
||||||
|
├── Academico/
|
||||||
|
│ ├── CodigosSence.aspx
|
||||||
|
│ ├── CodigosSencePC.aspx
|
||||||
|
│ ├── Cursos.aspx
|
||||||
|
│ ├── CursosPC.aspx
|
||||||
|
│ ├── index.aspx
|
||||||
|
│ ├── Libros.aspx
|
||||||
|
│ ├── PlanDeEstudio.aspx
|
||||||
|
│ └── Ponderaciones.aspx
|
||||||
|
├── Administrador/
|
||||||
|
│ └── ActualizarSesiones.aspx
|
||||||
|
├── Alumnos/
|
||||||
|
│ ├── EvaluacionPresencial.aspx
|
||||||
|
│ ├── Ficha.aspx
|
||||||
|
│ └── Index.aspx
|
||||||
|
├── Clientes/
|
||||||
|
│ ├── Autorizador.aspx
|
||||||
|
│ ├── DesactivaContratos.aspx
|
||||||
|
│ ├── Ficha.aspx
|
||||||
|
│ ├── Index.aspx
|
||||||
|
│ └── InfoEmpresas.aspx
|
||||||
|
├── Cursos/
|
||||||
|
│ ├── Administrador.aspx
|
||||||
|
│ ├── Index.aspx
|
||||||
|
│ └── Reemplazo.aspx
|
||||||
|
├── Informes/
|
||||||
|
│ ├── AlumnosActivos.aspx
|
||||||
|
│ ├── AlumnosCursos.aspx
|
||||||
|
│ ├── AlumnosEmpresas.aspx
|
||||||
|
│ ├── AlumnosPeriodos.aspx
|
||||||
|
│ ├── Autorizados.aspx
|
||||||
|
│ ├── ContratosHistorial.aspx
|
||||||
|
│ ├── CursosActivos.aspx
|
||||||
|
│ ├── CursosAsistencias.aspx
|
||||||
|
│ ├── CursosDocentes.aspx
|
||||||
|
│ ├── CursosDocentesFinalizados.aspx
|
||||||
|
│ ├── CursosFechas.aspx
|
||||||
|
│ ├── CursosInicios.aspx
|
||||||
|
│ ├── Index.aspx
|
||||||
|
│ ├── PollAnalysis.aspx
|
||||||
|
│ ├── PollStudents.aspx
|
||||||
|
│ ├── SesionesEstipuladas.aspx
|
||||||
|
│ └── SesionesProfesores.aspx
|
||||||
|
├── Profesor/
|
||||||
|
│ └── Ficha.aspx
|
||||||
|
└── Index.aspx
|
||||||
+352
@@ -0,0 +1,352 @@
|
|||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
|
||||||
|
<link href="../css/check-radio.css" rel="stylesheet" />
|
||||||
|
<script src="../js/jquery-ui-1.9.2.custom.min.js"></script>
|
||||||
|
<link href="../css/jquery-ui.css" rel="stylesheet" />
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$(".cargando").click(function () {
|
||||||
|
|
||||||
|
$("#mensajeCargando").modal("show");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
$(".datepicker").datepicker({
|
||||||
|
changeMonth: true,
|
||||||
|
changeYear: true,
|
||||||
|
dateFormat: "yy-mm-dd",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(function ($) {
|
||||||
|
$.datepicker.dates = {
|
||||||
|
closeText: 'Cerrar',
|
||||||
|
prevText: '< Ant',
|
||||||
|
nextText: 'Sig >',
|
||||||
|
currentText: 'Hoy',
|
||||||
|
monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
|
||||||
|
monthNamesShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
|
||||||
|
dayNames: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
|
||||||
|
dayNamesShort: ['Dom', 'Lun', 'Mar', 'Mié', 'Juv', 'Vie', 'Sáb'],
|
||||||
|
dayNamesMin: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sá"],
|
||||||
|
weekHeader: 'Sm',
|
||||||
|
dateFormat: 'dd-mm-yy',
|
||||||
|
firstDay: 1,
|
||||||
|
isRTL: false,
|
||||||
|
showMonthAfterYear: false,
|
||||||
|
yearSuffix: ''
|
||||||
|
};
|
||||||
|
$.datepicker.setDefaults($.datepicker.regional['es']);
|
||||||
|
});
|
||||||
|
|
||||||
|
function valideKey(evt) {
|
||||||
|
|
||||||
|
// code is the decimal ASCII representation of the pressed key.
|
||||||
|
var code = (evt.which) ? evt.which : evt.keyCode;
|
||||||
|
|
||||||
|
if (code == 8) { // backspace.
|
||||||
|
return true;
|
||||||
|
} else if (code >= 48 && code <= 57) { // is a number.
|
||||||
|
return true;
|
||||||
|
} else { // other keys.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="alert alert-light text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<strong>
|
||||||
|
<i class='bx bx-user' style="font-size: 24px"></i>
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span class="ms-2">Empresas por mes</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col text-end">
|
||||||
|
<a href="<%=Page.ResolveUrl("~/Alumnos/Index.aspx") %>" class="btn btn-warning text-dark btn-sm"><strong>Volver</strong></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div class="alert alert-light text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="fw-bold">Mes</span>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<asp:DropDownList ID="ListaMeses" runat="server" CssClass="form-select"></asp:DropDownList>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="fw-bold">Agno</span>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<asp:TextBox ID="TextBoxYear" class="form-control form-control-sm" runat="server"></asp:TextBox>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<asp:LinkButton ID="LinkButtonBuscar" CssClass="btn btn-primary btn-sm d-grid" runat="server" OnClick="LinkButtonBuscar_Click">Buscar</asp:LinkButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" runat="server" id="div_reporte">
|
||||||
|
<div class="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mx-auto" runat="server">
|
||||||
|
<asp:LinkButton ID="LinkButtonExcel" runat="server" CssClass="text-decoration-none" OnClick="LinkButtonExcel_Click">
|
||||||
|
<div class="alert alert-success shadow" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h1><i class='bx bx-export'></i></h1>
|
||||||
|
</div>
|
||||||
|
<div class="col text-center">
|
||||||
|
<span class="text-muted"><strong>Excel</strong></span>
|
||||||
|
<h5><strong>
|
||||||
|
<asp:Label ID="Label1" runat="server" Text="Exportar"></asp:Label>
|
||||||
|
</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</asp:LinkButton>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" runat="server">
|
||||||
|
<div class="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 text-center">
|
||||||
|
<h1><i class="fa-solid fa-users-line"></i></h1>
|
||||||
|
<span class="fw-bold"><strong>Alumnos</strong></span>
|
||||||
|
</div>
|
||||||
|
<div class="col text-center mt-3">
|
||||||
|
<span class="text-muted"><strong>Total</strong></span>
|
||||||
|
<h5><strong>
|
||||||
|
<asp:Label ID="LabelTotAlumnos" runat="server" Text="0"></asp:Label>
|
||||||
|
</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" runat="server">
|
||||||
|
<div class="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 text-center">
|
||||||
|
<h1><i class='bx bx-building-house bx-lg'></i></h1>
|
||||||
|
<span class="fw-bold"><strong>Empresas</strong></span>
|
||||||
|
</div>
|
||||||
|
<div class="col text-center mt-3">
|
||||||
|
<span class="text-muted"><strong>Total</strong></span>
|
||||||
|
<h5><strong>
|
||||||
|
<asp:Label ID="LabelEmpTotal" runat="server" Text="0"></asp:Label>
|
||||||
|
</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-12" runat="server">
|
||||||
|
<div class="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 text-start">
|
||||||
|
<h1><i class="fa-solid fa-swatchbook"></i></h1>
|
||||||
|
<span class="fw-bold"><strong>Alumnos</strong></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 text-start">
|
||||||
|
<span class="text-muted"><strong>Con SENCE</strong></span>
|
||||||
|
<h5><strong>
|
||||||
|
<asp:Label ID="LabelAlmConSNC" runat="server" Text="0"></asp:Label>
|
||||||
|
</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 text-start">
|
||||||
|
<span class="text-muted"><strong>Sin SENCE</strong></span>
|
||||||
|
<h5><strong>
|
||||||
|
<asp:Label ID="LabelAlmSinSNC" runat="server" Text="0"></asp:Label>
|
||||||
|
</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 text-start">
|
||||||
|
<span class="text-muted"><strong>Total</strong></span>
|
||||||
|
<h5><strong>
|
||||||
|
<asp:Label ID="LabelAlumnosTotal" runat="server" Text="0"></asp:Label>
|
||||||
|
</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 mt-3" runat="server">
|
||||||
|
<div class="alert alert-light" role="alert">
|
||||||
|
<div class="table-responsive" width="100%">
|
||||||
|
<h3>Alumnos de empresas</h3>
|
||||||
|
<table class="table table-sm mb-0 table-hover" style="font-size: 12px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-start" style="width: 20%">Tipo</th>
|
||||||
|
<th class="text-start" style="width: 5%">Cantidad</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="text-start" style="width: 20%">Cursos Abierto
|
||||||
|
</td>
|
||||||
|
<td class="text-start" style="width: 5%">
|
||||||
|
<asp:Label ID="Labelcnttipoabierto" runat="server" Text="0"></asp:Label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-start" style="width: 20%">Cursos Cerrado
|
||||||
|
</td>
|
||||||
|
<td class="text-start" style="width: 5%">
|
||||||
|
<asp:Label ID="Labelcnttipocerrado" runat="server" Text="0"></asp:Label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="text-start" style="width: 20%">Total
|
||||||
|
</th>
|
||||||
|
<th class="text-start" style="width: 5%">
|
||||||
|
<asp:Label ID="LabelcnttipoTotal" runat="server" Text="0"></asp:Label>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" runat="server">
|
||||||
|
<div class="alert alert-light text-dark" role="alert">
|
||||||
|
<div class="row">
|
||||||
|
<h4 class="text-center"><small><u>Sedes con alumnos de empresas</u></small></h4>
|
||||||
|
<div class="col-md-8 text-start">
|
||||||
|
<h1><i class="fa-solid fa-school"></i></h1>
|
||||||
|
<span class="fw-bold"><strong>Sedes</strong></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-center mt-1">
|
||||||
|
<div class="progress" role="progressbar" aria-label="Default striped example" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div class="progress-bar progress-bar-striped" style="width: 100%">Alumnos sin SENCE</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="progress" role="progressbar" aria-label="Warning striped example" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div class="progress-bar progress-bar-striped bg-warning text-dark" style="width: 100%">Alumnos con SENCE</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12 text-center">
|
||||||
|
<h5>
|
||||||
|
<strong>Moneda</strong>
|
||||||
|
</h5>
|
||||||
|
<div class="progress-stacked">
|
||||||
|
<div class="progress" role="progressbar" aria-label="Segment one" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div id="mone" runat="server" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
||||||
|
<div id="moneSNC" runat="server" class="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Providencia</strong>
|
||||||
|
</h5>
|
||||||
|
<div class="progress-stacked">
|
||||||
|
<div class="progress" role="progressbar" aria-label="Info example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div id="prov" runat="server" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
||||||
|
<div id="provSNC" runat="server" class="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>La Florida</strong>
|
||||||
|
</h5>
|
||||||
|
<div class="progress-stacked">
|
||||||
|
<div class="progress" role="progressbar" aria-label="Info example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div id="flor" runat="server" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
||||||
|
<div id="florSNC" runat="server" class="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Online</strong>
|
||||||
|
</h5>
|
||||||
|
<div class="progress-stacked">
|
||||||
|
<div class="progress" role="progressbar" aria-label="Info example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div id="onli" runat="server" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
||||||
|
<div id="onliSNC" runat="server" class="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
<div class="progress-stacked">
|
||||||
|
<div class="progress" role="progressbar" aria-label="Info example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
<div id="corp" runat="server" class="progress-bar progress-bar-striped progress-bar-animated"></div>
|
||||||
|
<div id="corpSNC" runat="server" class="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 align-middle mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12" id="TipoDeVentas">
|
||||||
|
<div class="alert alert-light text-dark offcanvas-lg offcanvas-sm container-md container-sm"
|
||||||
|
role="alert">
|
||||||
|
<h3><span><b><u>Tipos de ventas</u></b></span></h3>
|
||||||
|
<canvas id="ventaPie" class="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
|
||||||
|
<script>
|
||||||
|
var pieLabels;
|
||||||
|
var pieData;
|
||||||
|
const ctz = document.getElementById('ventaPie');
|
||||||
|
new Chart(ctz, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: pieLabels,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Cantidad',
|
||||||
|
data: pieData,
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var $canvas = $("#canvas");
|
||||||
|
var $parent = $canvas.parent();
|
||||||
|
$canvas.width($parent.width());
|
||||||
|
$canvas.height($parent.height());
|
||||||
|
</script>
|
||||||
|
</asp:Content>
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@boxicons/react": "^1.0.3",
|
"@boxicons/react": "^1.0.3",
|
||||||
"bootstrap": "5.3.8",
|
"bootstrap": "5.3.8",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
"next": "16.2.12",
|
"next": "16.2.12",
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4",
|
"react-dom": "19.2.4",
|
||||||
|
|||||||
Generated
+115
-95
@@ -14,9 +14,12 @@ importers:
|
|||||||
bootstrap:
|
bootstrap:
|
||||||
specifier: 5.3.8
|
specifier: 5.3.8
|
||||||
version: 5.3.8(@popperjs/core@2.11.8)
|
version: 5.3.8(@popperjs/core@2.11.8)
|
||||||
|
chart.js:
|
||||||
|
specifier: ^4.5.1
|
||||||
|
version: 4.5.1
|
||||||
next:
|
next:
|
||||||
specifier: 16.2.12
|
specifier: 16.2.12
|
||||||
version: 16.2.12(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
react:
|
react:
|
||||||
specifier: 19.2.4
|
specifier: 19.2.4
|
||||||
version: 19.2.4
|
version: 19.2.4
|
||||||
@@ -44,10 +47,10 @@ importers:
|
|||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9
|
specifier: ^9
|
||||||
version: 9.39.5
|
version: 9.39.5(supports-color@7.2.0)
|
||||||
eslint-config-next:
|
eslint-config-next:
|
||||||
specifier: 16.2.12
|
specifier: 16.2.12
|
||||||
version: 16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)
|
version: 16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5
|
specifier: ^5
|
||||||
version: 5.9.3
|
version: 5.9.3
|
||||||
@@ -365,6 +368,9 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.31':
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
|
'@kurkle/color@0.3.4':
|
||||||
|
resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==}
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.2.0':
|
'@napi-rs/wasm-runtime@1.2.0':
|
||||||
resolution: {integrity: sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA==}
|
resolution: {integrity: sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA==}
|
||||||
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
|
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
|
||||||
@@ -802,6 +808,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
chart.js@4.5.1:
|
||||||
|
resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==}
|
||||||
|
engines: {pnpm: '>=8'}
|
||||||
|
|
||||||
client-only@0.0.1:
|
client-only@0.0.1:
|
||||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||||
|
|
||||||
@@ -1869,20 +1879,20 @@ snapshots:
|
|||||||
|
|
||||||
'@babel/compat-data@7.29.7': {}
|
'@babel/compat-data@7.29.7': {}
|
||||||
|
|
||||||
'@babel/core@7.29.7':
|
'@babel/core@7.29.7(supports-color@7.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.29.7
|
'@babel/code-frame': 7.29.7
|
||||||
'@babel/generator': 7.29.7
|
'@babel/generator': 7.29.7
|
||||||
'@babel/helper-compilation-targets': 7.29.7
|
'@babel/helper-compilation-targets': 7.29.7
|
||||||
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7)
|
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
'@babel/helpers': 7.29.7
|
'@babel/helpers': 7.29.7
|
||||||
'@babel/parser': 7.29.7
|
'@babel/parser': 7.29.7
|
||||||
'@babel/template': 7.29.7
|
'@babel/template': 7.29.7
|
||||||
'@babel/traverse': 7.29.7
|
'@babel/traverse': 7.29.7(supports-color@7.2.0)
|
||||||
'@babel/types': 7.29.7
|
'@babel/types': 7.29.7
|
||||||
'@jridgewell/remapping': 2.3.5
|
'@jridgewell/remapping': 2.3.5
|
||||||
convert-source-map: 2.0.0
|
convert-source-map: 2.0.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
gensync: 1.0.0-beta.2
|
gensync: 1.0.0-beta.2
|
||||||
json5: 2.2.3
|
json5: 2.2.3
|
||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
@@ -1907,19 +1917,19 @@ snapshots:
|
|||||||
|
|
||||||
'@babel/helper-globals@7.29.7': {}
|
'@babel/helper-globals@7.29.7': {}
|
||||||
|
|
||||||
'@babel/helper-module-imports@7.29.7':
|
'@babel/helper-module-imports@7.29.7(supports-color@7.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/traverse': 7.29.7
|
'@babel/traverse': 7.29.7(supports-color@7.2.0)
|
||||||
'@babel/types': 7.29.7
|
'@babel/types': 7.29.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
|
'@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.7
|
'@babel/core': 7.29.7(supports-color@7.2.0)
|
||||||
'@babel/helper-module-imports': 7.29.7
|
'@babel/helper-module-imports': 7.29.7(supports-color@7.2.0)
|
||||||
'@babel/helper-validator-identifier': 7.29.7
|
'@babel/helper-validator-identifier': 7.29.7
|
||||||
'@babel/traverse': 7.29.7
|
'@babel/traverse': 7.29.7(supports-color@7.2.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -1944,7 +1954,7 @@ snapshots:
|
|||||||
'@babel/parser': 7.29.7
|
'@babel/parser': 7.29.7
|
||||||
'@babel/types': 7.29.7
|
'@babel/types': 7.29.7
|
||||||
|
|
||||||
'@babel/traverse@7.29.7':
|
'@babel/traverse@7.29.7(supports-color@7.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.29.7
|
'@babel/code-frame': 7.29.7
|
||||||
'@babel/generator': 7.29.7
|
'@babel/generator': 7.29.7
|
||||||
@@ -1952,7 +1962,7 @@ snapshots:
|
|||||||
'@babel/parser': 7.29.7
|
'@babel/parser': 7.29.7
|
||||||
'@babel/template': 7.29.7
|
'@babel/template': 7.29.7
|
||||||
'@babel/types': 7.29.7
|
'@babel/types': 7.29.7
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -1986,17 +1996,17 @@ snapshots:
|
|||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@eslint-community/eslint-utils@4.10.1(eslint@9.39.5)':
|
'@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(supports-color@7.2.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
|
|
||||||
'@eslint-community/regexpp@4.12.2': {}
|
'@eslint-community/regexpp@4.12.2': {}
|
||||||
|
|
||||||
'@eslint/config-array@0.21.2':
|
'@eslint/config-array@0.21.2(supports-color@7.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint/object-schema': 2.1.7
|
'@eslint/object-schema': 2.1.7
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
minimatch: 3.1.5
|
minimatch: 3.1.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -2009,10 +2019,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/json-schema': 7.0.15
|
'@types/json-schema': 7.0.15
|
||||||
|
|
||||||
'@eslint/eslintrc@3.3.6':
|
'@eslint/eslintrc@3.3.6(supports-color@7.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.15.0
|
ajv: 6.15.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
espree: 10.4.0
|
espree: 10.4.0
|
||||||
globals: 14.0.0
|
globals: 14.0.0
|
||||||
ignore: 5.3.2
|
ignore: 5.3.2
|
||||||
@@ -2164,6 +2174,8 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
'@kurkle/color@0.3.4': {}
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
'@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/core': 1.10.0
|
'@emnapi/core': 1.10.0
|
||||||
@@ -2250,15 +2262,15 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.2.3
|
csstype: 3.2.3
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.2
|
'@eslint-community/regexpp': 4.12.2
|
||||||
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/scope-manager': 8.65.0
|
'@typescript-eslint/scope-manager': 8.65.0
|
||||||
'@typescript-eslint/type-utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/type-utils': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.65.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
ignore: 7.0.6
|
ignore: 7.0.6
|
||||||
natural-compare: 1.4.0
|
natural-compare: 1.4.0
|
||||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
ts-api-utils: 2.5.0(typescript@5.9.3)
|
||||||
@@ -2266,23 +2278,23 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 8.65.0
|
'@typescript-eslint/scope-manager': 8.65.0
|
||||||
'@typescript-eslint/types': 8.65.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/visitor-keys': 8.65.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/project-service@8.65.0(typescript@5.9.3)':
|
'@typescript-eslint/project-service@8.65.0(supports-color@7.2.0)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/types': 8.65.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -2296,13 +2308,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
|
|
||||||
'@typescript-eslint/type-utils@8.65.0(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/type-utils@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.65.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
ts-api-utils: 2.5.0(typescript@5.9.3)
|
ts-api-utils: 2.5.0(typescript@5.9.3)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -2310,13 +2322,13 @@ snapshots:
|
|||||||
|
|
||||||
'@typescript-eslint/types@8.65.0': {}
|
'@typescript-eslint/types@8.65.0': {}
|
||||||
|
|
||||||
'@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3)':
|
'@typescript-eslint/typescript-estree@8.65.0(supports-color@7.2.0)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/project-service': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/project-service': 8.65.0(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3)
|
||||||
'@typescript-eslint/types': 8.65.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/visitor-keys': 8.65.0
|
'@typescript-eslint/visitor-keys': 8.65.0
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
minimatch: 10.2.6
|
minimatch: 10.2.6
|
||||||
semver: 7.8.5
|
semver: 7.8.5
|
||||||
tinyglobby: 0.2.17
|
tinyglobby: 0.2.17
|
||||||
@@ -2325,13 +2337,13 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@typescript-eslint/utils@8.65.0(eslint@9.39.5)(typescript@5.9.3)':
|
'@typescript-eslint/utils@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5)
|
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(supports-color@7.2.0))
|
||||||
'@typescript-eslint/scope-manager': 8.65.0
|
'@typescript-eslint/scope-manager': 8.65.0
|
||||||
'@typescript-eslint/types': 8.65.0
|
'@typescript-eslint/types': 8.65.0
|
||||||
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -2579,6 +2591,10 @@ snapshots:
|
|||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
supports-color: 7.2.0
|
supports-color: 7.2.0
|
||||||
|
|
||||||
|
chart.js@4.5.1:
|
||||||
|
dependencies:
|
||||||
|
'@kurkle/color': 0.3.4
|
||||||
|
|
||||||
client-only@0.0.1: {}
|
client-only@0.0.1: {}
|
||||||
|
|
||||||
codepage@1.15.0: {}
|
codepage@1.15.0: {}
|
||||||
@@ -2623,13 +2639,17 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
is-data-view: 1.0.2
|
is-data-view: 1.0.2
|
||||||
|
|
||||||
debug@3.2.7:
|
debug@3.2.7(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
optionalDependencies:
|
||||||
|
supports-color: 7.2.0
|
||||||
|
|
||||||
debug@4.4.3:
|
debug@4.4.3(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
optionalDependencies:
|
||||||
|
supports-color: 7.2.0
|
||||||
|
|
||||||
deep-is@0.1.4: {}
|
deep-is@0.1.4: {}
|
||||||
|
|
||||||
@@ -2777,18 +2797,18 @@ snapshots:
|
|||||||
|
|
||||||
escape-string-regexp@4.0.0: {}
|
escape-string-regexp@4.0.0: {}
|
||||||
|
|
||||||
eslint-config-next@16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3):
|
eslint-config-next@16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/eslint-plugin-next': 16.2.12
|
'@next/eslint-plugin-next': 16.2.12
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
eslint-import-resolver-node: 0.3.10
|
eslint-import-resolver-node: 0.3.10(supports-color@7.2.0)
|
||||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5))(eslint@9.39.5)
|
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5)
|
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5)
|
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(supports-color@7.2.0))
|
||||||
eslint-plugin-react: 7.37.5(eslint@9.39.5)
|
eslint-plugin-react: 7.37.5(eslint@9.39.5(supports-color@7.2.0))
|
||||||
eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5)
|
eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
globals: 16.4.0
|
globals: 16.4.0
|
||||||
typescript-eslint: 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
typescript-eslint: 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -2797,52 +2817,52 @@ snapshots:
|
|||||||
- eslint-plugin-import-x
|
- eslint-plugin-import-x
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-import-resolver-node@0.3.10:
|
eslint-import-resolver-node@0.3.10(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7(supports-color@7.2.0)
|
||||||
is-core-module: 2.16.2
|
is-core-module: 2.16.2
|
||||||
resolve: 2.0.0-next.7
|
resolve: 2.0.0-next.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5))(eslint@9.39.5):
|
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nolyfill/is-core-module': 1.0.39
|
'@nolyfill/is-core-module': 1.0.39
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
get-tsconfig: 4.14.0
|
get-tsconfig: 4.14.0
|
||||||
is-bun-module: 2.0.0
|
is-bun-module: 2.0.0
|
||||||
stable-hash: 0.0.5
|
stable-hash: 0.0.5
|
||||||
tinyglobby: 0.2.17
|
tinyglobby: 0.2.17
|
||||||
unrs-resolver: 1.12.2
|
unrs-resolver: 1.12.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5)
|
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5))(eslint@9.39.5))(eslint@9.39.5):
|
eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7(supports-color@7.2.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
eslint-import-resolver-node: 0.3.10
|
eslint-import-resolver-node: 0.3.10(supports-color@7.2.0)
|
||||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5))(eslint@9.39.5)
|
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5):
|
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rtsao/scc': 1.1.0
|
'@rtsao/scc': 1.1.0
|
||||||
array-includes: 3.1.9
|
array-includes: 3.1.9
|
||||||
array.prototype.findlastindex: 1.2.6
|
array.prototype.findlastindex: 1.2.6
|
||||||
array.prototype.flat: 1.3.3
|
array.prototype.flat: 1.3.3
|
||||||
array.prototype.flatmap: 1.3.3
|
array.prototype.flatmap: 1.3.3
|
||||||
debug: 3.2.7
|
debug: 3.2.7(supports-color@7.2.0)
|
||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
eslint-import-resolver-node: 0.3.10
|
eslint-import-resolver-node: 0.3.10(supports-color@7.2.0)
|
||||||
eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5))(eslint@9.39.5))(eslint@9.39.5)
|
eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)
|
||||||
hasown: 2.0.4
|
hasown: 2.0.4
|
||||||
is-core-module: 2.16.2
|
is-core-module: 2.16.2
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@@ -2854,13 +2874,13 @@ snapshots:
|
|||||||
string.prototype.trimend: 1.0.10
|
string.prototype.trimend: 1.0.10
|
||||||
tsconfig-paths: 3.15.0
|
tsconfig-paths: 3.15.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- eslint-import-resolver-typescript
|
- eslint-import-resolver-typescript
|
||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5):
|
eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(supports-color@7.2.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
aria-query: 5.3.2
|
aria-query: 5.3.2
|
||||||
array-includes: 3.1.9
|
array-includes: 3.1.9
|
||||||
@@ -2870,7 +2890,7 @@ snapshots:
|
|||||||
axobject-query: 4.1.0
|
axobject-query: 4.1.0
|
||||||
damerau-levenshtein: 1.0.8
|
damerau-levenshtein: 1.0.8
|
||||||
emoji-regex: 9.2.2
|
emoji-regex: 9.2.2
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
hasown: 2.0.4
|
hasown: 2.0.4
|
||||||
jsx-ast-utils: 3.3.5
|
jsx-ast-utils: 3.3.5
|
||||||
language-tags: 1.0.9
|
language-tags: 1.0.9
|
||||||
@@ -2879,18 +2899,18 @@ snapshots:
|
|||||||
safe-regex-test: 1.1.0
|
safe-regex-test: 1.1.0
|
||||||
string.prototype.includes: 2.0.1
|
string.prototype.includes: 2.0.1
|
||||||
|
|
||||||
eslint-plugin-react-hooks@7.1.1(eslint@9.39.5):
|
eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.7
|
'@babel/core': 7.29.7(supports-color@7.2.0)
|
||||||
'@babel/parser': 7.29.7
|
'@babel/parser': 7.29.7
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
hermes-parser: 0.25.1
|
hermes-parser: 0.25.1
|
||||||
zod: 4.4.3
|
zod: 4.4.3
|
||||||
zod-validation-error: 4.0.2(zod@4.4.3)
|
zod-validation-error: 4.0.2(zod@4.4.3)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-react@7.37.5(eslint@9.39.5):
|
eslint-plugin-react@7.37.5(eslint@9.39.5(supports-color@7.2.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
array-includes: 3.1.9
|
array-includes: 3.1.9
|
||||||
array.prototype.findlast: 1.2.5
|
array.prototype.findlast: 1.2.5
|
||||||
@@ -2898,7 +2918,7 @@ snapshots:
|
|||||||
array.prototype.tosorted: 1.1.4
|
array.prototype.tosorted: 1.1.4
|
||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
es-iterator-helpers: 1.4.0
|
es-iterator-helpers: 1.4.0
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
estraverse: 5.3.0
|
estraverse: 5.3.0
|
||||||
hasown: 2.0.4
|
hasown: 2.0.4
|
||||||
jsx-ast-utils: 3.3.5
|
jsx-ast-utils: 3.3.5
|
||||||
@@ -2923,14 +2943,14 @@ snapshots:
|
|||||||
|
|
||||||
eslint-visitor-keys@5.0.1: {}
|
eslint-visitor-keys@5.0.1: {}
|
||||||
|
|
||||||
eslint@9.39.5:
|
eslint@9.39.5(supports-color@7.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5)
|
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(supports-color@7.2.0))
|
||||||
'@eslint-community/regexpp': 4.12.2
|
'@eslint-community/regexpp': 4.12.2
|
||||||
'@eslint/config-array': 0.21.2
|
'@eslint/config-array': 0.21.2(supports-color@7.2.0)
|
||||||
'@eslint/config-helpers': 0.4.2
|
'@eslint/config-helpers': 0.4.2
|
||||||
'@eslint/core': 0.17.0
|
'@eslint/core': 0.17.0
|
||||||
'@eslint/eslintrc': 3.3.6
|
'@eslint/eslintrc': 3.3.6(supports-color@7.2.0)
|
||||||
'@eslint/js': 9.39.5
|
'@eslint/js': 9.39.5
|
||||||
'@eslint/plugin-kit': 0.4.1
|
'@eslint/plugin-kit': 0.4.1
|
||||||
'@humanfs/node': 0.16.8
|
'@humanfs/node': 0.16.8
|
||||||
@@ -2940,7 +2960,7 @@ snapshots:
|
|||||||
ajv: 6.15.0
|
ajv: 6.15.0
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
debug: 4.4.3
|
debug: 4.4.3(supports-color@7.2.0)
|
||||||
escape-string-regexp: 4.0.0
|
escape-string-regexp: 4.0.0
|
||||||
eslint-scope: 8.4.0
|
eslint-scope: 8.4.0
|
||||||
eslint-visitor-keys: 4.2.1
|
eslint-visitor-keys: 4.2.1
|
||||||
@@ -3352,7 +3372,7 @@ snapshots:
|
|||||||
|
|
||||||
natural-compare@1.4.0: {}
|
natural-compare@1.4.0: {}
|
||||||
|
|
||||||
next@16.2.12(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
next@16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 16.2.12
|
'@next/env': 16.2.12
|
||||||
'@swc/helpers': 0.5.15
|
'@swc/helpers': 0.5.15
|
||||||
@@ -3361,7 +3381,7 @@ snapshots:
|
|||||||
postcss: 8.4.31
|
postcss: 8.4.31
|
||||||
react: 19.2.4
|
react: 19.2.4
|
||||||
react-dom: 19.2.4(react@19.2.4)
|
react-dom: 19.2.4(react@19.2.4)
|
||||||
styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.4)
|
styled-jsx: 5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.2.4)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@next/swc-darwin-arm64': 16.2.12
|
'@next/swc-darwin-arm64': 16.2.12
|
||||||
'@next/swc-darwin-x64': 16.2.12
|
'@next/swc-darwin-x64': 16.2.12
|
||||||
@@ -3717,12 +3737,12 @@ snapshots:
|
|||||||
|
|
||||||
strip-json-comments@3.1.1: {}
|
strip-json-comments@3.1.1: {}
|
||||||
|
|
||||||
styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.4):
|
styled-jsx@5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.2.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
client-only: 0.0.1
|
client-only: 0.0.1
|
||||||
react: 19.2.4
|
react: 19.2.4
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@babel/core': 7.29.7
|
'@babel/core': 7.29.7(supports-color@7.2.0)
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3789,13 +3809,13 @@ snapshots:
|
|||||||
possible-typed-array-names: 1.1.0
|
possible-typed-array-names: 1.1.0
|
||||||
reflect.getprototypeof: 1.0.10
|
reflect.getprototypeof: 1.0.10
|
||||||
|
|
||||||
typescript-eslint@8.65.0(eslint@9.39.5)(typescript@5.9.3):
|
typescript-eslint@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/parser': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3)
|
'@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5)(typescript@5.9.3)
|
'@typescript-eslint/utils': 8.65.0(eslint@9.39.5(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)
|
||||||
eslint: 9.39.5
|
eslint: 9.39.5(supports-color@7.2.0)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|||||||
@@ -0,0 +1,483 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
User,
|
||||||
|
Buildings,
|
||||||
|
Book,
|
||||||
|
UserCircle,
|
||||||
|
// Export,
|
||||||
|
CheckCircle,
|
||||||
|
// ErrorCircle,
|
||||||
|
} from "@boxicons/react";
|
||||||
|
|
||||||
|
// Interfaz para el listado de cursos
|
||||||
|
interface CursoItem {
|
||||||
|
Codigo: string;
|
||||||
|
Curso: string;
|
||||||
|
TipoCurso: string;
|
||||||
|
Periodo: string;
|
||||||
|
Titular: string;
|
||||||
|
Sede: string;
|
||||||
|
Alumnos: number;
|
||||||
|
Inicio: string;
|
||||||
|
Termino: string;
|
||||||
|
Schedule: string;
|
||||||
|
Estado: "Finalizado" | "En curso" | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CursosPorMesPage() {
|
||||||
|
// Filtros de búsqueda (Mes y Año)
|
||||||
|
const [mes, setMes] = useState("1");
|
||||||
|
const [agno, setAgno] = useState(new Date().getFullYear().toString());
|
||||||
|
|
||||||
|
// Visibilidad del reporte
|
||||||
|
const [mostrarReporte, setMostrarReporte] = useState(false);
|
||||||
|
|
||||||
|
// Totales
|
||||||
|
const [empTotal, setEmpTotal] = useState("0");
|
||||||
|
const [cursosTotal, setCursosTotal] = useState("0 %");
|
||||||
|
const [almConSnc, setAlmConSnc] = useState("0");
|
||||||
|
const [almSinSnc, setAlmSinSnc] = useState("0");
|
||||||
|
const [alumnosTotal, setAlumnosTotal] = useState("0");
|
||||||
|
|
||||||
|
// Lista de cursos
|
||||||
|
const [cursos, setCursos] = useState<CursoItem[]>([]);
|
||||||
|
|
||||||
|
// Modales de estado
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [modalAlerta, setModalAlerta] = useState<{
|
||||||
|
show: boolean;
|
||||||
|
mensaje: string;
|
||||||
|
}>({ show: false, mensaje: "" });
|
||||||
|
|
||||||
|
// Manejador del botón Buscar
|
||||||
|
const handleBuscar = () => {
|
||||||
|
if (!agno) {
|
||||||
|
setModalAlerta({
|
||||||
|
show: true,
|
||||||
|
mensaje: "Por favor, ingrese un año válido.",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
// Simulación de carga de datos
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setMostrarReporte(true);
|
||||||
|
|
||||||
|
// Datos de ejemplo
|
||||||
|
setEmpTotal("8");
|
||||||
|
setCursosTotal("90 %");
|
||||||
|
setAlmConSnc("32");
|
||||||
|
setAlmSinSnc("10");
|
||||||
|
setAlumnosTotal("42");
|
||||||
|
|
||||||
|
setCursos([
|
||||||
|
{
|
||||||
|
Codigo: "CUR-201",
|
||||||
|
Curso: "Inglés de Negocios A2",
|
||||||
|
TipoCurso: "Cerrado",
|
||||||
|
Periodo: `${agno}-${mes}`,
|
||||||
|
Titular: "Carlos Mendoza",
|
||||||
|
Sede: "Santiago Centro",
|
||||||
|
Alumnos: 12,
|
||||||
|
Inicio: `01/${mes.padStart(2, "0")}/${agno}`,
|
||||||
|
Termino: `28/${mes.padStart(2, "0")}/${agno}`,
|
||||||
|
Schedule: "Lun-Mié 10:00 - 12:00",
|
||||||
|
Estado: "Finalizado",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Codigo: "CUR-202",
|
||||||
|
Curso: "Inglés Conversacional B1",
|
||||||
|
TipoCurso: "Abierto",
|
||||||
|
Periodo: `${agno}-${mes}`,
|
||||||
|
Titular: "Patricia Silva",
|
||||||
|
Sede: "Providencia",
|
||||||
|
Alumnos: 15,
|
||||||
|
Inicio: `05/${mes.padStart(2, "0")}/${agno}`,
|
||||||
|
Termino: `30/${mes.padStart(2, "0")}/${agno}`,
|
||||||
|
Schedule: "Mar-Jue 19:00 - 21:00",
|
||||||
|
Estado: "En curso",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Restablecer vista
|
||||||
|
const handleVolver = () => {
|
||||||
|
setMostrarReporte(false);
|
||||||
|
setCursos([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exportar Excel
|
||||||
|
const handleExportarExcel = () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setModalAlerta({
|
||||||
|
show: true,
|
||||||
|
mensaje: "El reporte en Excel ha sido generado con éxito.",
|
||||||
|
});
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12" id="cursos_periodo">
|
||||||
|
<div className="row">
|
||||||
|
{/* ENCABEZADO Y VOLVER */}
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Cursos por Mes</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
onClick={handleVolver}
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* FILTROS MES Y AÑO */}
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Mes</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<select
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
value={mes}
|
||||||
|
onChange={(e) => setMes(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="1">Enero</option>
|
||||||
|
<option value="2">Febrero</option>
|
||||||
|
<option value="3">Marzo</option>
|
||||||
|
<option value="4">Abril</option>
|
||||||
|
<option value="5">Mayo</option>
|
||||||
|
<option value="6">Junio</option>
|
||||||
|
<option value="7">Julio</option>
|
||||||
|
<option value="8">Agosto</option>
|
||||||
|
<option value="9">Septiembre</option>
|
||||||
|
<option value="10">Octubre</option>
|
||||||
|
<option value="11">Noviembre</option>
|
||||||
|
<option value="12">Diciembre</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Agno</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
value={agno}
|
||||||
|
onChange={(e) => setAgno(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
onClick={handleBuscar}
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* REPORTE Y RESULTADOS */}
|
||||||
|
{mostrarReporte && (
|
||||||
|
<div className="col-md-12" id="div_reporte">
|
||||||
|
<div className="row">
|
||||||
|
{/* METRICA EMPRESAS */}
|
||||||
|
<div className="col-md-2" id="promedio_emp">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
<Buildings />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{empTotal}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* METRICA CURSOS */}
|
||||||
|
<div className="col-md-2" id="promedio_cursos">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
<Book />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Cursos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{cursosTotal}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* METRICA ALUMNOS */}
|
||||||
|
<div className="col-md-6" id="Div1">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
<UserCircle />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9 text-center mt-3">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Con SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{almConSnc}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Sin SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{almSinSnc}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{alumnosTotal}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* BOTÓN EXPORTAR EXCEL */}
|
||||||
|
<div className="col-md-2 mx-auto" id="Div2">
|
||||||
|
<div className="alert alert-success shadow-sm" role="alert">
|
||||||
|
<div className="row mt-2 align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
{/* <Export /> */}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Excel</strong>
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-link text-decoration-none p-0 d-block mx-auto"
|
||||||
|
onClick={handleExportarExcel}
|
||||||
|
>
|
||||||
|
<h5 className="mb-0 text-success">
|
||||||
|
<strong>Exportar</strong>
|
||||||
|
</h5>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* TABLA DE RESULTADOS */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: "12px" }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "3%" }}></th>
|
||||||
|
<th className="text-center" style={{ width: "5%" }}>Tipo de Curso</th>
|
||||||
|
<th className="text-start" style={{ width: "23%" }}>Curso</th>
|
||||||
|
<th className="text-start" style={{ width: "6%" }}>Periodo</th>
|
||||||
|
<th className="text-start" style={{ width: "14%" }}>Profesor</th>
|
||||||
|
<th className="text-center" style={{ width: "7%" }}>Sede</th>
|
||||||
|
<th className="text-center" style={{ width: "4%" }}>Alumnos</th>
|
||||||
|
<th className="text-center" style={{ width: "12%" }}>Fecha</th>
|
||||||
|
<th className="text-center" style={{ width: "20%" }}>Schedule</th>
|
||||||
|
<th className="text-center" style={{ width: "8%" }}>Estado</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{cursos.map((item, idx) => (
|
||||||
|
<tr key={idx}>
|
||||||
|
<td className="text-start" style={{ width: "3%" }}>
|
||||||
|
{item.TipoCurso === "Cerrado" ? (
|
||||||
|
<a href={`../Cursos/Administrador.aspx?codigo=${item.Codigo}&type=Cerrado`}>
|
||||||
|
<span className="badge bg-primary" style={{ fontWeight: "normal" }}>
|
||||||
|
Ver
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<a href={`https://sam.norteamericano.cl/academico/Empresas/Cursos/Administrador.aspx?codigo=${item.Codigo}`}>
|
||||||
|
<span className="badge bg-primary" style={{ fontWeight: "normal" }}>
|
||||||
|
Ver
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "5%" }}>
|
||||||
|
{item.TipoCurso}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "23%" }}>
|
||||||
|
{`${item.Codigo} - ${item.Curso}`}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "6%" }}>
|
||||||
|
{item.Periodo}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "14%" }}>
|
||||||
|
{item.Titular}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "7%" }}>
|
||||||
|
{item.Sede}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "4%" }}>
|
||||||
|
{item.Alumnos}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "12%" }}>
|
||||||
|
{`${item.Inicio} || ${item.Termino}`}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "20%" }}>
|
||||||
|
{item.Schedule}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "8%" }}>
|
||||||
|
{item.Estado === "Finalizado" ? (
|
||||||
|
<span className="text-success d-inline-flex align-items-center">
|
||||||
|
<CheckCircle className="me-1" /> Finalizado
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-warning d-inline-flex align-items-center">
|
||||||
|
{/* <ErrorCircle className="me-1" /> */} En curso
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL DE ALERTA / MENSAJE */}
|
||||||
|
{modalAlerta.show && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block bg-dark bg-opacity-50"
|
||||||
|
tabIndex={-1}
|
||||||
|
role="dialog"
|
||||||
|
aria-labelledby="resultPreAdvanced"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary mb-0">
|
||||||
|
<h5 className="float-start mt-2">
|
||||||
|
<strong>Módulo Academico - Empresa</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close float-end mt-1"
|
||||||
|
aria-label="Close"
|
||||||
|
onClick={() => setModalAlerta({ show: false, mensaje: "" })}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert mb-0" style={{ textAlign: "justify" }}>
|
||||||
|
<div className="row">
|
||||||
|
<div className="row mb-2">
|
||||||
|
<div className="col-md-12 text-center">
|
||||||
|
<h5>
|
||||||
|
<strong>{modalAlerta.mensaje}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setModalAlerta({ show: false, mensaje: "" })}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL DE CARGANDO */}
|
||||||
|
{isLoading && (
|
||||||
|
<div className="modal fade show d-block bg-dark bg-opacity-50" tabIndex={-1} role="dialog">
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="col-md-12 text-center py-3">
|
||||||
|
<div className="spinner-border text-primary" role="status">
|
||||||
|
<span className="visually-hidden">Cargando...</span>
|
||||||
|
</div>
|
||||||
|
<p className="mt-2 mb-0 fw-bold">Cargando información...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,285 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { User, InfoCircle } from "@boxicons/react";
|
||||||
|
|
||||||
|
// Interfaz para la estructura del listado del informe
|
||||||
|
interface InformeItem {
|
||||||
|
Codigo: string;
|
||||||
|
Curso: string;
|
||||||
|
idAlumno: string;
|
||||||
|
Alumno: string;
|
||||||
|
RegsitroAcademico: string;
|
||||||
|
idEmpresas: string;
|
||||||
|
Empresa: string;
|
||||||
|
contrato: string;
|
||||||
|
Sede: string;
|
||||||
|
Jornada: string;
|
||||||
|
Fecha: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function InformeCursosPage() {
|
||||||
|
// Estados para textos e información dinámica
|
||||||
|
const [mensajeLabel, setMensajeLabel] = useState("Información del reporte cargada correctamente.");
|
||||||
|
const [fechTypeLabel, setFechTypeLabel] = useState("Fecha Inicio");
|
||||||
|
|
||||||
|
// Estado para el listado de datos
|
||||||
|
const [informeList, setInformeList] = useState<InformeItem[]>([
|
||||||
|
{
|
||||||
|
Codigo: "CUR-101",
|
||||||
|
Curso: "Inglés Técnico para Empresas",
|
||||||
|
idAlumno: "18.765.432-1",
|
||||||
|
Alumno: "Roberto Gómez",
|
||||||
|
RegsitroAcademico: "REG-2026-01",
|
||||||
|
idEmpresas: "76.543.210-K",
|
||||||
|
Empresa: "Servicios Tecnológicos SpA",
|
||||||
|
contrato: "CTR-88",
|
||||||
|
Sede: "Santiago Centro",
|
||||||
|
Jornada: "Vespertina",
|
||||||
|
Fecha: "15/03/2026",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Codigo: "CUR-102",
|
||||||
|
Curso: "Inglés Negocios B1",
|
||||||
|
idAlumno: "19.123.456-7",
|
||||||
|
Alumno: "Andrea Morales",
|
||||||
|
RegsitroAcademico: "REG-2026-02",
|
||||||
|
idEmpresas: "77.111.222-3",
|
||||||
|
Empresa: "Consultoras Unidas S.A.",
|
||||||
|
contrato: "CTR-92",
|
||||||
|
Sede: "Providencia",
|
||||||
|
Jornada: "Diurna",
|
||||||
|
Fecha: "18/03/2026",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Estados para modales
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [modalAlerta, setModalAlerta] = useState<{
|
||||||
|
show: boolean;
|
||||||
|
mensaje: string;
|
||||||
|
}>({ show: false, mensaje: "" });
|
||||||
|
|
||||||
|
// Evento para descargar Excel
|
||||||
|
const handleDescargarExcel = () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setModalAlerta({
|
||||||
|
show: true,
|
||||||
|
mensaje: "El archivo Excel se ha generado y descargado con éxito.",
|
||||||
|
});
|
||||||
|
}, 1200);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="row">
|
||||||
|
{/* ENCABEZADO Y BOTÓN VOLVER */}
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Informe</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<a
|
||||||
|
href="../Cursos/Index.aspx"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* SECCIÓN INFORMACIÓN Y DESCARGA EXCEL */}
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col m-1 d-flex align-items-center">
|
||||||
|
<strong>
|
||||||
|
<InfoCircle style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="fw-bold ms-2">{mensajeLabel}</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col m-1 text-end">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-success"
|
||||||
|
onClick={handleDescargarExcel}
|
||||||
|
>
|
||||||
|
Descargar Excel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* TABLA PRINCIPAL DEL INFORME */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover"
|
||||||
|
style={{ fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "5%" }}>
|
||||||
|
Curso ID
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "15%" }}>
|
||||||
|
Curso
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "7%" }}>
|
||||||
|
Alumno RUN
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "15%" }}>
|
||||||
|
Alumno
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "7%" }}>
|
||||||
|
Registro
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "7%" }}>
|
||||||
|
Empresa Rut
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "15%" }}>
|
||||||
|
Empresa
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "5%" }}>
|
||||||
|
Contrato
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "6%" }}>
|
||||||
|
Sede
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "6%" }}>
|
||||||
|
Jornada
|
||||||
|
</th>
|
||||||
|
<th className="text-center" style={{ width: "12%" }}>
|
||||||
|
{fechTypeLabel} Curso
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{informeList.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="text-start" style={{ width: "5%" }}>
|
||||||
|
{item.Codigo}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
{item.Curso}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "7%" }}>
|
||||||
|
{item.idAlumno}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
{item.Alumno}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "7%" }}>
|
||||||
|
{item.RegsitroAcademico}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "7%" }}>
|
||||||
|
{item.idEmpresas}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
{item.Empresa}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "5%" }}>
|
||||||
|
{item.contrato}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "6%" }}>
|
||||||
|
{item.Sede}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "6%" }}>
|
||||||
|
{item.Jornada}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "12%" }}>
|
||||||
|
{item.Fecha}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL DE ALERTA / MENSAJE DE ERROR O ÉXITO */}
|
||||||
|
{modalAlerta.show && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block bg-dark bg-opacity-50"
|
||||||
|
tabIndex={-1}
|
||||||
|
role="dialog"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary mb-0">
|
||||||
|
<h5 className="float-start mt-2">
|
||||||
|
<strong>Módulo Académico - Informe</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close float-end mt-1"
|
||||||
|
aria-label="Close"
|
||||||
|
onClick={() => setModalAlerta({ show: false, mensaje: "" })}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert mb-0" style={{ textAlign: "justify" }}>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 text-center py-2">
|
||||||
|
<h5>
|
||||||
|
<strong>{modalAlerta.mensaje}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setModalAlerta({ show: false, mensaje: "" })}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL DE CARGANDO / LOADING */}
|
||||||
|
{isLoading && (
|
||||||
|
<div className="modal fade show d-block bg-dark bg-opacity-50" tabIndex={-1} role="dialog">
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="col-md-12 text-center py-3">
|
||||||
|
<div className="spinner-border text-primary" role="status">
|
||||||
|
<span className="visually-hidden">Procesando...</span>
|
||||||
|
</div>
|
||||||
|
<p className="mt-2 mb-0 fw-bold">Procesando descarga...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,483 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
User,
|
||||||
|
Buildings,
|
||||||
|
Book,
|
||||||
|
UserCircle,
|
||||||
|
//Export,
|
||||||
|
CheckCircle,
|
||||||
|
//ErrorCircle,
|
||||||
|
} from "@boxicons/react";
|
||||||
|
|
||||||
|
// Interfaz para la estructura del listado de cursos
|
||||||
|
interface CursoItem {
|
||||||
|
Codigo: string;
|
||||||
|
Curso: string;
|
||||||
|
TipoCurso: string;
|
||||||
|
Periodo: string;
|
||||||
|
Titular: string;
|
||||||
|
Sede: string;
|
||||||
|
Alumnos: number;
|
||||||
|
Inicio: string;
|
||||||
|
Termino: string;
|
||||||
|
Schedule: string;
|
||||||
|
Estado: "Finalizado" | "En curso" | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CursosIniciadosPage() {
|
||||||
|
// Filtros de fecha
|
||||||
|
const [fechaInicio, setFechaInicio] = useState("");
|
||||||
|
const [fechaTermino, setFechaTermino] = useState("");
|
||||||
|
|
||||||
|
// Visibilidad de datos / reporte
|
||||||
|
const [mostrarReporte, setMostrarReporte] = useState(false);
|
||||||
|
|
||||||
|
// Totales
|
||||||
|
const [empTotal, setEmpTotal] = useState("0");
|
||||||
|
const [cursosTotal, setCursosTotal] = useState("0 %");
|
||||||
|
const [almConSnc, setAlmConSnc] = useState("0");
|
||||||
|
const [almSinSnc, setAlmSinSnc] = useState("0");
|
||||||
|
const [alumnosTotal, setAlumnosTotal] = useState("0");
|
||||||
|
|
||||||
|
// Lista de datos
|
||||||
|
const [cursos, setCursos] = useState<CursoItem[]>([]);
|
||||||
|
|
||||||
|
// Modals de estado
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [modalAlerta, setModalAlerta] = useState<{
|
||||||
|
show: boolean;
|
||||||
|
mensaje: string;
|
||||||
|
}>({ show: false, mensaje: "" });
|
||||||
|
|
||||||
|
// Manejador del botón Buscar
|
||||||
|
const handleBuscar = () => {
|
||||||
|
if (!fechaInicio || !fechaTermino) {
|
||||||
|
setModalAlerta({
|
||||||
|
show: true,
|
||||||
|
mensaje: "Por favor, seleccione un rango de fechas válido.",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
// Simulación de consulta API
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setMostrarReporte(true);
|
||||||
|
|
||||||
|
// Datos ficticios de prueba basados en el modelo
|
||||||
|
setEmpTotal("12");
|
||||||
|
setCursosTotal("85 %");
|
||||||
|
setAlmConSnc("45");
|
||||||
|
setAlmSinSnc("15");
|
||||||
|
setAlumnosTotal("60");
|
||||||
|
|
||||||
|
setCursos([
|
||||||
|
{
|
||||||
|
Codigo: "CUR-001",
|
||||||
|
Curso: "Inglés Avanzado B2",
|
||||||
|
TipoCurso: "Cerrado",
|
||||||
|
Periodo: "2026-1",
|
||||||
|
Titular: "Juan Pérez",
|
||||||
|
Sede: "Santiago Centro",
|
||||||
|
Alumnos: 15,
|
||||||
|
Inicio: "01/03/2026",
|
||||||
|
Termino: "30/06/2026",
|
||||||
|
Schedule: "Lun-Mié 09:00 - 11:00",
|
||||||
|
Estado: "Finalizado",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Codigo: "CUR-002",
|
||||||
|
Curso: "Inglés Intermedio A2",
|
||||||
|
TipoCurso: "Abierto",
|
||||||
|
Periodo: "2026-1",
|
||||||
|
Titular: "María González",
|
||||||
|
Sede: "Providencia",
|
||||||
|
Alumnos: 20,
|
||||||
|
Inicio: "10/03/2026",
|
||||||
|
Termino: "15/07/2026",
|
||||||
|
Schedule: "Mar-Jue 18:30 - 20:30",
|
||||||
|
Estado: "En curso",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manejador para volver o limpiar
|
||||||
|
const handleVolver = () => {
|
||||||
|
setMostrarReporte(false);
|
||||||
|
setFechaInicio("");
|
||||||
|
setFechaTermino("");
|
||||||
|
setCursos([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manejador para exportar a Excel
|
||||||
|
const handleExportarExcel = () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
setModalAlerta({
|
||||||
|
show: true,
|
||||||
|
mensaje: "El reporte en Excel ha sido generado con éxito.",
|
||||||
|
});
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12" id="cursos_periodo">
|
||||||
|
<div className="row">
|
||||||
|
{/* ENCABEZADO Y BOTÓN VOLVER */}
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Cursos iniciados por fecha</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
onClick={handleVolver}
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* FILTROS DE FECHA Y BÚSQUEDA */}
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Inicio</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
value={fechaInicio}
|
||||||
|
onChange={(e) => setFechaInicio(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Termino</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
value={fechaTermino}
|
||||||
|
onChange={(e) => setFechaTermino(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
onClick={handleBuscar}
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* SECCIÓN REPORTE / RESULTADOS */}
|
||||||
|
{mostrarReporte && (
|
||||||
|
<div className="col-md-12" id="div_reporte">
|
||||||
|
<div className="row">
|
||||||
|
{/* METRICA EMPRESAS */}
|
||||||
|
<div className="col-md-2" id="promedio_emp">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
<Buildings />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{empTotal}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* METRICA CURSOS */}
|
||||||
|
<div className="col-md-2" id="promedio_cursos">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
<Book />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Cursos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{cursosTotal}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* METRICA ALUMNOS */}
|
||||||
|
<div className="col-md-6" id="Div1">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
<UserCircle />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9 text-center mt-3">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Con SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{almConSnc}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Sin SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{almSinSnc}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>{alumnosTotal}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* BOTÓN EXPORTAR EXCEL */}
|
||||||
|
<div className="col-md-2 mx-auto" id="Div2">
|
||||||
|
<div className="alert alert-success shadow-sm" role="alert">
|
||||||
|
<div className="row mt-2 align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1 className="mb-0">
|
||||||
|
{/* <Export /> */}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Excel</strong>
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-link text-decoration-none p-0 d-block mx-auto"
|
||||||
|
onClick={handleExportarExcel}
|
||||||
|
>
|
||||||
|
<h5 className="mb-0 text-success">
|
||||||
|
<strong>Exportar</strong>
|
||||||
|
</h5>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* TABLA DE RESULTADOS */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: "12px" }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "3%" }}></th>
|
||||||
|
<th className="text-center" style={{ width: "5%" }}>Tipo de Curso</th>
|
||||||
|
<th className="text-start" style={{ width: "23%" }}>Curso</th>
|
||||||
|
<th className="text-start" style={{ width: "6%" }}>Periodo</th>
|
||||||
|
<th className="text-start" style={{ width: "14%" }}>Profesor</th>
|
||||||
|
<th className="text-center" style={{ width: "7%" }}>Sede</th>
|
||||||
|
<th className="text-center" style={{ width: "4%" }}>Alumnos</th>
|
||||||
|
<th className="text-center" style={{ width: "12%" }}>Fecha</th>
|
||||||
|
<th className="text-center" style={{ width: "20%" }}>Schedule</th>
|
||||||
|
<th className="text-center" style={{ width: "8%" }}>Estado</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{cursos.map((item, idx) => (
|
||||||
|
<tr key={idx}>
|
||||||
|
<td className="text-start" style={{ width: "3%" }}>
|
||||||
|
{item.TipoCurso === "Cerrado" ? (
|
||||||
|
<a
|
||||||
|
href={`../Cursos/Administrador.aspx?codigo=${item.Codigo}&type=Cerrado`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="badge bg-primary"
|
||||||
|
style={{ fontWeight: "normal" }}
|
||||||
|
>
|
||||||
|
Ver
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<a
|
||||||
|
href={`https://modulos.sam.norteamericano.cl/proyectoSam/Cursos/Administrador.aspx?codigo=${item.Codigo}`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="badge bg-primary"
|
||||||
|
style={{ fontWeight: "normal" }}
|
||||||
|
>
|
||||||
|
Ver
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "5%" }}>
|
||||||
|
{item.TipoCurso}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "23%" }}>
|
||||||
|
{`${item.Codigo} - ${item.Curso}`}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "6%" }}>
|
||||||
|
{item.Periodo}
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "14%" }}>
|
||||||
|
{item.Titular}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "7%" }}>
|
||||||
|
{item.Sede}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "4%" }}>
|
||||||
|
{item.Alumnos}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "12%" }}>
|
||||||
|
{`${item.Inicio} || ${item.Termino}`}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "20%" }}>
|
||||||
|
{item.Schedule}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "8%" }}>
|
||||||
|
{item.Estado === "Finalizado" ? (
|
||||||
|
<span className="text-success d-inline-flex align-items-center">
|
||||||
|
<CheckCircle className="me-1" /> Finalizado
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-warning d-inline-flex align-items-center">
|
||||||
|
{/* <ErrorCircle className="me-1" /> En curso */}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL DE ALERTA / MENSAJE */}
|
||||||
|
{modalAlerta.show && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block bg-dark bg-opacity-50"
|
||||||
|
tabIndex={-1}
|
||||||
|
role="dialog"
|
||||||
|
aria-labelledby="resultPreAdvanced"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary mb-0">
|
||||||
|
<h5 className="float-start mt-2">
|
||||||
|
<strong>Módulo Academico - Empresa</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close float-end mt-1"
|
||||||
|
aria-label="Close"
|
||||||
|
onClick={() => setModalAlerta({ show: false, mensaje: "" })}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert mb-0" style={{ textAlign: "justify" }}>
|
||||||
|
<div className="row">
|
||||||
|
<div className="row mb-2">
|
||||||
|
<div className="col-md-12 text-center">
|
||||||
|
<h5>
|
||||||
|
<strong>{modalAlerta.mensaje}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setModalAlerta({ show: false, mensaje: "" })}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL DE CARGANDO */}
|
||||||
|
{isLoading && (
|
||||||
|
<div className="modal fade show d-block bg-dark bg-opacity-50" tabIndex={-1} role="dialog">
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="col-md-12 text-center py-3">
|
||||||
|
<div className="spinner-border text-primary" role="status">
|
||||||
|
<span className="visually-hidden">Cargando...</span>
|
||||||
|
</div>
|
||||||
|
<p className="mt-2 mb-0 fw-bold">Cargando información...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,649 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import {
|
||||||
|
User,
|
||||||
|
// AlertOctagon,
|
||||||
|
// Export,
|
||||||
|
Buildings,
|
||||||
|
UserCircle,
|
||||||
|
BookLibrary,
|
||||||
|
// Error as ErrorIcon,
|
||||||
|
} from "@boxicons/react";
|
||||||
|
|
||||||
|
import Chart from "chart.js/auto";
|
||||||
|
|
||||||
|
export default function AlumnosPorMesPage() {
|
||||||
|
// Estados para controlar las vistas
|
||||||
|
const [divReporteV2, setDivReporteV2] = useState(true);
|
||||||
|
const [divReporte, setDivReporte] = useState(false);
|
||||||
|
|
||||||
|
// Estados para modales
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showAlertModal, setShowAlertModal] = useState(false);
|
||||||
|
const [mensajeAlerta, setMensajeAlerta] = useState("");
|
||||||
|
|
||||||
|
// Datos simulados para tablas
|
||||||
|
const [regiones] = useState([
|
||||||
|
{ Region: "Región Metropolitana", Cantidad: 150 },
|
||||||
|
{ Region: "Valparaíso", Cantidad: 45 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const [comunas] = useState([
|
||||||
|
{ Comuna: "Santiago", Cantidad: 80 },
|
||||||
|
{ Comuna: "Providencia", Cantidad: 70 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Manejador de búsqueda
|
||||||
|
const handleBuscar = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inicialización de gráficos Chart.js
|
||||||
|
useEffect(() => {
|
||||||
|
// Gráfico de Ocupación (Bar)
|
||||||
|
const ctxOcupacion = document.getElementById(
|
||||||
|
"OcupacionBar"
|
||||||
|
) as HTMLCanvasElement;
|
||||||
|
let chartOcupacion: Chart | null = null;
|
||||||
|
if (ctxOcupacion) {
|
||||||
|
chartOcupacion = new Chart(ctxOcupacion, {
|
||||||
|
type: "bar",
|
||||||
|
data: {
|
||||||
|
labels: ["Enero", "Febrero", "Marzo"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [12, 19, 3],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: { responsive: true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gráfico de Profesiones (Pie)
|
||||||
|
const ctxProfesion = document.getElementById(
|
||||||
|
"ProfesionPies"
|
||||||
|
) as HTMLCanvasElement;
|
||||||
|
let chartProfesion: Chart | null = null;
|
||||||
|
if (ctxProfesion) {
|
||||||
|
chartProfesion = new Chart(ctxProfesion, {
|
||||||
|
type: "pie",
|
||||||
|
data: {
|
||||||
|
labels: ["Ingeniería", "Medicina", "Educación", "Otros"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [30, 20, 15, 35],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: { responsive: true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limpieza al desmontar componente
|
||||||
|
return () => {
|
||||||
|
if (chartOcupacion) chartOcupacion.destroy();
|
||||||
|
if (chartProfesion) chartProfesion.destroy();
|
||||||
|
};
|
||||||
|
}, [divReporteV2]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
<div className="row">
|
||||||
|
{/* Encabezado y Filtros */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Alumnos por Mes</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<Link
|
||||||
|
href="/Alumnos/Index"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<form onSubmit={handleBuscar} className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Mes</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<select id="ListaMeses" className="form-select form-select-sm">
|
||||||
|
<option value="1">Enero</option>
|
||||||
|
<option value="2">Febrero</option>
|
||||||
|
<option value="3">Marzo</option>
|
||||||
|
{/* Agregar el resto de los meses */}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Año</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="TextBoxAgno"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
defaultValue={2026}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Reporte V2 */}
|
||||||
|
{divReporteV2 && (
|
||||||
|
<div className="col-md-12" id="div_reporteV2">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
{/* Columna Izquierda (Totales, Exportar y Grafico Bar) */}
|
||||||
|
<div className="col-md-3 mt-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3 mx-auto">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn p-0 border-0 w-100 text-decoration-none"
|
||||||
|
onClick={() => {
|
||||||
|
setMensajeAlerta("Generando reporte Excel...");
|
||||||
|
setShowAlertModal(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="alert alert-success shadow" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<h1>
|
||||||
|
{/* <Export /> */}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Excel</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>Exportar</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<UserCircle />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12 mt-3" id="Ocupacion">
|
||||||
|
<div
|
||||||
|
className="alert alert-light shadow text-dark offcanvas-lg offcanvas-sm"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<canvas id="OcupacionBar" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna Central (Tablas Regiones y Comunas) */}
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="alert alert-light" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover"
|
||||||
|
style={{ fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
Regiones
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
Cantidad
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{regiones.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="text-start">{item.Region}</td>
|
||||||
|
<td className="text-start">{item.Cantidad}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover"
|
||||||
|
style={{ fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
Comuna
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
Cantidad
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{comunas.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="text-start">{item.Comuna}</td>
|
||||||
|
<td className="text-start">{item.Cantidad}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna Derecha (Gráfico de Profesiones) */}
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12" id="Profesion">
|
||||||
|
<div
|
||||||
|
className="alert alert-light text-dark offcanvas-lg offcanvas-sm"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<b>
|
||||||
|
<u>Profesiones</u>
|
||||||
|
</b>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<canvas
|
||||||
|
id="ProfesionPies"
|
||||||
|
className="w-100 h-100"
|
||||||
|
></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Reporte V1 (Oculto por defecto) */}
|
||||||
|
{divReporte && (
|
||||||
|
<div className="col-md-12" id="div_reporte">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<Buildings />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<Buildings />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Cursos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-6">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<UserCircle />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9 text-center mt-3">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Con SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Sin SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<Buildings />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-4" id="resize">
|
||||||
|
<div className="alert alert-light shadow text-dark offcanvas-lg" role="alert">
|
||||||
|
<canvas id="myChart" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="alert alert-primary" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<BookLibrary />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos por Planes</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9 text-center mt-3" style={{ fontSize: "14px" }}>
|
||||||
|
<div className="row g-0 text-center">
|
||||||
|
<div className="col-6 col-md-4">
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Adults</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-6 col-md-8">
|
||||||
|
<strong>0</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row g-0 text-center">
|
||||||
|
<div className="col-6 col-md-4">
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Business</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-6 col-md-8">
|
||||||
|
<strong>0</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row g-0 text-center">
|
||||||
|
<div className="col-6 col-md-4">
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Teens</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-6 col-md-8">
|
||||||
|
<strong>0</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row g-0 text-center">
|
||||||
|
<div className="col-6 col-md-4">
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Kids</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-6 col-md-8">
|
||||||
|
<strong>0</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<UserCircle />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Condicion de registro</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9 text-center mt-3">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Plan Central</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Curso Cerrado</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-4" id="resizev2">
|
||||||
|
<div className="alert alert-light shadow text-dark offcanvas-lg" role="alert">
|
||||||
|
<canvas id="myLines" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4" id="resizev3">
|
||||||
|
<div className="alert alert-light shadow text-dark offcanvas-lg" role="alert">
|
||||||
|
<canvas id="myPies" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL DE MENSAJES/ALERTAS */}
|
||||||
|
{showAlertModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>Módulo Académico - Reporte</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center">
|
||||||
|
<h5>
|
||||||
|
<strong>{mensajeAlerta}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
>
|
||||||
|
Cerrar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL CARGANDO */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>SAM - Académico Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-4">
|
||||||
|
<h5>
|
||||||
|
<strong>Procesando, espere un momento...</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="mt-3">
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,658 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { User,
|
||||||
|
//Export
|
||||||
|
|
||||||
|
} from "@boxicons/react";
|
||||||
|
|
||||||
|
export default function CursosPorMesPage() {
|
||||||
|
// Estados para modales
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showAlertModal, setShowAlertModal] = useState(false);
|
||||||
|
const [mensajeAlerta, setMensajeAlerta] = useState("");
|
||||||
|
|
||||||
|
// Datos simulados para la tabla de Planes (DataList en ASP.NET)
|
||||||
|
const [planes] = useState([
|
||||||
|
{ Plan: "Intensivo Adults", Cantidad: 45 },
|
||||||
|
{ Plan: "Regular Kids", Cantidad: 30 },
|
||||||
|
{ Plan: "Business Express", Cantidad: 25 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Manejo de búsqueda
|
||||||
|
const handleBuscar = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manejo de exportación a Excel
|
||||||
|
const handleExportarExcel = (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setMensajeAlerta("Generando y descargando archivo Excel...");
|
||||||
|
setShowAlertModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Carga de Chart.js mediante importación dinámica
|
||||||
|
useEffect(() => {
|
||||||
|
let chartJornadas: any = null;
|
||||||
|
let chartPlan: any = null;
|
||||||
|
|
||||||
|
import("chart.js/auto").then(({ default: Chart }) => {
|
||||||
|
// Gráfico de Jornadas (Bar)
|
||||||
|
const ctxJornadas = document.getElementById(
|
||||||
|
"jornadasBar"
|
||||||
|
) as HTMLCanvasElement;
|
||||||
|
if (ctxJornadas) {
|
||||||
|
chartJornadas = new Chart(ctxJornadas, {
|
||||||
|
type: "bar",
|
||||||
|
data: {
|
||||||
|
labels: ["Mañana", "Tarde", "Noche", "Sábado"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [15, 25, 40, 10],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gráfico de Programas (Pie)
|
||||||
|
const ctxPlan = document.getElementById("planPie") as HTMLCanvasElement;
|
||||||
|
if (ctxPlan) {
|
||||||
|
chartPlan = new Chart(ctxPlan, {
|
||||||
|
type: "pie",
|
||||||
|
data: {
|
||||||
|
labels: ["Adults", "Kids", "Teens", "Business"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [45, 30, 15, 25],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: "left",
|
||||||
|
labels: {
|
||||||
|
font: {
|
||||||
|
size: 11,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (chartJornadas) chartJornadas.destroy();
|
||||||
|
if (chartPlan) chartPlan.destroy();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
<div className="row">
|
||||||
|
{/* Filtros superiores */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Cursos por mes</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<Link
|
||||||
|
href="/Alumnos/Index"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<form onSubmit={handleBuscar} className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Mes</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<select
|
||||||
|
id="ListaMeses"
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
>
|
||||||
|
<option value="1">Enero</option>
|
||||||
|
<option value="2">Febrero</option>
|
||||||
|
<option value="3">Marzo</option>
|
||||||
|
<option value="4">Abril</option>
|
||||||
|
<option value="5">Mayo</option>
|
||||||
|
<option value="6">Junio</option>
|
||||||
|
<option value="7">Julio</option>
|
||||||
|
<option value="8">Agosto</option>
|
||||||
|
<option value="9">Septiembre</option>
|
||||||
|
<option value="10">Octubre</option>
|
||||||
|
<option value="11">Noviembre</option>
|
||||||
|
<option value="12">Diciembre</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Año</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="TextBoxAgno"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
defaultValue={2026}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sección Reporte Principal */}
|
||||||
|
<div className="col-md-12" id="div_reporte">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
{/* Columna Izquierda: Tarjetas y métricas */}
|
||||||
|
<div className="col-md-3 mt-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mx-auto">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleExportarExcel}
|
||||||
|
className="btn p-0 border-0 w-100 text-decoration-none"
|
||||||
|
>
|
||||||
|
<div className="alert alert-success shadow" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<h1>
|
||||||
|
{/* <Export /> */}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Excel</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>Exportar</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-users-line"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-book"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Cursos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-swatchbook"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Inscripción de Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start mt-2">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Con SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Sin SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna Central: Tabla de Planes y Progreso de Sedes */}
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="alert alert-light" role="alert">
|
||||||
|
<div className="table-responsive" style={{ width: "100%" }}>
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover"
|
||||||
|
style={{ fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
Plan
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
Cantidad
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{planes.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="text-start">{item.Plan}</td>
|
||||||
|
<td className="text-start">{item.Cantidad}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover mt-2"
|
||||||
|
style={{ fontSize: "12px", width: "100%" }}
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
<strong>TOTAL</strong>
|
||||||
|
</th>
|
||||||
|
<td className="text-start fw-bold" style={{ width: "20%" }}>
|
||||||
|
{planes.reduce((acc, curr) => acc + curr.Cantidad, 0)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<h4 className="text-center">
|
||||||
|
<small>
|
||||||
|
<u>Cursos por sedes con alumnos de empresas</u>
|
||||||
|
</small>
|
||||||
|
</h4>
|
||||||
|
<div className="col-md-8 text-start">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-school"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Sedes</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center mt-1">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Default striped example"
|
||||||
|
aria-valuenow={100}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="progress-bar progress-bar-striped"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
Cursos sin SENCE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Warning striped example"
|
||||||
|
aria-valuenow={100}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="progress-bar progress-bar-striped bg-warning text-dark"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
Cursos con SENCE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12 text-center mt-3">
|
||||||
|
<h5>
|
||||||
|
<strong>Moneda</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Segment one"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="mone"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "50%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="moneSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "50%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Providencia</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="prov"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "60%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="provSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "40%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>La Florida</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="flor"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "70%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="florSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "30%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Online</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="onli"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "80%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="onliSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "20%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="corp"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "40%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="corpSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "60%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Columna Derecha: Gráficos de Jornadas y Programas */}
|
||||||
|
<div className="col-md-5 align-middle">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12" id="Jornadas">
|
||||||
|
<div
|
||||||
|
className="alert alert-light text-dark offcanvas-lg offcanvas-sm"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<b>
|
||||||
|
<u>Jornadas</u>
|
||||||
|
</b>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<canvas id="jornadasBar" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12" id="Programas">
|
||||||
|
<div
|
||||||
|
className="alert alert-light text-dark offcanvas-lg offcanvas-sm container-md container-sm"
|
||||||
|
style={{ height: "40vh" }}
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<b>
|
||||||
|
<u>Programas</u>
|
||||||
|
</b>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<canvas id="planPie" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL ALERTA / MENSAJES */}
|
||||||
|
{showAlertModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>Módulo Académico - Cursos</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-3">
|
||||||
|
<h5>
|
||||||
|
<strong>{mensajeAlerta}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
>
|
||||||
|
Cerrar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL CARGANDO */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>SAM - Académico Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-4">
|
||||||
|
<h5>
|
||||||
|
<strong>Procesando, espere un momento...</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="mt-3">
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,666 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { User } from "@boxicons/react";
|
||||||
|
|
||||||
|
export default function CursosPlanCentralPage() {
|
||||||
|
// Estado para visibilidad del reporte (corresponde a visible="false" en ASP.NET)
|
||||||
|
const [divReporte, setDivReporte] = useState(true);
|
||||||
|
|
||||||
|
// Estados para modales de carga y mensajes/errores
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showAlertModal, setShowAlertModal] = useState(false);
|
||||||
|
const [mensajeAlerta, setMensajeAlerta] = useState("");
|
||||||
|
|
||||||
|
// Estado para los filtros de Periodo y Letras
|
||||||
|
const [periodo, setPeriodo] = useState("");
|
||||||
|
const [letras, setLetras] = useState<string[]>([]);
|
||||||
|
|
||||||
|
// Datos para la tabla de Planes (DataList en ASP.NET)
|
||||||
|
const [planes] = useState([
|
||||||
|
{ Plan: "Plan Central General", Cantidad: 35 },
|
||||||
|
{ Plan: "Plan Intensivo", Cantidad: 20 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Evento al cambiar Periodo (simula el AutoPostBack de ASP.NET)
|
||||||
|
const handlePeriodoChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
const val = e.target.value;
|
||||||
|
setPeriodo(val);
|
||||||
|
|
||||||
|
// Actualización dinámica de select según el periodo seleccionado
|
||||||
|
if (val === "1") {
|
||||||
|
setLetras(["A", "B", "C"]);
|
||||||
|
} else if (val === "2") {
|
||||||
|
setLetras(["D", "E", "F"]);
|
||||||
|
} else {
|
||||||
|
setLetras([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manejo de búsqueda
|
||||||
|
const handleBuscar = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
setDivReporte(true); // Hace visible el reporte tras buscar
|
||||||
|
}, 1200);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exportar a Excel
|
||||||
|
const handleExportarExcel = (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setMensajeAlerta("Generando y exportando reporte Excel...");
|
||||||
|
setShowAlertModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inicialización de Chart.js dinámico en cliente
|
||||||
|
useEffect(() => {
|
||||||
|
if (!divReporte) return;
|
||||||
|
|
||||||
|
let chartJornadas: any = null;
|
||||||
|
let chartPlan: any = null;
|
||||||
|
|
||||||
|
import("chart.js/auto").then(({ default: Chart }) => {
|
||||||
|
// Gráfico de Jornadas (Bar)
|
||||||
|
const ctxJornadas = document.getElementById(
|
||||||
|
"jornadasBar"
|
||||||
|
) as HTMLCanvasElement;
|
||||||
|
|
||||||
|
if (ctxJornadas) {
|
||||||
|
chartJornadas = new Chart(ctxJornadas, {
|
||||||
|
type: "bar",
|
||||||
|
data: {
|
||||||
|
labels: ["Mañana", "Tarde", "Noche"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [12, 19, 8],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gráfico de Programas (Pie)
|
||||||
|
const ctxPlan = document.getElementById("planPie") as HTMLCanvasElement;
|
||||||
|
|
||||||
|
if (ctxPlan) {
|
||||||
|
chartPlan = new Chart(ctxPlan, {
|
||||||
|
type: "pie",
|
||||||
|
data: {
|
||||||
|
labels: ["Programa A", "Programa B", "Programa C"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [20, 15, 10],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: "left",
|
||||||
|
labels: {
|
||||||
|
font: {
|
||||||
|
size: 11,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (chartJornadas) chartJornadas.destroy();
|
||||||
|
if (chartPlan) chartPlan.destroy();
|
||||||
|
};
|
||||||
|
}, [divReporte]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
<div className="row">
|
||||||
|
{/* Encabezado y Filtros */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">
|
||||||
|
Cursos plan central por mes
|
||||||
|
</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<Link
|
||||||
|
href="/Alumnos/Index"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<form onSubmit={handleBuscar} className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Año</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="TextBoxAgno"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
defaultValue={2026}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Periodo</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<select
|
||||||
|
id="ListaPeriodo"
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
value={periodo}
|
||||||
|
onChange={handlePeriodoChange}
|
||||||
|
>
|
||||||
|
<option value="">Seleccione</option>
|
||||||
|
<option value="1">Periodo 1</option>
|
||||||
|
<option value="2">Periodo 2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<select
|
||||||
|
id="ListaLetras"
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
>
|
||||||
|
{letras.map((item, index) => (
|
||||||
|
<option key={index} value={item}>
|
||||||
|
{item}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sección Reporte Principal */}
|
||||||
|
{divReporte && (
|
||||||
|
<div className="col-md-12" id="div_reporte">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
{/* Métricas y Tarjetas Izquierda */}
|
||||||
|
<div className="col-md-3 mt-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mx-auto">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleExportarExcel}
|
||||||
|
className="btn p-0 border-0 w-100 text-decoration-none"
|
||||||
|
>
|
||||||
|
<div className="alert alert-success shadow" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<h1>
|
||||||
|
{/* <Export /> */}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Excel</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>Exportar</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-users-line"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-book"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Cursos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-swatchbook"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Inscripción de Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start mt-2">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Con SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Sin SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tabla de Planes y Progreso de Sedes */}
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="alert alert-light" role="alert">
|
||||||
|
<div className="table-responsive" style={{ width: "100%" }}>
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover"
|
||||||
|
style={{ fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
Plan
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
Cantidad
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{planes.map((item, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="text-start">{item.Plan}</td>
|
||||||
|
<td className="text-start">{item.Cantidad}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover mt-2"
|
||||||
|
style={{ fontSize: "12px", width: "100%" }}
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
<strong>TOTAL</strong>
|
||||||
|
</th>
|
||||||
|
<td className="text-start fw-bold" style={{ width: "20%" }}>
|
||||||
|
{planes.reduce((acc, curr) => acc + curr.Cantidad, 0)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<h4 className="text-center">
|
||||||
|
<small>
|
||||||
|
<u>Cursos por sedes con Alumnos de empresas</u>
|
||||||
|
</small>
|
||||||
|
</h4>
|
||||||
|
<div className="col-md-8 text-start">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-school"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Sedes</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center mt-1">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Default striped example"
|
||||||
|
aria-valuenow={100}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="progress-bar progress-bar-striped"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
Cursos sin SENCE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Warning striped example"
|
||||||
|
aria-valuenow={100}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="progress-bar progress-bar-striped bg-warning text-dark"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
Cursos con SENCE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12 text-center mt-3">
|
||||||
|
<h5>
|
||||||
|
<strong>Moneda</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Segment one"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="mone"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "50%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="moneSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "50%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Providencia</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="prov"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "60%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="provSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "40%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>La Florida</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="flor"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "70%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="florSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "30%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Online</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="onli"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "80%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="onliSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "20%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Canvas de Gráficos */}
|
||||||
|
<div className="col-md-5 align-middle">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12" id="Jornadas">
|
||||||
|
<div
|
||||||
|
className="alert alert-light text-dark offcanvas-lg offcanvas-sm"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<b>
|
||||||
|
<u>Jornadas</u>
|
||||||
|
</b>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<canvas id="jornadasBar" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12" id="Programas">
|
||||||
|
<div
|
||||||
|
className="alert alert-light text-dark offcanvas-lg offcanvas-sm container-md container-sm"
|
||||||
|
style={{ height: "40vh" }}
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<b>
|
||||||
|
<u>Programas</u>
|
||||||
|
</b>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<canvas id="planPie" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL ALERTA / MENSAJES */}
|
||||||
|
{showAlertModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>Módulo Académico - Plan Central</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-3">
|
||||||
|
<h5>
|
||||||
|
<strong>{mensajeAlerta}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
>
|
||||||
|
Cerrar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL CARGANDO */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>SAM - Académico Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-4">
|
||||||
|
<h5>
|
||||||
|
<strong>Procesando, espere un momento...</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="mt-3">
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,611 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { User, BuildingHouse } from "@boxicons/react";
|
||||||
|
|
||||||
|
export default function EmpresasPorMesPage() {
|
||||||
|
// Estado de visibilidad del reporte principal (div_reporte)
|
||||||
|
const [divReporte, setDivReporte] = useState(true);
|
||||||
|
|
||||||
|
// Estados para modales de Carga y Alertas/Errores
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showAlertModal, setShowAlertModal] = useState(false);
|
||||||
|
const [mensajeAlerta, setMensajeAlerta] = useState("");
|
||||||
|
|
||||||
|
// Manejo de búsqueda
|
||||||
|
const handleBuscar = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
setDivReporte(true);
|
||||||
|
}, 1200);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Manejo de exportación Excel
|
||||||
|
const handleExportarExcel = (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setMensajeAlerta("Generando y exportando reporte Excel...");
|
||||||
|
setShowAlertModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Carga e inicialización de Chart.js dinámico para Tipo de Ventas (Doughnut)
|
||||||
|
useEffect(() => {
|
||||||
|
if (!divReporte) return;
|
||||||
|
|
||||||
|
let chartVenta: any = null;
|
||||||
|
|
||||||
|
import("chart.js/auto").then(({ default: Chart }) => {
|
||||||
|
const ctxVenta = document.getElementById(
|
||||||
|
"ventaPie"
|
||||||
|
) as HTMLCanvasElement;
|
||||||
|
|
||||||
|
if (ctxVenta) {
|
||||||
|
chartVenta = new Chart(ctxVenta, {
|
||||||
|
type: "doughnut",
|
||||||
|
data: {
|
||||||
|
labels: ["Directa", "Licitación", "Convenio Marco", "Otros"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Cantidad",
|
||||||
|
data: [40, 25, 20, 15],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (chartVenta) chartVenta.destroy();
|
||||||
|
};
|
||||||
|
}, [divReporte]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
<div className="row">
|
||||||
|
{/* Encabezado y Filtros */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Empresas por mes</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<Link
|
||||||
|
href="/Alumnos/Index"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<form onSubmit={handleBuscar} className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Mes</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<select
|
||||||
|
id="ListaMeses"
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
>
|
||||||
|
<option value="1">Enero</option>
|
||||||
|
<option value="2">Febrero</option>
|
||||||
|
<option value="3">Marzo</option>
|
||||||
|
<option value="4">Abril</option>
|
||||||
|
<option value="5">Mayo</option>
|
||||||
|
<option value="6">Junio</option>
|
||||||
|
<option value="7">Julio</option>
|
||||||
|
<option value="8">Agosto</option>
|
||||||
|
<option value="9">Septiembre</option>
|
||||||
|
<option value="10">Octubre</option>
|
||||||
|
<option value="11">Noviembre</option>
|
||||||
|
<option value="12">Diciembre</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">Año</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="TextBoxYear"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
defaultValue={2026}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sección Reporte Principal */}
|
||||||
|
{divReporte && (
|
||||||
|
<div className="col-md-12" id="div_reporte">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
{/* Métricas y Tarjetas Izquierda */}
|
||||||
|
<div className="col-md-3 mt-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mx-auto">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleExportarExcel}
|
||||||
|
className="btn p-0 border-0 w-100 text-decoration-none"
|
||||||
|
>
|
||||||
|
<div className="alert alert-success shadow" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<h1>
|
||||||
|
{/* <Export /> */}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Excel</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>Exportar</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-users-line"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-3 text-center">
|
||||||
|
<h1>
|
||||||
|
<BuildingHouse style={{ fontSize: "36px" }} />
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center mt-3">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light shadow text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-swatchbook"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Alumnos</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start mt-2">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Con SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Sin SENCE</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Total</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>0</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tabla Alumnos de empresas y Progreso de Sedes */}
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="alert alert-light" role="alert">
|
||||||
|
<div className="table-responsive" style={{ width: "100%" }}>
|
||||||
|
<h3>Alumnos de empresas</h3>
|
||||||
|
<table
|
||||||
|
className="table table-sm mb-0 table-hover"
|
||||||
|
style={{ fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
Tipo
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
Cantidad
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "80%" }}>
|
||||||
|
Cursos Abierto
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}>
|
||||||
|
0
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "80%" }}>
|
||||||
|
Cursos Cerrado
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}>
|
||||||
|
0
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "80%" }}>
|
||||||
|
Total
|
||||||
|
</th>
|
||||||
|
<th className="text-start" style={{ width: "20%" }}>
|
||||||
|
0
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<h4 className="text-center">
|
||||||
|
<small>
|
||||||
|
<u>Sedes con alumnos de empresas</u>
|
||||||
|
</small>
|
||||||
|
</h4>
|
||||||
|
<div className="col-md-8 text-start">
|
||||||
|
<h1>
|
||||||
|
<i className="fa-solid fa-school"></i>
|
||||||
|
</h1>
|
||||||
|
<span className="fw-bold">
|
||||||
|
<strong>Sedes</strong>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center mt-1">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Default striped example"
|
||||||
|
aria-valuenow={100}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="progress-bar progress-bar-striped"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
Alumnos sin SENCE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Warning striped example"
|
||||||
|
aria-valuenow={100}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="progress-bar progress-bar-striped bg-warning text-dark"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
Alumnos con SENCE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12 text-center mt-3">
|
||||||
|
<h5>
|
||||||
|
<strong>Moneda</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Segment one"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="mone"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "50%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="moneSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "50%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Providencia</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="prov"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "60%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="provSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "40%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>La Florida</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="flor"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "70%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="florSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "30%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Online</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="onli"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "80%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="onliSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "20%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<h5>
|
||||||
|
<strong>Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="progress-stacked">
|
||||||
|
<div
|
||||||
|
className="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Info example"
|
||||||
|
aria-valuenow={50}
|
||||||
|
aria-valuemin={0}
|
||||||
|
aria-valuemax={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="corp"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||||
|
style={{ width: "40%" }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
id="corpSNC"
|
||||||
|
className="progress-bar progress-bar-striped progress-bar-animated bg-warning text-dark"
|
||||||
|
style={{ width: "60%" }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Canvas de Gráfico Tipos de Ventas */}
|
||||||
|
<div className="col-md-5 align-middle mt-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12" id="TipoDeVentas">
|
||||||
|
<div
|
||||||
|
className="alert alert-light text-dark offcanvas-lg offcanvas-sm container-md container-sm"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<b>
|
||||||
|
<u>Tipos de ventas</u>
|
||||||
|
</b>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<canvas id="ventaPie" className="w-100 h-100"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL ALERTA / ERRORES */}
|
||||||
|
{showAlertModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>Módulo Académico - Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-3">
|
||||||
|
<h5>
|
||||||
|
<strong>{mensajeAlerta}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
>
|
||||||
|
Cerrar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL CARGANDO */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="modal-title">
|
||||||
|
<strong>SAM - Académico Empresas</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-4">
|
||||||
|
<h5>
|
||||||
|
<strong>Procesando, espere un momento...</strong>
|
||||||
|
</h5>
|
||||||
|
<div className="mt-3">
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -15,25 +15,25 @@ export default function Page() {
|
|||||||
icon: <File className="bx-sm bx-border" />,
|
icon: <File className="bx-sm bx-border" />,
|
||||||
color: "text-warning",
|
color: "text-warning",
|
||||||
label: "Informe cursos iniciados por fecha",
|
label: "Informe cursos iniciados por fecha",
|
||||||
href: "/Informes/Index?boton=periodo",
|
href: "/Informes/CursosInicio",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <File className="bx-sm bx-border" />,
|
icon: <File className="bx-sm bx-border" />,
|
||||||
color: "text-warning",
|
color: "text-warning",
|
||||||
label: "Informe cursos activos por mes",
|
label: "Informe cursos activos por mes",
|
||||||
href: "/Informes/Index?boton=activos",
|
href: "/Informes/CursosActivos",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <File className="bx-sm bx-border" />,
|
icon: <File className="bx-sm bx-border" />,
|
||||||
color: "text-info",
|
color: "text-info",
|
||||||
label: "Cursos por iniciar",
|
label: "Cursos por iniciar",
|
||||||
href: "/Informes/CursosInicios?search=CURSOSINICIAN",
|
href: "/Informes/CursosIniTer",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <File className="bx-sm bx-border" />,
|
icon: <File className="bx-sm bx-border" />,
|
||||||
color: "text-info",
|
color: "text-info",
|
||||||
label: "Cursos por finalizar",
|
label: "Cursos por finalizar",
|
||||||
href: "/Informes/CursosInicios?search=CURSOSFINALIZAN",
|
href: "/Informes/CursosIniTer",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,386 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
// TransferAlt,
|
||||||
|
Check,
|
||||||
|
X,
|
||||||
|
// Error as ErrorIcon,
|
||||||
|
// ErrorCircle,
|
||||||
|
CheckCircle,
|
||||||
|
} from "@boxicons/react";
|
||||||
|
|
||||||
|
// Interfaz para los datos del reemplazo
|
||||||
|
interface ReemplazoItem {
|
||||||
|
idCursoAbierto: string;
|
||||||
|
Curso: string;
|
||||||
|
FechaAsistencia: string;
|
||||||
|
HoraInicio: string;
|
||||||
|
HoraSalida: string;
|
||||||
|
rutProfesor: string;
|
||||||
|
Profesor: string;
|
||||||
|
Estado: string;
|
||||||
|
idAsistenciaProfesor: string;
|
||||||
|
Email?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interfaz para la configuración de la confirmación
|
||||||
|
interface ModalConfirmacionState {
|
||||||
|
show: boolean;
|
||||||
|
accion: "autorizar" | "rechazar" | null;
|
||||||
|
item: ReemplazoItem | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ReemplazosPendientesPage() {
|
||||||
|
// Estado con datos de ejemplo
|
||||||
|
const [reemplazos, setReemplazos] = useState<ReemplazoItem[]>([
|
||||||
|
{
|
||||||
|
idCursoAbierto: "CUR-101",
|
||||||
|
Curso: "Inglés Básico A1",
|
||||||
|
FechaAsistencia: "15-02-2026",
|
||||||
|
HoraInicio: "09:00",
|
||||||
|
HoraSalida: "10:30",
|
||||||
|
rutProfesor: "12.345.678-9",
|
||||||
|
Profesor: "Juan Pérez",
|
||||||
|
Estado: "Pendiente",
|
||||||
|
idAsistenciaProfesor: "SES-001",
|
||||||
|
Email: "jperez@correo.cl",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
idCursoAbierto: "CUR-102",
|
||||||
|
Curso: "Inglés Intermedio B2",
|
||||||
|
FechaAsistencia: "16-02-2026",
|
||||||
|
HoraInicio: "11:00",
|
||||||
|
HoraSalida: "12:30",
|
||||||
|
rutProfesor: "15.987.654-3",
|
||||||
|
Profesor: "María González",
|
||||||
|
Estado: "Pendiente",
|
||||||
|
idAsistenciaProfesor: "SES-002",
|
||||||
|
Email: "mgonzalez@correo.cl",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Estados para diálogos y procesamientos
|
||||||
|
const [modalConfirm, setModalConfirm] = useState<ModalConfirmacionState>({
|
||||||
|
show: false,
|
||||||
|
accion: null,
|
||||||
|
item: null,
|
||||||
|
});
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [modalRespuesta, setModalRespuesta] = useState<{
|
||||||
|
show: boolean;
|
||||||
|
errorMsg: string;
|
||||||
|
okMsg: string;
|
||||||
|
}>({ show: false, errorMsg: "", okMsg: "" });
|
||||||
|
|
||||||
|
// Abrir modal customizado de confirmación
|
||||||
|
const abrirConfirmacion = (item: ReemplazoItem, accion: "autorizar" | "rechazar") => {
|
||||||
|
setModalConfirm({
|
||||||
|
show: true,
|
||||||
|
accion,
|
||||||
|
item,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Procesar la autorización / rechazo
|
||||||
|
const handleConfirmar = () => {
|
||||||
|
if (!modalConfirm.item || !modalConfirm.accion) return;
|
||||||
|
|
||||||
|
const { idAsistenciaProfesor } = modalConfirm.item;
|
||||||
|
const accion = modalConfirm.accion;
|
||||||
|
|
||||||
|
// Cerrar modal de confirmación y mostrar loader
|
||||||
|
setModalConfirm({ show: false, accion: null, item: null });
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsLoading(false);
|
||||||
|
// Eliminar el ítem procesado de la lista
|
||||||
|
setReemplazos((prev) => prev.filter((r) => r.idAsistenciaProfesor !== idAsistenciaProfesor));
|
||||||
|
setModalRespuesta({
|
||||||
|
show: true,
|
||||||
|
errorMsg: "",
|
||||||
|
okMsg: `El reemplazo se ha ${
|
||||||
|
accion === "autorizar" ? "autorizado" : "rechazado"
|
||||||
|
} correctamente.`,
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="row">
|
||||||
|
{/* ENCABEZADO */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-1 text-center">
|
||||||
|
{/* <TransferAlt className="text-warning fs-3 border rounded p-1" /> */}
|
||||||
|
</div>
|
||||||
|
<div className="col-md-9">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Autorización</strong>
|
||||||
|
</span>
|
||||||
|
<h5 className="mb-0">
|
||||||
|
<strong>Reemplazos Pendientes</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* TABLA O ALERTA */}
|
||||||
|
{reemplazos.length > 0 ? (
|
||||||
|
<div className="col-md-12" id="divTablaReemplazos">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: "14px" }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "18%" }}>Curso</th>
|
||||||
|
<th className="text-center" style={{ width: "10%" }}>Sesión</th>
|
||||||
|
<th className="text-center" style={{ width: "8%" }}>Inicio</th>
|
||||||
|
<th className="text-center" style={{ width: "8%" }}>Salida</th>
|
||||||
|
<th className="text-center" style={{ width: "14%" }}>Run</th>
|
||||||
|
<th className="text-center" style={{ width: "14%" }}>Reemplazante</th>
|
||||||
|
<th className="text-center" style={{ width: "10%" }}>Estado Sesion</th>
|
||||||
|
<th className="text-center" style={{ width: "18%" }}>Acción</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{reemplazos.map((item) => (
|
||||||
|
<tr key={item.idAsistenciaProfesor}>
|
||||||
|
<td className="text-start" style={{ width: "18%" }}>
|
||||||
|
<strong>{item.Curso}</strong>
|
||||||
|
<span className="badge bg-secondary ms-1">
|
||||||
|
{item.idCursoAbierto}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "10%" }}>
|
||||||
|
{item.FechaAsistencia}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "8%" }}>
|
||||||
|
{item.HoraInicio}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "8%" }}>
|
||||||
|
{item.HoraSalida}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "14%" }}>
|
||||||
|
{item.rutProfesor}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "14%" }}>
|
||||||
|
{item.Profesor}
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "10%" }}>
|
||||||
|
<span className="badge bg-warning text-dark">
|
||||||
|
{item.Estado}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-center" style={{ width: "18%" }}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-success btn-sm me-1"
|
||||||
|
onClick={() => abrirConfirmacion(item, "autorizar")}
|
||||||
|
>
|
||||||
|
<Check className="me-1" /> Autorizar
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-danger btn-sm"
|
||||||
|
onClick={() => abrirConfirmacion(item, "rechazar")}
|
||||||
|
>
|
||||||
|
<X className="me-1" /> Rechazar
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="col-md-12" id="divSinReemplazos">
|
||||||
|
<div className="alert alert-light text-dark shadow text-center py-4" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3"></div>
|
||||||
|
<div className="col-md-6 text-center">
|
||||||
|
<div className="alert alert-light text-dark mt-5" role="alert">
|
||||||
|
<strong>
|
||||||
|
{/* <ErrorIcon className="text-primary" style={{ fontSize: "90px" }} /> */}
|
||||||
|
</strong>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<h5>
|
||||||
|
<strong>No hay reemplazos pendientes de autorización</strong>
|
||||||
|
</h5>
|
||||||
|
<hr />
|
||||||
|
<strong className="text-muted">
|
||||||
|
Si cree que esto es un error, contáctenos.{" "}
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
href="https://norteamericano.freshdesk.com/support/tickets/new"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Generar Ticket
|
||||||
|
</a>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* MODAL PERSONALIZADO DE CONFIRMACIÓN (REEMPLAZO DE SWEETALERT2) */}
|
||||||
|
{modalConfirm.show && modalConfirm.item && (
|
||||||
|
<div className="modal fade show d-block bg-dark bg-opacity-50" tabIndex={-1} role="dialog">
|
||||||
|
<div className="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div className="modal-content rounded-4 p-3">
|
||||||
|
<div className="modal-body text-center">
|
||||||
|
{modalConfirm.accion === "autorizar" ? (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#198754" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
|
||||||
|
<polyline points="22 4 12 14.01 9 11.01" />
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#dc3545" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<circle cx="12" cy="12" r="10" />
|
||||||
|
<line x1="15" y1="9" x2="9" y2="15" />
|
||||||
|
<line x1="9" y1="9" x2="15" y2="15" />
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<h4 className="mt-2 mb-1 fw-bold" style={{ color: "#1f2937" }}>
|
||||||
|
{modalConfirm.accion === "autorizar" ? "Autorizar Reemplazo" : "Rechazar Reemplazo"}
|
||||||
|
</h4>
|
||||||
|
<p className="text-muted mb-3" style={{ fontSize: "14px" }}>
|
||||||
|
{modalConfirm.accion === "autorizar"
|
||||||
|
? "Se asignará al profesor reemplazante"
|
||||||
|
: "Se rechazará al profesor reemplazante"}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="p-3 text-start rounded-3"
|
||||||
|
style={{
|
||||||
|
backgroundColor: modalConfirm.accion === "autorizar" ? "#f0fdf4" : "#fef2f2",
|
||||||
|
border: `1px solid ${modalConfirm.accion === "autorizar" ? "#a3cfbb" : "#f1aeb5"}`,
|
||||||
|
fontSize: "13px",
|
||||||
|
color: "#374151",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="d-flex justify-content-between mb-2">
|
||||||
|
<span className="fw-bold">Curso</span>
|
||||||
|
<span>
|
||||||
|
{modalConfirm.item.Curso}{" "}
|
||||||
|
<span className="badge bg-secondary ms-1">
|
||||||
|
{modalConfirm.item.idCursoAbierto}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between mb-2">
|
||||||
|
<span className="fw-bold">Sesión</span>
|
||||||
|
<span>
|
||||||
|
{modalConfirm.item.FechaAsistencia} | {modalConfirm.item.HoraInicio} - {modalConfirm.item.HoraSalida}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between mb-2">
|
||||||
|
<span className="fw-bold">Profesor</span>
|
||||||
|
<span>{modalConfirm.item.rutProfesor}</span>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex justify-content-between">
|
||||||
|
<span className="fw-bold">Reemplazante</span>
|
||||||
|
<span
|
||||||
|
className="fw-bold"
|
||||||
|
style={{
|
||||||
|
color: modalConfirm.accion === "autorizar" ? "#198754" : "#dc3545",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{modalConfirm.item.Profesor}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex justify-content-end gap-2 mt-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-secondary"
|
||||||
|
onClick={() => setModalConfirm({ show: false, accion: null, item: null })}
|
||||||
|
>
|
||||||
|
Cancelar
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`btn ${modalConfirm.accion === "autorizar" ? "btn-success" : "btn-danger"}`}
|
||||||
|
onClick={handleConfirmar}
|
||||||
|
>
|
||||||
|
{modalConfirm.accion === "autorizar" ? "Sí, autorizar" : "Sí, rechazar"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL RESPUESTA */}
|
||||||
|
{modalRespuesta.show && (
|
||||||
|
<div className="modal fade show d-block bg-dark bg-opacity-50" tabIndex={-1} role="dialog">
|
||||||
|
<div className="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header text-white text-center" style={{ backgroundColor: "#373193" }}>
|
||||||
|
<h5 className="modal-title">Reemplazos</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
{modalRespuesta.errorMsg && (
|
||||||
|
<div>
|
||||||
|
<strong style={{ color: "#e22523" }}>
|
||||||
|
{/* <ErrorCircle className="me-1" /> */}
|
||||||
|
<span>{modalRespuesta.errorMsg}</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{modalRespuesta.okMsg && (
|
||||||
|
<div>
|
||||||
|
<strong style={{ color: "#00285d" }}>
|
||||||
|
<CheckCircle className="me-1" />
|
||||||
|
<span>{modalRespuesta.okMsg}</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-secondary"
|
||||||
|
onClick={() => setModalRespuesta({ show: false, errorMsg: "", okMsg: "" })}
|
||||||
|
>
|
||||||
|
Cerrar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL CARGANDO */}
|
||||||
|
{isLoading && (
|
||||||
|
<div className="modal fade show d-block bg-dark bg-opacity-50" tabIndex={-1} role="dialog">
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="col-md-12 text-center py-3">
|
||||||
|
<div className="spinner-border text-info" role="status">
|
||||||
|
<span className="visually-hidden">Procesando...</span>
|
||||||
|
</div>
|
||||||
|
<p className="mt-2 mb-0">Procesando la información...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,533 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { User, Save, Receipt } from "@boxicons/react";
|
||||||
|
|
||||||
|
export default function EvaluacionAlumnosPage() {
|
||||||
|
// Estados para visibilidad de secciones (equivalente a Visible="false")
|
||||||
|
const [showCreateAlm, setShowCreateAlm] = useState(false);
|
||||||
|
const [showUpdatePlacement, setShowUpdatePlacement] = useState(false);
|
||||||
|
|
||||||
|
// Estados para modales
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showAlertModal, setShowAlertModal] = useState(false);
|
||||||
|
const [mensajeAlerta, setMensajeAlerta] = useState("Mensaje de prueba");
|
||||||
|
|
||||||
|
// Estados para botones con estado de carga
|
||||||
|
const [isSearching, setIsSearching] = useState(false);
|
||||||
|
const [isSavingAlumno, setIsSavingAlumno] = useState(false);
|
||||||
|
const [isSavingEvaluacion, setIsSavingEvaluacion] = useState(false);
|
||||||
|
|
||||||
|
// Handlers para simular acciones
|
||||||
|
const handleBuscar = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsSearching(true);
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsSearching(false);
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
// Muestra la sección deseada al terminar la búsqueda
|
||||||
|
setShowUpdatePlacement(true);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGuardarAlumno = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsSavingAlumno(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsSavingAlumno(false);
|
||||||
|
setMensajeAlerta("Alumno guardado correctamente.");
|
||||||
|
setShowAlertModal(true);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGuardarEvaluacion = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsSavingEvaluacion(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsSavingEvaluacion(false);
|
||||||
|
setMensajeAlerta("Evaluación guardada correctamente.");
|
||||||
|
setShowAlertModal(true);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
<div className="row">
|
||||||
|
{/* Búsqueda del alumno */}
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-5">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">
|
||||||
|
<strong>
|
||||||
|
<User style={{ fontSize: "24px" }} />
|
||||||
|
</strong>
|
||||||
|
<strong>
|
||||||
|
<span className="ms-2">Evaluación alumnos</span>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div className="col text-end">
|
||||||
|
<Link
|
||||||
|
href="/Academico/Index"
|
||||||
|
className="btn btn-warning text-dark btn-sm"
|
||||||
|
>
|
||||||
|
<strong>Volver</strong>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-7">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<form onSubmit={handleBuscar} className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<span className="fw-bold">RUN del alumno</span>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="TextBoxIDRun"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn btn-primary btn-sm d-grid w-100"
|
||||||
|
disabled={isSearching}
|
||||||
|
>
|
||||||
|
<div className="contenedor-boton">
|
||||||
|
{isSearching ? (
|
||||||
|
<div className="col-12 text-center py-1">
|
||||||
|
<span
|
||||||
|
className="spinner-border spinner-border-sm me-2"
|
||||||
|
role="status"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
|
<strong>Buscando alumno...</strong>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
"Buscar"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Carta de ingreso alumno nuevo */}
|
||||||
|
{showCreateAlm && (
|
||||||
|
<div className="col-md-6 mx-auto" id="create_alm">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<table className="table w-100">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
R.U.N.
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<input type="text" id="TextBoxId" className="form-control" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
Nombre
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<input type="text" id="TextBoxName" className="form-control" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
Apellido Paterno
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="TextBoxApPaterno"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
Apellido Materno
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="TextBoxApMaterno"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
Dirección
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="TextBoxDirAlm"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
Región
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<select id="ListRegion" className="form-select">
|
||||||
|
<option value="0">Seleccionar</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
Comuna
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "15%" }}>
|
||||||
|
<select id="ListComuna" className="form-select">
|
||||||
|
<option value="0">Seleccionar</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}>
|
||||||
|
Telefono
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "35%" }}>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
id="TextBoxFono"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}>
|
||||||
|
Email
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "35%" }}>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="TextBoxEmail"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}>
|
||||||
|
Fecha de nacimiento
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "35%" }}>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
id="TextBoxNacimiento"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}>
|
||||||
|
Profesion
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "35%" }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="TextBoxProfesion"
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "20%" }}></td>
|
||||||
|
<td className="text-start" style={{ width: "35%" }}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleGuardarAlumno}
|
||||||
|
className="btn p-0 border-0 text-start w-100"
|
||||||
|
disabled={isSavingAlumno}
|
||||||
|
>
|
||||||
|
<div className="alert alert-success shadow mb-0" role="alert">
|
||||||
|
<div className="row contenedor-boton">
|
||||||
|
{isSavingAlumno ? (
|
||||||
|
<div className="col-12 text-center py-2">
|
||||||
|
<span
|
||||||
|
className="spinner-border spinner-border-sm me-2"
|
||||||
|
role="status"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
|
<strong>Guardando alumno...</strong>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="col text-end">
|
||||||
|
<h2>
|
||||||
|
<Save />
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="col text-start">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Guardar</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>Evaluacion</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Carta del alumno y selección de nivel */}
|
||||||
|
{showUpdatePlacement && (
|
||||||
|
<div className="col-md-12" id="update_placement">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-4 text-end">
|
||||||
|
<table className="table table-sm table-borderless shadow mb-0 text-center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<User
|
||||||
|
className="text-primary bx-border mb-2 bx-burst-hover"
|
||||||
|
style={{ fontSize: "50px" }}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<span className="fs-5">Juan Pérez</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<strong>
|
||||||
|
<span className="fs-5">12.345.678-9</span>
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<strong>
|
||||||
|
<span className="fs-5">Nivel Inicial</span>
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<h3>Evaluacion</h3>
|
||||||
|
<div className="form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
className="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id="CheckBox1"
|
||||||
|
/>
|
||||||
|
<label className="form-check-label" htmlFor="CheckBox1">
|
||||||
|
Presencial/Online
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
className="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id="CheckBox2"
|
||||||
|
/>
|
||||||
|
<label className="form-check-label" htmlFor="CheckBox2">
|
||||||
|
Placement Test
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<span>Nivel</span>
|
||||||
|
<select id="listNiveles" className="form-select">
|
||||||
|
<option value="0">Seleccionar Nivel</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4 text-start">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleGuardarEvaluacion}
|
||||||
|
className="btn p-0 border-0 text-decoration-none w-100"
|
||||||
|
disabled={isSavingEvaluacion}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="alert alert-success shadow mb-0"
|
||||||
|
role="alert"
|
||||||
|
id="ContenedorBoton"
|
||||||
|
>
|
||||||
|
<div className="row contenedor-boton align-items-center">
|
||||||
|
{isSavingEvaluacion ? (
|
||||||
|
<div className="col-12 text-center py-2">
|
||||||
|
<span
|
||||||
|
className="spinner-border spinner-border-sm me-2"
|
||||||
|
role="status"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
|
<strong>Guardando evaluación...</strong>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<h2>
|
||||||
|
<Receipt />
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="col text-center">
|
||||||
|
<span className="text-muted">
|
||||||
|
<strong>Guardar</strong>
|
||||||
|
</span>
|
||||||
|
<h5>
|
||||||
|
<strong>Evaluacion</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* POPUPS Y MODALES */}
|
||||||
|
|
||||||
|
{/* Modal Alerta */}
|
||||||
|
{showAlertModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="float-start mt-2">
|
||||||
|
<strong>Módulo Academico - Empresa</strong>
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close float-end"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert text-justify">
|
||||||
|
<div className="row">
|
||||||
|
<div className="row mb-2">
|
||||||
|
<div className="col-md-12 text-center">
|
||||||
|
<h5>
|
||||||
|
<strong>{mensajeAlerta}</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={() => setShowAlertModal(false)}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Modal Cargando */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div
|
||||||
|
className="modal fade show d-block"
|
||||||
|
style={{ backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||||
|
tabIndex={-1}
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="float-start mt-2">
|
||||||
|
<strong>SAM - Académico Empresas </strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert text-justify">
|
||||||
|
<div className="row">
|
||||||
|
<div className="row mb-2">
|
||||||
|
<div className="col-md-12 text-center"></div>
|
||||||
|
<div className="col-md-12 text-center">
|
||||||
|
<h5>
|
||||||
|
<strong>Procesando, espere un momento</strong>
|
||||||
|
</h5>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-primary me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="spinner-grow spinner-grow-sm text-danger me-1"
|
||||||
|
role="status"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,846 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import {
|
||||||
|
//Transfer,
|
||||||
|
User,
|
||||||
|
// PhoneCall,
|
||||||
|
// MailSend,
|
||||||
|
Envelope,
|
||||||
|
// CurrentLocation,
|
||||||
|
// Cake,
|
||||||
|
Edit,
|
||||||
|
Pencil,
|
||||||
|
File,
|
||||||
|
UserPlus,
|
||||||
|
Certification,
|
||||||
|
// Comment,
|
||||||
|
// Error as ErrorIcon,
|
||||||
|
RefreshCwDot,
|
||||||
|
// Download,
|
||||||
|
// FilePdf,
|
||||||
|
Save
|
||||||
|
} from '@boxicons/react';
|
||||||
|
|
||||||
|
export default function FichaAlumnoPage() {
|
||||||
|
// --- ESTADOS DE PESTAÑAS ---
|
||||||
|
const [activeTab, setActiveTab] = useState<'cursos' | 'contratos' | 'apoderados' | 'certificados' | 'comentarios'>('cursos');
|
||||||
|
|
||||||
|
// --- ESTADOS DE VISTAS INTERNAS ---
|
||||||
|
const [subViewCursos, setSubViewCursos] = useState<'reporte' | 'error' | 'detalle' | 'confirma_cambio'>('reporte');
|
||||||
|
const [hasCursosError, setHasCursosError] = useState(false);
|
||||||
|
|
||||||
|
// --- ESTADOS DE MODALS ---
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showErrorModal, setShowErrorModal] = useState(false);
|
||||||
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
|
||||||
|
const [showModalNotas, setShowModalNotas] = useState(false);
|
||||||
|
const [showModalAsistencia, setShowModalAsistencia] = useState(false);
|
||||||
|
const [showModalCursosDisp, setShowModalCursosDisp] = useState(false);
|
||||||
|
const [showModalEditarAlumno, setShowModalEditarAlumno] = useState(false);
|
||||||
|
|
||||||
|
// --- ESTADOS DE FORMULARIOS ---
|
||||||
|
const [comentarioInput, setComentarioInput] = useState('');
|
||||||
|
const [confirmCambioCheck, setConfirmCambioCheck] = useState(false);
|
||||||
|
|
||||||
|
const [editForm, setEditForm] = useState({
|
||||||
|
nombre: '',
|
||||||
|
paterno: '',
|
||||||
|
materno: '',
|
||||||
|
nacimiento: '',
|
||||||
|
fono: '',
|
||||||
|
mail: '',
|
||||||
|
direccion: '',
|
||||||
|
region: '',
|
||||||
|
comuna: '',
|
||||||
|
ocupacion: '',
|
||||||
|
profesion: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- DISPARADORES DE EJEMPLO PARA ACCIONES Y CARGAS ---
|
||||||
|
const handleSimulateLoading = (action: () => void) => {
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
action();
|
||||||
|
}, 1200);
|
||||||
|
};
|
||||||
|
|
||||||
|
const triggerError = (msg: string) => {
|
||||||
|
setErrorMessage(msg);
|
||||||
|
setShowErrorModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
{/* BARRA SUPERIOR */}
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<h5 className="mb-0">
|
||||||
|
<strong className="text-muted">Ficha</strong> <strong>Alumno</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 text-end">
|
||||||
|
<Link href="/index" className="btn btn-primary btn-sm">
|
||||||
|
{/* <Transfer className="me-2" /> */}
|
||||||
|
Cambiar Alumno
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* PANEL IZQUIERDO: INFORMACIÓN DE CONTACTO */}
|
||||||
|
<div className="col-md-3">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<table className="table table-sm table-borderless mb-0 text-center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<User className="text-primary mb-2" style={{ fontSize: '50px' }} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<span className="fs-5 fw-bold">Juan Pérez González</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<strong>12.345.678-9</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm"
|
||||||
|
// onClick={() => handleTokyPopup('+56912345678')}
|
||||||
|
>
|
||||||
|
{/* <PhoneCall className="me-1" /> */}
|
||||||
|
Llamar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-light btn-sm border"
|
||||||
|
// onClick={() => handleGmailPopup('alumno@email.com')}
|
||||||
|
>
|
||||||
|
{/* <MailSend className="me-1" /> */}
|
||||||
|
Mensaje
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table className="table table-sm table-borderless mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<span className="text-dark" style={{ fontSize: '18px' }}>Contacto</span>
|
||||||
|
<hr className="my-2" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style={{ width: '25px' }}>
|
||||||
|
{/* <PhoneCall /> */}
|
||||||
|
</td>
|
||||||
|
<td>+56 9 1234 5678</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><Envelope /></td>
|
||||||
|
<td>alumno@email.com</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <CurrentLocation /> */}
|
||||||
|
</td>
|
||||||
|
<td>Av. Providencia 1234</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <CurrentLocation /> */}
|
||||||
|
</td>
|
||||||
|
<td>Providencia, Región Metropolitana</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <Cake /> */}
|
||||||
|
</td>
|
||||||
|
<td>15/08/1995</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<button
|
||||||
|
className="btn btn-warning btn-sm"
|
||||||
|
onClick={() => setShowModalEditarAlumno(true)}
|
||||||
|
>
|
||||||
|
<strong><Edit className="me-1" /> Editar</strong>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* PANEL DERECHO: PESTAÑAS Y CONTENIDOS */}
|
||||||
|
<div className="col-md-9">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
{/* NAVEGACIÓN TAB */}
|
||||||
|
<div className="d-grid gap-2 mb-3">
|
||||||
|
<div className="btn-group" role="group">
|
||||||
|
<button
|
||||||
|
className={`btn btn-light border-top-0 border-end-0 border-start-0 border-3 ${activeTab === 'cursos' ? 'border-primary active' : ''}`}
|
||||||
|
onClick={() => setActiveTab('cursos')}
|
||||||
|
>
|
||||||
|
<Pencil className="me-2" style={{ fontSize: '18px' }} /> Cursos
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`btn btn-light border-top-0 border-end-0 border-start-0 border-3 ${activeTab === 'contratos' ? 'border-primary active' : ''}`}
|
||||||
|
onClick={() => setActiveTab('contratos')}
|
||||||
|
>
|
||||||
|
<File className="me-2" style={{ fontSize: '18px' }} /> Contratos
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`btn btn-light border-top-0 border-end-0 border-start-0 border-3 ${activeTab === 'apoderados' ? 'border-primary active' : ''}`}
|
||||||
|
onClick={() => setActiveTab('apoderados')}
|
||||||
|
>
|
||||||
|
<UserPlus className="me-2" style={{ fontSize: '18px' }} /> Apoderado
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`btn btn-light border-top-0 border-end-0 border-start-0 border-3 ${activeTab === 'certificados' ? 'border-primary active' : ''}`}
|
||||||
|
onClick={() => setActiveTab('certificados')}
|
||||||
|
>
|
||||||
|
<Certification className="me-2" style={{ fontSize: '18px' }} /> Certificados
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`btn btn-light border-top-0 border-end-0 border-start-0 border-3 ${activeTab === 'comentarios' ? 'border-primary active' : ''}`}
|
||||||
|
onClick={() => setActiveTab('comentarios')}
|
||||||
|
>
|
||||||
|
{/* <Comment className="me-2" style={{ fontSize: '18px' }} /> */}
|
||||||
|
Comentarios
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* --- PESTAÑA: CURSOS --- */}
|
||||||
|
{activeTab === 'cursos' && (
|
||||||
|
<div>
|
||||||
|
{subViewCursos === 'reporte' && !hasCursosError && (
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="table-responsive mt-3">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" style={{ width: '10%' }}></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '5%' }}><strong>Year</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '6%' }}><strong>ID</strong></th>
|
||||||
|
<th scope="col" className="text-start" style={{ width: '32%' }}><strong>Curso</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '20%' }}><strong>Contrato</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '17%' }}><strong>Fecha</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '10%' }}><strong>Estado</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start">
|
||||||
|
<button
|
||||||
|
className="btn btn-link p-0 text-decoration-none"
|
||||||
|
onClick={() => setSubViewCursos('detalle')}
|
||||||
|
>
|
||||||
|
<h6><span className="badge bg-secondary style-normal">Ingresar</span></h6>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td className="text-center">2026</td>
|
||||||
|
<td className="text-center">1024</td>
|
||||||
|
<td className="text-start">2026-1 - Inglés Avanzado C1</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<strong className="text-primary">PARTICULAR</strong>
|
||||||
|
</td>
|
||||||
|
<td className="text-center">01/03/2026 | 30/06/2026</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<span className="badge bg-primary style-normal" style={{ fontSize: '12px' }}>
|
||||||
|
<span className="me-2 ms-2">Cursando</span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{hasCursosError && (
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3"></div>
|
||||||
|
<div className="col-md-6 text-center">
|
||||||
|
<div className="alert alert-light text-dark mt-5" role="alert">
|
||||||
|
{/* <ErrorIcon className="text-primary" style={{ fontSize: '90px' }} /> */}
|
||||||
|
<br /><br />
|
||||||
|
<h5><strong>El alumno no tiene Cursos disponibles</strong></h5>
|
||||||
|
<hr />
|
||||||
|
<strong className="text-muted">
|
||||||
|
Si cree que esto es un error, contáctenos.{' '}
|
||||||
|
<a target="_blank" rel="noreferrer" href="https://norteamericano.freshdesk.com/support/tickets/new">Generar Ticket</a>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{subViewCursos === 'detalle' && (
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row mt-4">
|
||||||
|
<div className="col-md-7">
|
||||||
|
<table className="table table-sm mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Curso</td>
|
||||||
|
<td style={{ fontSize: '16px' }}><strong>Inglés Avanzado C1</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Código</td>
|
||||||
|
<td><strong>1024</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Estado</td>
|
||||||
|
<td><strong>Cursando</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sede</td>
|
||||||
|
<td><strong>Providencia</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Profesor</td>
|
||||||
|
<td><strong>John Doe</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sala</td>
|
||||||
|
<td><strong>Lab 402</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Horario</td>
|
||||||
|
<td><strong>Lu-Mi-Vi 19:00 - 21:00</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Inicio</td>
|
||||||
|
<td><strong>01/03/2026</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Término</td>
|
||||||
|
<td><strong>30/06/2026</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-5">
|
||||||
|
<table className="table table-sm mb-4">
|
||||||
|
<tbody>
|
||||||
|
<tr className="table-secondary text-dark">
|
||||||
|
<td colSpan={3}><strong>Opciones</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={3}>
|
||||||
|
<button
|
||||||
|
className="btn btn-link p-0 fw-bold text-decoration-none"
|
||||||
|
onClick={() => setSubViewCursos('confirma_cambio')}
|
||||||
|
>
|
||||||
|
Cambiar de Curso
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<table className="table table-sm mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr className="table-secondary text-dark">
|
||||||
|
<td colSpan={3}><strong>RollBook</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Nota</td>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<button
|
||||||
|
className="btn btn-link p-0 fw-bold text-decoration-none"
|
||||||
|
onClick={() => setShowModalNotas(true)}
|
||||||
|
>
|
||||||
|
Ver
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Asistencia</td>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<button
|
||||||
|
className="btn btn-link p-0 fw-bold text-decoration-none"
|
||||||
|
onClick={() => setShowModalAsistencia(true)}
|
||||||
|
>
|
||||||
|
Ver
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Estado</td>
|
||||||
|
<td colSpan={2}><strong>En proceso</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Certificado</td>
|
||||||
|
<td>
|
||||||
|
<button className="btn btn-link p-0 text-decoration-none">
|
||||||
|
<RefreshCwDot /> Refrescar certificado
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td><strong>---</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{subViewCursos === 'confirma_cambio' && (
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-5">
|
||||||
|
<table className="table table-sm mb-0 caption-top">
|
||||||
|
<caption><strong><u>Actual Curso</u></strong></caption>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Curso</td>
|
||||||
|
<td style={{ fontSize: '16px' }}><strong>Inglés Avanzado C1</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Código</td>
|
||||||
|
<td><strong>1024</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sede</td>
|
||||||
|
<td><strong>Providencia</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 style-center-vh">
|
||||||
|
<h2 className="text-center">
|
||||||
|
{/* <Transfer /> */}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-5">
|
||||||
|
<table className="table table-sm mb-0 caption-top">
|
||||||
|
<caption><strong><u>Nuevo Curso</u></strong></caption>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Curso</td>
|
||||||
|
<td style={{ fontSize: '16px' }}><strong>Inglés Intensivo C1</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Código</td>
|
||||||
|
<td><strong>2048</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sede</td>
|
||||||
|
<td><strong>Santiago Centro</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-center mb-0 mt-3">
|
||||||
|
<div className="form-check d-inline-block">
|
||||||
|
<input
|
||||||
|
className="form-check-input me-2"
|
||||||
|
type="checkbox"
|
||||||
|
id="chkConfirm"
|
||||||
|
checked={confirmCambioCheck}
|
||||||
|
onChange={(e) => setConfirmCambioCheck(e.target.checked)}
|
||||||
|
/>
|
||||||
|
<label className="form-check-label" htmlFor="chkConfirm">
|
||||||
|
Confirmo y autorizo el cambio de curso con la información mostrada en pantalla.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 text-center mt-2">
|
||||||
|
<button
|
||||||
|
className="btn btn-success"
|
||||||
|
onClick={() => handleSimulateLoading(() => setSubViewCursos('detalle'))}
|
||||||
|
disabled={!confirmCambioCheck}
|
||||||
|
>
|
||||||
|
Actualizar Curso
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- PESTAÑA: CONTRATOS --- */}
|
||||||
|
{activeTab === 'contratos' && (
|
||||||
|
<div>
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="table-responsive mt-3">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '11px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" style={{ width: '10%' }}></th>
|
||||||
|
<th scope="col" style={{ width: '7%' }}><strong>Fecha</strong></th>
|
||||||
|
<th scope="col" style={{ width: '7%' }}><strong>Contrato</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '8%' }}><strong>Tipo</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '12%' }}><strong>RUT Empresa</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '25%' }}><strong>Empresa</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '15%' }}><strong>Curso</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '10%' }}><strong>Registro</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<button className="btn btn-secondary btn-sm p-0 px-2" style={{ fontSize: '10px' }}>
|
||||||
|
Ver
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td>01/01/2026</td>
|
||||||
|
<td><strong>CNT-991</strong></td>
|
||||||
|
<td className="text-center">Empresa</td>
|
||||||
|
<td className="text-center">76.123.456-7</td>
|
||||||
|
<td className="text-center"><strong>Corporación X</strong></td>
|
||||||
|
<td className="text-center">Inglés C1</td>
|
||||||
|
<td className="text-center">SENCE</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- PESTAÑA: APODERADOS --- */}
|
||||||
|
{activeTab === 'apoderados' && (
|
||||||
|
<div>
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="table-responsive mt-3">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" style={{ width: '10%' }}></th>
|
||||||
|
<th scope="col" style={{ width: '12%' }}><strong>Fecha</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '12%' }}><strong>RUT Empresa</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '30%' }}><strong>Empresa</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>10/02/2026</td>
|
||||||
|
<td className="text-center"><strong>76.123.456-7</strong></td>
|
||||||
|
<td className="text-center"><strong>Corporación X</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- PESTAÑA: CERTIFICADOS --- */}
|
||||||
|
{activeTab === 'certificados' && (
|
||||||
|
<div>
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="table-responsive mt-3">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" style={{ width: '10%' }}></th>
|
||||||
|
<th scope="col" style={{ width: '20%' }}><strong>Cursos</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '10%' }}><strong>Estado</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '15%' }}><strong>Fecha</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '10%' }}><strong>Nota</strong></th>
|
||||||
|
<th scope="col" className="text-center" style={{ width: '10%' }}><strong>Asistencia</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="#" target="_blank" rel="noreferrer" className="text-decoration-none">
|
||||||
|
{/* <FilePdf className="me-1" style={{ fontSize: '12px' }} /> */}
|
||||||
|
Ver Certificado
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>Inglés B2 Finalizado</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<span className="badge bg-success" style={{ fontWeight: 100, fontSize: '12px' }}>Aprobado</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-center"><strong>20/12/2025</strong></td>
|
||||||
|
<td className="text-center"><strong>6.5</strong></td>
|
||||||
|
<td className="text-center"><strong>95%</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- PESTAÑA: COMENTARIOS --- */}
|
||||||
|
{activeTab === 'comentarios' && (
|
||||||
|
<div>
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12 mt-3">
|
||||||
|
<div className="table-responsive mt-3">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" style={{ width: '10%' }}><strong>Fecha</strong></th>
|
||||||
|
<th scope="col" style={{ width: '10%' }}><strong>Hora</strong></th>
|
||||||
|
<th scope="col" style={{ width: '60%' }}><strong>Comentario</strong></th>
|
||||||
|
<th scope="col" style={{ width: '20%' }}><strong>Usuario</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>14/09/2026</td>
|
||||||
|
<td>10:30</td>
|
||||||
|
<td>Alumno solicita cambio de horario.</td>
|
||||||
|
<td>Admin_User</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-12 mt-5">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-1"></div>
|
||||||
|
<div className="col-md-9">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Escribe un comentario"
|
||||||
|
className="form-control"
|
||||||
|
value={comentarioInput}
|
||||||
|
onChange={(e) => setComentarioInput(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<button
|
||||||
|
className="btn btn-primary btn-sm w-100"
|
||||||
|
onClick={() => handleSimulateLoading(() => setComentarioInput(''))}
|
||||||
|
>
|
||||||
|
Agregar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* --- MODAL NOTAS --- */}
|
||||||
|
{showModalNotas && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-lg modal-dialog-scrollable">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title">Notas</h5>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setShowModalNotas(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-center" style={{ width: '20%' }}><strong>Fecha</strong></th>
|
||||||
|
<th className="text-center" style={{ width: '60%' }}><strong>Test</strong></th>
|
||||||
|
<th className="text-center" style={{ width: '20%' }}><strong>Grade</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: '20%' }}><strong>05/04/2026</strong></td>
|
||||||
|
<td className="text-start" style={{ width: '60%' }}><strong>Midterm Exam</strong></td>
|
||||||
|
<td className="text-center" style={{ width: '20%' }}><strong>92%</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-secondary" onClick={() => setShowModalNotas(false)}>Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- MODAL ASISTENCIA --- */}
|
||||||
|
{showModalAsistencia && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-lg modal-dialog-scrollable">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title">Asistencia</h5>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setShowModalAsistencia(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '18px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-center" style={{ width: '50%' }}><strong>Fecha</strong></th>
|
||||||
|
<th className="text-center" style={{ width: '50%' }}><strong>Marcaciones</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-center"><strong>01/03/2026</strong></td>
|
||||||
|
<td className="text-center"><strong className="text-success">Present</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-secondary" onClick={() => setShowModalAsistencia(false)}>Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- MODAL EDITAR ALUMNO --- */}
|
||||||
|
{showModalEditarAlumno && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title">Editar Alumno</h5>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setShowModalEditarAlumno(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<table className="table table-sm">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Nombre</strong></td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
value={editForm.nombre}
|
||||||
|
onChange={(e) => setEditForm({ ...editForm, nombre: e.target.value })}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Paterno</strong></td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
value={editForm.paterno}
|
||||||
|
onChange={(e) => setEditForm({ ...editForm, paterno: e.target.value })}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
className="btn btn-warning text-dark"
|
||||||
|
onClick={() => handleSimulateLoading(() => setShowModalEditarAlumno(false))}
|
||||||
|
>
|
||||||
|
<strong><Save className="me-2" /> Guardar</strong>
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-secondary" onClick={() => setShowModalEditarAlumno(false)}>Cancelar</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- MODAL CARGANDO (LOADING) --- */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary mb-0">
|
||||||
|
<h5 className="mt-2"><strong>SAM - Empresas</strong></h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert text-center" style={{ textAlign: 'justify' }}>
|
||||||
|
<div className="row mb-2">
|
||||||
|
<div className="col-md-12 text-center">
|
||||||
|
<h5 className="mb-3"><strong>Procesando, espere un momento</strong></h5>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-primary mx-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-danger mx-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-primary mx-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-danger mx-1" role="status"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* --- MODAL ERROR / ALERTA --- */}
|
||||||
|
{showErrorModal && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary mb-0">
|
||||||
|
<h5 className="float-start mt-2"><strong>Módulo Academico - Empresa</strong></h5>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setShowErrorModal(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert" style={{ textAlign: 'justify' }}>
|
||||||
|
<div className="row mb-2">
|
||||||
|
<div className="col-md-12 text-center">
|
||||||
|
<h5><strong>{errorMessage || 'Ocurrió un error en la operación.'}</strong></h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-primary" onClick={() => setShowErrorModal(false)}>Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,703 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
// UserDetail,
|
||||||
|
Plus,
|
||||||
|
Save,
|
||||||
|
User,
|
||||||
|
// MailSend,
|
||||||
|
// PhoneCall,
|
||||||
|
Envelope,
|
||||||
|
// CurrentLocation,
|
||||||
|
// Cake,
|
||||||
|
Flag,
|
||||||
|
Edit,
|
||||||
|
UserCheck,
|
||||||
|
Pencil,
|
||||||
|
File,
|
||||||
|
Book,
|
||||||
|
// Error as ErrorIcon,
|
||||||
|
CheckCircle,
|
||||||
|
XCircle,
|
||||||
|
} from "@boxicons/react";
|
||||||
|
|
||||||
|
export default function ProfesorPage() {
|
||||||
|
// Estados para controlar vistas del flujo ASP.NET
|
||||||
|
const [vistas, setVistas] = useState({
|
||||||
|
divBuscar: true,
|
||||||
|
divBuscarResultado: false,
|
||||||
|
agregarProfe: false,
|
||||||
|
fichaProfe: false,
|
||||||
|
profeCursosActivos: true,
|
||||||
|
profeCursosActivosOk: false,
|
||||||
|
profeCursosActivosError: false,
|
||||||
|
profeCursosFinalizados: false,
|
||||||
|
profeCursosFinalizadosOk: false,
|
||||||
|
profeCursosFinalizadosError: false,
|
||||||
|
profePerfil: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Estados para Modales
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showAlertModal, setShowAlertModal] = useState(false);
|
||||||
|
const [showEditModal, setShowEditModal] = useState(false);
|
||||||
|
const [mensajeAlerta, setMensajeAlerta] = useState("Mensaje de prueba");
|
||||||
|
|
||||||
|
// Función equivalente a GmailPopup
|
||||||
|
const handleGmailPopup = (mail: string, name: string) => {
|
||||||
|
const title = "Contacto";
|
||||||
|
const w = 800;
|
||||||
|
const h = 600;
|
||||||
|
const options = "scrollbars=no,resizable=no";
|
||||||
|
const url = `https://mail.google.com/mail/u/0/?view=cm&fs=1&to=${mail.toLowerCase()}&su=Contacto%20Ichn`;
|
||||||
|
|
||||||
|
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
|
||||||
|
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;
|
||||||
|
const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
|
||||||
|
const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
|
||||||
|
|
||||||
|
const left = width / 2 - w / 2 + dualScreenLeft;
|
||||||
|
const top = height / 2 - h / 2 + dualScreenTop;
|
||||||
|
|
||||||
|
window.open(url, title, `${options}, width=${w}, height=${h}, top=${top}, left=${left}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Solo números para teléfono
|
||||||
|
const handleOnlyNumbers = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (!/[0-9]/.test(e.key) && e.key !== "Backspace" && e.key !== "Tab") {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-3">
|
||||||
|
{/* SECCIÓN DE BÚSQUEDA */}
|
||||||
|
{vistas.divBuscar && (
|
||||||
|
<div className="row" id="div_buscar">
|
||||||
|
<div className="col-md-1"></div>
|
||||||
|
<div className="col-md-10">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-1 mt-2 text-end">
|
||||||
|
<div className="mt-2">
|
||||||
|
<strong>Profesor</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3 mt-2">
|
||||||
|
<select className="form-select" id="ListaTipoBusqueda">
|
||||||
|
<option value="">Seleccione filtro...</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 mt-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
id="TextBoxProfe"
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-1 mt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-sm btn-primary"
|
||||||
|
onClick={() => setVistas({ ...vistas, divBuscarResultado: true })}
|
||||||
|
>
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3 text-end mt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-success text-dark"
|
||||||
|
>
|
||||||
|
{/* <UserDetail className="me-1" /> */}
|
||||||
|
<strong>Listado Profesores</strong>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2 text-end mt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-warning text-dark me-4"
|
||||||
|
onClick={() => setVistas({ ...vistas, agregarProfe: true })}
|
||||||
|
>
|
||||||
|
<Plus className="me-1" /> <strong>Agregar</strong>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RESULTADOS BÚSQUEDA */}
|
||||||
|
{vistas.divBuscarResultado && (
|
||||||
|
<div className="row" id="div_buscar_resultado">
|
||||||
|
<div className="col-md-12 mt-4">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: "14px" }}>
|
||||||
|
<thead className="alert-secondary text-dark">
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "10%" }}></th>
|
||||||
|
<th className="text-start" style={{ width: "10%" }}><strong>Run</strong></th>
|
||||||
|
<th className="text-start" style={{ width: "28%" }}><strong>Nombre</strong></th>
|
||||||
|
<th className="text-center" style={{ width: "10%" }}><strong>Estado</strong></th>
|
||||||
|
<th className="text-start" style={{ width: "10%" }}><strong>Fono</strong></th>
|
||||||
|
<th className="text-start" style={{ width: "29%" }}><strong>Mail</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-link p-0 text-decoration-none"
|
||||||
|
onClick={() => setVistas({ ...vistas, fichaProfe: true })}
|
||||||
|
>
|
||||||
|
<span className="badge bg-primary" style={{ fontWeight: "normal" }}>
|
||||||
|
Seleccionar
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}><strong>12345678-9</strong></td>
|
||||||
|
<td className="text-start" style={{ width: "14%" }}><strong>Pérez</strong></td>
|
||||||
|
<td className="text-start" style={{ width: "14%" }}><strong>Juan</strong></td>
|
||||||
|
<td className="text-center" style={{ width: "10%" }}>
|
||||||
|
<span className="badge rounded-pill bg-success">Activo</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: "10%" }}><strong>912345678</strong></td>
|
||||||
|
<td className="text-start" style={{ width: "29%" }}><strong>juan.perez@example.com</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<nav aria-label="...">
|
||||||
|
<ul className="pagination justify-content-center">
|
||||||
|
<li className="page-item"><button className="page-link">First</button></li>
|
||||||
|
<li className="page-item"><button className="page-link">Previous</button></li>
|
||||||
|
<li className="page-item"><button className="page-link">Next</button></li>
|
||||||
|
<li className="page-item"><button className="page-link">Last</button></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* SECCIÓN AGREGAR PROFESOR */}
|
||||||
|
{vistas.agregarProfe && (
|
||||||
|
<div className="row" id="agregar_profe">
|
||||||
|
<div className="col-md-1"></div>
|
||||||
|
<div className="col-md-10">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<table className="table table-sm mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" colSpan={4}>
|
||||||
|
<h5><strong>Información Personal</strong></h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style={{ width: "20%" }}><strong className="text-muted">Run</strong></td>
|
||||||
|
<td><input type="text" className="form-control" autoComplete="off" /></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong className="text-muted">Nombre</strong></td>
|
||||||
|
<td><input type="text" className="form-control" autoComplete="off" /></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong className="text-muted">Paterno</strong></td>
|
||||||
|
<td><input type="text" className="form-control" autoComplete="off" /></td>
|
||||||
|
<td><strong className="text-muted">Materno</strong></td>
|
||||||
|
<td><input type="text" className="form-control" autoComplete="off" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong className="text-muted">Nacimiento</strong></td>
|
||||||
|
<td><input type="date" className="form-control datepicker" autoComplete="off" /></td>
|
||||||
|
<td><strong className="text-muted">Nacionalidad</strong></td>
|
||||||
|
<td><select className="form-select"><option value="">Seleccione...</option></select></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<table className="table table-sm mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start" colSpan={2}>
|
||||||
|
<h5><strong>Información de contacto</strong></h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong className="text-muted">Fono (+56)</strong></td>
|
||||||
|
<td colSpan={3}>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
maxLength={9}
|
||||||
|
onKeyDown={handleOnlyNumbers}
|
||||||
|
className="form-control"
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="needs-validation">
|
||||||
|
<td><strong className="text-muted">Mail</strong></td>
|
||||||
|
<td colSpan={3}>
|
||||||
|
<input type="email" className="form-control" placeholder="name@example.com" autoComplete="off" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong className="text-muted">Dirección</strong></td>
|
||||||
|
<td colSpan={3}><input type="text" className="form-control" autoComplete="off" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong className="text-muted">Región</strong></td>
|
||||||
|
<td style={{ width: "35%" }}><select className="form-select"><option value="">Seleccione...</option></select></td>
|
||||||
|
<td style={{ width: "10%" }}><strong className="text-muted">Comuna</strong></td>
|
||||||
|
<td style={{ width: "35%" }}><select className="form-select"><option value="">Seleccione...</option></select></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table className="table table-sm mb-0 mt-3">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style={{ width: "70%" }}></td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button type="button" className="btn btn-primary">
|
||||||
|
<Save className="me-2" /> Guardar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-secondary"
|
||||||
|
onClick={() => setVistas({ ...vistas, agregarProfe: false })}
|
||||||
|
>
|
||||||
|
Cancelar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* SECCIÓN FICHA PROFESOR */}
|
||||||
|
{vistas.fichaProfe && (
|
||||||
|
<div className="row" id="ficha_profe">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<h5>
|
||||||
|
<strong className="text-muted">Ficha</strong> <strong>Profesor</strong>
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 text-end">
|
||||||
|
<button type="button" className="btn btn-primary btn-sm">
|
||||||
|
<i className="bx bx-transfer me-2"></i> Cambiar Profesor
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-3">
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<table className="table table-sm table-borderless mb-0 text-center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<User className="text-primary mb-2" style={{ fontSize: "50px" }} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<span className="fs-5">Juan Pérez</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<strong><span className="fs-5">12.345.678-9</span></strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-light btn-sm border"
|
||||||
|
onClick={() => handleGmailPopup("juan@example.com", "Juan")}
|
||||||
|
>
|
||||||
|
{/* <MailSend className="me-1" /> */}
|
||||||
|
Mensaje
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="alert alert-light text-dark shadow" role="alert">
|
||||||
|
<table className="table table-sm table-borderless mb-0" style={{ fontSize: "14px" }}>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<span className="text-dark" style={{ fontSize: "18px" }}>Contacto</span>
|
||||||
|
<hr />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <PhoneCall /> */}
|
||||||
|
</td>
|
||||||
|
<td>+56 9 1234 5678</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Envelope />
|
||||||
|
</td>
|
||||||
|
<td>juan.perez@example.com</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <CurrentLocation /> */}
|
||||||
|
</td>
|
||||||
|
<td>Av. Siempre Viva 123</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <CurrentLocation /> */}
|
||||||
|
</td>
|
||||||
|
<td>Santiago</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <Cake /> */}
|
||||||
|
</td>
|
||||||
|
<td>01/01/1990</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><Flag /></td>
|
||||||
|
<td>Chilena</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-warning btn-sm"
|
||||||
|
onClick={() => setShowEditModal(true)}
|
||||||
|
>
|
||||||
|
<strong><Edit className="me-1" /> Editar</strong>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-9">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark mb-0" role="alert">
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<div className="btn-group" role="group">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-light border-top-0 border-end-0 border-start-0 border border-primary border-3"
|
||||||
|
onClick={() => setVistas({ ...vistas, profePerfil: true, profeCursosActivos: false, profeCursosFinalizados: false })}
|
||||||
|
>
|
||||||
|
<UserCheck className="me-2" style={{ fontSize: "18px" }} />Perfil
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-light border-top-0 border-end-0 border-start-0 border border-3"
|
||||||
|
onClick={() => setVistas({ ...vistas, profePerfil: false, profeCursosActivos: true, profeCursosFinalizados: false })}
|
||||||
|
>
|
||||||
|
<Pencil className="me-2" style={{ fontSize: "18px" }} />Cursos Activos
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-light border-top-0 border-end-0 border-start-0 border border-3"
|
||||||
|
onClick={() => setVistas({ ...vistas, profePerfil: false, profeCursosActivos: false, profeCursosFinalizados: true })}
|
||||||
|
>
|
||||||
|
<File className="me-2" style={{ fontSize: "18px" }} />Cursos Finalizados
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-light border-top-0 border-end-0 border-start-0 border border-3 disabled"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* CURSOS ACTIVOS */}
|
||||||
|
{vistas.profeCursosActivos && (
|
||||||
|
<div id="profe_cursos_activos">
|
||||||
|
{vistas.profeCursosActivosOk ? (
|
||||||
|
<div className="row mt-3">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="row text-center">
|
||||||
|
<div className="col-md-3"></div>
|
||||||
|
<div className="col-md-1">
|
||||||
|
<Book className="text-primary mt-2" style={{ fontSize: "50px" }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<span className="text-muted"><strong>Cursos</strong></span>
|
||||||
|
<h3><strong>2</strong></h3>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-1">
|
||||||
|
<User className="text-success mt-2" style={{ fontSize: "50px" }} />
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<span className="text-muted"><strong>Alumnos</strong></span>
|
||||||
|
<h3><strong>25</strong></h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-12">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<div className="table-responsive">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: "14px" }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" style={{ width: "5%" }}></th>
|
||||||
|
<th className="text-start" style={{ width: "5%" }}>ID</th>
|
||||||
|
<th className="text-start" style={{ width: "10%" }}>Curso</th>
|
||||||
|
<th className="text-start" style={{ width: "27%" }}>Curso</th>
|
||||||
|
<th className="text-center" style={{ width: "7%" }}>Participantes</th>
|
||||||
|
<th className="text-center" style={{ width: "10%" }}>Dias</th>
|
||||||
|
<th className="text-center" style={{ width: "18%" }}>Horas</th>
|
||||||
|
<th className="text-center" style={{ width: "20%" }}>Fechas</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start">
|
||||||
|
<a href="#"><span className="badge bg-primary" style={{ fontWeight: "normal" }}>Ver</span></a>
|
||||||
|
</td>
|
||||||
|
<td className="text-start">101</td>
|
||||||
|
<td className="text-start">Inglés</td>
|
||||||
|
<td className="text-start">Inglés Básico</td>
|
||||||
|
<td className="text-center">12</td>
|
||||||
|
<td className="text-center">Lu-Mi</td>
|
||||||
|
<td className="text-center">19:00 - 21:00</td>
|
||||||
|
<td className="text-center">01/03 / 30/04</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="alert alert-light text-dark mt-3" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3"></div>
|
||||||
|
<div className="col-md-6 text-center">
|
||||||
|
<div className="alert alert-light text-dark" role="alert">
|
||||||
|
<strong>
|
||||||
|
{/* <ErrorIcon className="text-primary" style={{ fontSize: "90px" }} /> */}
|
||||||
|
</strong>
|
||||||
|
<br /><br />
|
||||||
|
<h5><strong>El profesor no tiene Cursos Activos</strong></h5>
|
||||||
|
<hr />
|
||||||
|
<strong className="text-muted">
|
||||||
|
Si cree que esto es un error, contáctenos.{" "}
|
||||||
|
<a target="_blank" rel="noreferrer" href="https://norteamericano.freshdesk.com/support/tickets/new">
|
||||||
|
Generar Ticket
|
||||||
|
</a>
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* CURSOS FINALIZADOS */}
|
||||||
|
{vistas.profeCursosFinalizados && (
|
||||||
|
<div id="profe_cursos_finalizados">
|
||||||
|
<div className="alert alert-light text-dark mt-3" role="alert">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-3"></div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<table className="table table-sm table-borderless mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><span className="text-muted"><strong>Año</strong></span></td>
|
||||||
|
<td><input type="text" className="form-control form-control-sm" /></td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button type="button" className="btn btn-primary btn-sm">Buscar</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* PERFIL */}
|
||||||
|
{vistas.profePerfil && (
|
||||||
|
<div id="profe_perfil" className="mt-3">
|
||||||
|
<div className="alert alert-light text-dark">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="progress text-start mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> DIURNO</strong></div>
|
||||||
|
</div>
|
||||||
|
<div className="progress text-center mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> VESPERTINO</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="progress mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> 0</strong></div>
|
||||||
|
</div>
|
||||||
|
<div className="progress mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> 0</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="progress text-start mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> PRESENCIAL</strong></div>
|
||||||
|
</div>
|
||||||
|
<div className="progress text-center mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> ONLINE</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-2">
|
||||||
|
<div className="progress mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> 0</strong></div>
|
||||||
|
</div>
|
||||||
|
<div className="progress mb-2" style={{ height: "61px" }}>
|
||||||
|
<div style={{ fontSize: "20px", marginTop: "17px" }}><strong> 0</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL CARGANDO */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div className="modal fade show d-block" style={{ backgroundColor: "rgba(0,0,0,0.5)" }} tabIndex={-1}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="float-start mt-2"><strong>SAM - Empresas</strong></h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert text-center">
|
||||||
|
<h5><strong>Procesando, espere un momento</strong></h5>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-primary me-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-danger me-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-primary me-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-danger me-1" role="status"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL ALERTA / MENSAJES */}
|
||||||
|
{showAlertModal && (
|
||||||
|
<div className="modal fade show d-block" style={{ backgroundColor: "rgba(0,0,0,0.5)" }} tabIndex={-1}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary">
|
||||||
|
<h5 className="float-start mt-2"><strong>Módulo Academico - Empresa</strong></h5>
|
||||||
|
<button type="button" className="btn-close float-end" onClick={() => setShowAlertModal(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body alert text-center">
|
||||||
|
<h5><strong>{mensajeAlerta}</strong></h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-primary" onClick={() => setShowAlertModal(false)}>Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL EDITAR PROFESOR */}
|
||||||
|
{showEditModal && (
|
||||||
|
<div className="modal fade show d-block" style={{ backgroundColor: "rgba(0,0,0,0.5)" }} tabIndex={-1}>
|
||||||
|
<div className="modal-dialog">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title">Editar Profe</h5>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setShowEditModal(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<table className="table table-sm">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Nombre</strong></td>
|
||||||
|
<td><input type="text" className="form-control" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Paterno</strong></td>
|
||||||
|
<td><input type="text" className="form-control" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Materno</strong></td>
|
||||||
|
<td><input type="text" className="form-control" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Fono (+56)</strong></td>
|
||||||
|
<td><input type="text" maxLength={9} className="form-control" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Mail</strong></td>
|
||||||
|
<td><input type="email" className="form-control" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2">
|
||||||
|
<button type="button" className="btn btn-warning text-dark">
|
||||||
|
<strong><Save className="me-2" /> Guardar</strong>
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-secondary" onClick={() => setShowEditModal(false)}>Cancelar</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+400
-1
@@ -1,3 +1,402 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import {
|
||||||
|
User,
|
||||||
|
//Graduation,
|
||||||
|
File,
|
||||||
|
//IdCard,
|
||||||
|
ContactBook,
|
||||||
|
Book,
|
||||||
|
AddressBook,
|
||||||
|
//ErrorAlt
|
||||||
|
} from '@boxicons/react';
|
||||||
|
|
||||||
|
interface Alumno {
|
||||||
|
idAlumno: string;
|
||||||
|
AP_Paterno: string;
|
||||||
|
AP_Materno: string;
|
||||||
|
Nombres: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <h1>Hello, Next.js!</h1>;
|
// --- ESTADOS DE VISTA ---
|
||||||
|
const [currentView, setCurrentView] = useState<'menu' | 'buscar'>('menu');
|
||||||
|
const [errorData, setErrorData] = useState(false);
|
||||||
|
|
||||||
|
// --- ESTADOS DE FORMULARIO DE BÚSQUEDA ---
|
||||||
|
const [tipoBusqueda, setTipoBusqueda] = useState('run');
|
||||||
|
const [textoBusqueda, setTextoBusqueda] = useState('');
|
||||||
|
|
||||||
|
// --- ESTADOS DE MODALES ---
|
||||||
|
const [showModalResultados, setShowModalResultados] = useState(false);
|
||||||
|
const [showLoadingModal, setShowLoadingModal] = useState(false);
|
||||||
|
const [showErrorModal, setShowErrorModal] = useState(false);
|
||||||
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
|
||||||
|
// --- DATOS DE EJEMPLO PARA RESULTADOS ---
|
||||||
|
const [alumnosEncontrados, setAlumnosEncontrados] = useState<Alumno[]>([]);
|
||||||
|
|
||||||
|
// --- MANEJADORES DE EVENTOS ---
|
||||||
|
const handleOpenBuscarAlumno = () => {
|
||||||
|
setCurrentView('buscar');
|
||||||
|
setErrorData(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBuscarAlumno = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!textoBusqueda.trim()) {
|
||||||
|
setErrorData(true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setErrorData(false);
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
// Simulación de búsqueda
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
const mockResultados: Alumno[] = [
|
||||||
|
{ idAlumno: '12.345.678-9', AP_Paterno: 'Pérez', AP_Materno: 'González', Nombres: 'Juan Carlos' },
|
||||||
|
{ idAlumno: '98.765.432-1', AP_Paterno: 'Pérez', AP_Materno: 'Muñoz', Nombres: 'María José' }
|
||||||
|
];
|
||||||
|
setAlumnosEncontrados(mockResultados);
|
||||||
|
setShowModalResultados(true);
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSeleccionarAlumno = (alumno: Alumno) => {
|
||||||
|
setShowModalResultados(false);
|
||||||
|
setShowLoadingModal(true);
|
||||||
|
|
||||||
|
// Redirección o acción con el alumno seleccionado
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLoadingModal(false);
|
||||||
|
alert(`Alumno seleccionado: ${alumno.Nombres} ${alumno.AP_Paterno}`);
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid py-4">
|
||||||
|
{/* VISTA: MENÚ PRINCIPAL */}
|
||||||
|
{currentView === 'menu' && (
|
||||||
|
<div id="menu">
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-2" />
|
||||||
|
|
||||||
|
{/* SECCIÓN SECRETARÍA */}
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm">
|
||||||
|
<h5><strong>Secretaria</strong></h5>
|
||||||
|
<hr />
|
||||||
|
<table className="table table-hover mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style={{ width: '5%' }}>
|
||||||
|
<User className="text-primary border rounded p-1" style={{ fontSize: '32px' }} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleOpenBuscarAlumno}
|
||||||
|
className="btn btn-link text-start p-0 text-decoration-none alert-link"
|
||||||
|
>
|
||||||
|
Ficha del Alumno
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{/* <Graduation className="text-primary border rounded p-1" style={{ fontSize: '32px' }} /> */}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<Link href="/secretaria/FichaProfesor" className="text-decoration-none alert-link">
|
||||||
|
Ficha del Profesor
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<File className="text-success border rounded p-1" style={{ fontSize: '32px' }} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<Link href="/secretaria/EvaluacionPO" className="text-decoration-none alert-link">
|
||||||
|
Ingreso de evaluación
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* SECCIÓN INFORMES */}
|
||||||
|
<div className="col-md-4">
|
||||||
|
<div className="alert alert-light text-dark shadow-sm">
|
||||||
|
<h5><strong>Informes</strong></h5>
|
||||||
|
<hr />
|
||||||
|
<table className="table table-hover mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style={{ width: '5%' }}>
|
||||||
|
{/* <IdCard className="text-danger border rounded p-1" style={{ fontSize: '32px' }} /> */}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<Link href="/Informes/SEAlumnos" className="text-decoration-none alert-link">
|
||||||
|
Informes de Alumnos
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<ContactBook className="text-warning border rounded p-1" style={{ fontSize: '32px' }} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<Link href="/Informes/SEAlumnosCursosCC" className="text-decoration-none alert-link">
|
||||||
|
Informes de Alumnos por cursos
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Book className="text-warning border rounded p-1" style={{ fontSize: '32px' }} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<Link href="/Informes/SEAlumnosCursosPC" className="text-decoration-none alert-link">
|
||||||
|
Informes de Alumnos por cursos (Plan central)
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<AddressBook className="text-danger-emphasis border rounded p-1" style={{ fontSize: '32px' }} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<Link href="/Informes/SEAlumnosEmpresas" className="text-decoration-none alert-link">
|
||||||
|
Informes de Alumnos por empresas
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* VISTA: BUSCAR ALUMNO */}
|
||||||
|
{currentView === 'buscar' && (
|
||||||
|
<div id="buscar_alumno">
|
||||||
|
<div className="row" style={{ marginTop: '5%' }}>
|
||||||
|
<div className="col-md-4" />
|
||||||
|
<div className="col-md-4 text-center">
|
||||||
|
<strong>
|
||||||
|
<User className="text-primary border rounded p-2 mb-2" style={{ fontSize: '60px' }} />
|
||||||
|
</strong>
|
||||||
|
|
||||||
|
<div className="alert alert-light text-dark shadow-sm" role="alert">
|
||||||
|
<form onSubmit={handleBuscarAlumno}>
|
||||||
|
<table className="table table-borderless mb-0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td className="text-start">
|
||||||
|
<h5><strong>Ficha del Alumno</strong></h5>
|
||||||
|
</td>
|
||||||
|
<td className="text-end">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-link p-0 text-decoration-none"
|
||||||
|
onClick={() => setCurrentView('menu')}
|
||||||
|
>
|
||||||
|
Volver
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<br />
|
||||||
|
<select
|
||||||
|
className="form-select"
|
||||||
|
value={tipoBusqueda}
|
||||||
|
onChange={(e) => setTipoBusqueda(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="run">Búsqueda por RUN</option>
|
||||||
|
<option value="nombre">Búsqueda por Nombre</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="Ingrese término de búsqueda..."
|
||||||
|
value={textoBusqueda}
|
||||||
|
onChange={(e) => setTextoBusqueda(e.target.value)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{errorData && (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<div className="alert alert-danger text-center mb-0 mt-2">
|
||||||
|
<h5 className="mb-0 d-flex align-items-center justify-center gap-2">
|
||||||
|
{/* <ErrorAlt /> */}
|
||||||
|
Error en el RUN seleccionado
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}>
|
||||||
|
<div className="d-grid gap-2 mt-2">
|
||||||
|
<button type="submit" className="btn btn-primary">
|
||||||
|
Buscar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-4" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL: RESULTADOS ALUMNOS */}
|
||||||
|
{showModalResultados && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
<h5 className="modal-title">Ficha Alumno</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={() => setShowModalResultados(false)}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center">
|
||||||
|
<table className="table table-sm mb-0" style={{ fontSize: '14px' }}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start" scope="col" style={{ width: '11%' }}></th>
|
||||||
|
<th className="text-start" scope="col" style={{ width: '12%' }}><strong>Run</strong></th>
|
||||||
|
<th className="text-start" scope="col" style={{ width: '25%' }}><strong>Paterno</strong></th>
|
||||||
|
<th className="text-start" scope="col" style={{ width: '25%' }}><strong>Materno</strong></th>
|
||||||
|
<th className="text-start" scope="col" style={{ width: '27%' }}><strong>Nombre</strong></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{alumnosEncontrados.map((alumno, index) => (
|
||||||
|
<tr key={index}>
|
||||||
|
<td className="text-start" style={{ width: '11%' }}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn p-0 border-0 background-transparent"
|
||||||
|
onClick={() => handleSeleccionarAlumno(alumno)}
|
||||||
|
>
|
||||||
|
<span className="badge bg-warning text-dark">Seleccionar</span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: '12%' }}>
|
||||||
|
<strong>{alumno.idAlumno}</strong>
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: '25%' }}>
|
||||||
|
<span>{alumno.AP_Paterno}</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: '25%' }}>
|
||||||
|
<span>{alumno.AP_Materno}</span>
|
||||||
|
</td>
|
||||||
|
<td className="text-start" style={{ width: '27%' }}>
|
||||||
|
<span>{alumno.Nombres}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-secondary"
|
||||||
|
onClick={() => setShowModalResultados(false)}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL: CARGANDO (LOADING) */}
|
||||||
|
{showLoadingModal && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-secondary mb-0">
|
||||||
|
<h5 className="mt-2 mb-0"><strong>Secretaría</strong></h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-4">
|
||||||
|
<h5 className="mb-3"><strong>Procesando, espere un momento</strong></h5>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-primary mx-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-danger mx-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-primary mx-1" role="status"></div>
|
||||||
|
<div className="spinner-grow spinner-grow-sm text-danger mx-1" role="status"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* MODAL: ERROR */}
|
||||||
|
{showErrorModal && (
|
||||||
|
<div className="modal fade show d-block" tabIndex={-1} style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
|
||||||
|
<div className="modal-dialog modal-dialog-centered">
|
||||||
|
<div className="modal-content text-dark">
|
||||||
|
<div className="modal-header alert alert-danger mb-0">
|
||||||
|
<h5 className="mt-2 mb-0"><strong>Error</strong></h5>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setShowErrorModal(false)}></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body text-center py-4">
|
||||||
|
<h5><strong>{errorMessage || 'Ocurrió un error en la operación.'}</strong></h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="button" className="btn btn-secondary" onClick={() => setShowErrorModal(false)}>
|
||||||
|
Cerrar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user