273 lines
12 KiB
PHP
273 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Términos y Condiciones — Historial de Aceptaciones
|
|
*/
|
|
require_once 'config/config.php';
|
|
|
|
if (!isUserLoggedIn()) {
|
|
header('Location: login.php');
|
|
exit;
|
|
}
|
|
if (isEnfermero()) { header('Location: enfermero_portal.php'); exit; }
|
|
|
|
$adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['username'] ?? 'Admin';
|
|
|
|
// Filtros
|
|
$filterEstado = $_GET['estado'] ?? '';
|
|
$filterFecha = $_GET['fecha'] ?? '';
|
|
$filterPhone = trim($_GET['phone'] ?? '');
|
|
|
|
// Paginación
|
|
$page = max(1, (int)($_GET['page'] ?? 1));
|
|
$perPage = 50;
|
|
$offset = ($page - 1) * $perPage;
|
|
|
|
try {
|
|
$db = Database::getInstance();
|
|
|
|
// Versión activa
|
|
$activeVersion = $db->fetch("SELECT * FROM terms_versions WHERE activa = 1 ORDER BY id DESC LIMIT 1");
|
|
|
|
// Construcción dinámica del WHERE
|
|
$where = [];
|
|
$params = [];
|
|
|
|
if ($filterEstado !== '') {
|
|
$where[] = 'ta.estado = :estado';
|
|
$params[':estado'] = $filterEstado;
|
|
}
|
|
if ($filterFecha !== '') {
|
|
$where[] = 'DATE(ta.fecha_envio) = :fecha';
|
|
$params[':fecha'] = $filterFecha;
|
|
}
|
|
if ($filterPhone !== '') {
|
|
$where[] = 'ta.phone_number LIKE :phone';
|
|
$params[':phone'] = '%' . $filterPhone . '%';
|
|
}
|
|
|
|
$whereClause = $where ? 'WHERE ' . implode(' AND ', $where) : '';
|
|
|
|
$total = (int)($db->fetch(
|
|
"SELECT COUNT(*) as c FROM terms_acceptance ta $whereClause",
|
|
$params
|
|
)['c'] ?? 0);
|
|
|
|
$rows = $db->fetchAll(
|
|
"SELECT ta.id, ta.phone_number, ta.estado, ta.fecha_envio, ta.fecha_respuesta,
|
|
tv.version AS terms_version,
|
|
u.name AS user_name
|
|
FROM terms_acceptance ta
|
|
LEFT JOIN terms_versions tv ON tv.id = ta.terms_version_id
|
|
LEFT JOIN users u ON u.id = ta.user_id
|
|
$whereClause
|
|
ORDER BY ta.id DESC
|
|
LIMIT $perPage OFFSET $offset",
|
|
$params
|
|
);
|
|
|
|
$totalPages = max(1, ceil($total / $perPage));
|
|
|
|
} catch (Exception $e) {
|
|
$rows = [];
|
|
$total = 0;
|
|
$totalPages = 1;
|
|
$activeVersion = null;
|
|
$dbError = $e->getMessage();
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Términos y Condiciones — Aceptaciones</title>
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="./assets/css/styles.css?v=12" rel="stylesheet">
|
|
<style>
|
|
.estado-aceptado { background:#d1e7dd; color:#0f5132; }
|
|
.estado-rechazado { background:#f8d7da; color:#842029; }
|
|
.estado-pendiente { background:#fff3cd; color:#664d03; }
|
|
.estado-badge { font-size:.72rem; padding:.25em .55em; border-radius:.35rem; font-weight:600; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="sidebar">
|
|
<div class="sidebar-header"><h4><i class="fas fa-flask"></i> Módulo Lab</h4></div>
|
|
<ul class="sidebar-menu">
|
|
<li><a href="lab_dashboard.php"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
|
|
<li><a href="lab_pacientes.php"><i class="fas fa-users"></i> Pacientes</a></li>
|
|
<li><a href="lab_ordenes.php"><i class="fas fa-clipboard-list"></i> Órdenes</a></li>
|
|
<li><a href="lab_domicilios.php"><i class="fas fa-home"></i> Domicilios</a></li>
|
|
<li class="active"><a href="lab_terminos.php"><i class="fas fa-file-contract"></i> Términos</a></li>
|
|
<li><a href="index.php"><i class="fas fa-cog"></i> Configuración</a></li>
|
|
<li><a href="logout.php"><i class="fas fa-sign-out-alt"></i> Cerrar sesión</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<div class="main-content">
|
|
<div class="content-header d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h1><i class="fas fa-file-contract me-2"></i>Términos y Condiciones</h1>
|
|
<p class="text-muted mb-0">Historial de aceptaciones de usuarios</p>
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<a href="lab_terminos_export.php?<?= http_build_query(array_filter(['estado' => $filterEstado, 'fecha' => $filterFecha, 'phone' => $filterPhone])) ?>"
|
|
class="btn btn-outline-success btn-sm">
|
|
<i class="fas fa-file-csv me-1"></i>Exportar CSV
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Versión activa -->
|
|
<?php if ($activeVersion): ?>
|
|
<div class="alert alert-info d-flex align-items-center gap-3 mb-4 py-2">
|
|
<i class="fas fa-info-circle fa-lg"></i>
|
|
<div>
|
|
<strong>Versión activa:</strong> <?= htmlspecialchars($activeVersion['version']) ?>
|
|
<?php if ($activeVersion['documento_url']): ?>
|
|
— <a href="<?= htmlspecialchars($activeVersion['documento_url']) ?>" target="_blank" class="alert-link">
|
|
<i class="fas fa-external-link-alt me-1"></i>Ver documento
|
|
</a>
|
|
<?php endif; ?>
|
|
<?php if ($activeVersion['forzar_reenvio']): ?>
|
|
<span class="badge bg-warning text-dark ms-2">Re-aceptación forzada activa</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (isset($dbError)): ?>
|
|
<div class="alert alert-danger"><i class="fas fa-exclamation-circle me-1"></i><?= htmlspecialchars($dbError) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Estadísticas rápidas -->
|
|
<?php
|
|
$statsRaw = !isset($dbError) ? $db->fetchAll(
|
|
"SELECT estado, COUNT(*) as total FROM terms_acceptance GROUP BY estado"
|
|
) : [];
|
|
$stats = [];
|
|
foreach ($statsRaw as $s) $stats[$s['estado']] = (int)$s['total'];
|
|
?>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-6 col-md-3">
|
|
<div class="card border-0 shadow-sm text-center py-3">
|
|
<div class="fs-4 fw-bold text-success"><?= $stats['aceptado'] ?? 0 ?></div>
|
|
<small class="text-muted">Aceptaciones</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-md-3">
|
|
<div class="card border-0 shadow-sm text-center py-3">
|
|
<div class="fs-4 fw-bold text-danger"><?= $stats['rechazado'] ?? 0 ?></div>
|
|
<small class="text-muted">Rechazos</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-md-3">
|
|
<div class="card border-0 shadow-sm text-center py-3">
|
|
<div class="fs-4 fw-bold text-warning"><?= $stats['pendiente'] ?? 0 ?></div>
|
|
<small class="text-muted">Pendientes</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-6 col-md-3">
|
|
<div class="card border-0 shadow-sm text-center py-3">
|
|
<div class="fs-4 fw-bold text-primary"><?= $total ?></div>
|
|
<small class="text-muted">Total registros</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filtros -->
|
|
<div class="card mb-4">
|
|
<div class="card-body py-2">
|
|
<form method="GET" class="row g-2 align-items-end">
|
|
<div class="col-auto">
|
|
<label class="form-label mb-1 small">Teléfono</label>
|
|
<input type="text" name="phone" class="form-control form-control-sm"
|
|
value="<?= htmlspecialchars($filterPhone) ?>" placeholder="Buscar teléfono">
|
|
</div>
|
|
<div class="col-auto">
|
|
<label class="form-label mb-1 small">Estado</label>
|
|
<select name="estado" class="form-select form-select-sm">
|
|
<option value="">Todos</option>
|
|
<option value="aceptado" <?= $filterEstado === 'aceptado' ? 'selected' : '' ?>>Aceptados</option>
|
|
<option value="rechazado" <?= $filterEstado === 'rechazado' ? 'selected' : '' ?>>Rechazados</option>
|
|
<option value="pendiente" <?= $filterEstado === 'pendiente' ? 'selected' : '' ?>>Pendientes</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-auto">
|
|
<label class="form-label mb-1 small">Fecha</label>
|
|
<input type="date" name="fecha" class="form-control form-control-sm"
|
|
value="<?= htmlspecialchars($filterFecha) ?>">
|
|
</div>
|
|
<div class="col-auto d-flex gap-1">
|
|
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-search me-1"></i>Filtrar</button>
|
|
<a href="lab_terminos.php" class="btn btn-outline-secondary btn-sm">Limpiar</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabla -->
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>#</th>
|
|
<th>Teléfono</th>
|
|
<th>Nombre</th>
|
|
<th>Versión</th>
|
|
<th>Estado</th>
|
|
<th>Enviado</th>
|
|
<th>Respondido</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($rows)): ?>
|
|
<tr><td colspan="7" class="text-center text-muted py-4">No hay registros para los filtros seleccionados.</td></tr>
|
|
<?php else: ?>
|
|
<?php foreach ($rows as $r): ?>
|
|
<tr>
|
|
<td class="text-muted small"><?= (int)$r['id'] ?></td>
|
|
<td><code><?= htmlspecialchars($r['phone_number']) ?></code></td>
|
|
<td><?= htmlspecialchars($r['user_name'] ?: '—') ?></td>
|
|
<td><?= htmlspecialchars($r['terms_version'] ?: '—') ?></td>
|
|
<td>
|
|
<span class="estado-badge estado-<?= htmlspecialchars($r['estado']) ?>">
|
|
<?= ucfirst(htmlspecialchars($r['estado'])) ?>
|
|
</span>
|
|
</td>
|
|
<td class="small text-muted"><?= $r['fecha_envio'] ? date('d/m/Y H:i', strtotime($r['fecha_envio'])) : '—' ?></td>
|
|
<td class="small text-muted"><?= $r['fecha_respuesta'] ? date('d/m/Y H:i', strtotime($r['fecha_respuesta'])) : '—' ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!-- Paginación -->
|
|
<?php if ($totalPages > 1): ?>
|
|
<div class="card-footer d-flex justify-content-between align-items-center py-2">
|
|
<small class="text-muted">Página <?= $page ?> de <?= $totalPages ?> — <?= $total ?> registros</small>
|
|
<nav>
|
|
<ul class="pagination pagination-sm mb-0">
|
|
<?php for ($p = 1; $p <= $totalPages; $p++): ?>
|
|
<li class="page-item <?= $p === $page ? 'active' : '' ?>">
|
|
<a class="page-link" href="?<?= http_build_query(array_merge($_GET, ['page' => $p])) ?>"><?= $p ?></a>
|
|
</li>
|
|
<?php endfor; ?>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="assets/js/lab-sidebar.js"></script>
|
|
</body>
|
|
</html>
|