feat(turnero): dispositivos por IP, firmas, formularios y muestras prolongadas
- login.php: detectar dispositivo por IP al autenticar y redirigir al lugar asignado - dashboard.php / lugar.php / recepcion.php: bloquear acceso por dispositivo (IP→lugar) - lugar.php: modal firma profesional pre-guardada; compact 2-col en iframe; botón WA solo cuando el formulario requiere firma del paciente - ver_formulario_enviado.php: modo compact tablet, auto-save borrador (merge), firma profesional en 1 clic, Muestras Prolongadas (countdown + Finalizar), auto_profesional pre-fill desde sesión, fecha→fecha_hoy en campos de toma/recepción - get_consentimientos.php: añadir requiere_firma_paciente para controlar botón WA - save_firma_profesional.php: API para guardar firma pre-configurada del profesional - migrations: turnero_dispositivos, admin_users.firma_svg, clon VIH F-LAB-05 para turnero Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
4de9c2f9b4
commit
8760b685ad
@@ -55,10 +55,10 @@ foreach ($consentimientos as &$c) {
|
||||
$decoded = json_decode($esquema, true);
|
||||
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
||||
}
|
||||
$c['requiere_firma_profesional'] = !empty(array_filter(
|
||||
$campos,
|
||||
fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'
|
||||
));
|
||||
$tieneFirmaPro = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$c['requiere_firma_profesional'] = $tieneFirmaPro;
|
||||
$c['requiere_firma_paciente'] = !($tieneFirmaPro && !$tieneFirmaPac); // false solo si es solo-profesional
|
||||
unset($c['formulario_esquema']);
|
||||
}
|
||||
unset($c);
|
||||
@@ -205,10 +205,10 @@ if ($incluirSolicitud) {
|
||||
$decoded = json_decode($esquema, true);
|
||||
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
||||
}
|
||||
$c['requiere_firma_profesional'] = !empty(array_filter(
|
||||
$campos,
|
||||
fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'
|
||||
));
|
||||
$tieneFirmaPro = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$c['requiere_firma_profesional'] = $tieneFirmaPro;
|
||||
$c['requiere_firma_paciente'] = !($tieneFirmaPro && !$tieneFirmaPac);
|
||||
unset($c['formulario_esquema']);
|
||||
}
|
||||
unset($c);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* POST — Guarda la firma pre-configurada del profesional en su perfil (admin_users).
|
||||
* Body JSON: { firma_svg: "data:image/png;base64,..." }
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$body = inputJson();
|
||||
$svg = $body['firma_svg'] ?? '';
|
||||
if (strlen($svg) < 100) jsonError('Firma requerida.');
|
||||
if (!preg_match('/^data:image\/(svg\+xml|png|jpeg|webp);base64,/i', $svg)) {
|
||||
jsonError('Formato de firma no válido.');
|
||||
}
|
||||
|
||||
$uid = (int)($_SESSION['admin_user']['id'] ?? 0);
|
||||
if (!$uid) jsonError('Sin sesión activa.');
|
||||
|
||||
db()->prepare("UPDATE admin_users SET firma_svg = ? WHERE id = ?")->execute([$svg, $uid]);
|
||||
|
||||
jsonOk(['mensaje' => 'Firma guardada correctamente.']);
|
||||
Reference in New Issue
Block a user