feat(lugar): botón quitar consentimiento con motivo obligatorio y auditoría
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* modules/turnero/api/quitar_consentimiento.php
|
||||
* POST {consent_id, motivo} → elimina un consentimiento con auditoría
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
require_once __DIR__ . '/../../../classes/lab/ActividadAdmin.php';
|
||||
|
||||
requireTurnero();
|
||||
requireMethod('POST');
|
||||
|
||||
$input = inputJson();
|
||||
$consentId = (int)($input['consent_id'] ?? 0);
|
||||
$motivo = trim($input['motivo'] ?? '');
|
||||
|
||||
if (!$consentId) jsonError('consent_id requerido');
|
||||
if ($motivo === '') jsonError('Debe ingresar un motivo para quitar el consentimiento');
|
||||
|
||||
$pdo = db();
|
||||
|
||||
// Leer datos antes de borrar (para el log)
|
||||
$row = $pdo->prepare(
|
||||
"SELECT tc.id, tc.turno_id, tc.formulario_id, tc.estado,
|
||||
lf.nombre AS formulario_nombre,
|
||||
t.codigo AS turno_codigo
|
||||
FROM turnero_consentimientos tc
|
||||
JOIN lab_formularios lf ON lf.id = tc.formulario_id
|
||||
JOIN turnero_turnos t ON t.id = tc.turno_id
|
||||
WHERE tc.id = ? LIMIT 1"
|
||||
);
|
||||
$row->execute([$consentId]);
|
||||
$consent = $row->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$consent) jsonError('Consentimiento no encontrado', 404);
|
||||
|
||||
$pdo->prepare('DELETE FROM turnero_consentimientos WHERE id = ?')->execute([$consentId]);
|
||||
|
||||
(new ActividadAdmin())->registrar(
|
||||
adminId(),
|
||||
'turnero_config',
|
||||
'quitar_consentimiento',
|
||||
$consentId,
|
||||
[
|
||||
'turno_codigo' => $consent['turno_codigo'],
|
||||
'turno_id' => $consent['turno_id'],
|
||||
'formulario_id' => $consent['formulario_id'],
|
||||
'formulario_nombre' => $consent['formulario_nombre'],
|
||||
'estado_previo' => $consent['estado'],
|
||||
'motivo' => $motivo,
|
||||
]
|
||||
);
|
||||
|
||||
jsonOk([], 'Consentimiento quitado');
|
||||
@@ -843,6 +843,40 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php';
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Modal: quitar consentimiento ───────────────────────────── -->
|
||||
<div id="modal-quitar-consent" style="
|
||||
display:none;position:fixed;inset:0;z-index:9100;
|
||||
background:rgba(0,0,0,.55);align-items:center;justify-content:center;padding:16px">
|
||||
<div style="background:#fff;border-radius:14px;box-shadow:0 8px 40px rgba(0,0,0,.25);
|
||||
width:min(96vw,480px);padding:24px;display:flex;flex-direction:column;gap:14px">
|
||||
<div style="font-weight:700;font-size:.95rem;color:#1e293b">
|
||||
<i class="fas fa-trash me-2 text-danger"></i>Quitar consentimiento
|
||||
</div>
|
||||
<div style="font-size:.85rem;color:#475569">
|
||||
<strong id="mqc-nombre"></strong>
|
||||
</div>
|
||||
<div>
|
||||
<label style="font-size:.82rem;font-weight:600;color:#374151;display:block;margin-bottom:4px">
|
||||
Motivo <span style="color:#dc2626">*</span>
|
||||
</label>
|
||||
<textarea id="mqc-motivo" rows="3" placeholder="Explique por qué se quita este consentimiento…"
|
||||
style="width:100%;border:1px solid #d1d5db;border-radius:8px;padding:8px 10px;
|
||||
font-size:.85rem;resize:vertical;font-family:inherit"></textarea>
|
||||
<div id="mqc-error" style="color:#dc2626;font-size:.78rem;margin-top:4px;display:none"></div>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;justify-content:flex-end">
|
||||
<button onclick="_cerrarModalQuitarConsent()"
|
||||
style="padding:7px 18px;border:1px solid #d1d5db;border-radius:8px;
|
||||
background:#fff;cursor:pointer;font-size:.85rem">Cancelar</button>
|
||||
<button id="mqc-btn-confirmar" onclick="_confirmarQuitarConsent()"
|
||||
style="padding:7px 18px;border:none;border-radius:8px;
|
||||
background:#dc2626;color:#fff;cursor:pointer;font-weight:600;font-size:.85rem">
|
||||
<i class="fas fa-trash me-1"></i>Quitar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Modal de consentimiento embebido (modo embebido) ────────── -->
|
||||
<div id="modal-consentimiento" style="
|
||||
display:none;position:fixed;inset:0;z-index:9000;
|
||||
@@ -1476,17 +1510,60 @@ function renderConsentimientos(lista) {
|
||||
}
|
||||
}
|
||||
|
||||
const btnQuitar = `<button class="btn btn-outline-danger" title="Quitar consentimiento"
|
||||
onclick="_abrirModalQuitarConsent(${idJs}, ${nomJs.replace(/"/g,'"')})">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>`;
|
||||
|
||||
return `<div class="consent-row ${c.estado}" data-consent-id="${c.id}">
|
||||
<i class="fas ${ico}"></i>
|
||||
<span class="nom-form">${escHtml(c.formulario_nombre || 'Consentimiento')}</span>
|
||||
${progresoBadge}
|
||||
${countdownEl}
|
||||
<span class="c-badge">${label}</span>
|
||||
<div class="acciones-consent">${btnAccion}${btnVer}</div>
|
||||
<div class="acciones-consent">${btnAccion}${btnVer}${btnQuitar}</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// ── Quitar consentimiento ─────────────────────────────────────
|
||||
let _mqcConsentId = null;
|
||||
function _abrirModalQuitarConsent(consentId, formNombre) {
|
||||
_mqcConsentId = consentId;
|
||||
document.getElementById('mqc-nombre').textContent = formNombre;
|
||||
document.getElementById('mqc-motivo').value = '';
|
||||
document.getElementById('mqc-error').style.display = 'none';
|
||||
document.getElementById('modal-quitar-consent').style.display = 'flex';
|
||||
setTimeout(() => document.getElementById('mqc-motivo').focus(), 50);
|
||||
}
|
||||
function _cerrarModalQuitarConsent() {
|
||||
document.getElementById('modal-quitar-consent').style.display = 'none';
|
||||
_mqcConsentId = null;
|
||||
}
|
||||
async function _confirmarQuitarConsent() {
|
||||
const motivo = document.getElementById('mqc-motivo').value.trim();
|
||||
const errEl = document.getElementById('mqc-error');
|
||||
if (!motivo) { errEl.textContent = 'El motivo es obligatorio.'; errEl.style.display = ''; return; }
|
||||
const btn = document.getElementById('mqc-btn-confirmar');
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Quitando…';
|
||||
try {
|
||||
const res = await fetch(`${API}quitar_consentimiento.php`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({consent_id: _mqcConsentId, motivo})
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.ok) { errEl.textContent = json.error || 'Error al quitar.'; errEl.style.display = ''; }
|
||||
else {
|
||||
_cerrarModalQuitarConsent();
|
||||
if (turnoActivo?.id) actualizarConsentimientos(turnoActivo.id);
|
||||
}
|
||||
} catch(e) { errEl.textContent = 'Error de red.'; errEl.style.display = ''; }
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="fas fa-trash me-1"></i>Quitar';
|
||||
}
|
||||
|
||||
async function actualizarConsentimientos(turnoId) {
|
||||
if (!turnoId) return;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user