Przeglądaj źródła

Upgrade search, and cache login

latapp 9 miesięcy temu
rodzic
commit
d0a497f429
3 zmienionych plików z 98 dodań i 9 usunięć
  1. 1 1
      auth/security.py
  2. 10 5
      public/main/index.html
  3. 87 3
      public/main/js/app.js

+ 1 - 1
auth/security.py

@@ -16,7 +16,7 @@ from services.logging_service import structured_logger, LogLevel
 logger = getLogger(__name__)
 
 ALGORITHM = "HS256"
-ACCESS_TOKEN_EXPIRE_DAYS = 60 * 24 * 7
+ACCESS_TOKEN_EXPIRE_DAYS = 7
 security = HTTPBearer()
 pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
 user_data_service = UserDataService()

+ 10 - 5
public/main/index.html

@@ -279,7 +279,7 @@
     </div>
 
     <div class="space-y-4">
-      <div>
+      <div id="emailInputContainer">
         <label for="emailInput" class="block text-sm font-medium text-gray-700 mb-2">
           Correo electrónico
         </label>
@@ -291,7 +291,7 @@
                required />
       </div>
 
-      <div>
+      <div id="pinInputContainer">
         <label for="pinInput" class="block text-sm font-medium text-gray-700 mb-2">
           PIN de 4 dígitos
         </label>
@@ -305,15 +305,14 @@
                required />
       </div>
 
-      <div>
+      <div id="tableInputContainer">
         <label for="tableInput" class="block text-sm font-medium text-gray-700 mb-2">
           Número de mesa
         </label>
         <input id="tableInput"
                name="table"
                type="number" 
-               min="1" 
-               max="99"
+               min="1"
                class="w-full border border-gray-300 px-4 py-3 rounded-lg focus:ring-2 focus:ring-[#101419] focus:border-transparent outline-none transition-all"
                placeholder="Ej: 5" 
                required />
@@ -325,6 +324,12 @@
             class="w-full bg-[#101419] hover:bg-[#37404a] text-white py-3 rounded-lg font-medium transition-colors duration-200 focus:ring-2 focus:ring-offset-2 focus:ring-[#101419]">
       Comenzar pedido
     </button>
+    <button id="logoutBtn"
+            type="button"
+            class="w-full hidden bg-gray-100 hover:bg-gray-200 text-gray-700 py-3 rounded-lg font-medium transition-colors duration-200 focus:ring-2 focus:ring-offset-2 focus:ring-gray-300">
+      Cerrar sesión
+
+    </button>
   </form>
 </div>
 

+ 87 - 3
public/main/js/app.js

@@ -7,6 +7,7 @@ import { showError } from './utils/error.js';
 import { addHistoryRow, setupShoppingCart } from './utils/shoppingCart.js';
 import { hideGUI, showGUI } from './utils/gui.js';
 import { smartSearch } from './utils/searching.js';
+import { getUserData } from './service/user.js';
 // --- Variables de Usuario ---
 let userId = -1;
 let userName = "Cliente";
@@ -16,6 +17,7 @@ let userToken = null;
 let Allproducts = [];
 let cart = [];
 let itsEmpty = true;
+let cacheMode = false
 
 // --- Categorias Importantes ---
 
@@ -68,12 +70,17 @@ async function initializeApp() {
 function initializeLoginModal() {
     const sessionModal = document.getElementById('sessionModal');
     const loginForm = document.getElementById('loginForm');
+    const logoutBtn = document.getElementById('logoutBtn');
     sessionModal.classList.remove('hidden');
 
     loginForm.addEventListener('submit', async (event) => {
         event.preventDefault();
         event.stopPropagation();
-
+        if (cacheMode) {
+            sessionModal.classList.add('hidden');
+            initializeApp();
+            return;
+        }
         const fd = new FormData(loginForm);
         const email = fd.get('email').trim();
         const pin = fd.get('pin').trim();
@@ -88,6 +95,7 @@ function initializeLoginModal() {
             userToken = data.token;
             userName = data.name;
             userId = data.id;
+            setCookie("userToken", userToken, 7);
             updateProgress(data.reward_progress || 0);
             if (!userToken || data.id === undefined) {
                 showError("Error al iniciar sesión.");
@@ -101,6 +109,25 @@ function initializeLoginModal() {
             console.error(error)
         }
     })
+    if (logoutBtn) {
+        logoutBtn.addEventListener('click', () => {
+            setCookie("userToken", "", -1); // Eliminar cookie
+            userId = -1;
+            userName = "Cliente";
+            userTable = null;
+            userToken = null;
+            cacheMode = false;
+            hideGUI();
+            sessionModal.classList.remove('hidden');
+            document.querySelector("#emailInputContainer").classList.remove("hidden");
+            document.querySelector("#pinInputContainer").classList.remove("hidden");
+            // Restaurar atributos required a los inputs
+            document.querySelector("#emailInput").setAttribute("required", "");
+            document.querySelector("#pinInput").setAttribute("required", "");
+            logoutBtn.classList.add("hidden");
+        });
+    }
+
 }   
 function initializeChat() {
     if (!chatForm) return;
@@ -132,7 +159,9 @@ function setupSearchListener() {
     searchInput.addEventListener("input", () => {
         // Limpiar el timer anterior si existe
         clearTimeout(debounceTimer);
-        
+        const specialCases = {
+            "shop": ["shop","cerveza"]
+        }
         // Agregar una clase de "buscando" para el feedback visual
         productListElement.style.opacity = "0.7";
         productListElement.style.transform = "scale(0.98)";
@@ -146,7 +175,9 @@ function setupSearchListener() {
                 return;
             }
             const finded = Allproducts.filter(product => {
-                return smartSearch(product.name.split(" "), searchTerm).length > 0;
+                const productKeywords = [product.name.split(" "), product.type.toLowerCase()].flat();
+                const specialKeywords = specialCases[product.type.toLowerCase()] || [];
+                return smartSearch([...productKeywords, ...specialKeywords], searchTerm).length > 0;
             });
             // Renderizar con animación
             renderProductsWithAnimation(finded);
@@ -156,7 +187,55 @@ function setupSearchListener() {
 //#endregion
 //#region ===== Utilidad =====
 
+function setCookie(name, value, days) {
+    const expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString();
+    document.cookie = `${name}=${value}; expires=${expires}; path=/`;
+}
+function getCookie(name) {
+    const cookies = document.cookie.split('; ');
+    for (const cookie of cookies) {
+        const [cookieName, cookieValue] = cookie.split('=');
+        if (cookieName === name) {
+            return decodeURIComponent(cookieValue);
+        }
+    }
+    return null;
+}
 
+async function checkCache() {
+    const tokenCache = getCookie("userToken");
+    let user = null
+    if (tokenCache) {
+        userToken = tokenCache;
+        try{
+            const data = await getUserData(userToken);
+            console.log(data)
+            user = data.data
+        }catch (error) {
+            console.error("Error fetching user data:", error);
+            console.error("Invalid user token, clearing cache.");
+            setCookie("userToken", "", -1); // Eliminar cookie si es inválida
+            return false;
+        }
+        if (user) {
+            console.log("User data loaded from cache:", user);
+            userId = user.id;
+            userName = user.name;
+            userTable = user.table;
+            updateProgress(user.reward_progress || 0);
+            const [emailInputContainer, pinInputContainer] = [document.getElementById("emailInputContainer"), document.getElementById("pinInputContainer")];
+            const [emailInput, pinInput] = [document.getElementById("emailInput"), document.getElementById("pinInput")];
+            emailInputContainer.classList.add("hidden");
+            emailInput.removeAttribute("required");
+            pinInputContainer.classList.add("hidden");
+            pinInput.removeAttribute("required");
+            document.querySelector("#logoutBtn").classList.remove("hidden");
+            cacheMode = true;     
+            return true
+        }
+    }
+    return cacheMode
+}
 
 function formatPrice(price) {
     return price.toLocaleString("es-CL", { style: "currency", currency: "CLP" });
@@ -700,6 +779,11 @@ function resetRewardProgress() {
 //#endregion
 // --- APP initialization ---
 document.addEventListener("DOMContentLoaded", async () => {
+    const isCacheValid = await checkCache();
+    if (!isCacheValid) {
+        // Si la caché no es válida, redirigir al usuario o mostrar un mensaje
+        console.warn("Cache is invalid");
+    }
     createGlobalLoader();
     initializeLoginModal();
     hideGUI();