221 lines
12 KiB
Plaintext
221 lines
12 KiB
Plaintext
<%- include('../partials/header') %>
|
|
<% title = 'Ticket #' + ticket.id + ' — ' + ticket.asunto; %>
|
|
|
|
<!-- Alertas Flash -->
|
|
<% if (success_msg && success_msg.length > 0) { %>
|
|
<% success_msg.forEach(msg => { %>
|
|
<div class="alert alert-success alert-dismissible fade show rounded-3 border-0 shadow-sm mb-3" role="alert">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-check-circle me-2 fs-5 text-success"></i>
|
|
<div><%= msg %></div>
|
|
</div>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
<% }) %>
|
|
<% } %>
|
|
<% if (error_msg && error_msg.length > 0) { %>
|
|
<% error_msg.forEach(msg => { %>
|
|
<div class="alert alert-danger alert-dismissible fade show rounded-3 border-0 shadow-sm mb-3" role="alert">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-exclamation-triangle me-2 fs-5 text-danger"></i>
|
|
<div><%= msg %></div>
|
|
</div>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
<% }) %>
|
|
<% } %>
|
|
|
|
<!-- Cabecera del Ticket -->
|
|
<div class="page-header d-flex flex-wrap justify-content-between align-items-center gap-3 mb-4">
|
|
<div>
|
|
<div class="d-flex flex-wrap align-items-center gap-2 mb-1">
|
|
<span class="badge bg-light text-dark border px-2.5 py-1.5 fw-bold" style="font-size: 0.85rem;">Ticket #<%= ticket.id %></span>
|
|
<h1 class="page-title h3 mb-0"><%= ticket.asunto %></h1>
|
|
</div>
|
|
<div class="d-flex flex-wrap align-items-center gap-2 text-muted small">
|
|
<span><i class="far fa-calendar-alt me-1"></i><%= new Date(ticket.created_at).toLocaleString('es-ES') %></span>
|
|
<span>•</span>
|
|
<span><i class="fas fa-folder me-1"></i><%= ticket.departamento_nombre || 'Soporte General' %></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex align-items-center gap-2">
|
|
<% if (ticket.status !== 'cerrado') { %>
|
|
<form action="/client/ticket/<%= ticket.id %>/close" method="POST" style="display:inline">
|
|
<button type="submit" class="btn btn-outline-warning btn-sm d-inline-flex align-items-center gap-1.5 rounded-pill px-3" onclick="return confirm('¿Confirmas dar por resuelto y cerrar este ticket?')">
|
|
<i class="fas fa-check"></i>
|
|
<span>Cerrar Ticket</span>
|
|
</button>
|
|
</form>
|
|
<% } %>
|
|
<a href="/client/dashboard" class="btn btn-outline-secondary btn-sm d-inline-flex align-items-center gap-1.5 rounded-pill px-3">
|
|
<i class="fas fa-arrow-left"></i>
|
|
<span>Volver</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<!-- Columna Izquierda: Información de Ficha -->
|
|
<div class="col-lg-4 order-lg-2">
|
|
<div class="app-card mb-3">
|
|
<div class="app-card-header p-3 border-bottom d-flex align-items-center justify-content-between">
|
|
<h6 class="mb-0 fw-bold" style="font-size: 0.88rem;">
|
|
<i class="fas fa-info-circle text-primary me-1.5"></i> Ficha del Ticket
|
|
</h6>
|
|
</div>
|
|
<div class="card-body p-3">
|
|
<div class="ticket-meta-item mb-2.5">
|
|
<span class="text-muted small d-block">Estado de Atención:</span>
|
|
<% if (ticket.status === 'abierto') { %>
|
|
<span class="status-pill status-abierto mt-1"><span class="status-dot"></span>Abierto</span>
|
|
<% } else if (ticket.status === 'en_progreso') { %>
|
|
<span class="status-pill status-en-progreso mt-1"><span class="status-dot"></span>En Progreso</span>
|
|
<% } else { %>
|
|
<span class="status-pill status-cerrado mt-1"><span class="status-dot"></span>Cerrado</span>
|
|
<% } %>
|
|
</div>
|
|
|
|
<div class="ticket-meta-item mb-2.5">
|
|
<span class="text-muted small d-block">Prioridad:</span>
|
|
<% if (ticket.prioridad === 'critica') { %>
|
|
<span class="priority-pill priority-critica mt-1"><i class="fas fa-fire me-1"></i>Crítica</span>
|
|
<% } else if (ticket.prioridad === 'alta') { %>
|
|
<span class="priority-pill priority-alta mt-1"><i class="fas fa-exclamation-circle me-1"></i>Alta</span>
|
|
<% } else if (ticket.prioridad === 'media') { %>
|
|
<span class="priority-pill priority-media mt-1"><i class="fas fa-minus-circle me-1"></i>Media</span>
|
|
<% } else { %>
|
|
<span class="priority-pill priority-baja mt-1"><i class="fas fa-arrow-down me-1"></i>Baja</span>
|
|
<% } %>
|
|
</div>
|
|
|
|
<div class="ticket-meta-item mb-2.5">
|
|
<span class="text-muted small d-block">Especialista Asignado:</span>
|
|
<div class="fw-semibold text-dark mt-1 d-flex align-items-center gap-1.5" style="font-size: 0.84rem;">
|
|
<i class="fas fa-user-shield text-indigo" style="color: #4f46e5;"></i>
|
|
<span><%= ticket.asignado_nombre || 'En asignación de guardia' %></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ticket-meta-item">
|
|
<span class="text-muted small d-block">Solicitante:</span>
|
|
<div class="fw-medium text-dark mt-1" style="font-size: 0.84rem;">
|
|
<%= ticket.usuario_nombre %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Asistencia Rápida -->
|
|
<div class="app-card p-3 text-center bg-light border">
|
|
<img src="/img/bot-soporte.svg" alt="Bot Soporte" width="46" height="46" class="mb-2">
|
|
<div class="fw-bold text-dark" style="font-size: 0.8rem;">¿Requieres añadir más detalles?</div>
|
|
<small class="text-muted d-block" style="font-size: 0.72rem;">Usa la caja de comentarios abajo para enviar mensajes directamente al técnico.</small>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Columna Derecha: Hilo de Conversación -->
|
|
<div class="col-lg-8 order-lg-1">
|
|
|
|
<!-- Mensaje Original del Cliente -->
|
|
<div class="app-card mb-4 border-start border-4 border-primary">
|
|
<div class="app-card-header p-3 bg-light border-bottom d-flex align-items-center justify-content-between">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="user-avatar-initials-sm bg-primary text-white">
|
|
<%= (ticket.usuario_nombre || 'C').charAt(0).toUpperCase() %>
|
|
</div>
|
|
<div>
|
|
<span class="fw-bold text-dark" style="font-size: 0.85rem;"><%= ticket.usuario_nombre %></span>
|
|
<span class="badge bg-primary-subtle text-primary border border-primary-subtle ms-1" style="font-size: 0.68rem;">Autor del Ticket</span>
|
|
</div>
|
|
</div>
|
|
<small class="text-muted" style="font-size: 0.72rem;"><%= new Date(ticket.created_at).toLocaleString('es-ES') %></small>
|
|
</div>
|
|
<div class="card-body p-3 p-md-4">
|
|
<div class="ticket-description-body" style="white-space: pre-line; font-size: 0.92rem; line-height: 1.6;">
|
|
<%= ticket.mensaje %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hilo de Respuestas -->
|
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
|
<h5 class="fw-bold mb-0 text-dark" style="font-size: 0.95rem;">
|
|
<i class="fas fa-comments text-primary me-1.5"></i> Hilo de Conversación (<%= respuestas.length %>)
|
|
</h5>
|
|
</div>
|
|
|
|
<% if (respuestas.length === 0) { %>
|
|
<div class="app-card p-4 text-center mb-4 bg-light border">
|
|
<i class="far fa-clock text-muted fs-3 mb-2"></i>
|
|
<h6 class="fw-semibold text-secondary">Aún no hay respuestas en este ticket</h6>
|
|
<small class="text-muted">Un agente técnico revisará tu solicitud a la brevedad posible.</small>
|
|
</div>
|
|
<% } %>
|
|
|
|
<div class="conversation-thread mb-4 d-flex flex-column gap-3">
|
|
<% respuestas.forEach(r => { %>
|
|
<% const isStaff = ['agent', 'admin', 'superadmin'].includes(r.usuario_rol); %>
|
|
<div class="ticket-message-card <%= isStaff ? 'message-staff' : 'message-client' %>">
|
|
<div class="message-card-header d-flex align-items-center justify-content-between p-2.5 px-3 border-bottom">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="user-avatar-initials-sm <%= isStaff ? 'bg-indigo text-white' : 'bg-secondary text-white' %>" style="<%= isStaff ? 'background: #4f46e5;' : '' %>">
|
|
<%= (r.usuario_nombre || 'U').charAt(0).toUpperCase() %>
|
|
</div>
|
|
<div>
|
|
<span class="fw-bold text-dark" style="font-size: 0.84rem;"><%= r.usuario_nombre %></span>
|
|
<% if (isStaff) { %>
|
|
<span class="badge bg-indigo-subtle text-indigo border ms-1" style="font-size: 0.68rem; color: #4f46e5; border-color: rgba(79,70,229,0.2) !important;">
|
|
<i class="fas fa-shield-alt me-0.5"></i> Soporte Oficial
|
|
</span>
|
|
<% } else { %>
|
|
<span class="badge bg-secondary-subtle text-secondary border ms-1" style="font-size: 0.68rem;">Cliente</span>
|
|
<% } %>
|
|
</div>
|
|
</div>
|
|
<small class="text-muted" style="font-size: 0.72rem;">
|
|
<%= new Date(r.created_at).toLocaleString('es-ES') %>
|
|
</small>
|
|
</div>
|
|
<div class="message-card-body p-3">
|
|
<div style="white-space: pre-line; font-size: 0.90rem; line-height: 1.55;">
|
|
<%= r.mensaje %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% }) %>
|
|
</div>
|
|
|
|
<!-- Caja de Respuesta -->
|
|
<% if (ticket.status !== 'cerrado') { %>
|
|
<div class="app-card border shadow-sm">
|
|
<div class="app-card-header p-3 border-bottom d-flex align-items-center gap-2">
|
|
<i class="fas fa-reply text-primary"></i>
|
|
<h6 class="mb-0 fw-bold" style="font-size: 0.88rem;">Añadir Respuesta o Información Adicional</h6>
|
|
</div>
|
|
<div class="card-body p-3 p-md-4">
|
|
<form action="/client/ticket/<%= ticket.id %>/respond" method="POST">
|
|
<div class="mb-3">
|
|
<textarea name="mensaje" class="form-control" rows="4" placeholder="Escribe aquí tu respuesta, confirmación o detalle adicional para el equipo técnico..." required></textarea>
|
|
</div>
|
|
<div class="d-flex justify-content-end">
|
|
<button type="submit" class="btn btn-primary btn-cta d-inline-flex align-items-center gap-2 shadow-sm">
|
|
<i class="fas fa-paper-plane"></i>
|
|
<span>Enviar Mensaje</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<% } else { %>
|
|
<div class="alert alert-secondary d-flex align-items-center gap-2 rounded-3 border">
|
|
<i class="fas fa-lock fs-5"></i>
|
|
<div>Este ticket se encuentra cerrado. Si experimentas una nueva incidencia, por favor abre un nuevo ticket.</div>
|
|
</div>
|
|
<% } %>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<%- include('../partials/footer') %>
|