Browse Source

cart count, and error catching

latapp 10 tháng trước cách đây
mục cha
commit
3d9c4c5ae6
4 tập tin đã thay đổi với 62 bổ sung24 xóa
  1. 5 1
      main.py
  2. 10 5
      public/index.html
  3. 32 18
      public/js/app.js
  4. 15 0
      public/styles.css

+ 5 - 1
main.py

@@ -1,6 +1,7 @@
 import csv
 import os
 import json
+import re
 import secrets
 from typing import List, Dict, Union, Annotated
 
@@ -211,7 +212,10 @@ async def printer_order(order: OrderWeb):
     table = order.table
     printer = PrinterUSB(0xfe6,0x811e)
     print_order = Order(order.customerName,[Item(item.name, item.price, item.quantity) for item in items])
-    printer.print_order(print_order, table)
+    try:
+        printer.print_order(print_order, table)
+    except:
+        return JSONResponse(status_code=424, content={"message": "No se pudo imprimir el Pedido, impresora desconectada"})
     if not os.path.exists('logs.csv'):
         with open('logs.csv', 'w', newline='') as f:
             writer = csv.writer(f)

+ 10 - 5
public/index.html

@@ -58,6 +58,8 @@
             <div class="flex items-center gap-3">
               <button class="add-to-cart-btn flex items-center gap-1 w-fit h-8 px-3
                              rounded-full bg-[#101419] hover:bg-[#37404a] text-white text-sm font-medium">
+                             
+                
                 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
                   <path d="M12 5v14m7-7H5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                 </svg>
@@ -130,11 +132,14 @@
         <span class="text-xs font-medium">Menú</span>
       </button>
       <button data-target="cartTab" class="tab-btn flex-1 flex flex-col items-center text-[#58728d]">
-        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
-             viewBox="0 0 256 256" class="h-8">
-          <path
-            d="M222.14,58.87A8,8,0,0,0,216,56H54.68L49.79,29.14A16,16,0,0,0,34.05,16H16a8,8,0,0,0,0,16h18L59.56,172.29a24,24,0,0,0,5.33,11.27,28,28,0,1,0,44.4,8.44h45.42A27.75,27.75,0,0,0,152,204a28,28,0,1,0,28-28H83.17a8,8,0,0,1-7.87-6.57L72.13,152h116a24,24,0,0,0,23.61-19.71l12.16-66.86A8,8,0,0,0,222.14,58.87ZM96,204a12,12,0,1,1-12-12A12,12,0,0,1,96,204Zm96,0a12,12,0,1,1-12-12A12,12,0,0,1,192,204Zm4-74.57A8,8,0,0,1,188.1,136H69.22L57.59,72H206.41Z" />
-        </svg>
+        <div id="cartIcon">
+          <span id="cartCount">0</span>
+          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
+               viewBox="0 0 256 256" class="h-8">
+            <path
+              d="M222.14,58.87A8,8,0,0,0,216,56H54.68L49.79,29.14A16,16,0,0,0,34.05,16H16a8,8,0,0,0,0,16h18L59.56,172.29a24,24,0,0,0,5.33,11.27,28,28,0,1,0,44.4,8.44h45.42A27.75,27.75,0,0,0,152,204a28,28,0,1,0,28-28H83.17a8,8,0,0,1-7.87-6.57L72.13,152h116a24,24,0,0,0,23.61-19.71l12.16-66.86A8,8,0,0,0,222.14,58.87ZM96,204a12,12,0,1,1-12-12A12,12,0,0,1,96,204Zm96,0a12,12,0,1,1-12-12A12,12,0,0,1,192,204Zm4-74.57A8,8,0,0,1,188.1,136H69.22L57.59,72H206.41Z" />
+          </svg>
+        </div>
         <span class="text-xs font-medium">Carrito</span>
       </button>
     </nav>

+ 32 - 18
public/js/app.js

@@ -4,7 +4,7 @@ let userName = '';
 let userTable = null;
 
 let products = [];
-
+let itsEmpty = true;
 let cart = [];
 let chatHistory = [
     { role: "system", content: "¡Hola! Soy tu asistente en Biergarten Klein. ¿Te gustaría una recomendación de nuestras cervezas artesanales?" }
@@ -17,24 +17,13 @@ const cartTotalElement = document.getElementById("cartTotal");
 const emptyCartTextElement = document.getElementById("emptyCartText");
 const checkoutButton = document.getElementById("checkoutButton");
 const originalCheckoutButtonText = checkoutButton ? checkoutButton.textContent : "Finalizar Pedido";
-
+console.log(originalCheckoutButtonText)
 const chatMessagesElement = document.getElementById("chatMessages");
 const chatInputElement = document.getElementById("chatInput");
 const sendChatButton = document.getElementById("sendChatButton");
 const aiLoadingIndicator = document.getElementById("aiLoadingIndicator");
 
-// --- Modales ---
-const welcomeModal = document.getElementById("welcomeModal");
-const startOrderButton = document.getElementById("startOrderButton");
-const userNameInput = document.getElementById("userNameInput");
-const userTableInput = document.getElementById("userTableInput");
-
-const orderConfirmationModal = document.getElementById("orderConfirmationModal");
-const closeConfirmationModalButton = document.getElementById("closeConfirmationModalButton");
-const orderErrorModal = document.getElementById("orderErrorModal");
-const closeOrderErrorModalButton = document.getElementById("closeOrderErrorModalButton");
-const newOrderButton = document.getElementById("newOrderButton");
-const retryButton = document.getElementById("retryButton");
+const cartCountElement = document.getElementById("cartCount");
 
 // --- Loader Global ---
 let globalLoaderElement = null;
@@ -95,9 +84,11 @@ async function processOrder() {
         console.error("Error al procesar la orden:", error);
         alert(`Hubo un problema: ${error.message || "Por favor, inténtalo de nuevo."}`);
         
+        
     } finally {
         hideGlobalLoader();
         checkoutButton.disabled = cart.length === 0;
+        checkoutButton.textContent = originalCheckoutButtonText
 
     }
 }
@@ -120,9 +111,6 @@ async function renderProducts() {
         clone.querySelector(".product-price").textContent = formatPrice(product.price);
         clone.querySelector(".product-image").style.backgroundImage = `url('${product.image}')`;
 
-        const button = clone.querySelector(".product-price");
-        button.dataset.productId = product.id;
-        button.classList.add("add-to-cart-btn");
         const addBtn = clone.querySelector(".add-to-cart-btn");
         addBtn.dataset.productId = product.id;   // el listener usa esta info
 
@@ -180,12 +168,38 @@ window.removeFromCart = (productId, removeAll = false) => {
 };
 
 function updateCartDisplay() {
-    if (!cartItemsElement || !emptyCartTextElement || !checkoutButton) return;
+    if (!cartItemsElement || !emptyCartTextElement || !checkoutButton || !cartCountElement) return;
     cartItemsElement.innerHTML = "";
+    cartCountElement.textContent = cart.length;
     if (cart.length === 0) {
+        cartCountElement.classList.add("hidden");
         emptyCartTextElement.classList.remove("hidden");
         checkoutButton.disabled = true;
+        itsEmpty = true;
     } else {
+        cartCountElement.classList.remove("hidden");
+        if (cartCountElement && itsEmpty) {
+            itsEmpty = false;
+            cartCountElement.animate([
+                { transform: 'scale(0)' },
+                { transform: 'scale(1)' }
+            ],{
+                duration: 300,
+                iterations: 1,
+                easing: 'ease-in-out'
+            })
+        }else {
+            cartCountElement.animate([
+                { transform: 'scale(1) rotate(0deg)' },
+                { transform: 'scale(1.2) rotate(180deg)' },
+                { transform: 'scale(1) rotate(360deg)' }
+
+            ], {
+                duration: 300,
+                iterations: 1,
+                easing: 'ease-in-out'
+            })
+        }
         emptyCartTextElement.classList.add("hidden");
         checkoutButton.disabled = false;
         cart.forEach(item => {

+ 15 - 0
public/styles.css

@@ -152,6 +152,21 @@ footer.bg-black { background-color: var(--background-header); }
     margin: 0 auto;
 }
 
+#cartIcon{
+    position: relative;
+}
+#cartCount{
+    position: absolute;
+    top: -20%;
+    left: -20%;
+    width: 20px;
+    height: 20px;
+    border-radius: 50%;
+    background: red;
+    color: white;
+    
+
+}
 @keyframes spin {
     0% { transform: rotate(0deg); }
     100% { transform: rotate(360deg); }