diff --git a/api/get_stats.php b/api/get_stats.php index 38156f2..2d9f332 100644 --- a/api/get_stats.php +++ b/api/get_stats.php @@ -40,12 +40,19 @@ try { // Total de mensajes $totalconversations = $db->fetch("SELECT COUNT(*) as count FROM conversations")['count']; + + // Mensajes pendientes / no leídos: preferir columna is_read si existe, si no usar status = 'received' + $unreadResult = $db->fetch( + "SELECT COUNT(*) as count FROM conversations WHERE direction = 'incoming' AND ( (is_read IS NULL OR is_read = 0) OR status = 'received' )" + ); + $unreadMessages = intval($unreadResult['count'] ?? 0); $stats = [ 'total_users' => (int)$totalUsers, 'conversations_today' => (int)$conversationsToday, 'active_users' => (int)$activeUsers, - 'total_conversations' => (int)$totalconversations + 'total_conversations' => (int)$totalconversations, + 'unread_messages' => $unreadMessages ]; echo json_encode($stats); diff --git a/api/upload_media.php b/api/upload_media.php index e4c7244..b36402b 100644 --- a/api/upload_media.php +++ b/api/upload_media.php @@ -6,9 +6,17 @@ require_once '../config/config.php'; +// Asegurar que errores no se impriman al cliente y se registren en logs +error_reporting(E_ALL); +@ini_set('display_errors', 0); +@ini_set('log_errors', 1); + // Verificar autenticación requireAuthentication(); +// Forzar buffer para poder limpiar salidas accidentales +if (ob_get_level() === 0) ob_start(); + header('Content-Type: application/json; charset=utf-8'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST'); @@ -23,7 +31,13 @@ if ($_SERVER['REQUEST_METHOD'] !== 'POST') { try { // Verificar que se subió un archivo if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) { - throw new Exception('No se recibió ningún archivo o hubo un error en la carga'); + // Log for debugging + error_log('upload_media.php - FILES content: ' . print_r($_FILES, true)); + // Make sure any buffered content is cleared before sending JSON + if (ob_get_length()) ob_clean(); + http_response_code(400); + echo json_encode(['success' => false, 'error' => 'No se recibió ningún archivo o hubo un error en la carga']); + exit; } $file = $_FILES['file']; diff --git a/assets/js/app.js b/assets/js/app.js index 6693801..c05a904 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -194,10 +194,10 @@ class WhatsAppBotManager { document.getElementById('active-users').textContent = stats.active_users || 0; document.getElementById('total-conversations').textContent = stats.total_conversations || 0; - // Actualizar badge de conversaciones en el menú lateral + // Actualizar badge de conversaciones en el menú lateral (usar mensajes pendientes si existe) const convBadge = document.getElementById('conversations-count'); if (convBadge) { - const val = stats.total_conversations || 0; + const val = (typeof stats.unread_messages !== 'undefined') ? stats.unread_messages : (stats.total_conversations || 0); convBadge.textContent = val; convBadge.style.display = val > 0 ? 'inline-block' : 'none'; } diff --git a/assets/js/app_simple.js b/assets/js/app_simple.js index b6eacec..72713bd 100644 --- a/assets/js/app_simple.js +++ b/assets/js/app_simple.js @@ -274,10 +274,10 @@ class SimpleWhatsAppManager { } }); - // Actualizar badge de conversaciones en el menú lateral (compatibilidad con versión simple) + // Actualizar badge de conversaciones en el menú lateral (usar mensajes pendientes si existe) const convBadge = document.getElementById('conversations-count'); if (convBadge) { - const val = stats.total_conversations || 0; + const val = (typeof stats.unread_messages !== 'undefined') ? stats.unread_messages : (stats.total_conversations || 0); convBadge.textContent = val; convBadge.style.display = val > 0 ? 'inline-block' : 'none'; } diff --git a/chat_window.php b/chat_window.php index bfc06a7..6579d5c 100644 --- a/chat_window.php +++ b/chat_window.php @@ -530,8 +530,11 @@ if (empty($user_id)) { } return JSON.parse(text); } catch (err) { + // Incluir parte del cuerpo en el error para ayudar al diagnóstico (truncado) console.error('apiCall parse error for', url, err); - throw new Error('Invalid JSON response from ' + url + ': ' + err.message); + const respText = await response.text().catch(() => ''); + const snippet = (respText && respText.length > 0) ? respText.substr(0, 1000) : ''; + throw new Error('Invalid JSON response from ' + url + ': ' + err.message + ' -- response snippet: ' + snippet); } } }