This commit is contained in:
Lizandro Guarnizo
2026-02-03 21:30:55 -05:00
parent 44423adb32
commit 1aae148396
89 changed files with 8581 additions and 7687 deletions
+640 -26
View File
@@ -30,8 +30,10 @@ try {
<title>WhatsApp Bot Manager</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.3.0/dist/select2-bootstrap-5-theme.min.css" rel="stylesheet" />
<link href="./assets/css/styles.css?v=11" rel="stylesheet">
<link href="./assets/css/diagnostic.css?v=10" rel="stylesheet">
<link href="./assets/css/diagnostic.css?v=11" rel="stylesheet">
</head>
<body>
@@ -45,7 +47,10 @@ try {
<li><a href="#conversations" class="nav-link" data-tab="conversations"><i class="fas fa-comments"></i> Conversaciones <span id="conversations-count" class="sidebar-badge badge bg-danger" style="display:none; font-size:0.72rem; padding:0.15rem 0.4rem;">0</span></a></li>
<li><a href="#users" class="nav-link" data-tab="users"><i class="fas fa-users"></i> Usuarios</a></li>
<li><a href="#menus" class="nav-link" data-tab="menus"><i class="fas fa-list"></i> Menús</a></li>
<li><a href="#admin_users" class="nav-link" data-tab="admin_users"><i class="fas fa-user-shield"></i> Usuarios del Sistema</a></li>
<li><a href="#send_message" class="nav-link" data-tab="send_message"><i class="fas fa-paper-plane"></i> Enviar Mensaje</a></li>
<li><a href="#broadcast" class="nav-link" data-tab="broadcast"><i class="fas fa-broadcast-tower"></i> Envío Masivo <span class="badge bg-success ms-1">NUEVO</span></a></li>
<li><a href="scheduled_messages.php" class="nav-link"><i class="fas fa-clock"></i> Mensajes Programados</a></li>
<li><a href="#templates" class="nav-link" data-tab="templates"><i class="fas fa-file-text"></i> Plantillas</a></li>
<li><a href="#autoresponses" class="nav-link" data-tab="autoresponses"><i class="fas fa-robot"></i> Respuestas Auto</a></li>
<li><a href="#system_config" class="nav-link" data-tab="system_config"><i class="fas fa-cog"></i> Configuración</a></li>
@@ -236,6 +241,22 @@ try {
</button>
</div>
<div class="card-body">
<!-- Búsqueda de usuarios -->
<div class="mb-3">
<div class="input-group">
<span class="input-group-text">
<i class="fas fa-search"></i>
</span>
<input
type="text"
class="form-control"
id="users-search"
placeholder="Buscar por teléfono, nombre o email..."
onkeyup="searchUsers()"
>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
@@ -254,6 +275,9 @@ try {
</tbody>
</table>
</div>
<!-- Paginación -->
<div id="users-pagination"></div>
</div>
</div>
</div>
@@ -290,6 +314,46 @@ try {
</div>
</div>
<!-- Admin Users Tab -->
<div id="admin_users" class="tab-content">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-user-shield"></i> Usuarios del Sistema</h5>
<button class="btn btn-primary" onclick="showCreateAdminUserModal()">
<i class="fas fa-plus"></i> Nuevo Usuario
</button>
</div>
<div class="card-body">
<div class="alert alert-info mb-3">
<i class="fas fa-info-circle"></i>
Gestiona los usuarios administradores que tienen acceso al sistema.
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Usuario</th>
<th>Nombre Completo</th>
<th>Email</th>
<th>Estado</th>
<th>Último Acceso</th>
<th>Fecha Creación</th>
<th>Acciones</th>
</tr>
</thead>
<tbody id="admin-users-table">
<tr>
<td colspan="7" class="text-center">
<i class="fas fa-spinner fa-spin"></i> Cargando usuarios...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- conversations Tab -->
<div id="send_message" class="tab-content">
<div class="row">
@@ -336,10 +400,26 @@ try {
</div>
<div class="mb-3" id="template-group" style="display: none;">
<label class="form-label">Plantilla</label>
<select class="form-control" id="message-template">
<select class="form-control" id="message-template" onchange="loadMessageTemplateDetails()">
<option value="">Seleccionar plantilla...</option>
</select>
</div>
<!-- Variables de la plantilla -->
<div id="message-template-variables" class="mb-3" style="display: none;">
<!-- Se llenarán dinámicamente -->
</div>
<!-- Preview de la plantilla -->
<div id="message-template-preview" class="mb-3" style="display: none;">
<label class="form-label"><i class="fas fa-eye"></i> Vista Previa</label>
<div class="card bg-light">
<div class="card-body">
<div id="message-preview-content"></div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-paper-plane"></i> Enviar Mensaje
</button>
@@ -348,33 +428,154 @@ try {
</div>
</div>
</div>
<div class="col-lg-6" id="broadcast-section" style="display:none;">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-broadcast-tower"></i> Mensaje Masivo (oculto)</h5>
</div>
</div>
<!-- Broadcast Tab -->
<div id="broadcast" class="tab-content">
<div class="row">
<div class="col-lg-8 mx-auto">
<div class="card shadow-lg">
<div class="card-header bg-warning text-white">
<h4 class="mb-0"><i class="fas fa-broadcast-tower"></i> Envío Masivo de Mensajes</h4>
</div>
<div class="card-body">
<form id="broadcast-form">
<div class="mb-3">
<label class="form-label">Filtro de Usuarios</label>
<select class="form-control" id="broadcast-filter">
<option value="all">Todos los usuarios</option>
<option value="active">Solo usuarios activos</option>
<option value="recent">Usuarios recientes (30 días)</option>
<div class="alert alert-success mb-4">
<i class="fas fa-check-circle"></i>
<strong>¡Envío Masivo Activo!</strong> Ahora puedes enviar mensajes a múltiples usuarios simultáneamente.
</div>
<form id="broadcast-form" onsubmit="return handleBroadcastSubmit(event)">
<div class="mb-4">
<label class="form-label fw-bold">
<i class="fas fa-filter"></i> Tipo de Selección
</label>
<select class="form-control form-control-lg" id="broadcast-selection-type" onchange="toggleBroadcastSelectionType()">
<option value="filter">📋 Por filtro de usuarios</option>
<option value="specific">👥 Usuarios específicos</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Mensaje</label>
<textarea class="form-control" id="broadcast-message" rows="4" placeholder="Mensaje para envío masivo..."></textarea>
<!-- Filtro de usuarios -->
<div class="mb-4" id="broadcast-filter-container">
<label class="form-label fw-bold">
<i class="fas fa-filter"></i> Filtro de Usuarios
</label>
<select class="form-control form-control-lg" id="broadcast-filter">
<option value="all">📋 Todos los usuarios activos</option>
<option value="active">🔥 Solo usuarios con conversaciones recientes (7 días)</option>
<option value="recent">✨ Usuarios recientes (30 días)</option>
</select>
<small class="form-text text-muted">
<i class="fas fa-info-circle"></i> Selecciona qué usuarios recibirán el mensaje
</small>
</div>
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle"></i>
<strong>Cuidado:</strong> Este mensaje se enviará a múltiples usuarios.
<!-- Selección específica de usuarios -->
<div class="mb-4" id="broadcast-users-container" style="display: none;">
<label class="form-label fw-bold">
<i class="fas fa-users"></i> Seleccionar Usuarios
</label>
<select class="form-control" id="broadcast-users" multiple="multiple">
<!-- Opciones cargadas dinámicamente -->
</select>
<small class="form-text text-muted">
<i class="fas fa-info-circle"></i> Selecciona uno o más usuarios para enviar el mensaje
</small>
</div>
<div class="mb-4">
<label class="form-label fw-bold">
<i class="fas fa-envelope"></i> Tipo de Mensaje
</label>
<select class="form-control form-control-lg" id="broadcast-message-type" onchange="toggleBroadcastMessageType()">
<option value="text">📝 Mensaje de texto</option>
<option value="template">📋 Plantilla de WhatsApp</option>
</select>
</div>
<!-- Mensaje de texto -->
<div class="mb-4" id="broadcast-text-container">
<label class="form-label fw-bold">
<i class="fas fa-comment-dots"></i> Mensaje
</label>
<textarea
class="form-control"
id="broadcast-message"
rows="6"
placeholder="Escribe el mensaje que deseas enviar a todos los usuarios...
Ejemplo:
¡Hola! 👋 Tenemos una promoción especial para ti..."
maxlength="4096"></textarea>
<div class="d-flex justify-content-between mt-2">
<small class="form-text text-muted">
<i class="fas fa-keyboard"></i> Máximo 4096 caracteres
</small>
<small class="form-text text-muted">
<span id="char-count">0</span> / 4096
</small>
</div>
</div>
<!-- Selección de plantilla -->
<div class="mb-4" id="broadcast-template-container" style="display: none;">
<label class="form-label fw-bold">
<i class="fas fa-file-text"></i> Seleccionar Plantilla
</label>
<select class="form-control form-control-lg" id="broadcast-template" onchange="loadBroadcastTemplateDetails()">
<option value="">-- Selecciona una plantilla --</option>
</select>
<small class="form-text text-muted">
<i class="fas fa-info-circle"></i> Solo plantillas aprobadas
</small>
</div>
<!-- Variables de plantilla -->
<div id="broadcast-template-variables" class="mb-4" style="display: none;">
<!-- Variables dinámicas -->
</div>
<!-- Vista previa de plantilla -->
<div id="broadcast-template-preview" class="mb-4" style="display: none;">
<label class="form-label fw-bold">
<i class="fas fa-eye"></i> Vista Previa
</label>
<div class="alert alert-info" id="broadcast-preview-content">
<!-- Contenido de vista previa -->
</div>
</div>
<div class="alert alert-warning d-flex align-items-center">
<i class="fas fa-exclamation-triangle fa-2x me-3"></i>
<div>
<strong>Importante:</strong> Este mensaje se enviará a múltiples usuarios.
<br>Verifica cuidadosamente el contenido antes de enviar.
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-warning btn-lg">
<i class="fas fa-broadcast-tower"></i> Enviar Mensaje Masivo
</button>
</div>
<button type="submit" class="btn btn-warning">
<i class="fas fa-broadcast-tower"></i> Envío Masivo
</button>
</form>
<div class="mt-4">
<div class="card bg-light">
<div class="card-body">
<h6 class="fw-bold"><i class="fas fa-lightbulb text-warning"></i> Consejos para envío masivo:</h6>
<ul class="mb-0 small">
<li>Personaliza tu mensaje para que sea relevante</li>
<li>Evita enviar mensajes muy frecuentes</li>
<li>Respeta la ventana de 24 horas de WhatsApp</li>
<li>Usa plantillas aprobadas para nuevos contactos</li>
<li>Prueba con un grupo pequeño primero</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -386,11 +587,24 @@ try {
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-file-text"></i> Plantillas de Mensaje</h5>
<button class="btn btn-primary" id="btn-new-template" onclick="showCreateTemplateModal()">
<i class="fas fa-plus"></i> Nueva Plantilla
</button>
<div>
<button class="btn btn-success" id="btn-sync-templates" onclick="syncTemplatesFromFacebook()">
<i class="fas fa-sync-alt"></i> Sincronizar desde Facebook
</button>
</div>
</div>
<div class="card-body">
<!-- Mensaje informativo sobre creación de plantillas -->
<div class="alert alert-info" role="alert">
<h6 class="alert-heading"><i class="fas fa-info-circle"></i> ¿Cómo crear nuevas plantillas?</h6>
<p class="mb-2">Las plantillas de WhatsApp deben crearse directamente en el Administrador de Meta Business.</p>
<p class="mb-3">Una vez creadas y aprobadas por Meta, puedes sincronizarlas aquí usando el botón "Sincronizar desde Facebook".</p>
<a href="https://business.facebook.com/latest/whatsapp_manager/message_templates?business_id=2144688622601603"
class="btn btn-primary btn-sm" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt"></i> Ir al Administrador de Plantillas de Meta
</a>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
@@ -462,6 +676,11 @@ try {
<label class="form-label">Phone Number ID</label>
<input type="text" class="form-control" id="phone-number-id" placeholder="ID del número de teléfono">
</div>
<div class="mb-3">
<label class="form-label">Business Account ID (WABA ID)</label>
<input type="text" class="form-control" id="business-account-id" placeholder="ID de la cuenta de WhatsApp Business">
<small class="form-text text-muted">Necesario para sincronizar plantillas desde Facebook</small>
</div>
<div class="mb-3">
<label class="form-label">Webhook Verify Token</label>
<input type="text" class="form-control" id="webhook-token" placeholder="Token de verificación del webhook">
@@ -667,10 +886,104 @@ try {
</div>
</div>
<!-- Modal para crear/editar usuario administrador -->
<div class="modal fade" id="adminUserModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="adminUserModalLabel">
<i class="fas fa-user-shield"></i> <span id="admin-user-modal-title">Nuevo Usuario</span>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="admin-user-form">
<input type="hidden" id="admin-user-id">
<div class="mb-3">
<label class="form-label">Nombre de Usuario *</label>
<input type="text" class="form-control" id="admin-username" required
placeholder="usuario123">
<small class="text-muted">Usado para iniciar sesión</small>
</div>
<div class="mb-3">
<label class="form-label">Nombre Completo</label>
<input type="text" class="form-control" id="admin-fullname"
placeholder="Juan Pérez">
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" id="admin-email"
placeholder="usuario@ejemplo.com">
</div>
<div class="mb-3" id="password-group">
<label class="form-label">Contraseña *</label>
<input type="password" class="form-control" id="admin-password"
placeholder="Mínimo 6 caracteres">
<small class="text-muted">Mínimo 6 caracteres</small>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="fas fa-times"></i> Cancelar
</button>
<button type="button" class="btn btn-primary" onclick="saveAdminUser()">
<i class="fas fa-save"></i> Guardar
</button>
</div>
</div>
</div>
</div>
<!-- Modal para cambiar contraseña -->
<div class="modal fade" id="changePasswordModal" tabindex="-1">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-key"></i> Cambiar Contraseña
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="change-password-user-id">
<p class="mb-3">Usuario: <strong id="change-password-username"></strong></p>
<div class="mb-3">
<label class="form-label">Nueva Contraseña *</label>
<input type="password" class="form-control" id="new-password"
placeholder="Mínimo 6 caracteres" required>
<small class="text-muted">Mínimo 6 caracteres</small>
</div>
<div class="mb-3">
<label class="form-label">Confirmar Contraseña *</label>
<input type="password" class="form-control" id="confirm-password"
placeholder="Repite la contraseña" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="fas fa-times"></i> Cancelar
</button>
<button type="button" class="btn btn-primary" onclick="saveNewPassword()">
<i class="fas fa-key"></i> Cambiar Contraseña
</button>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="./assets/js/app_simple.js?v=14"></script>
<script src="./assets/js/app_simple.js?v=18"></script>
<script>
// Función de diagnóstico mejorada
function runDiagnostic() {
@@ -1192,9 +1505,310 @@ try {
}
};
// ====== Funciones para Broadcast con Plantillas y Múltiples Usuarios ======
// Manejador del formulario de broadcast
async function handleBroadcastSubmit(event) {
event.preventDefault();
event.stopPropagation();
console.log('Formulario de broadcast enviado');
// Validar que existe el manager
if (!window.whatsappManager || !window.whatsappManager.sendBroadcast) {
console.error('whatsappManager no disponible');
alert('Error: Sistema no inicializado. Recarga la página.');
return false;
}
// Validar variables de plantilla si se seleccionó plantilla
const messageType = document.getElementById('broadcast-message-type').value;
if (messageType === 'template') {
const templateId = document.getElementById('broadcast-template').value;
if (!templateId) {
alert('Por favor selecciona una plantilla');
return false;
}
// Validar que las variables requeridas estén llenas
const varInputs = document.querySelectorAll('.broadcast-template-var');
let hasEmpty = false;
varInputs.forEach(input => {
if (!input.value.trim()) {
input.classList.add('is-invalid');
hasEmpty = true;
} else {
input.classList.remove('is-invalid');
}
});
if (hasEmpty) {
alert('Por favor completa todos los campos de variables de la plantilla');
return false;
}
}
// Llamar al método del manager
await window.whatsappManager.sendBroadcast();
return false;
}
function initializeBroadcastSelect2() {
// Inicializar Select2 para usuarios con transport personalizado
$('#broadcast-users').select2({
theme: 'bootstrap-5',
placeholder: 'Buscar y seleccionar usuarios...',
allowClear: true,
ajax: {
transport: function (params, success, failure) {
const searchTerm = params.data.term || '';
const page = params.data.page || 1;
fetch(`api/get_users.php?search=${encodeURIComponent(searchTerm)}&page=${page}&limit=50`, {
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
success(data);
} else {
failure();
}
})
.catch(error => {
console.error('Error cargando usuarios:', error);
failure();
});
},
delay: 250,
processResults: function (data, params) {
params.page = params.page || 1;
if (!data || !data.data) {
return { results: [] };
}
return {
results: data.data.map(user => ({
id: user.id,
text: `${user.name || 'Sin nombre'} (${user.phone_number})`
})),
pagination: {
more: data.pagination && data.pagination.hasNext
}
};
},
cache: true
},
minimumInputLength: 0
});
// Cargar plantillas aprobadas
loadBroadcastTemplates();
}
function toggleBroadcastSelectionType() {
const selectionType = document.getElementById('broadcast-selection-type').value;
const filterContainer = document.getElementById('broadcast-filter-container');
const usersContainer = document.getElementById('broadcast-users-container');
if (selectionType === 'filter') {
filterContainer.style.display = 'block';
usersContainer.style.display = 'none';
} else {
filterContainer.style.display = 'none';
usersContainer.style.display = 'block';
}
}
function toggleBroadcastMessageType() {
const messageType = document.getElementById('broadcast-message-type').value;
const textContainer = document.getElementById('broadcast-text-container');
const templateContainer = document.getElementById('broadcast-template-container');
if (messageType === 'text') {
textContainer.style.display = 'block';
templateContainer.style.display = 'none';
document.getElementById('broadcast-template-variables').style.display = 'none';
document.getElementById('broadcast-template-preview').style.display = 'none';
} else {
textContainer.style.display = 'none';
templateContainer.style.display = 'block';
}
}
async function loadBroadcastTemplates() {
try {
console.log('🔵 Cargando plantillas para broadcast...');
if (!window.whatsappManager) {
console.error('❌ whatsappManager no está disponible');
return;
}
const response = await window.whatsappManager.apiCall('get_templates.php');
console.log('Respuesta de get_templates:', response);
if (response && response.success && response.data) {
const select = document.getElementById('broadcast-template');
if (!select) {
console.error('Elemento broadcast-template no encontrado');
return;
}
select.innerHTML = '<option value="">-- Selecciona una plantilla --</option>';
const approvedTemplates = response.data.filter(t =>
t.status && (t.status.toUpperCase() === 'APPROVED' || t.status.toLowerCase() === 'approved')
);
console.log('Plantillas aprobadas encontradas:', approvedTemplates.length);
approvedTemplates.forEach(template => {
const option = document.createElement('option');
option.value = template.id;
option.textContent = `${template.name} (${template.language_code || template.language || 'es'})`;
option.dataset.templateId = template.id;
select.appendChild(option);
});
if (approvedTemplates.length === 0) {
console.warn('No hay plantillas aprobadas disponibles');
select.innerHTML = '<option value="">No hay plantillas aprobadas</option>';
}
} else {
console.error('Respuesta inválida del API:', response);
}
} catch (error) {
console.error('Error cargando plantillas:', error);
}
}
async function loadBroadcastTemplateDetails() {
console.log('🔵 loadBroadcastTemplateDetails llamado');
const select = document.getElementById('broadcast-template');
const templateId = select.value;
console.log('Template ID seleccionado:', templateId);
if (!templateId) {
document.getElementById('broadcast-template-variables').style.display = 'none';
document.getElementById('broadcast-template-preview').style.display = 'none';
return;
}
try {
const response = await window.whatsappManager.apiCall(`get_template_details.php?id=${templateId}`);
console.log('✅ Detalles de plantilla:', response);
if (response && response.success) {
const template = response.template || response.data;
if (!template) {
console.error('❌ No se encontró template en la respuesta');
return;
}
console.log('📋 Template data:', template);
console.log('📋 Variables:', template.variables);
const variablesContainer = document.getElementById('broadcast-template-variables');
if (template.variables && template.variables.length > 0) {
console.log(`✅ Se encontraron ${template.variables.length} variables`);
let html = '<label class="form-label fw-bold"><i class="fas fa-edit"></i> Variables de la Plantilla</label>';
template.variables.forEach((variable, index) => {
console.log(`Variable ${index}:`, variable);
const placeholder = variable.example || `Valor para Variable ${variable.index}`;
const label = variable.label || `Variable ${variable.index}`;
html += `
<div class="mb-2">
<label class="form-label small">${label}</label>
<input
type="text"
class="form-control broadcast-template-var"
data-var="${variable.index}"
data-placeholder="${variable.placeholder}"
placeholder="${placeholder}"
onkeyup="updateBroadcastPreview()"
>
</div>
`;
});
console.log('📝 HTML generado para variables:', html);
variablesContainer.innerHTML = html;
variablesContainer.style.display = 'block';
console.log('✅ Variables container mostrado');
} else {
console.log('⚠️ Template sin variables');
variablesContainer.innerHTML = '<p class="text-muted small">Esta plantilla no tiene variables</p>';
variablesContainer.style.display = 'block';
}
updateBroadcastPreview();
} else {
console.error('❌ Respuesta sin success:', response);
}
} catch (error) {
console.error('❌ Error cargando detalles de plantilla:', error);
window.whatsappManager.showError('Error cargando plantilla');
}
}
async function updateBroadcastPreview() {
const templateId = document.getElementById('broadcast-template').value;
if (!templateId) return;
// Recolectar variables como array (por índice)
const variablesArray = [];
document.querySelectorAll('.broadcast-template-var').forEach(input => {
const index = parseInt(input.dataset.var) - 1; // Convertir a índice de array (0-based)
variablesArray[index] = input.value || `{{${input.dataset.var}}}`;
});
try {
const response = await window.whatsappManager.apiCall('preview_template.php', {
method: 'POST',
body: { template_id: templateId, parameters: variablesArray }
});
if (response && response.success && response.preview) {
const previewContainer = document.getElementById('broadcast-template-preview');
const previewContent = document.getElementById('broadcast-preview-content');
// Usar el HTML pre-formateado del servidor
previewContent.innerHTML = response.preview.html || response.preview.body.replace(/\n/g, '<br>');
previewContainer.style.display = 'block';
} else {
console.error('Error en preview:', response);
}
} catch (error) {
console.error('Error generando vista previa:', error);
}
}
// ====== Fin de funciones de Broadcast ======
document.addEventListener('DOMContentLoaded', () => {
try { NotificationManager.init(); } catch(e) { console.error('NotificationManager init failed', e); }
// Inicializar Select2 para broadcast cuando el manager esté listo
const waitForManager = setInterval(() => {
if (window.whatsappManager) {
clearInterval(waitForManager);
console.log('Inicializando broadcast Select2...');
try {
initializeBroadcastSelect2();
} catch(e) {
console.error('Error inicializando broadcast Select2:', e);
}
}
}, 100);
// Timeout de seguridad
setTimeout(() => clearInterval(waitForManager), 5000);
// Sidebar toggle logic for responsive/mobile
const sidebar = document.querySelector('.sidebar');
const toggleBtn = document.getElementById('sidebar-toggle');