From f9c5623d439afe8bfbe23fec447529e36e218c5d Mon Sep 17 00:00:00 2001 From: Brisa Date: Tue, 30 Jun 2026 15:01:01 -0300 Subject: [PATCH] panel admin: asistente, backups y ayuda --- admin/asistente.php | 219 ++++++++++++++ admin/ayuda_admin.php | 622 +++++++++++++++++++++++++++++++++++++++ admin/backup.php | 276 +++++++++++++++++ admin/descargar_file.php | 34 +++ 4 files changed, 1151 insertions(+) create mode 100644 admin/asistente.php create mode 100644 admin/ayuda_admin.php create mode 100644 admin/backup.php create mode 100644 admin/descargar_file.php diff --git a/admin/asistente.php b/admin/asistente.php new file mode 100644 index 0000000..eaa7405 --- /dev/null +++ b/admin/asistente.php @@ -0,0 +1,219 @@ +connect_error) { + die("Error de conexión: " . $conn->connect_error); +} + +// 2. LÓGICA PARA GUARDAR CAMBIOS (PROCESAMIENTO) +$mensaje_alerta = ""; + +// Agregar nueva pregunta CORREGIDO (Incluye keywords y categoría dinámica) +if (isset($_POST['agregar_pregunta'])) { + $preg = $conn->real_escape_string($_POST['nueva_pregunta']); + $resp = $conn->real_escape_string($_POST['nueva_respuesta']); + $keys = $conn->real_escape_string($_POST['nuevas_keywords']); + + // Procesamiento inteligente de la categoría + $cat_seleccionada = $_POST['categoria_existente']; + if ($cat_seleccionada === 'nueva') { + $cat = $conn->real_escape_string(trim(strtolower($_POST['nueva_categoria']))); + } else { + $cat = $conn->real_escape_string($cat_seleccionada); + } + + if (!empty($preg) && !empty($resp) && !empty($keys) && !empty($cat)) { + // Ejecución del INSERT incluyendo la nueva columna + $conn->query("INSERT INTO bot_preguntas (pregunta, respuesta, keywords, categoria) VALUES ('$preg', '$resp', '$keys', '$cat')"); + $mensaje_alerta = "Pregunta, palabras clave y categoría agregadas con éxito."; + } else { + $mensaje_alerta = "Error: Todos los campos del asistente virtual, incluida la categoría, son obligatorios."; + } +} + +// Eliminar pregunta +if (isset($_GET['eliminar'])) { + $id_del = intval($_GET['eliminar']); + $conn->query("DELETE FROM bot_preguntas WHERE id = $id_del"); + header("Location: asistente.php"); // Recargar para limpiar la URL + exit(); +} + +// Consultas dinámicas para la vista y el selector +$preguntas = $conn->query("SELECT * FROM bot_preguntas ORDER BY id DESC"); +$categorias_existentes = $conn->query("SELECT DISTINCT categoria FROM bot_preguntas WHERE categoria IS NOT NULL AND categoria != '' ORDER BY categoria ASC"); +?> + + + + + + Panel Asistente Virtual | La Pecosa + + + + + +
+ +
+ + + + +

Asistente Virtual La Pecosa - Administración

+
+ + +
+ + +
+
+

Nueva pregunta frecuente

+
+
+ + +
+ +
+ + +
+ + + +
+ + + Si el usuario escribe alguna de estas palabras, el bot responderá. +
+
+ + +
+ +
+
+ +
+

Base de conocimiento

+ + + + + + + + + + + fetch_assoc()): ?> + + + + + + + + +
Pregunta / KeywordsCategoríaRespuesta configuradaAcción
+
+ Palabras clave:
+ '.htmlspecialchars(trim($k)).''; + } + ?> +
+ + + + + +
+
+
+
+ + + + + \ No newline at end of file diff --git a/admin/ayuda_admin.php b/admin/ayuda_admin.php new file mode 100644 index 0000000..7b0dad8 --- /dev/null +++ b/admin/ayuda_admin.php @@ -0,0 +1,622 @@ + + + + + + + Manual de Administrador - La Pecosa + + + + + + + + +
+ + + +
+ + + + + + +
+ +
+

Panel de control

+
+
+ + Tarjetas de resumen en tiempo real +
+

El dashboard muestra tres métricas clave al tope de la página:

+
+ Ventas de hoy — sumatoria monetaria de todos los pedidos del día.

+ Pedidos activos — contador de órdenes en estado Pendiente o En cocina que todavía no se cerraron.

+
+
+ +
+
+ + Top 5 productos más vendidos +
+

Gráfico de barras que acumula unidades despachadas por artículo. Útil para medir el impacto de las promociones del día y planificar insumos de alta rotación.

+
+ +
+
+ + Últimos 10 movimientos +
+

Historial rápido con cliente, monto total y estado de cada orden. Ideal para un vistazo rápido sin entrar al módulo de Pedidos.

+
+ +
+
+ + Abrir / Cerrar la página al público +
+

El botón en la esquina superior derecha del apartado Estadísticas restringe temporalmente el acceso de compra en el frontend. Usalo cuando la cocina esté saturada o surja algún imprevisto.

+
+ + Cuando la página está cerrada, los clientes ven un aviso pero no pueden agregar productos al carrito ni confirmar pedidos. +
+
+
+ +
+

Gestión de comandas

+
+
+ + Búsqueda y filtrado +
+

Escribí en la barra superior el #ID del pedido, el nombre del cliente o su ID de usuario y presioná Buscar. El sistema filtra las filas al instante, útil cuando un cliente llama a consultar por su orden.

+
+ +
+
+ + Ver detalle y comprobantes +
+

El botón "Ver detalle" abre el desglose exacto del pedido: productos, cantidades y notas del cliente.

+
+ Comprobante de transferencia: aparece automáticamente solo cuando el cliente eligió envío a domicilio con pago por transferencia. Expandilo para verificar que el pago haya impactado antes de despachar. +
+
+ +
+
+ + Flujo de estados +
+

Para cambiar la fase de un pedido: desplegá el selector en la columna "Cambiar estado", elegí la instancia y confirmá con .

+
+
Pendiente El pedido ingresó al sistema y espera ser tomado por cocina.
+
En cocina Los cocineros ya están preparando la orden.
+
Listo para retirar Para modalidad para llevar. El cliente puede pasar a buscarlo.
+
En camino El delivery está llevando el pedido al domicilio.
+
Entregado Cierre definitivo. Las ventas se contabilizan en el panel de Estadísticas.
+
Cancelado Falta de insumos, pago rechazado o cancelación del cliente.
+
+
+
+ +
+

Menú y stock

+
+
+
+ + Agregar un producto +
+

Completá nombre, categoría, precio, stock inicial y foto. Ideal para platos del día o artículos nuevos de forma rápida.

+
+
+
+ + Carga masiva (.csv) +
+

Para actualizaciones grandes de precios o stocks. Armá el Excel, guardalo como CSV y presioná Procesar catálogo.

+
+
+ +
+
+ + Estructura requerida del CSV +
+

El archivo debe tener exactamente estas columnas, separadas por punto y coma:

+
+ id ; nombre ; precio ; categoria ; imagen ; activo ; stock +
+

Categorías válidas: Almacén, Carne, Bebidas, Limpieza, Lácteos, Verdura, Vinoteca, Panadería.

+
+ +
+
+ + Regla de quiebre de stock +
+

Cuando un artículo llega a 0 unidades, el botón "Agregar al carrito" se deshabilita automáticamente en el frontend. El cliente ve el producto pero no puede comprarlo. Actualizá el stock apenas haya reposición para reactivarlo.

+
+
+ +
+

Ofertas y menú del día

+
+
+ + Publicar una promoción +
+

Completá los campos del formulario y presioná Publicar promoción. La oferta aparece inmediatamente en la portada del cliente.

+
+ Mensaje: El texto que verá el cliente. Ej: ¡2 Lomitos + papas fritas por $X!

+ Precio y stock: El valor de oferta y los combos límite disponibles para cocina.

+ Imagen: Acepta PNG, JPG o WEBP. Se muestra como banner en el catálogo. +
+
+ +
+
+ + Historial y baja de promociones +
+

La tabla inferior registra todas las ofertas lanzadas con fecha, hora y mensaje. Para dar de baja una promo, presioná el ícono de borrar en la columna Acción, se elimina del frontend de forma inmediata.

+
+
+ +
+

Respuestas automáticas

+ +
+
+
+
+ + Añadir Preguntas y Palabras Clave +
+

El bot responde de forma dinámica basándose en coincidencias de términos. Rellená los siguientes campos para alimentarlo:

+
+ Pregunta de referencia: Título orientativo de la consulta para organizarte en el panel administrativo.

+ Categoría del bot: Desplegable obligatorio para agrupar las respuestas. Permite reutilizar una categoría previa de la lista o seleccionar "+ Crear una nueva categoría...", lo que desplegará dinámicamente un campo de texto adicional para que agregues una nueva.

+ Respuesta del asistente virtual: El mensaje exacto que el cliente va a recibir cuando invoque la palabra clave.

+ Palabras clave (Keywords): Términos separados por comas que dispararán la respuesta. Ej: horario,abierto,cierran. El sistema procesa los ingresos omitiendo mayúsculas y acentos automáticamente. +
+
+ +
+
+ + Recomendaciones de configuración +
+

Mantené las palabras clave cortas e intuitivas (una sola palabra por ítem). Si una consulta del usuario no coincide con ninguna palabra clave de la base de datos, el bot responderá con un mensaje genérico invitándolo a comunicarse por teléfono.

+
+
+ +
+

Vista previa del asistente virtual

+
+
+ 🍎 La Pecosa Asistente Virtual + +
+ +
+
+
¡Hola! Soy el asistente de La Pecosa 🍎 ¿En qué puedo ayudarte?
+
+
+ ¿Aceptan tarjeta? +
+
+
Aceptamos efectivo y transferencia bancaria. Al retirar tu pedido podés coordinar el método de pago con el local.
+
+
+ + +
+
+
+
+ +
+

Copias de seguridad

+
+
+ + Generar un respaldo completo +
+

Presioná Generar respaldo (.zip). El servidor empaqueta automáticamente:

+
+ Volcado SQL — estructura y datos de todas las tablas: pedidos, clientes, stock, promociones.

+ Archivos de configuracióndb.php y configuraciones del sistema necesarias para reinstalar.

+ Imágenes — todos los recursos multimedia subidos por la administración (/img e /imagenes). +
+
+ + No cerrés ni recargués la pestaña mientras se genera el backup. El proceso puede tardar unos segundos porque comprime imágenes además del SQL. El archivo aparecerá en la tabla inferior cuando esté listo. +
+
+ +
+
+ + Descargar y guardar el respaldo +
+

Los archivos generados se listan en la tabla con su nombre de marcación temporal (backup_sistema_completo_YYYY-MM-DD.zip). Presioná Descargar .zip para guardar la copia en tu computadora.

+
+ + Guardá el ZIP en un pendrive o servicio de nube externo (Google Drive, Dropbox). Si el servidor falla, con el ZIP y el código fuente en GitHub podés restaurar el sistema completo. +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/admin/backup.php b/admin/backup.php new file mode 100644 index 0000000..9d423c2 --- /dev/null +++ b/admin/backup.php @@ -0,0 +1,276 @@ + $ruta_sql_temporal"; + system($comando, $resultado_sql); + + // 2. Si el SQL se generó correctamente, procedemos a empaquetar archivos de configuración y recursos + if ($resultado_sql === 0 && file_exists($ruta_sql_temporal)) { + + $zip = new ZipArchive(); + + if ($zip->open($ruta_zip_final, ZipArchive::CREATE) === TRUE) { + + // A. Añadir el script SQL de la Base de Datos al ZIP + $zip->addFile($ruta_sql_temporal, $nombre_sql); + + // B. Añadir el archivo crítico de configuración técnica (db.php) + if (file_exists("../db.php")) { + $zip->addFile("../db.php", "config/db.php"); + } + + // C. Añadir de forma recursiva la carpeta de imágenes generales de diseño (../imagenes) + $ruta_imagenes = "../imagenes"; + if (file_exists($ruta_imagenes)) { + $archivos_imagenes = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($ruta_imagenes, RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::SELF_FIRST + ); + + foreach ($archivos_imagenes as $item) { + $ruta_real = $item->getRealPath(); + $ruta_relativa_zip = "imagenes_sitio/" . substr($ruta_real, strlen(realpath($ruta_imagenes)) + 1); + + if ($item->isDir()) { + $zip->addEmptyDir($ruta_relativa_zip); + } else { + $zip->addFile($ruta_real, $ruta_relativa_zip); + } + } + } + + // Añadir de forma recursiva la carpeta de fotos de productos cargados (../img) + $ruta_img_productos = "../img"; + if (file_exists($ruta_img_productos)) { + $archivos_productos = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($ruta_img_productos, RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::SELF_FIRST + ); + + foreach ($archivos_productos as $item) { + $ruta_real = $item->getRealPath(); + // Lo guardamos estructurado bajo una carpeta propia dentro del ZIP + $ruta_relativa_zip = "imagenes_productos/" . substr($ruta_real, strlen(realpath($ruta_img_productos)) + 1); + + if ($item->isDir()) { + $zip->addEmptyDir($ruta_relativa_zip); + } else { + $zip->addFile($ruta_real, $ruta_relativa_zip); + } + } + } + + // Cerramos y guardamos definitivamente el archivo ZIP + $zip->close(); + + // Borramos el archivo .sql suelto temporal para no duplicar espacio en el disco duro + unlink($ruta_sql_temporal); + + header("Location: backup.php?status=success&file=$nombre_zip"); + } else { + header("Location: backup.php?status=error_zip"); + } + } else { + header("Location: backup.php?status=error_sql"); + } + exit(); +} + +if (isset($_GET['status'])) { + if ($_GET['status'] === 'success') { + $file = htmlspecialchars($_GET['file']); + $mensaje = "¡Copia de seguridad del sistema completo generada con éxito! Archivo: $file"; + $tipo_mensaje = "success"; + } elseif ($_GET['status'] === 'error_sql') { + $mensaje = "Error al generar el volcado SQL de la Base de Datos. Verifique la ruta de mysqldump en XAMPP."; + $tipo_mensaje = "error"; + } elseif ($_GET['status'] === 'error_zip') { + $mensaje = "Error al comprimir el archivo ZIP. Asegúrese de que PHP tenga extensiones activas y permisos de escritura."; + $tipo_mensaje = "error"; + } +} + +// Escaneamos la carpeta buscando únicamente los archivos ZIP generados +$archivos_guardados = array_diff(scandir($carpeta_backups), array('.', '..')); +$archivos_guardados = array_filter($archivos_guardados, function($archivo) { + return pathinfo($archivo, PATHINFO_EXTENSION) === 'zip'; +}); +rsort($archivos_guardados); +?> + + + + + + + Copia de Seguridad - La Pecosa + + + + + + + + +
+ + + + +
+ + +
+ + +
+
+

Respaldar sistema completo e infraestructura

+

+ Al hacer clic en el botón se empaquetará un archivo comprimido .ZIP conteniendo el volcado SQL de la base de datos (tablas, pedidos, menú), los archivos de conexión y configuración del sistema, junto con la totalidad de imágenes y recursos multimedia subidos por la administración de La Pecosa. +

+
+
+ +
+
+ +
+

Respaldos integrales guardados en el servidor

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Nombre del Archivo CompletoTipo de PaqueteUbicación en ServidorAcción
+
+ No se encontraron paquetes comprimidos de seguridad. +
ZIP (BD + Archivos)/admin/backups_files/ + + Descargar .zip + +
+
+ +
+ + + \ No newline at end of file diff --git a/admin/descargar_file.php b/admin/descargar_file.php new file mode 100644 index 0000000..63dd38e --- /dev/null +++ b/admin/descargar_file.php @@ -0,0 +1,34 @@ + \ No newline at end of file