259 lines
13 KiB
Plaintext
259 lines
13 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title><%= set.nombre %> | Manifiesto de Herramientas</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<style>
|
|
:root {
|
|
--primary: #2563eb;
|
|
--primary-dark: #1d4ed8;
|
|
--surface: #ffffff;
|
|
--bg: #f1f5f9;
|
|
}
|
|
body {
|
|
background-color: var(--bg);
|
|
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
color: #1e293b;
|
|
padding-bottom: 2rem;
|
|
}
|
|
.header-bar {
|
|
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
|
|
color: white;
|
|
padding: 1.5rem 1rem;
|
|
border-bottom: 3px solid #3b82f6;
|
|
}
|
|
.set-card {
|
|
background: var(--surface);
|
|
border-radius: 0.85rem;
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
border: 1px solid #e2e8f0;
|
|
overflow: hidden;
|
|
margin-top: -1rem;
|
|
}
|
|
.tool-item {
|
|
transition: background-color 0.15s ease-in-out;
|
|
cursor: pointer;
|
|
}
|
|
.tool-item:hover {
|
|
background-color: #f8fafc;
|
|
}
|
|
.tool-item.checked {
|
|
background-color: #f0fdf4 !important;
|
|
border-left: 3px solid #22c55e;
|
|
}
|
|
.tool-item.checked .tool-name {
|
|
text-decoration: line-through;
|
|
color: #64748b;
|
|
}
|
|
.badge-tag {
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
padding: 0.35em 0.65em;
|
|
border-radius: 0.35rem;
|
|
}
|
|
@media (max-width: 576px) {
|
|
.header-bar {
|
|
padding: 1.25rem 0.75rem;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Cabecera Superior -->
|
|
<header class="header-bar text-center">
|
|
<div class="container" style="max-width: 600px;">
|
|
<div class="d-inline-flex align-items-center gap-2 mb-1">
|
|
<i class="fas fa-toolbox text-warning fs-5"></i>
|
|
<span class="text-uppercase fw-bold small tracking-wide" style="letter-spacing: 1px; color: #94a3b8;"><%= set.company_name || 'Telcotronics' %></span>
|
|
</div>
|
|
<h1 class="h4 fw-bold mb-1 text-white"><%= set.nombre %></h1>
|
|
<div class="d-flex align-items-center justify-content-center gap-2">
|
|
<span class="badge bg-secondary font-monospace"><%= set.codigo || 'KIT-' + set.id %></span>
|
|
<span class="badge bg-primary-subtle text-white border border-primary"><%= set.categoria %></span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="container" style="max-width: 600px;">
|
|
<div class="set-card p-3 p-sm-4 mb-3">
|
|
|
|
<!-- Fotografía de la Caja/Kit si existe -->
|
|
<% if (set.foto_url) { %>
|
|
<div class="mb-3 rounded overflow-hidden border shadow-sm position-relative" style="max-height: 220px; background-color: #000;">
|
|
<img src="<%= set.foto_url %>" alt="<%= set.nombre %>" style="width: 100%; height: 220px; object-fit: cover;">
|
|
</div>
|
|
<% } %>
|
|
|
|
<!-- Estado de Custodia Actual -->
|
|
<div class="mb-3 p-3 rounded-3 border <%= custodia ? 'border-success-subtle bg-success-subtle bg-opacity-25' : 'border-info-subtle bg-info-subtle bg-opacity-25' %>">
|
|
<div class="d-flex align-items-center justify-content-between mb-2">
|
|
<span class="fw-bold small text-uppercase" style="letter-spacing: 0.5px; font-size: 0.75rem;">
|
|
<i class="fas <%= custodia ? 'fa-user-check text-success' : 'fa-warehouse text-info' %> me-1"></i>
|
|
Estado Actual
|
|
</span>
|
|
<% if (custodia) { %>
|
|
<span class="badge bg-success"><i class="fas fa-check-circle me-1"></i> Asignado en Custodia</span>
|
|
<% } else { %>
|
|
<span class="badge bg-primary"><i class="fas fa-boxes-stacked me-1"></i> En Bodega / Disponible</span>
|
|
<% } %>
|
|
</div>
|
|
|
|
<% if (custodia) { %>
|
|
<div class="small">
|
|
<div class="fw-bold text-dark fs-6"><%= custodia.tecnico_nombre %></div>
|
|
<div class="text-muted"><i class="fas fa-envelope text-secondary me-1"></i> <%= custodia.tecnico_email %></div>
|
|
<div class="text-muted mt-1">
|
|
<i class="fas fa-calendar-alt text-secondary me-1"></i>
|
|
Asignado: <strong><%= new Date(custodia.fecha_asignacion).toLocaleString('es-EC') %></strong>
|
|
<span class="badge bg-light text-dark border ms-1 font-monospace" style="font-size: 0.68rem;">
|
|
<%= custodia.tipo_asignacion === 'dotacion_fija' ? 'Dotación Fija' : 'Visita FSM' %>
|
|
</span>
|
|
</div>
|
|
|
|
<% if (custodia.ticket_id) { %>
|
|
<div class="mt-2 pt-2 border-top border-success-subtle">
|
|
<span class="badge bg-primary me-1">Ticket #<%= custodia.ticket_id %></span>
|
|
<span class="text-dark fw-semibold"><%= custodia.visita_titulo || custodia.ticket_asunto || 'Visita Técnica' %></span>
|
|
</div>
|
|
<% } %>
|
|
|
|
<% if (custodia.foto_entrega_url) { %>
|
|
<div class="mt-2 pt-2 border-top border-success-subtle">
|
|
<a href="<%= custodia.foto_entrega_url %>" target="_blank" class="btn btn-outline-success btn-sm py-1 px-2 d-inline-flex align-items-center gap-1.5" style="font-size: 0.75rem;">
|
|
<i class="fas fa-camera"></i>
|
|
<span>Ver foto de entrega al técnico</span>
|
|
</a>
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
<% } else { %>
|
|
<div class="small text-muted">
|
|
Esta caja de herramientas se encuentra resguardada en bodega central y está lista para ser asignada a un técnico o visita técnica.
|
|
</div>
|
|
<% } %>
|
|
</div>
|
|
|
|
<% if (set.descripcion) { %>
|
|
<p class="text-muted small mb-3"><%= set.descripcion %></p>
|
|
<% } %>
|
|
|
|
<!-- Lista de Herramientas (Manifest) -->
|
|
<div class="d-flex align-items-center justify-content-between mb-2.5">
|
|
<h5 class="fw-bold text-dark h6 mb-0 d-flex align-items-center gap-1.5">
|
|
<i class="fas fa-clipboard-check text-primary"></i>
|
|
<span>Inventario de la Caja (<%= herramientas.length %>)</span>
|
|
</h5>
|
|
<span class="badge bg-light text-muted border font-monospace" id="contadorChecklist" style="font-size: 0.7rem;">0 / <%= herramientas.length %> verificadas</span>
|
|
</div>
|
|
|
|
<p class="text-muted small mb-3" style="font-size: 0.78rem;">
|
|
Toca cada herramienta para marcarla en el checklist físico al revisar el contenido de la caja.
|
|
</p>
|
|
|
|
<% if (herramientas.length === 0) { %>
|
|
<div class="p-3 text-center border rounded bg-light text-muted small">
|
|
No hay herramientas asociadas a este kit actualmente.
|
|
</div>
|
|
<% } %>
|
|
|
|
<div class="list-group rounded-3 shadow-none border" id="checklistContainer">
|
|
<% herramientas.forEach((h, idx) => { %>
|
|
<div class="list-group-item list-group-item-action p-2.5 d-flex align-items-center justify-content-between tool-item" onclick="toggleToolCheck(this)">
|
|
<div class="d-flex align-items-center gap-2.5 overflow-hidden me-2">
|
|
<input class="form-check-input flex-shrink-0 mt-0" type="checkbox" id="tool_<%= h.id %>" onclick="event.stopPropagation(); toggleToolCheck(this.closest('.tool-item'))">
|
|
|
|
<% if (h.foto_url) { %>
|
|
<a href="<%= h.foto_url %>" target="_blank" onclick="event.stopPropagation();" title="Ver foto">
|
|
<img src="<%= h.foto_url %>" alt="<%= h.nombre %>" class="rounded border flex-shrink-0" style="width: 44px; height: 44px; object-fit: cover;">
|
|
</a>
|
|
<% } else { %>
|
|
<div class="rounded border bg-light flex-shrink-0 d-flex align-items-center justify-content-center text-muted" style="width: 44px; height: 44px; font-size: 1rem;">
|
|
<i class="fas fa-wrench"></i>
|
|
</div>
|
|
<% } %>
|
|
|
|
<div class="overflow-hidden">
|
|
<div class="fw-bold text-dark tool-name text-truncate" style="font-size: 0.88rem;"><%= h.nombre %></div>
|
|
<div class="text-muted small text-truncate" style="font-size: 0.75rem;">
|
|
<%= h.marca || '' %> <%= h.modelo ? `(${h.modelo})` : '' %>
|
|
<% if (h.numero_serie) { %>
|
|
• <span class="font-monospace">SN: <%= h.numero_serie %></span>
|
|
<% } %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex-shrink-0 text-end">
|
|
<span class="badge bg-light text-muted border font-monospace" style="font-size: 0.68rem;"><%= h.codigo || 'HERR-' + h.id %></span>
|
|
<% if (h.estado === 'operativo') { %>
|
|
<div class="badge bg-success-subtle text-success border border-success-subtle p-1 mt-1 d-block" style="font-size: 0.62rem;">Operativa</div>
|
|
<% } else { %>
|
|
<div class="badge bg-warning-subtle text-dark border p-1 mt-1 d-block" style="font-size: 0.62rem;"><%= h.estado %></div>
|
|
<% } %>
|
|
</div>
|
|
</div>
|
|
<% }) %>
|
|
</div>
|
|
|
|
<!-- Botones de Acción -->
|
|
<div class="mt-4 pt-3 border-top d-flex flex-wrap align-items-center justify-content-between gap-2">
|
|
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="reiniciarChecklist()">
|
|
<i class="fas fa-rotate-left me-1"></i> Reiniciar Checklist
|
|
</button>
|
|
<button type="button" class="btn btn-primary btn-sm px-3 shadow-sm" onclick="window.location.reload()">
|
|
<i class="fas fa-arrows-rotate me-1"></i> Actualizar Estado
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<footer class="text-center text-muted small mt-3" style="font-size: 0.75rem;">
|
|
Sistema Help Desk & FSM • Telcotronics Ecosystem<br>
|
|
<span class="text-secondary font-monospace">Token Seguro: <%= set.qr_token %></span>
|
|
</footer>
|
|
</div>
|
|
|
|
<script>
|
|
function toggleToolCheck(rowElement) {
|
|
const checkbox = rowElement.querySelector('input[type="checkbox"]');
|
|
if (event.target !== checkbox) {
|
|
checkbox.checked = !checkbox.checked;
|
|
}
|
|
if (checkbox.checked) {
|
|
rowElement.classList.add('checked');
|
|
} else {
|
|
rowElement.classList.remove('checked');
|
|
}
|
|
actualizarContador();
|
|
}
|
|
|
|
function actualizarContador() {
|
|
const total = document.querySelectorAll('.tool-item').length;
|
|
const marcados = document.querySelectorAll('.tool-item input[type="checkbox"]:checked').length;
|
|
const badge = document.getElementById('contadorChecklist');
|
|
if (badge) {
|
|
badge.textContent = `${marcados} / ${total} verificadas`;
|
|
if (marcados === total && total > 0) {
|
|
badge.className = 'badge bg-success font-monospace';
|
|
} else {
|
|
badge.className = 'badge bg-light text-muted border font-monospace';
|
|
}
|
|
}
|
|
}
|
|
|
|
function reiniciarChecklist() {
|
|
document.querySelectorAll('.tool-item').forEach(el => {
|
|
el.classList.remove('checked');
|
|
const cb = el.querySelector('input[type="checkbox"]');
|
|
if (cb) cb.checked = false;
|
|
});
|
|
actualizarContador();
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|