up
This commit is contained in:
@@ -13,6 +13,12 @@ if (!file_exists($installationLockFile)) {
|
||||
|
||||
require_once 'config/config.php';
|
||||
|
||||
// Verificar autenticación - redirigir al login si no está logueado
|
||||
if (!isUserLoggedIn()) {
|
||||
header('Location: login.php');
|
||||
exit('Acceso denegado. <a href="login.php">Iniciar sesión</a>');
|
||||
}
|
||||
|
||||
// Verificar conexión a la base de datos
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
@@ -30,6 +36,7 @@ try {
|
||||
<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="./assets/css/styles.css" rel="stylesheet">
|
||||
<link href="./assets/css/diagnostic.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Sidebar -->
|
||||
@@ -47,6 +54,8 @@ try {
|
||||
<li><a href="#autoresponses" class="nav-link" data-tab="autoresponses"><i class="fas fa-robot"></i> Respuestas Auto</a></li>
|
||||
<li><a href="#settings" class="nav-link" data-tab="settings"><i class="fas fa-cog"></i> Configuración</a></li>
|
||||
<li><a href="#logs" class="nav-link" data-tab="logs"><i class="fas fa-file-alt"></i> Logs</a></li>
|
||||
<li class="sidebar-divider"></li>
|
||||
<li><a href="logout.php" class="nav-link logout-link" onclick="return confirm('¿Está seguro que desea cerrar sesión?')"><i class="fas fa-sign-out-alt"></i> Cerrar Sesión</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -54,14 +63,23 @@ try {
|
||||
<main class="main-content">
|
||||
<!-- Header -->
|
||||
<header class="content-header">
|
||||
<h1><i class="fas fa-robot"></i> Sistema de Gestión WhatsApp Bot</h1>
|
||||
<div>
|
||||
<h1><i class="fas fa-robot"></i> Sistema de Gestión WhatsApp Bot</h1>
|
||||
<small class="text-muted">
|
||||
<i class="fas fa-user"></i> Conectado como <strong><?= htmlspecialchars(ADMIN_USERNAME) ?></strong>
|
||||
| <i class="fas fa-clock"></i> Sesión desde: <?= date('H:i:s', $_SESSION['login_time'] ?? time()) ?>
|
||||
</small>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<span class="status-indicator online">
|
||||
<i class="fas fa-circle"></i> En línea
|
||||
</span>
|
||||
<button class="btn btn-primary" onclick="refreshData()">
|
||||
<button class="btn btn-primary me-2" onclick="refreshData()">
|
||||
<i class="fas fa-sync-alt"></i> Actualizar
|
||||
</button>
|
||||
<a href="logout.php" class="btn btn-outline-danger" onclick="return confirm('¿Está seguro que desea cerrar sesión?')">
|
||||
<i class="fas fa-sign-out-alt"></i> Cerrar Sesión
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -291,14 +309,28 @@ try {
|
||||
<div class="card-body">
|
||||
<form id="send-message-form">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Tipo de Destinatario</label>
|
||||
<select class="form-control" id="recipient-type" onchange="toggleRecipientType()">
|
||||
<option value="existing">Usuario Registrado</option>
|
||||
<option value="manual">Número Manual (Solo Plantillas)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3" id="existing-recipient-group">
|
||||
<label class="form-label">Destinatario</label>
|
||||
<select class="form-control" id="message-recipient" required>
|
||||
<select class="form-control" id="message-recipient">
|
||||
<option value="">Seleccionar usuario...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3" id="manual-recipient-group" style="display: none;">
|
||||
<label class="form-label">Número de WhatsApp</label>
|
||||
<input type="text" class="form-control" id="manual-recipient" placeholder="+57XXXXXXXXX">
|
||||
<small class="form-text text-warning">
|
||||
⚠️ Solo se pueden enviar plantillas aprobadas a números nuevos
|
||||
</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Tipo de Mensaje</label>
|
||||
<select class="form-control" id="message-type" required>
|
||||
<select class="form-control" id="message-type" onchange="toggleMessageType()">
|
||||
<option value="text">Texto</option>
|
||||
<option value="template">Plantilla</option>
|
||||
</select>
|
||||
@@ -358,7 +390,7 @@ 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" onclick="showCreateTemplateModal()">
|
||||
<button class="btn btn-primary" id="btn-new-template" onclick="showCreateTemplateModal()">
|
||||
<i class="fas fa-plus"></i> Nueva Plantilla
|
||||
</button>
|
||||
</div>
|
||||
@@ -460,6 +492,30 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<!-- Panel de Diagnóstico -->
|
||||
<div class="card mb-3">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5><i class="fas fa-stethoscope"></i> Diagnóstico</h5>
|
||||
<button class="btn btn-sm btn-outline-primary" onclick="runDiagnostic()">
|
||||
<i class="fas fa-play"></i> Ejecutar
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="diagnostic-results">
|
||||
<p class="text-muted">Haz clic en "Ejecutar" para verificar el estado del sistema</p>
|
||||
</div>
|
||||
<div class="mt-3" id="diagnostic-actions" style="display: none;">
|
||||
<a href="approve_templates.html" class="btn btn-success btn-sm" target="_blank">
|
||||
🔧 Solucionar Problema de Plantillas
|
||||
</a>
|
||||
<a href="GUIA_ERROR_PLANTILLAS.md" class="btn btn-info btn-sm" target="_blank">
|
||||
📋 Ver Guía Completa
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Información del Sistema -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-info-circle"></i> Información del Sistema</h5>
|
||||
@@ -522,9 +578,164 @@ try {
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Modal - Crear Plantilla -->
|
||||
<div class="modal fade" id="createTemplateModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">📝 Nueva Plantilla de WhatsApp</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="template-form">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nombre descriptivo *</label>
|
||||
<input type="text" class="form-control" id="template-name" required placeholder="ej: Bienvenida Cliente">
|
||||
<small class="form-text text-muted">Nombre interno para identificar la plantilla</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nombre en WhatsApp *</label>
|
||||
<input type="text" class="form-control" id="template-whatsapp-name" required placeholder="ej: welcome_customer">
|
||||
<small class="form-text text-muted">Debe coincidir exactamente con el nombre en WhatsApp Business Manager</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Idioma</label>
|
||||
<select class="form-control" id="template-language">
|
||||
<option value="es">Español</option>
|
||||
<option value="en">English</option>
|
||||
<option value="pt">Português</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Categoría</label>
|
||||
<select class="form-control" id="template-category">
|
||||
<option value="utility">Utilidad</option>
|
||||
<option value="marketing">Marketing</option>
|
||||
<option value="authentication">Autenticación</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="alert alert-info">
|
||||
<strong>⚠️ Importante:</strong> La plantilla debe ser creada y aprobada primero en WhatsApp Business Manager.
|
||||
Este formulario solo registra plantillas ya existentes en WhatsApp.
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
||||
<button type="button" class="btn btn-primary" onclick="app.saveTemplate()">Guardar Plantilla</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal de Crear Menú -->
|
||||
<div class="modal fade" id="createMenuModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">📋 Nuevo Menú</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="menu-form">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nombre del Menú *</label>
|
||||
<input type="text" class="form-control" id="menu-name" required placeholder="ej: Menú Principal">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Descripción</label>
|
||||
<textarea class="form-control" id="menu-description" rows="3" placeholder="Descripción del menú (opcional)"></textarea>
|
||||
</div>
|
||||
<div class="alert alert-info">
|
||||
<strong>ℹ️ Información:</strong> Después de crear el menú, podrás agregar opciones y configurar las respuestas.
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveNewMenu()">Crear Menú</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/chart.js"></script>
|
||||
<script src="./assets/js/app.js"></script>
|
||||
<script src="./assets/js/app_simple.js"></script>
|
||||
<script>
|
||||
// Función de diagnóstico mejorada
|
||||
function runDiagnostic() {
|
||||
const resultsDiv = document.getElementById('diagnostic-results');
|
||||
const actionsDiv = document.getElementById('diagnostic-actions');
|
||||
resultsDiv.innerHTML = '<p class="text-muted"><i class="fas fa-spinner fa-spin"></i> Ejecutando diagnóstico...</p>';
|
||||
|
||||
fetch('/api/diagnose_whatsapp.php')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
let html = '<div class="diagnostic-report">';
|
||||
|
||||
// Configuración
|
||||
html += `<div class="mb-3">
|
||||
<h6><i class="fas fa-cog"></i> Configuración WhatsApp</h6>
|
||||
<div class="alert alert-${data.config.status === 'complete' ? 'success' : 'warning'}">
|
||||
${data.config.message} (${data.config.completion}% completa)
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
// Plantillas
|
||||
const templateIssues = data.templates.approved === 0 && data.templates.pending > 0;
|
||||
html += `<div class="mb-3">
|
||||
<h6><i class="fas fa-file-alt"></i> Estado de Plantillas</h6>
|
||||
<div class="alert alert-${templateIssues ? 'danger' : 'success'}">
|
||||
${data.templates.message}
|
||||
<br><small>Aprobadas: ${data.templates.approved} | Pendientes: ${data.templates.pending}</small>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
// API
|
||||
html += `<div class="mb-3">
|
||||
<h6><i class="fas fa-plug"></i> Conectividad API</h6>
|
||||
<div class="alert alert-${data.api.status === 'ready' ? 'success' : 'warning'}">
|
||||
${data.api.message}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
// Recomendaciones
|
||||
if (data.recommendations && data.recommendations.length > 0) {
|
||||
html += `<div class="mb-3">
|
||||
<h6><i class="fas fa-lightbulb"></i> Recomendaciones</h6>
|
||||
<ul class="list-unstyled">`;
|
||||
|
||||
data.recommendations.forEach(rec => {
|
||||
html += `<li class="mb-1"><i class="fas fa-arrow-right text-primary"></i> ${rec}</li>`;
|
||||
});
|
||||
|
||||
html += `</ul></div>`;
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
resultsDiv.innerHTML = html;
|
||||
|
||||
// Mostrar botones de acción si hay problemas con plantillas
|
||||
if (templateIssues) {
|
||||
actionsDiv.style.display = 'block';
|
||||
} else {
|
||||
actionsDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
} else {
|
||||
resultsDiv.innerHTML = `<div class="alert alert-danger">Error: ${data.message}</div>`;
|
||||
actionsDiv.style.display = 'none';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
resultsDiv.innerHTML = '<div class="alert alert-danger">Error de conectividad</div>';
|
||||
actionsDiv.style.display = 'none';
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user