diff --git a/app/controllers/preferencias.php b/app/controllers/preferencias.php index b065464..cc1dbde 100644 --- a/app/controllers/preferencias.php +++ b/app/controllers/preferencias.php @@ -37,7 +37,7 @@ function notificaciones() $preferenciasRow = false; } - // Si no existe registro, crear valores por defecto + // Si no existe registro, crear valores por defecto (incluyendo horario) if (!$preferenciasRow) { $preferencias = [ 'nuevas_solicitudes' => 0, @@ -48,10 +48,15 @@ function notificaciones() 'documentos_expediente' => 0, 'nuevos_archivos' => 0, 'intentos_fallidos' => 0, - 'bloqueo_cuenta' => 0 + 'bloqueo_cuenta' => 0, + 'resumen_diario_hora' => '08:00:00', + 'resumen_diario_dias' => 'L-V' ]; } else { $preferencias = $preferenciasRow; + // Agregar campos de horario si no existen en el registro + $preferencias['resumen_diario_hora'] = $preferenciasRow['resumen_diario_hora'] ?? '08:00:00'; + $preferencias['resumen_diario_dias'] = $preferenciasRow['resumen_diario_dias'] ?? 'L-V'; } // Obtener tipos de notificaciones disponibles @@ -244,6 +249,81 @@ function guardarPreferenciasAjax() sqlsrv_free_stmt($stmt); break; + case 'resumen_diario_config': + $hora = $input['hora'] ?? '08:00'; + $dias = $input['dias'] ?? 'L-V'; + + // Validar formato de hora + if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $hora)) { + throw new Exception("Formato de hora inválido"); + } + + // Validar días + $dias_validos = ['L-V', 'TODOS', 'L-S']; + if (!in_array($dias, $dias_validos)) { + throw new Exception("Configuración de días inválida"); + } + + // Verificar que las notificaciones generales estén activadas + $query_check = "SELECT notificaciones FROM usuarios_sistema WHERE id_usuario = ?"; + $stmt_check = sqlsrv_prepare($conn, $query_check, [$id_usuario]); + if ($stmt_check && sqlsrv_execute($stmt_check)) { + $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); + sqlsrv_free_stmt($stmt_check); + + if (!$row || !$row['notificaciones']) { + throw new Exception("Las notificaciones generales deben estar activadas primero"); + } + } else { + throw new Exception("Error al verificar configuración"); + } + + // Verificar si existe el registro + $query_exists = "SELECT COUNT(*) as count FROM preferencias_notificaciones_usuario WHERE id_usuario = ?"; + $stmt_exists = sqlsrv_prepare($conn, $query_exists, [$id_usuario]); + $exists = false; + if ($stmt_exists && sqlsrv_execute($stmt_exists)) { + $row = sqlsrv_fetch_array($stmt_exists, SQLSRV_FETCH_ASSOC); + $exists = $row['count'] > 0; + sqlsrv_free_stmt($stmt_exists); + } + + if ($exists) { + // Actualizar configuración de resumen diario + $query = "UPDATE preferencias_notificaciones_usuario + SET resumen_diario_hora = ?, resumen_diario_dias = ? + WHERE id_usuario = ?"; + $stmt = sqlsrv_prepare($conn, $query, [$hora, $dias, $id_usuario]); + } else { + // Crear registro con valores por defecto + $tipos_default = [ + 'nuevas_solicitudes' => 0, + 'registro_solicitud' => 0, + 'cambio_estado' => 0, + 'resumen_diario' => 0, + 'alertas_tiempo' => 0, + 'documentos_expediente' => 0, + 'nuevos_archivos' => 0, + 'intentos_fallidos' => 0, + 'bloqueo_cuenta' => 0, + 'resumen_diario_hora' => $hora, + 'resumen_diario_dias' => $dias + ]; + + $campos = implode(', ', array_keys($tipos_default)); + $placeholders = rtrim(str_repeat('?, ', count($tipos_default)), ', '); + $query = "INSERT INTO preferencias_notificaciones_usuario (id_usuario, $campos) VALUES (?, $placeholders)"; + + $params = array_merge([$id_usuario], array_values($tipos_default)); + $stmt = sqlsrv_prepare($conn, $query, $params); + } + + if (!$stmt || !sqlsrv_execute($stmt)) { + throw new Exception("Error al actualizar configuración de resumen diario"); + } + sqlsrv_free_stmt($stmt); + break; + default: throw new Exception("Tipo de cambio no válido"); } diff --git a/notificaciones_table.txt b/notificaciones_table.txt index 8f808f7..e05364f 100644 --- a/notificaciones_table.txt +++ b/notificaciones_table.txt @@ -32,3 +32,7 @@ CREATE TABLE preferencias_notificaciones_usuario ( bloqueo_cuenta BIT DEFAULT 0, FOREIGN KEY (id_usuario) REFERENCES usuarios_sistema(id_usuario) ); + +ALTER TABLE preferencias_notificaciones_usuario +ADD resumen_diario_hora TIME DEFAULT '08:00:00', + resumen_diario_dias NVARCHAR(20) DEFAULT 'L-V'; -- L-V = Lunes a Viernes, o 'TODOS' para todos los días \ No newline at end of file diff --git a/views/preferencias/notificaciones.php b/views/preferencias/notificaciones.php index ae42a78..060a199 100644 --- a/views/preferencias/notificaciones.php +++ b/views/preferencias/notificaciones.php @@ -188,7 +188,7 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
> + >
📋 Tipos de Notificaciones
@@ -197,14 +197,50 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
> + name="" id="" + data-tipo="tipo_notificacion" data-nombre="" + >
+ + + +
+
+
⚙️ Configuración de Horario
+
+
+ + +
+
+ + +
+
+
+ + Recibirás un resumen con las actividades del día anterior +
+
+
+
@@ -465,6 +501,80 @@ include __DIR__ . '/../partials/sidebar_configuracion.php'; return e.returnValue; } }); + + // Event listener específico para el switch de resumen diario + document.getElementById('resumen_diario').addEventListener('change', function() { + const isChecked = this.checked; + const configSection = document.getElementById('resumen-diario-config'); + + // Mostrar/ocultar configuración de horario con animación + if (isChecked) { + configSection.style.display = 'block'; + setTimeout(() => { + configSection.style.opacity = '1'; + }, 10); + } else { + configSection.style.opacity = '0'; + setTimeout(() => { + configSection.style.display = 'none'; + }, 300); + } + }); + + // Event listeners para los controles de horario + document.getElementById('resumen_hora').addEventListener('change', function() { + const hora = this.value; + const dias = document.getElementById('resumen_dias').value; + + // Validar que resumen_diario esté activado + const resumenDiarioCheckbox = document.getElementById('resumen_diario'); + if (!resumenDiarioCheckbox.checked) { + showSaveIndicator('error', 'El resumen diario debe estar activado'); + return; + } + + // Deshabilitar controles temporalmente + const horaInput = this; + const diasSelect = document.getElementById('resumen_dias'); + horaInput.disabled = true; + diasSelect.disabled = true; + + // Guardar configuración + autoSave('resumen_diario_config', { + hora: hora, + dias: dias + }).finally(() => { + horaInput.disabled = false; + diasSelect.disabled = false; + }); + }); + + document.getElementById('resumen_dias').addEventListener('change', function() { + const hora = document.getElementById('resumen_hora').value; + const dias = this.value; + + // Validar que resumen_diario esté activado + const resumenDiarioCheckbox = document.getElementById('resumen_diario'); + if (!resumenDiarioCheckbox.checked) { + showSaveIndicator('error', 'El resumen diario debe estar activado'); + return; + } + + // Deshabilitar controles temporalmente + const horaInput = document.getElementById('resumen_hora'); + const diasSelect = this; + horaInput.disabled = true; + diasSelect.disabled = true; + + // Guardar configuración + autoSave('resumen_diario_config', { + hora: hora, + dias: dias + }).finally(() => { + horaInput.disabled = false; + diasSelect.disabled = false; + }); + });