Cambios
This commit is contained in:
@@ -663,6 +663,44 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Historial de Envíos Masivos -->
|
||||
<div class="card mt-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0"><i class="fas fa-history me-2 text-secondary"></i>Historial de Envíos Masivos</h5>
|
||||
<button class="btn btn-sm btn-outline-secondary" onclick="loadBroadcastHistory(1)">
|
||||
<i class="fas fa-sync-alt"></i> Actualizar
|
||||
</button>
|
||||
</div>
|
||||
<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>Fecha</th>
|
||||
<th>Tipo</th>
|
||||
<th>Mensaje / Plantilla</th>
|
||||
<th class="text-center">Total</th>
|
||||
<th class="text-center text-success">Enviados</th>
|
||||
<th class="text-center text-danger">Errores</th>
|
||||
<th>Enviado por</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="broadcast-history-tbody">
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-muted py-4">
|
||||
<i class="fas fa-spinner fa-spin me-1"></i> Cargando historial...
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="bh-pagination-row" class="d-flex justify-content-between align-items-center px-3 py-2 border-top" style="display:none!important">
|
||||
<small class="text-muted" id="bh-pagination-info"></small>
|
||||
<div class="d-flex gap-1" id="bh-pagination-btns"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WhatsApp Profile Tab -->
|
||||
@@ -2191,6 +2229,88 @@ try {
|
||||
})();
|
||||
</script>
|
||||
<!-- ── / T&C Aceptaciones JS ─────────────────────────────────────────── -->
|
||||
|
||||
<!-- ── Historial Envíos Masivos JS ──────────────────────────────────── -->
|
||||
<script>
|
||||
(function () {
|
||||
let _currentPage = 1;
|
||||
|
||||
window.loadBroadcastHistory = function (page) {
|
||||
page = page || 1;
|
||||
_currentPage = page;
|
||||
|
||||
const tbody = document.getElementById('broadcast-history-tbody');
|
||||
if (!tbody) return;
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-muted py-3"><i class="fas fa-spinner fa-spin me-1"></i> Cargando...</td></tr>';
|
||||
|
||||
fetch('api/get_broadcast_history.php?page=' + page + '&per_page=10')
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
if (!res.success || !res.data) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-muted py-3">Sin registros</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.data.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center text-muted py-3"><i class="fas fa-inbox me-1"></i> Aún no hay envíos masivos registrados</td></tr>';
|
||||
} else {
|
||||
const typeLabels = { text: 'Texto', template: 'Plantilla', image: 'Imagen', document: 'Documento' };
|
||||
const filterLabels = { all: 'Todos', active: 'Activos', recent: 'Recientes', null: '—' };
|
||||
tbody.innerHTML = res.data.map(r => {
|
||||
const fecha = r.sent_at ? r.sent_at.replace('T', ' ').substring(0, 16) : '—';
|
||||
const tipo = typeLabels[r.message_type] || r.message_type || '—';
|
||||
const msg = r.template_name
|
||||
? '<span class="badge bg-success-subtle text-success border border-success-subtle me-1">Plantilla</span>' + htmlEsc(r.template_name)
|
||||
: (r.message_preview ? htmlEsc(r.message_preview.substring(0, 60)) + (r.message_preview.length > 60 ? '…' : '') : '—');
|
||||
const pct = r.total_users > 0 ? Math.round(r.sent_count / r.total_users * 100) : 0;
|
||||
return `<tr>
|
||||
<td class="small text-nowrap">${fecha}</td>
|
||||
<td><span class="badge bg-secondary-subtle text-secondary border">${tipo}</span></td>
|
||||
<td class="small">${msg}</td>
|
||||
<td class="text-center fw-bold">${r.total_users}</td>
|
||||
<td class="text-center text-success fw-bold">${r.sent_count} <small class="text-muted">(${pct}%)</small></td>
|
||||
<td class="text-center ${r.error_count > 0 ? 'text-danger fw-bold' : 'text-muted'}">${r.error_count}</td>
|
||||
<td class="small text-muted">${htmlEsc(r.sent_by_name || 'Sistema')}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// Paginación
|
||||
const pagRow = document.getElementById('bh-pagination-row');
|
||||
const pagInfo = document.getElementById('bh-pagination-info');
|
||||
const pagBtns = document.getElementById('bh-pagination-btns');
|
||||
if (pagRow && res.pages > 1) {
|
||||
pagRow.style.display = '';
|
||||
pagInfo.textContent = 'Página ' + res.page + ' de ' + res.pages + ' (' + res.total + ' registros)';
|
||||
let btns = '';
|
||||
for (let p = 1; p <= res.pages; p++) {
|
||||
btns += `<button class="btn btn-sm ${p === res.page ? 'btn-secondary' : 'btn-outline-secondary'}" onclick="loadBroadcastHistory(${p})">${p}</button>`;
|
||||
}
|
||||
pagBtns.innerHTML = btns;
|
||||
} else if (pagRow) {
|
||||
pagRow.style.display = 'none';
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (tbody) tbody.innerHTML = '<tr><td colspan="7" class="text-center text-danger py-3">Error al cargar el historial</td></tr>';
|
||||
console.error('loadBroadcastHistory error:', err);
|
||||
});
|
||||
};
|
||||
|
||||
function htmlEsc(str) {
|
||||
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
||||
}
|
||||
|
||||
// Cargar al activar el tab de broadcast
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const broadcastLinks = document.querySelectorAll('.nav-link[data-tab="broadcast"], [data-tab="broadcast"]');
|
||||
broadcastLinks.forEach(link => {
|
||||
link.addEventListener('click', () => setTimeout(() => loadBroadcastHistory(1), 100));
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<!-- ── / Historial Envíos Masivos JS ─────────────────────────────────── -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user