diff --git a/api/delete_autoresponse.php b/api/delete_autoresponse.php new file mode 100644 index 0000000..92d804c --- /dev/null +++ b/api/delete_autoresponse.php @@ -0,0 +1,70 @@ +fetchAll("SELECT id, trigger_type, trigger_value FROM autoresponses WHERE id = ?", [$id]); + + if (empty($existing)) { + throw new Exception('Respuesta automática no encontrada'); + } + + // Eliminar + $deleted = $db->execute("DELETE FROM autoresponses WHERE id = ?", [$id]); + + if ($deleted) { + echo json_encode([ + 'success' => true, + 'message' => 'Respuesta automática eliminada correctamente', + 'deleted_id' => $id, + 'deleted_data' => $existing[0] + ]); + } else { + throw new Exception('No se pudo eliminar la respuesta automática'); + } + +} catch (Exception $e) { + error_log("Error en delete_autoresponse.php: " . $e->getMessage()); + http_response_code(500); + echo json_encode([ + 'success' => false, + 'error' => $e->getMessage(), + 'debug' => $e->getTraceAsString() + ]); +} +?> \ No newline at end of file diff --git a/api/get_autoresponses.php b/api/get_autoresponses.php new file mode 100644 index 0000000..d82e2bf --- /dev/null +++ b/api/get_autoresponses.php @@ -0,0 +1,118 @@ +fetchAll("SHOW TABLES LIKE 'autoresponses'"); + + if (empty($tablesExist)) { + error_log("Creando tabla autoresponses..."); + + $createAutoResponsesSQL = "CREATE TABLE IF NOT EXISTS autoresponses ( + id INT AUTO_INCREMENT PRIMARY KEY, + trigger_type ENUM('keyword', 'contains', 'exact', 'welcome', 'default') NOT NULL DEFAULT 'keyword', + trigger_value TEXT, + response_text TEXT NOT NULL, + response_type ENUM('text', 'template', 'menu') NOT NULL DEFAULT 'text', + template_name VARCHAR(255), + menu_id INT, + priority INT DEFAULT 0, + is_active BOOLEAN DEFAULT true, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_trigger_type (trigger_type), + INDEX idx_is_active (is_active), + INDEX idx_priority (priority) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; + + $db->execute($createAutoResponsesSQL); + + // Crear respuestas automáticas de ejemplo + $exampleResponses = [ + [ + 'trigger_type' => 'welcome', + 'trigger_value' => null, + 'response_text' => '¡Hola! 👋 Bienvenido a nuestro servicio. ¿En qué puedo ayudarte?', + 'response_type' => 'text', + 'priority' => 10, + 'is_active' => 1 + ], + [ + 'trigger_type' => 'keyword', + 'trigger_value' => 'hola,buenos días,buenas tardes,buenas noches,hi,hello', + 'response_text' => '¡Hola! 😊 Gracias por contactarnos. ¿En qué podemos ayudarte hoy?', + 'response_type' => 'text', + 'priority' => 5, + 'is_active' => 1 + ], + [ + 'trigger_type' => 'keyword', + 'trigger_value' => 'precio,precios,costo,costos,cuanto cuesta,tarifa', + 'response_text' => '💰 Para información sobre precios, por favor visita nuestro sitio web o contacta directamente con nuestro equipo de ventas.', + 'response_type' => 'text', + 'priority' => 3, + 'is_active' => 1 + ], + [ + 'trigger_type' => 'keyword', + 'trigger_value' => 'horario,horarios,abierto,cerrado,cuando abren', + 'response_text' => '🕒 Nuestros horarios de atención son:\nLunes a Viernes: 9:00 AM - 6:00 PM\nSábados: 9:00 AM - 2:00 PM\nDomingos: Cerrado', + 'response_type' => 'text', + 'priority' => 3, + 'is_active' => 1 + ], + [ + 'trigger_type' => 'default', + 'trigger_value' => null, + 'response_text' => 'Gracias por tu mensaje. Un representante se pondrá en contacto contigo pronto. 🤝', + 'response_type' => 'text', + 'priority' => 1, + 'is_active' => 1 + ] + ]; + + foreach ($exampleResponses as $response) { + $db->insert('autoresponses', $response); + } + + error_log("Tabla autoresponses creada con datos de ejemplo"); + } + + // Obtener todas las respuestas automáticas + $autoresponses = $db->fetchAll( + "SELECT * FROM autoresponses ORDER BY priority DESC, created_at DESC" + ); + + echo json_encode([ + 'success' => true, + 'data' => $autoresponses, + 'total' => count($autoresponses), + 'message' => 'Respuestas automáticas cargadas correctamente' + ]); + +} catch (Exception $e) { + error_log("Error en get_autoresponses.php: " . $e->getMessage()); + http_response_code(500); + echo json_encode([ + 'success' => false, + 'error' => 'Error interno del servidor', + 'debug' => $e->getMessage(), + 'data' => [] + ]); +} +?> \ No newline at end of file diff --git a/api/get_logs.php b/api/get_logs.php index afc645d..b27e57e 100644 --- a/api/get_logs.php +++ b/api/get_logs.php @@ -1,11 +1,14 @@ fetchAll( - "SELECT - id, - status_code, - ip_address, - created_at, - SUBSTRING(request_body, 1, 100) as request_preview, - SUBSTRING(response_body, 1, 100) as response_preview - FROM webhook_logs - ORDER BY created_at DESC - LIMIT :limit OFFSET :offset", - [ - 'limit' => (int)$limit, - 'offset' => (int)$offset - ] - ); + if ($limit > 100) $limit = 100; // Máximo 100 registros - echo json_encode($logs); + // Verificar qué tablas existen + $existingTables = $db->fetchAll("SHOW TABLES"); + $tableNames = array_column($existingTables, 'Tables_in_' . DB_NAME); + + $logs = []; + + if ($type === 'webhook' && in_array('webhook_logs', $tableNames)) { + // Logs de webhook (formato original) + $logs = $db->fetchAll( + "SELECT + id, + status_code, + ip_address, + created_at, + SUBSTRING(request_body, 1, 100) as request_preview, + SUBSTRING(response_body, 1, 100) as response_preview, + 'webhook' as source, + 'INFO' as level, + CONCAT('Webhook request - Status: ', COALESCE(status_code, 'N/A')) as message + FROM webhook_logs + ORDER BY created_at DESC + LIMIT ? OFFSET ?", + [$limit, $offset] + ); + + } else { + // Logs del sistema + if (!in_array('system_logs', $tableNames)) { + // Crear tabla de logs del sistema + $createLogsSQL = "CREATE TABLE IF NOT EXISTS system_logs ( + id INT AUTO_INCREMENT PRIMARY KEY, + datetime DATETIME DEFAULT CURRENT_TIMESTAMP, + level ENUM('ERROR', 'WARNING', 'INFO', 'DEBUG', 'SUCCESS') DEFAULT 'INFO', + message TEXT NOT NULL, + source VARCHAR(255) DEFAULT 'Sistema', + data JSON, + user_id INT, + ip_address VARCHAR(45), + user_agent TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + INDEX idx_datetime (datetime), + INDEX idx_level (level), + INDEX idx_source (source) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; + + $db->execute($createLogsSQL); + + // Insertar logs de ejemplo + $exampleLogs = [ + [ + 'level' => 'INFO', + 'message' => 'Sistema de WhatsApp Bot iniciado correctamente', + 'source' => 'Sistema', + 'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1' + ], + [ + 'level' => 'SUCCESS', + 'message' => 'Módulo de respuestas automáticas cargado', + 'source' => 'AutoResponse', + 'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1' + ], + [ + 'level' => 'INFO', + 'message' => 'Sistema de menús inicializado', + 'source' => 'MenuSystem', + 'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1' + ], + [ + 'level' => 'WARNING', + 'message' => 'Verificar configuración de tokens WhatsApp', + 'source' => 'Config', + 'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1' + ] + ]; + + foreach ($exampleLogs as $log) { + $db->insert('system_logs', $log); + } + } + + $logs = $db->fetchAll( + "SELECT + id, + datetime, + level, + message, + source, + data, + ip_address, + created_at + FROM system_logs + ORDER BY datetime DESC, id DESC + LIMIT ? OFFSET ?", + [$limit, $offset] + ); + } + + echo json_encode([ + 'success' => true, + 'data' => $logs, + 'total' => count($logs), + 'type' => $type, + 'message' => 'Logs cargados correctamente' + ]); } catch (Exception $e) { - error_log("Error in get_logs.php: " . $e->getMessage()); + error_log("Error en get_logs.php: " . $e->getMessage()); http_response_code(500); - echo json_encode(['error' => 'Error interno del servidor']); + echo json_encode([ + 'success' => false, + 'error' => 'Error interno del servidor', + 'debug' => $e->getMessage(), + 'data' => [] + ]); } ?> \ No newline at end of file diff --git a/api/save_autoresponse.php b/api/save_autoresponse.php new file mode 100644 index 0000000..a97eed2 --- /dev/null +++ b/api/save_autoresponse.php @@ -0,0 +1,117 @@ + false, 'error' => 'Método no permitido']); + exit; +} + +try { + $input = json_decode(file_get_contents('php://input'), true); + + if (!$input) { + throw new Exception('Datos no válidos'); + } + + // Validar campos requeridos + $required_fields = ['trigger_type', 'response_text']; + foreach ($required_fields as $field) { + if (!isset($input[$field]) || trim($input[$field]) === '') { + throw new Exception("El campo '$field' es requerido"); + } + } + + $db = Database::getInstance(); + + // Preparar datos para insertar/actualizar + $data = [ + 'trigger_type' => $input['trigger_type'], + 'response_text' => trim($input['response_text']), + 'response_type' => $input['response_type'] ?? 'text', + 'priority' => intval($input['priority'] ?? 0), + 'is_active' => isset($input['is_active']) ? (bool)$input['is_active'] : true, + 'updated_at' => date('Y-m-d H:i:s') + ]; + + // Campos opcionales + if (!empty($input['trigger_value'])) { + $data['trigger_value'] = trim($input['trigger_value']); + } + + if (!empty($input['template_name'])) { + $data['template_name'] = trim($input['template_name']); + } + + if (!empty($input['menu_id'])) { + $data['menu_id'] = intval($input['menu_id']); + } + + // Verificar si es actualización o inserción + if (!empty($input['id'])) { + // Actualización + $id = intval($input['id']); + + // Verificar que existe + $existing = $db->fetchAll("SELECT id FROM autoresponses WHERE id = ?", [$id]); + if (empty($existing)) { + throw new Exception('Respuesta automática no encontrada'); + } + + // Actualizar + $setClauses = []; + $values = []; + + foreach ($data as $key => $value) { + $setClauses[] = "$key = ?"; + $values[] = $value; + } + + $values[] = $id; + + $sql = "UPDATE autoresponses SET " . implode(', ', $setClauses) . " WHERE id = ?"; + $db->execute($sql, $values); + + $message = 'Respuesta automática actualizada correctamente'; + + } else { + // Inserción + $data['created_at'] = date('Y-m-d H:i:s'); + $id = $db->insert('autoresponses', $data); + $message = 'Respuesta automática creada correctamente'; + } + + // Obtener el registro actualizado/creado + $autoresponse = $db->fetchAll("SELECT * FROM autoresponses WHERE id = ?", [$id]); + + echo json_encode([ + 'success' => true, + 'data' => $autoresponse[0] ?? null, + 'message' => $message, + 'id' => $id + ]); + +} catch (Exception $e) { + error_log("Error en save_autoresponse.php: " . $e->getMessage()); + http_response_code(500); + echo json_encode([ + 'success' => false, + 'error' => $e->getMessage(), + 'debug' => $e->getTraceAsString() + ]); +} +?> \ No newline at end of file diff --git a/assets/js/app_simple.js b/assets/js/app_simple.js index 4ebd6e4..0470e17 100644 --- a/assets/js/app_simple.js +++ b/assets/js/app_simple.js @@ -117,6 +117,9 @@ class SimpleWhatsAppManager { case 'menus': this.loadMenus(); break; + case 'autoresponses': + this.loadAutoResponses(); + break; case 'logs': this.loadLogs(); break; @@ -1018,6 +1021,146 @@ class SimpleWhatsAppManager { } } + async loadAutoResponses() { + this.log('Cargando respuestas automáticas'); + + try { + const response = await this.apiCall('get_autoresponses.php'); + + if (response && response.success) { + this.updateAutoResponsesList(response.data || []); + } else if (response && Array.isArray(response)) { + this.updateAutoResponsesList(response); + } else { + this.showError('Error cargando respuestas automáticas'); + } + + } catch (error) { + this.showError('Error cargando respuestas automáticas: ' + error.message); + } + } + + updateAutoResponsesList(autoresponses) { + const container = document.getElementById('autoresponses-table'); + if (!container) return; + + // Almacenar los datos para uso posterior + this.autoResponsesData = autoresponses; + + if (autoresponses.length === 0) { + container.innerHTML = 'No hay respuestas automáticas configuradas'; + return; + } + + let html = ''; + + autoresponses.forEach(response => { + const typeLabels = { + 'keyword': '🔑 Palabra Clave', + 'contains': '📝 Contiene', + 'exact': '🎯 Exacta', + 'welcome': '👋 Bienvenida', + 'default': '🤖 Por Defecto' + }; + + const typeLabel = typeLabels[response.trigger_type] || response.trigger_type; + + html += ` + + ${typeLabel} + ${response.trigger_value || '-'} + ${this.truncateText(response.response_text || '', 60)} + ${response.is_active == 1 ? 'Activo' : 'Inactivo'} + + + + + + `; + }); + + container.innerHTML = html; + } + + async saveAutoResponse() { + this.log('Guardando respuesta automática'); + + try { + const responseData = { + trigger_type: document.getElementById('autoresponse-type')?.value || 'keyword', + trigger_value: document.getElementById('autoresponse-trigger')?.value || '', + response_text: document.getElementById('autoresponse-text')?.value || '', + response_type: document.getElementById('autoresponse-response-type')?.value || 'text', + is_active: document.getElementById('autoresponse-active')?.checked ? 1 : 0 + }; + + // Validar campos requeridos + if (!responseData.response_text) { + this.showError('El texto de respuesta es requerido'); + return; + } + + if (responseData.trigger_type !== 'welcome' && responseData.trigger_type !== 'default' && !responseData.trigger_value) { + this.showError('El disparador es requerido para este tipo de respuesta'); + return; + } + + this.log(`Datos de respuesta automática a guardar: ${JSON.stringify(responseData)}`); + + const response = await this.apiCall('save_autoresponse.php', { + method: 'POST', + body: responseData + }); + + if (response && response.success) { + this.showSuccess('Respuesta automática guardada correctamente'); + + // Cerrar modal + const modal = document.getElementById('createAutoResponseModal'); + if (modal) { + const bsModal = bootstrap.Modal.getInstance(modal); + if (bsModal) bsModal.hide(); + } + + // Limpiar formulario + const form = document.getElementById('autoresponse-form'); + if (form) form.reset(); + + // Recargar respuestas automáticas + this.loadAutoResponses(); + } else { + this.showError(`Error guardando respuesta automática: ${response?.error || 'Error desconocido'}`); + } + + } catch (error) { + this.showError('Error guardando respuesta automática: ' + error.message); + } + } + + async deleteAutoResponseAction(responseId) { + this.log(`Eliminando respuesta automática ID: ${responseId}`); + + try { + const response = await this.apiCall('delete_autoresponse.php', { + method: 'POST', + body: { response_id: responseId } + }); + + if (response && response.success) { + this.showSuccess('Respuesta automática eliminada correctamente'); + this.loadAutoResponses(); // Recargar la lista + } else { + this.showError(`Error eliminando respuesta automática: ${response?.error || 'Error desconocido'}`); + } + } catch (error) { + this.showError('Error eliminando respuesta automática: ' + error.message); + } + } + async deleteMenuAction(menuId) { this.log(`Eliminando menú ID: ${menuId}`); @@ -1154,6 +1297,139 @@ class SimpleWhatsAppManager { this.showError('Error cargando logs: ' + error.message); } } + + updateLogsTable(logs) { + const tbody = document.getElementById('logs-table'); + if (!tbody) { + this.log('Tabla de logs no encontrada', 'warning'); + return; + } + + tbody.innerHTML = ''; + + if (!logs || logs.length === 0) { + tbody.innerHTML = 'No hay logs registrados'; + return; + } + + logs.forEach(log => { + const row = this.createLogRow(log); + if (row) { + tbody.appendChild(row); + } + }); + } + + createLogRow(log) { + if (!log) return null; + + const tr = document.createElement('tr'); + + // Fecha y hora + const tdDateTime = document.createElement('td'); + tdDateTime.textContent = log.datetime || log.created_at || 'N/A'; + tr.appendChild(tdDateTime); + + // Nivel + const tdLevel = document.createElement('td'); + const levelBadge = document.createElement('span'); + levelBadge.className = `badge bg-${this.getLevelBadgeClass(log.level || log.tipo)}`; + levelBadge.textContent = (log.level || log.tipo || 'INFO').toUpperCase(); + tdLevel.appendChild(levelBadge); + tr.appendChild(tdLevel); + + // Mensaje + const tdMessage = document.createElement('td'); + tdMessage.textContent = this.truncateText(log.message || log.mensaje || '', 100); + tr.appendChild(tdMessage); + + // Origen + const tdSource = document.createElement('td'); + tdSource.textContent = log.source || log.origen || 'Sistema'; + tr.appendChild(tdSource); + + // Acciones + const tdActions = document.createElement('td'); + const viewButton = document.createElement('button'); + viewButton.className = 'btn btn-sm btn-outline-info'; + viewButton.innerHTML = ''; + viewButton.onclick = () => this.showLogDetails(log); + tdActions.appendChild(viewButton); + tr.appendChild(tdActions); + + return tr; + } + + getLevelBadgeClass(level) { + const levelClasses = { + 'ERROR': 'danger', + 'WARNING': 'warning', + 'WARN': 'warning', + 'INFO': 'info', + 'DEBUG': 'secondary', + 'SUCCESS': 'success' + }; + return levelClasses[level?.toUpperCase()] || 'secondary'; + } + + showLogDetails(log) { + const details = { + 'Fecha/Hora': log.datetime || log.created_at || 'N/A', + 'Nivel': (log.level || log.tipo || 'INFO').toUpperCase(), + 'Mensaje': log.message || log.mensaje || '', + 'Origen': log.source || log.origen || 'Sistema', + 'Datos Adicionales': log.data ? JSON.stringify(log.data, null, 2) : 'N/A' + }; + + let detailsHtml = '
'; + for (const [key, value] of Object.entries(details)) { + detailsHtml += ` +
+ ${key}: +
${value}
+
`; + } + detailsHtml += '
'; + + // Mostrar en modal o alert + if (typeof bootstrap !== 'undefined') { + // Si Bootstrap está disponible, crear modal + this.showModalAlert('Detalles del Log', detailsHtml); + } else { + // Fallback a alert simple + alert(`Detalles del Log:\n\n${Object.entries(details).map(([k,v]) => `${k}: ${v}`).join('\n')}`); + } + } + + showModalAlert(title, content) { + // Crear modal temporal si no existe + let modal = document.getElementById('tempLogModal'); + if (!modal) { + modal = document.createElement('div'); + modal.id = 'tempLogModal'; + modal.className = 'modal fade'; + modal.innerHTML = ` + `; + document.body.appendChild(modal); + } + + modal.querySelector('.modal-title').textContent = title; + modal.querySelector('.modal-body').innerHTML = content; + + const bootstrapModal = new bootstrap.Modal(modal); + bootstrapModal.show(); + } } // Inicializar cuando el DOM esté listo @@ -1581,6 +1857,11 @@ window.app = { if (window.whatsappManager) { window.whatsappManager.saveMenu(); } + }, + saveAutoResponse: function () { + if (window.whatsappManager) { + window.whatsappManager.saveAutoResponse(); + } } }; @@ -1659,19 +1940,228 @@ window.removeMenuOption = function (button) { } }; -// Función para actualizar numeración de opciones -function updateOptionNumbers() { - const container = document.getElementById('menu-options-container'); - if (!container) return; - - const options = container.querySelectorAll('.menu-option-item'); - options.forEach((option, index) => { - const header = option.querySelector('h6'); - if (header) { - header.textContent = `Opción ${index + 1}`; +// Funciones globales para gestión de respuestas automáticas +window.editAutoResponse = function (responseId) { + console.log('Editando respuesta automática:', responseId); + // TODO: Implementar edición de respuestas automáticas + alert(`Editar respuesta automática ${responseId} - Función en desarrollo`); +}; + +window.deleteAutoResponse = function (responseId) { + console.log('Eliminando respuesta automática:', responseId); + if (confirm(`¿Está seguro que desea eliminar la respuesta automática ${responseId}?`)) { + if (window.whatsappManager) { + window.whatsappManager.deleteAutoResponseAction(responseId); } - }); -} + } +}; + +// Funciones para modal de autorespuestas +window.showCreateAutoResponseModal = function() { + document.getElementById('autoresponse-form').reset(); + document.getElementById('autoresponse-id').value = ''; + document.getElementById('createAutoResponseModalLabel').innerHTML = ' Crear Nueva Respuesta Automática'; + + // Reset campos específicos + updateTriggerFields('keyword'); + updateResponseTypeFields('text'); + + const modal = new bootstrap.Modal(document.getElementById('createAutoResponseModal')); + modal.show(); +}; + +window.showEditAutoResponseModal = function(autoresponse) { + document.getElementById('autoresponse-id').value = autoresponse.id; + document.getElementById('createAutoResponseModalLabel').innerHTML = ' Editar Respuesta Automática'; + + // Llenar campos del formulario + document.getElementById('autoresponse-trigger-type').value = autoresponse.trigger_type; + document.getElementById('autoresponse-trigger-value').value = autoresponse.trigger_value || ''; + document.getElementById('autoresponse-text').value = autoresponse.response_text; + document.getElementById('autoresponse-type').value = autoresponse.response_type; + document.getElementById('autoresponse-priority').value = autoresponse.priority; + document.getElementById('autoresponse-active').value = autoresponse.is_active ? '1' : '0'; + document.getElementById('autoresponse-template-name').value = autoresponse.template_name || ''; + document.getElementById('autoresponse-menu-id').value = autoresponse.menu_id || ''; + + // Actualizar campos según el tipo + updateTriggerFields(autoresponse.trigger_type); + updateResponseTypeFields(autoresponse.response_type); + + const modal = new bootstrap.Modal(document.getElementById('createAutoResponseModal')); + modal.show(); +}; + +window.updateTriggerFields = function(triggerType) { + const valueGroup = document.getElementById('trigger-value-group'); + const valueLabel = document.getElementById('trigger-value-label'); + const valueInput = document.getElementById('autoresponse-trigger-value'); + const valueHelp = document.getElementById('trigger-value-help'); + + if (!valueGroup || !valueLabel || !valueInput || !valueHelp) { + console.warn('Elementos del modal de autorespuesta no encontrados'); + return; + } + + switch (triggerType) { + case 'keyword': + valueGroup.style.display = 'block'; + valueLabel.textContent = 'Palabras Clave *'; + valueInput.placeholder = 'hola,buenos días,hi,hello'; + valueInput.required = true; + valueHelp.textContent = 'Separa múltiples palabras con comas'; + break; + + case 'contains': + valueGroup.style.display = 'block'; + valueLabel.textContent = 'Texto a Buscar *'; + valueInput.placeholder = 'precio'; + valueInput.required = true; + valueHelp.textContent = 'Texto que debe contener el mensaje del usuario'; + break; + + case 'exact': + valueGroup.style.display = 'block'; + valueLabel.textContent = 'Mensaje Exacto *'; + valueInput.placeholder = 'quiero información'; + valueInput.required = true; + valueHelp.textContent = 'El mensaje debe coincidir exactamente'; + break; + + case 'welcome': + case 'default': + valueGroup.style.display = 'none'; + valueInput.required = false; + valueInput.value = ''; + break; + } +}; + +window.updateResponseTypeFields = function(responseType) { + const templateFields = document.getElementById('template-fields'); + const menuFields = document.getElementById('menu-fields'); + + if (!templateFields || !menuFields) { + console.warn('Campos adicionales del modal no encontrados'); + return; + } + + // Ocultar todos los campos adicionales + templateFields.style.display = 'none'; + menuFields.style.display = 'none'; + + // Mostrar campos según el tipo + switch (responseType) { + case 'template': + templateFields.style.display = 'block'; + break; + case 'menu': + menuFields.style.display = 'block'; + // Cargar menús disponibles si no están cargados + loadMenusForSelect(); + break; + } +}; + +window.loadMenusForSelect = function() { + fetch('/api/get_menus.php') + .then(response => response.json()) + .then(data => { + if (data.success) { + const select = document.getElementById('autoresponse-menu-id'); + if (select) { + select.innerHTML = ''; + + data.data.forEach(menu => { + const option = document.createElement('option'); + option.value = menu.id; + option.textContent = `${menu.name} (${menu.menu_key})`; + select.appendChild(option); + }); + } + } + }) + .catch(error => console.error('Error loading menus for select:', error)); +}; + +// Actualizar función editAutoResponse para usar el modal +window.editAutoResponse = function (responseId) { + console.log('Editando respuesta automática:', responseId); + + // Buscar la respuesta en los datos cargados + if (window.whatsappManager && window.whatsappManager.autoResponsesData) { + const autoresponse = window.whatsappManager.autoResponsesData.find(ar => ar.id == responseId); + if (autoresponse) { + showEditAutoResponseModal(autoresponse); + } else { + console.error('Respuesta automática no encontrada:', responseId); + alert('Error: No se pudo cargar la respuesta automática'); + } + } else { + console.error('Datos de respuestas automáticas no disponibles'); + alert('Error: Datos no disponibles, recarga la página'); + } +}; + +window.showCreateAutoResponseModal = function () { + console.log('🔵 Abriendo modal de respuesta automática...'); + + const modalElement = document.getElementById('createAutoResponseModal'); + if (!modalElement) { + console.error('❌ Modal de respuesta automática no encontrado'); + return; + } + + try { + const form = document.getElementById('autoresponse-form'); + if (form) form.reset(); + + if (typeof bootstrap !== 'undefined' && bootstrap.Modal) { + const modal = new bootstrap.Modal(modalElement); + modal.show(); + } else { + modalElement.style.display = 'block'; + modalElement.classList.add('show'); + } + console.log('✅ Modal de respuesta automática abierto'); + } catch (error) { + console.error('❌ Error abriendo modal de respuesta automática:', error); + } +}; + +// Función para cambiar tipo de disparador +window.toggleTriggerType = function () { + const triggerType = document.getElementById('autoresponse-type')?.value; + const triggerContainer = document.getElementById('trigger-container'); + + if (triggerContainer) { + if (triggerType === 'welcome' || triggerType === 'default') { + triggerContainer.style.display = 'none'; + } else { + triggerContainer.style.display = 'block'; + + const triggerInput = document.getElementById('autoresponse-trigger'); + const triggerLabel = document.querySelector('label[for="autoresponse-trigger"]'); + + if (triggerInput && triggerLabel) { + switch (triggerType) { + case 'keyword': + triggerLabel.textContent = 'Palabra Clave *'; + triggerInput.placeholder = 'ej: hola, info, precios'; + break; + case 'contains': + triggerLabel.textContent = 'Texto que debe contener *'; + triggerInput.placeholder = 'ej: precio, información'; + break; + case 'exact': + triggerLabel.textContent = 'Mensaje exacto *'; + triggerInput.placeholder = 'ej: ¿Cuáles son sus precios?'; + break; + } + } + } + } +}; // Funciones para el formulario de mensajes window.toggleRecipientType = function () { @@ -1834,51 +2324,37 @@ function displayDiagnosticResults(data) { -function updateLogsTable(logs) { - const tbody = document.getElementById('logs-table'); - if (!tbody) { - this.log('Tabla de logs no encontrada', 'warning'); - return; +// ============================================== +// EVENT LISTENERS PARA MODALES DE AUTORESPUESTAS +// ============================================== + +// Agregar event listeners cuando el DOM esté listo +document.addEventListener('DOMContentLoaded', function() { + // Event listener para cambio de tipo de trigger + const triggerTypeSelect = document.getElementById('autoresponse-trigger-type'); + if (triggerTypeSelect) { + triggerTypeSelect.addEventListener('change', function() { + updateTriggerFields(this.value); + }); } - - tbody.innerHTML = ''; - - if (!logs || logs.length === 0) { - tbody.innerHTML = 'No hay logs registrados'; - return; + + // Event listener para cambio de tipo de respuesta + const responseTypeSelect = document.getElementById('autoresponse-type'); + if (responseTypeSelect) { + responseTypeSelect.addEventListener('change', function() { + updateResponseTypeFields(this.value); + }); } - - logs.forEach(log => { - const row = this.createLogRow(log); - tbody.appendChild(row); - }); - - this.log(`${logs.length} logs cargados en la tabla`); -} - -function createLogRow(log) { - const tr = document.createElement('tr'); - const date = new Date(log.created_at); - const formatDate = date.toLocaleDateString() + ' ' + date.toLocaleTimeString('es', { hour: '2-digit', minute: '2-digit' }); - - tr.innerHTML = ` - ${formatDate} - ${log.ip_address || 'N/A'} - - - ${log.status_code || 'N/A'} - - - - - - - - - `; - return tr; -} \ No newline at end of file + + // Event listener para el modal cuando se muestre + const autoResponseModal = document.getElementById('createAutoResponseModal'); + if (autoResponseModal) { + autoResponseModal.addEventListener('shown.bs.modal', function () { + // Enfocar el primer campo cuando se abra el modal + const firstInput = autoResponseModal.querySelector('input, select, textarea'); + if (firstInput) { + firstInput.focus(); + } + }); + } +}); \ No newline at end of file diff --git a/index.php b/index.php index d4c9600..0b1bede 100644 --- a/index.php +++ b/index.php @@ -781,6 +781,107 @@ try { + + + \ No newline at end of file diff --git a/server.log b/server.log new file mode 100644 index 0000000..a6e9669 Binary files /dev/null and b/server.log differ