nuevas correciones
This commit is contained in:
@@ -1,9 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MieSystem.Models;
|
|
||||||
using MieSystem.Data.Interfaces;
|
using MieSystem.Data.Interfaces;
|
||||||
using AspNetCoreGeneratedDocument;
|
using MieSystem.Models;
|
||||||
using MieSystem.Models.ViewModels;
|
using MieSystem.Models.ViewModels;
|
||||||
|
|
||||||
namespace MieSystem.Controllers
|
namespace MieSystem.Controllers
|
||||||
@@ -20,24 +17,14 @@ namespace MieSystem.Controllers
|
|||||||
_hostingEnvironment = hostingEnvironment;
|
_hostingEnvironment = hostingEnvironment;
|
||||||
|
|
||||||
_expedienteRepository = expedienteRepository;
|
_expedienteRepository = expedienteRepository;
|
||||||
|
|
||||||
// Datos de prueba iniciales
|
|
||||||
/*if (_expedientes.Count == 0)
|
|
||||||
{
|
|
||||||
_ = InitializeTestData();
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InitializeTestData()
|
// GET: Expedientes
|
||||||
|
public async Task<IActionResult> Index()
|
||||||
{
|
{
|
||||||
var today = DateTime.Today;
|
var today = DateTime.Today;
|
||||||
var lst = await _expedienteRepository.GetAllAsync();
|
var lst = await _expedienteRepository.GetAllAsync();
|
||||||
_expedientes = [.. lst];
|
_expedientes = [.. lst];
|
||||||
}
|
|
||||||
|
|
||||||
// GET: Expedientes
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +32,6 @@ namespace MieSystem.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetDashboardStats()
|
public IActionResult GetDashboardStats()
|
||||||
{
|
{
|
||||||
_ = InitializeTestData();
|
|
||||||
var totalNinos = _expedientes.Count;
|
var totalNinos = _expedientes.Count;
|
||||||
var mesActual = DateTime.Now.Month;
|
var mesActual = DateTime.Now.Month;
|
||||||
|
|
||||||
@@ -78,9 +64,6 @@ namespace MieSystem.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetExpedientes(int page = 1, int pageSize = 10)
|
public IActionResult GetExpedientes(int page = 1, int pageSize = 10)
|
||||||
{
|
{
|
||||||
if (_expedientes.Count == 0)
|
|
||||||
_ = InitializeTestData();
|
|
||||||
|
|
||||||
var query = _expedientes
|
var query = _expedientes
|
||||||
.Where(e => e.Activo)
|
.Where(e => e.Activo)
|
||||||
.OrderBy(e => e.Apellidos)
|
.OrderBy(e => e.Apellidos)
|
||||||
@@ -122,7 +105,6 @@ namespace MieSystem.Controllers
|
|||||||
|
|
||||||
// POST: Expedientes/Create
|
// POST: Expedientes/Create
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
// [ValidateAntiForgeryToken]
|
|
||||||
public async Task<IActionResult> Create(ExpedienteViewModel model)
|
public async Task<IActionResult> Create(ExpedienteViewModel model)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header bg-primary text-white">
|
<div class="card-header text-white" style="background: linear-gradient(180deg, #2c3e50 0%, #1a2530 100%);">
|
||||||
<h5 class="mb-0"><i class="fas fa-filter"></i> Filtros</h5>
|
<h5 class="mb-0"><i class="fas fa-filter"></i> Filtros</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-2 d-flex align-items-end">
|
<div class="col-md-2 d-flex align-items-end">
|
||||||
<button type="submit" class="btn btn-primary w-100">
|
<button type="submit" class="btn w-100" style="background: linear-gradient(180deg, #2c3e50 0%, #1a2530 100%); color: white;">
|
||||||
<i class="fas fa-search"></i> Filtrar
|
<i class="fas fa-search text-white"></i> Filtrar
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -101,21 +101,29 @@
|
|||||||
|
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="table-responsive" style="max-height: 70vh; overflow-y: auto;">
|
<div class="table-responsive" style="max-height: 70vh; overflow-y: auto;">
|
||||||
<table class="table table-bordered table-striped mb-0" id="tablaAsistencia">
|
<table class="table table-bordered table-hover table-sm" id="tablaAsistencia">
|
||||||
<thead class="table-dark sticky-top" style="top: 0;">
|
<thead class="table-dark sticky-top">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="min-width: 200px; position: sticky; left: 0; background: #343a40; z-index: 10;">
|
<th class="sticky-left bg-dark text-white" style="min-width: 200px;">
|
||||||
Niño
|
<div>Nombre</div>
|
||||||
|
<div class="small">Edad</div>
|
||||||
</th>
|
</th>
|
||||||
|
@foreach (var dia in Model.DiasDelMes)
|
||||||
@foreach (var dia in diasAMostrar)
|
|
||||||
{
|
{
|
||||||
var esFinSemana = dia.DayOfWeek == DayOfWeek.Saturday || dia.DayOfWeek == DayOfWeek.Sunday;
|
var diaSemana = ((int)dia.DayOfWeek).ToString();
|
||||||
|
var isChecked = Model.DiasSemanaSeleccionados?.Contains(diaSemana) ?? true;
|
||||||
|
|
||||||
<th class="text-center @(esFinSemana ? "" : "")"
|
if (!string.IsNullOrEmpty(Model.DiasSemanaSeleccionados) && !isChecked)
|
||||||
style="min-width: 60px;">
|
{
|
||||||
<div class="small">@dia.ToString("ddd")</div>
|
continue;
|
||||||
<div class="fw-bold">@dia.Day</div>
|
}
|
||||||
|
|
||||||
|
var nombreDia = dia.ToString("ddd", new System.Globalization.CultureInfo("es-ES"));
|
||||||
|
var esFinDeSemana = dia.DayOfWeek == DayOfWeek.Saturday || dia.DayOfWeek == DayOfWeek.Sunday;
|
||||||
|
|
||||||
|
<th class="text-center @(esFinDeSemana ? "" : "")" style="min-width: 50px;">
|
||||||
|
<div>@dia.Day</div>
|
||||||
|
<div class="small">@nombreDia</div>
|
||||||
</th>
|
</th>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
@@ -123,23 +131,58 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var expediente in Model.Expedientes)
|
@foreach (var expediente in Model.Expedientes)
|
||||||
{
|
{
|
||||||
|
<!-- Calcular propiedades aquí mismo -->
|
||||||
|
|
||||||
|
var nombreCompleto = $"{expediente.Nombre} {expediente.Apellidos}".Trim();
|
||||||
|
var edad = 0;
|
||||||
|
if (expediente.FechaNacimiento != DateTime.MinValue)
|
||||||
|
{
|
||||||
|
var today = DateTime.Today;
|
||||||
|
edad = today.Year - expediente.FechaNacimiento.Year;
|
||||||
|
if (expediente.FechaNacimiento.Date > today.AddYears(-edad))
|
||||||
|
{
|
||||||
|
edad--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<tr data-expediente-id="@expediente.Id">
|
<tr data-expediente-id="@expediente.Id">
|
||||||
<td style="position: sticky; left: 0; background: white; z-index: 5;">
|
<td class="sticky-left bg-white" style="min-width: 200px;">
|
||||||
<div class="fw-bold">@expediente.NombreCompleto</div>
|
<div class="fw-bold">@nombreCompleto</div>
|
||||||
<div class="small text-muted">Edad: @expediente.Edad años</div>
|
<div class="small text-muted">Edad: @edad años</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
@foreach (var dia in diasAMostrar)
|
@foreach (var dia in Model.DiasDelMes)
|
||||||
{
|
{
|
||||||
|
var diaSemana = ((int)dia.DayOfWeek).ToString();
|
||||||
|
var isChecked = Model.DiasSemanaSeleccionados?.Contains(diaSemana) ?? true;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Model.DiasSemanaSeleccionados) && !isChecked)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var key = $"{expediente.Id}_{dia:yyyy-MM-dd}";
|
var key = $"{expediente.Id}_{dia:yyyy-MM-dd}";
|
||||||
var estadoActual = Model.Asistencias.ContainsKey(key)
|
var estadoActual = Model.Asistencias.ContainsKey(key)
|
||||||
? Model.Asistencias[key]
|
? Model.Asistencias[key]
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
<td class="text-center p-0 celda-asistencia"
|
// Determinar clase CSS según estado
|
||||||
|
var claseEstado = estadoActual switch
|
||||||
|
{
|
||||||
|
"P" => "celda-presente",
|
||||||
|
"T" => "celda-tarde",
|
||||||
|
"F" => "celda-falta",
|
||||||
|
_ => ""
|
||||||
|
};
|
||||||
|
|
||||||
|
var esFinDeSemana = dia.DayOfWeek == DayOfWeek.Saturday || dia.DayOfWeek == DayOfWeek.Sunday;
|
||||||
|
|
||||||
|
<td class="text-center p-0 celda-asistencia @claseEstado @(esFinDeSemana ? "bg-light" : "")"
|
||||||
data-expediente="@expediente.Id"
|
data-expediente="@expediente.Id"
|
||||||
data-fecha="@dia.ToString("yyyy-MM-dd")">
|
data-fecha="@dia.ToString("yyyy-MM-dd")"
|
||||||
<select class="form-select form-select-sm estado-select border-0 rounded-0 h-100 w-100"
|
style="min-width: 50px;">
|
||||||
|
|
||||||
|
<select class="form-select form-select-sm estado-select border-0 h-100 w-100"
|
||||||
data-initial="@estadoActual">
|
data-initial="@estadoActual">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
|
|
||||||
@@ -170,13 +213,13 @@
|
|||||||
<option value="F" class="bg-danger text-white">F</option>
|
<option value="F" class="bg-danger text-white">F</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -216,40 +259,77 @@
|
|||||||
|
|
||||||
@section Styles {
|
@section Styles {
|
||||||
<style>
|
<style>
|
||||||
|
/* Estilos generales de la tabla */
|
||||||
.table th, .table td {
|
.table th, .table td {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Colores para las celdas según estado */
|
||||||
|
.celda-presente {
|
||||||
|
background-color: #d1e7dd !important; /* Verde claro */
|
||||||
|
}
|
||||||
|
|
||||||
|
.celda-tarde {
|
||||||
|
background-color: #fff3cd !important; /* Amarillo claro */
|
||||||
|
}
|
||||||
|
|
||||||
|
.celda-falta {
|
||||||
|
background-color: #f8d7da !important; /* Rojo claro */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estilos para el select */
|
||||||
.estado-select {
|
.estado-select {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
|
border: 1px solid transparent !important;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.estado-select:hover {
|
/* Ocultar flecha del select */
|
||||||
transform: scale(1.05);
|
.estado-select::-ms-expand {
|
||||||
box-shadow: 0 0 5px rgba(0,0,0,0.2);
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.estado-select option[value="P"] {
|
.estado-select:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Colores para el select según estado */
|
||||||
|
.estado-select.bg-success {
|
||||||
background-color: #198754 !important;
|
background-color: #198754 !important;
|
||||||
color: white !important;
|
color: white !important;
|
||||||
|
border-color: #198754 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.estado-select option[value="T"] {
|
.estado-select.bg-warning {
|
||||||
background-color: #ffc107 !important;
|
background-color: #ffc107 !important;
|
||||||
color: black !important;
|
color: black !important;
|
||||||
|
border-color: #ffc107 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.estado-select.bg-danger {
|
||||||
|
background-color: #dc3545 !important;
|
||||||
|
color: white !important;
|
||||||
|
border-color: #dc3545 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select vacío */
|
||||||
|
.estado-select:not([value]):not([value=""]) {
|
||||||
|
background-color: white !important;
|
||||||
|
color: black !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.estado-select option[value="F"] {
|
/* Celdas cambiadas (no guardadas) */
|
||||||
background-color: #dc3545 !important;
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.celda-asistencia.changed {
|
.celda-asistencia.changed {
|
||||||
outline: 2px solid #0d6efd;
|
outline: 2px solid #0d6efd;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Posición fija para la primera columna */
|
||||||
.sticky-left {
|
.sticky-left {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -257,6 +337,7 @@
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Estilos para checkboxes de días */
|
||||||
.dias-semana-checkboxes {
|
.dias-semana-checkboxes {
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -264,19 +345,135 @@
|
|||||||
border: 1px solid #dee2e6;
|
border: 1px solid #dee2e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-lunes { background-color: #e3f2fd !important; }
|
/* Colores para días de semana en encabezados */
|
||||||
.bg-martes { background-color: #f3e5f5 !important; }
|
.bg-lunes {
|
||||||
.bg-miercoles { background-color: #e8f5e8 !important; }
|
background-color: #e3f2fd !important;
|
||||||
.bg-jueves { background-color: #fff3e0 !important; }
|
}
|
||||||
.bg-viernes { background-color: #fce4ec !important; }
|
|
||||||
.bg-sabado { background-color: #f1f8e9 !important; }
|
.bg-martes {
|
||||||
.bg-domingo { background-color: #fff8e1 !important; }
|
background-color: #f3e5f5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-miercoles {
|
||||||
|
background-color: #e8f5e8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-jueves {
|
||||||
|
background-color: #fff3e0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-viernes {
|
||||||
|
background-color: #fce4ec !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-sabado {
|
||||||
|
background-color: #f1f8e9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-domingo {
|
||||||
|
background-color: #fff8e1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estilos para encabezados fijos */
|
||||||
|
.table-dark.sticky-top {
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estilos para tarjetas de estadísticas */
|
||||||
|
.card .display-6 {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progress bars en estadísticas */
|
||||||
|
.progress {
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover effects para celdas */
|
||||||
|
.celda-asistencia:hover {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.celda-presente:hover {
|
||||||
|
background-color: #c3e6cb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.celda-tarde:hover {
|
||||||
|
background-color: #ffeaa7 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.celda-falta:hover {
|
||||||
|
background-color: #f5c6cb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive adjustments */
|
||||||
|
@@media (max-width: 768px) {
|
||||||
|
.table-responsive
|
||||||
|
|
||||||
|
{
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.estado-select {
|
||||||
|
padding: 0.25rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dias-semana-checkboxes .form-check-inline {
|
||||||
|
display: block;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animación suave para cambios de color */
|
||||||
|
.celda-asistencia, .estado-select {
|
||||||
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Estilos para fin de semana */
|
||||||
|
.bg-light {
|
||||||
|
background-color: #f8f9fa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leyenda de colores */
|
||||||
|
.leyenda .badge {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 0.4em 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cambia de 50px a 65px */
|
||||||
|
.celda-asistencia {
|
||||||
|
min-width: 65px !important; /* ← Cambiado de 50px */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table th.text-center {
|
||||||
|
min-width: 65px !important; /* ← Cambiado de 50px */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cambia de 200px a 240px */
|
||||||
|
.sticky-left {
|
||||||
|
min-width: 240px !important; /* ← Cambiado de 200px */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Aumenta el padding del select */
|
||||||
|
.estado-select {
|
||||||
|
padding: 10px 4px !important; /* ← Más padding */
|
||||||
|
font-size: 14px !important; /* ← Texto más grande */
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
// Actualizar estadísticas al cargar
|
||||||
|
cargarEstadisticas();
|
||||||
|
|
||||||
|
// Manejar checkboxes de días de semana
|
||||||
$('.dia-checkbox').change(function() {
|
$('.dia-checkbox').change(function() {
|
||||||
var diasSeleccionados = $('.dia-checkbox:checked').map(function() {
|
var diasSeleccionados = $('.dia-checkbox:checked').map(function() {
|
||||||
return $(this).val();
|
return $(this).val();
|
||||||
@@ -284,26 +481,34 @@
|
|||||||
$('#diasSemanaInput').val(diasSeleccionados);
|
$('#diasSemanaInput').val(diasSeleccionados);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.estado-select').change(function() {
|
// Inicializar colores al cargar
|
||||||
var initial = $(this).data('initial');
|
inicializarColores();
|
||||||
var current = $(this).val();
|
|
||||||
|
|
||||||
if (initial !== current) {
|
|
||||||
$(this).closest('.celda-asistencia').addClass('changed');
|
|
||||||
} else {
|
|
||||||
$(this).closest('.celda-asistencia').removeClass('changed');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Guardar asistencia individual y actualizar colores
|
||||||
$('.estado-select').change(function() {
|
$('.estado-select').change(function() {
|
||||||
|
var estado = $(this).val();
|
||||||
var celda = $(this).closest('.celda-asistencia');
|
var celda = $(this).closest('.celda-asistencia');
|
||||||
|
var initial = $(this).data('initial');
|
||||||
|
|
||||||
|
// Actualizar colores
|
||||||
|
aplicarColorSelect($(this), estado);
|
||||||
|
aplicarColorCelda(celda, estado);
|
||||||
|
|
||||||
|
// Marcar como cambiado si es diferente
|
||||||
|
if (initial !== estado) {
|
||||||
|
celda.addClass('changed');
|
||||||
|
} else {
|
||||||
|
celda.removeClass('changed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guardar automáticamente
|
||||||
var expedienteId = celda.data('expediente');
|
var expedienteId = celda.data('expediente');
|
||||||
var fecha = celda.data('fecha');
|
var fecha = celda.data('fecha');
|
||||||
var estado = $(this).val();
|
|
||||||
|
|
||||||
guardarAsistencia(expedienteId, fecha, estado, celda);
|
guardarAsistencia(expedienteId, fecha, estado, celda);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Guardar todas las asistencias cambiadas
|
||||||
$('#btnGuardarTodo').click(function() {
|
$('#btnGuardarTodo').click(function() {
|
||||||
var cambios = [];
|
var cambios = [];
|
||||||
var celdasCambiadas = $('.celda-asistencia.changed');
|
var celdasCambiadas = $('.celda-asistencia.changed');
|
||||||
@@ -333,6 +538,7 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Enviar cambios masivos
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '@Url.Action("GuardarAsistenciasMasivas", "Asistencia")',
|
url: '@Url.Action("GuardarAsistenciasMasivas", "Asistencia")',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
@@ -341,6 +547,7 @@
|
|||||||
success: function(response) {
|
success: function(response) {
|
||||||
$('#modalCarga').modal('hide');
|
$('#modalCarga').modal('hide');
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
|
// Quitar marca de cambiado y actualizar estado inicial
|
||||||
$('.celda-asistencia').removeClass('changed');
|
$('.celda-asistencia').removeClass('changed');
|
||||||
$('.estado-select').each(function() {
|
$('.estado-select').each(function() {
|
||||||
$(this).data('initial', $(this).val());
|
$(this).data('initial', $(this).val());
|
||||||
@@ -358,6 +565,7 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Exportar a Excel
|
||||||
$('#btnExportar').click(function() {
|
$('#btnExportar').click(function() {
|
||||||
var año = $('#selectAnio').val();
|
var año = $('#selectAnio').val();
|
||||||
var mes = $('#selectMes').val();
|
var mes = $('#selectMes').val();
|
||||||
@@ -371,13 +579,74 @@
|
|||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Cambiar mes/año con selects
|
||||||
$('#selectAnio, #selectMes').change(function() {
|
$('#selectAnio, #selectMes').change(function() {
|
||||||
$('#filtroForm').submit();
|
$('#filtroForm').submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Aplicar colores a días de semana
|
||||||
aplicarColoresDias();
|
aplicarColoresDias();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Función para aplicar color a una celda según el estado
|
||||||
|
function aplicarColorCelda(celda, estado) {
|
||||||
|
// Remover todas las clases de color
|
||||||
|
celda.removeClass('celda-presente celda-tarde celda-falta');
|
||||||
|
|
||||||
|
// Aplicar nueva clase según estado
|
||||||
|
switch(estado) {
|
||||||
|
case 'P':
|
||||||
|
celda.addClass('celda-presente');
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
celda.addClass('celda-tarde');
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
celda.addClass('celda-falta');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Vacío - no aplicar color
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para aplicar color al select según estado
|
||||||
|
function aplicarColorSelect(select, estado) {
|
||||||
|
// Remover todas las clases de color
|
||||||
|
select.removeClass('bg-success bg-warning bg-danger text-white');
|
||||||
|
|
||||||
|
// Aplicar nueva clase según estado
|
||||||
|
switch(estado) {
|
||||||
|
case 'P':
|
||||||
|
select.addClass('bg-success text-white');
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
select.addClass('bg-warning');
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
select.addClass('bg-danger text-white');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Vacío - color por defecto
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para inicializar colores al cargar la página
|
||||||
|
function inicializarColores() {
|
||||||
|
$('.estado-select').each(function() {
|
||||||
|
var estado = $(this).val();
|
||||||
|
var celda = $(this).closest('.celda-asistencia');
|
||||||
|
|
||||||
|
aplicarColorSelect($(this), estado);
|
||||||
|
aplicarColorCelda(celda, estado);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// FUNCIONES PARA GUARDAR ASISTENCIA
|
||||||
|
// ============================================
|
||||||
|
|
||||||
function guardarAsistencia(expedienteId, fecha, estado, celda) {
|
function guardarAsistencia(expedienteId, fecha, estado, celda) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '@Url.Action("GuardarAsistencia", "Asistencia")',
|
url: '@Url.Action("GuardarAsistencia", "Asistencia")',
|
||||||
@@ -391,86 +660,231 @@
|
|||||||
if (response.success) {
|
if (response.success) {
|
||||||
celda.removeClass('changed');
|
celda.removeClass('changed');
|
||||||
celda.find('.estado-select').data('initial', estado);
|
celda.find('.estado-select').data('initial', estado);
|
||||||
toastr.success('Guardado');
|
toastr.success('Guardado correctamente');
|
||||||
cargarEstadisticas();
|
cargarEstadisticas();
|
||||||
} else {
|
} else {
|
||||||
toastr.error(response.message);
|
toastr.error(response.message);
|
||||||
|
// Revertir color si hay error
|
||||||
|
var select = celda.find('.estado-select');
|
||||||
|
var initial = select.data('initial');
|
||||||
|
aplicarColorSelect(select, initial);
|
||||||
|
aplicarColorCelda(celda, initial);
|
||||||
|
select.val(initial);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
toastr.error('Error al guardar');
|
toastr.error('Error de conexión');
|
||||||
|
// Revertir color
|
||||||
|
var select = celda.find('.estado-select');
|
||||||
|
var initial = select.data('initial');
|
||||||
|
aplicarColorSelect(select, initial);
|
||||||
|
aplicarColorCelda(celda, initial);
|
||||||
|
select.val(initial);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// FUNCIONES PARA ESTADÍSTICAS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
function cargarEstadisticas() {
|
function cargarEstadisticas() {
|
||||||
var año = $('#selectAnio').val();
|
var año = $('#selectAnio').val();
|
||||||
var mes = $('#selectMes').val();
|
var mes = $('#selectMes').val();
|
||||||
|
|
||||||
|
// Mostrar indicador de carga
|
||||||
|
$('#estadisticasContainer').html(`
|
||||||
|
<div class="col-md-12 text-center">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Cargando...</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2">Cargando estadísticas...</p>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '@Url.Action("ObtenerEstadisticas", "Asistencia")',
|
url: '@Url.Action("ObtenerEstadisticas", "Asistencia")',
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
data: { año: año, mes: mes },
|
data: { año: año, mes: mes },
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
if (data.error) {
|
// Verificar si data es null o undefined
|
||||||
console.error(data.error);
|
if (!data) {
|
||||||
|
mostrarEstadisticasVacias();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var total = data.total || 0;
|
// Verificar si hay error
|
||||||
var presentes = data.presentes || 0;
|
if (data.error) {
|
||||||
var tardes = data.tardes || 0;
|
console.error('Error del servidor:', data.error);
|
||||||
var faltas = data.faltas || 0;
|
mostrarEstadisticasVacias('Error: ' + data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var porcentajePresentes = total > 0 ? ((presentes / total) * 100).toFixed(1) : 0;
|
// Extraer valores con manejo seguro
|
||||||
var porcentajeTardes = total > 0 ? ((tardes / total) * 100).toFixed(1) : 0;
|
var total = extraerNumero(data, 'total');
|
||||||
var porcentajeFaltas = total > 0 ? ((faltas / total) * 100).toFixed(1) : 0;
|
var presentes = extraerNumero(data, 'presentes');
|
||||||
|
var tardes = extraerNumero(data, 'tardes');
|
||||||
|
var faltas = extraerNumero(data, 'faltas');
|
||||||
|
|
||||||
|
// Verificar consistencia
|
||||||
|
var suma = presentes + tardes + faltas;
|
||||||
|
if (total > 0 && suma !== total) {
|
||||||
|
console.warn('Inconsistencia en datos: total=' + total + ', suma=' + suma);
|
||||||
|
total = suma;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calcular porcentajes
|
||||||
|
var porcentajePresentes = calcularPorcentaje(presentes, total);
|
||||||
|
var porcentajeTardes = calcularPorcentaje(tardes, total);
|
||||||
|
var porcentajeFaltas = calcularPorcentaje(faltas, total);
|
||||||
|
|
||||||
|
// Mostrar estadísticas
|
||||||
|
mostrarEstadisticasHTML(total, presentes, tardes, faltas,
|
||||||
|
porcentajePresentes, porcentajeTardes, porcentajeFaltas);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('Error AJAX:', status, error);
|
||||||
|
mostrarEstadisticasVacias('Error al cargar estadísticas');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función auxiliar para extraer números de forma segura
|
||||||
|
function extraerNumero(obj, propiedad) {
|
||||||
|
if (!obj || obj[propiedad] === null || obj[propiedad] === undefined) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var valor = obj[propiedad];
|
||||||
|
|
||||||
|
// Convertir a número si es string
|
||||||
|
if (typeof valor === 'string') {
|
||||||
|
valor = parseFloat(valor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar que sea un número válido
|
||||||
|
if (isNaN(valor) || !isFinite(valor)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redondear a entero si es decimal
|
||||||
|
return Math.round(valor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para calcular porcentajes
|
||||||
|
function calcularPorcentaje(parcial, total) {
|
||||||
|
if (!total || total <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var porcentaje = (parcial / total) * 100;
|
||||||
|
|
||||||
|
// Redondear a 1 decimal
|
||||||
|
return Math.round(porcentaje * 10) / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para mostrar estadísticas vacías o con error
|
||||||
|
function mostrarEstadisticasVacias(mensaje) {
|
||||||
|
var mensajeMostrar = mensaje || 'No hay datos de asistencia para este período';
|
||||||
|
|
||||||
|
$('#estadisticasContainer').html(`
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<i class="fas fa-exclamation-triangle"></i> ${mensajeMostrar}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para mostrar estadísticas en HTML
|
||||||
|
function mostrarEstadisticasHTML(total, presentes, tardes, faltas,
|
||||||
|
porcentajePresentes, porcentajeTardes, porcentajeFaltas) {
|
||||||
|
|
||||||
|
// Calcular porcentaje de asistencia general
|
||||||
|
var asistenciaGeneral = total > 0 ?
|
||||||
|
((presentes + tardes) / total * 100).toFixed(1) : 0;
|
||||||
|
|
||||||
$('#estadisticasContainer').html(`
|
$('#estadisticasContainer').html(`
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card bg-success text-white">
|
<div class="card bg-success text-white">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h6 class="card-title">Presentes</h6>
|
<h6 class="card-title">
|
||||||
<h2>${presentes}</h2>
|
<i class="fas fa-check-circle"></i> Presentes
|
||||||
|
</h6>
|
||||||
|
<h2 class="display-6">${presentes.toLocaleString()}</h2>
|
||||||
|
<div class="mt-2">
|
||||||
<small>${porcentajePresentes}%</small>
|
<small>${porcentajePresentes}%</small>
|
||||||
|
<div class="progress mt-1" style="height: 5px;">
|
||||||
|
<div class="progress-bar bg-light"
|
||||||
|
style="width: ${porcentajePresentes}%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card bg-warning">
|
<div class="card bg-warning">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h6 class="card-title">Tardes</h6>
|
<h6 class="card-title">
|
||||||
<h2>${tardes}</h2>
|
<i class="fas fa-clock"></i> Tardes
|
||||||
|
</h6>
|
||||||
|
<h2 class="display-6">${tardes.toLocaleString()}</h2>
|
||||||
|
<div class="mt-2">
|
||||||
<small>${porcentajeTardes}%</small>
|
<small>${porcentajeTardes}%</small>
|
||||||
|
<div class="progress mt-1" style="height: 5px;">
|
||||||
|
<div class="progress-bar bg-dark"
|
||||||
|
style="width: ${porcentajeTardes}%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card bg-danger text-white">
|
<div class="card bg-danger text-white">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h6 class="card-title">Faltas</h6>
|
<h6 class="card-title">
|
||||||
<h2>${faltas}</h2>
|
<i class="fas fa-times-circle"></i> Faltas
|
||||||
|
</h6>
|
||||||
|
<h2 class="display-6">${faltas.toLocaleString()}</h2>
|
||||||
|
<div class="mt-2">
|
||||||
<small>${porcentajeFaltas}%</small>
|
<small>${porcentajeFaltas}%</small>
|
||||||
|
<div class="progress mt-1" style="height: 5px;">
|
||||||
|
<div class="progress-bar bg-light"
|
||||||
|
style="width: ${porcentajeFaltas}%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card bg-info text-white">
|
<div class="card bg-info text-white">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h6 class="card-title">Total Registros</h6>
|
<h6 class="card-title">
|
||||||
<h2>${total}</h2>
|
<i class="fas fa-chart-bar"></i> Resumen
|
||||||
<small>Asistencia: ${porcentajePresentes}%</small>
|
</h6>
|
||||||
|
<h2 class="display-6">${total.toLocaleString()}</h2>
|
||||||
|
<div class="mt-2">
|
||||||
|
<small>Asistencia: ${asistenciaGeneral}%</small>
|
||||||
|
<div class="progress mt-1" style="height: 5px;">
|
||||||
|
<div class="progress-bar bg-light"
|
||||||
|
style="width: ${asistenciaGeneral}%"></div>
|
||||||
|
</div>
|
||||||
|
<div class="small mt-2">
|
||||||
|
<div>Presentes: ${presentes}</div>
|
||||||
|
<div>Tardes: ${tardes}</div>
|
||||||
|
<div>Faltas: ${faltas}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
console.error('Error cargando estadísticas');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// FUNCIONES ADICIONALES
|
||||||
|
// ============================================
|
||||||
|
|
||||||
function aplicarColoresDias() {
|
function aplicarColoresDias() {
|
||||||
$('th.text-center').each(function() {
|
$('th.text-center').each(function() {
|
||||||
var textoDia = $(this).find('.small').text().trim();
|
var textoDia = $(this).find('.small').text().trim();
|
||||||
@@ -480,7 +894,7 @@
|
|||||||
case 'Lun': claseColor = 'bg-lunes'; break;
|
case 'Lun': claseColor = 'bg-lunes'; break;
|
||||||
case 'Mar': claseColor = 'bg-martes'; break;
|
case 'Mar': claseColor = 'bg-martes'; break;
|
||||||
case 'Mié': claseColor = 'bg-miercoles'; break;
|
case 'Mié': claseColor = 'bg-miercoles'; break;
|
||||||
case 'Jue': claseColor = 'bg-jueves'; break
|
case 'Jue': claseColor = 'bg-jueves'; break;
|
||||||
case 'Vie': claseColor = 'bg-viernes'; break;
|
case 'Vie': claseColor = 'bg-viernes'; break;
|
||||||
case 'Sáb': claseColor = 'bg-sabado'; break;
|
case 'Sáb': claseColor = 'bg-sabado'; break;
|
||||||
case 'Dom': claseColor = 'bg-domingo'; break;
|
case 'Dom': claseColor = 'bg-domingo'; break;
|
||||||
@@ -491,5 +905,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,7 +530,7 @@
|
|||||||
<button onclick="window.print()" class="btn btn-primary">
|
<button onclick="window.print()" class="btn btn-primary">
|
||||||
<i class="bi bi-printer"></i> Imprimir Documento
|
<i class="bi bi-printer"></i> Imprimir Documento
|
||||||
</button>
|
</button>
|
||||||
<button onclick="downloadPDF()" class="btn btn-info">
|
<button onclick="downloadPDF()" style="visibility:hidden" class="btn btn-info">
|
||||||
<i class="bi bi-download"></i> Guardar como PDF
|
<i class="bi bi-download"></i> Guardar como PDF
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -323,10 +323,8 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
renderExpedientesTable(filtered);
|
renderExpedientesTable(filtered);
|
||||||
$('#pagination').empty(); // Limpiar paginación en búsqueda
|
$('#pagination').empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guardar nuevo expediente
|
|
||||||
function saveExpediente() {
|
function saveExpediente() {
|
||||||
const formData = new FormData($('#createForm')[0]);
|
const formData = new FormData($('#createForm')[0]);
|
||||||
|
|
||||||
@@ -337,7 +335,6 @@
|
|||||||
processData: false,
|
processData: false,
|
||||||
contentType: false,
|
contentType: false,
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
// Mostrar siempre el mensaje que viene en response.message
|
|
||||||
const message = response.message ||
|
const message = response.message ||
|
||||||
(response.success ? 'Operación completada' : 'Error en la operación');
|
(response.success ? 'Operación completada' : 'Error en la operación');
|
||||||
|
|
||||||
@@ -351,7 +348,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(xhr) {
|
error: function(xhr) {
|
||||||
// Extraer el message del JSON si existe
|
|
||||||
let message = 'Error en la solicitud';
|
let message = 'Error en la solicitud';
|
||||||
try {
|
try {
|
||||||
const jsonResponse = JSON.parse(xhr.responseText);
|
const jsonResponse = JSON.parse(xhr.responseText);
|
||||||
@@ -359,7 +355,6 @@
|
|||||||
message = jsonResponse.message;
|
message = jsonResponse.message;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Si no es JSON válido, usar el texto de respuesta
|
|
||||||
if (xhr.responseText) {
|
if (xhr.responseText) {
|
||||||
message = xhr.responseText;
|
message = xhr.responseText;
|
||||||
}
|
}
|
||||||
@@ -378,7 +373,6 @@
|
|||||||
$('#editModalBody').html(data);
|
$('#editModalBody').html(data);
|
||||||
$('#editModal').modal('show');
|
$('#editModal').modal('show');
|
||||||
|
|
||||||
// Mostrar/ocultar botón de eliminar imagen según si hay imagen personalizada
|
|
||||||
const fotoUrl = $('#editForm input[name="FotoUrl"]').val();
|
const fotoUrl = $('#editForm input[name="FotoUrl"]').val();
|
||||||
const deleteBtn = $('#deleteFotoEdit');
|
const deleteBtn = $('#deleteFotoEdit');
|
||||||
if (fotoUrl && fotoUrl !== '/images/default-avatar.png') {
|
if (fotoUrl && fotoUrl !== '/images/default-avatar.png') {
|
||||||
@@ -441,8 +435,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== FUNCIONES PARA MANEJO DE IMÁGENES ==========
|
|
||||||
|
|
||||||
// Mostrar vista previa de imagen
|
// Mostrar vista previa de imagen
|
||||||
function previewImage(input, previewId) {
|
function previewImage(input, previewId) {
|
||||||
const preview = document.getElementById(previewId);
|
const preview = document.getElementById(previewId);
|
||||||
@@ -519,16 +511,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
showAlert('error', message);
|
showAlert('error', message);
|
||||||
// Restaurar imagen predeterminada
|
|
||||||
preview.src = '/images/default-avatar.png';
|
preview.src = '/images/default-avatar.png';
|
||||||
// Ocultar botón de eliminar
|
|
||||||
const deleteBtnId = isEdit ? 'deleteFotoEdit' : 'deleteFoto';
|
const deleteBtnId = isEdit ? 'deleteFotoEdit' : 'deleteFoto';
|
||||||
$(`#${deleteBtnId}`).hide();
|
$(`#${deleteBtnId}`).hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eliminar imagen
|
|
||||||
function deleteImage(isEdit = false) {
|
function deleteImage(isEdit = false) {
|
||||||
const formId = isEdit ? 'editForm' : 'createForm';
|
const formId = isEdit ? 'editForm' : 'createForm';
|
||||||
const hiddenInput = $(`#${formId} input[name="FotoUrl"]`);
|
const hiddenInput = $(`#${formId} input[name="FotoUrl"]`);
|
||||||
@@ -544,7 +533,6 @@
|
|||||||
data: { imageUrl: imageUrl },
|
data: { imageUrl: imageUrl },
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
// Restaurar imagen predeterminada
|
|
||||||
$(`#${previewId}`).attr('src', '/images/default-avatar.png');
|
$(`#${previewId}`).attr('src', '/images/default-avatar.png');
|
||||||
hiddenInput.val('/images/default-avatar.png');
|
hiddenInput.val('/images/default-avatar.png');
|
||||||
$(`#${deleteBtnId}`).hide();
|
$(`#${deleteBtnId}`).hide();
|
||||||
@@ -561,9 +549,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== FUNCIONES UTILITARIAS ==========
|
|
||||||
|
|
||||||
// Calcular edad
|
|
||||||
function calculateAge(birthDate) {
|
function calculateAge(birthDate) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const birth = new Date(birthDate);
|
const birth = new Date(birthDate);
|
||||||
@@ -577,7 +562,6 @@
|
|||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formatear fecha
|
|
||||||
function formatDate(dateString) {
|
function formatDate(dateString) {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
return date.toLocaleDateString('es-ES', {
|
return date.toLocaleDateString('es-ES', {
|
||||||
@@ -587,9 +571,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mostrar alerta
|
|
||||||
function showAlert(type, message) {
|
function showAlert(type, message) {
|
||||||
// Crear elemento de alerta
|
|
||||||
const alertDiv = document.createElement('div');
|
const alertDiv = document.createElement('div');
|
||||||
alertDiv.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
|
alertDiv.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
|
||||||
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 1050; min-width: 300px;';
|
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 1050; min-width: 300px;';
|
||||||
@@ -598,10 +580,8 @@
|
|||||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Agregar al body
|
|
||||||
document.body.appendChild(alertDiv);
|
document.body.appendChild(alertDiv);
|
||||||
|
|
||||||
// Auto-eliminar después de 5 segundos
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (alertDiv.parentNode) {
|
if (alertDiv.parentNode) {
|
||||||
alertDiv.remove();
|
alertDiv.remove();
|
||||||
|
|||||||
@@ -257,32 +257,32 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<!-- Separador y sección de administración -->
|
<!-- Separador y sección de administración -->
|
||||||
<li class="mt-4">
|
<li class="mt-4" style="visibility:hidden">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<h6 class="text-uppercase text-muted small">Administración</h6>
|
<h6 class="text-uppercase text-muted small" >Administración</h6>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li style="visibility:hidden">
|
||||||
<a href="#" class="nav-link">
|
<a href="#" class="nav-link">
|
||||||
<i class="bi bi-people"></i> Niños
|
<i class="bi bi-people"></i> Niños
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li style="visibility:hidden">
|
||||||
<a href="#" class="nav-link">
|
<a href="#" class="nav-link">
|
||||||
<i class="bi bi-person-badge"></i> Maestros
|
<i class="bi bi-person-badge"></i> Maestros
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li style ="visibility:hidden">
|
||||||
<a href="#" class="nav-link">
|
<a href="#" class="nav-link">
|
||||||
<i class="bi bi-person-workspace"></i> Personal
|
<i class="bi bi-person-workspace" ></i> Personal
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li style="visibility:hidden">
|
||||||
<a href="#" class="nav-link">
|
<a href="#" class="nav-link">
|
||||||
<i class="bi bi-bar-chart"></i> Reportes
|
<i class="bi bi-bar-chart"></i> Reportes
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li style="visibility:hidden">
|
||||||
<a asp-area="" asp-controller="Home" asp-action="Privacy" class="nav-link @(ViewContext.RouteData.Values["Controller"]?.ToString() == "Home" && ViewContext.RouteData.Values["Action"]?.ToString() == "Privacy" ? "active" : "")">
|
<a asp-area="" asp-controller="Home" asp-action="Privacy" class="nav-link @(ViewContext.RouteData.Values["Controller"]?.ToString() == "Home" && ViewContext.RouteData.Values["Action"]?.ToString() == "Privacy" ? "active" : "")">
|
||||||
<i class="bi bi-shield-check"></i> Privacidad
|
<i class="bi bi-shield-check"></i> Privacidad
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user