Explorar el Código

Add pages for optimalization, and add items counter.

Cixo Develop hace 18 horas
padre
commit
2b8786d7f7

+ 4 - 1
application/assets/languages/english.json

@@ -69,5 +69,8 @@
     "created-new-product-success": "Product created successfully!",
     "close": "Close",
     "search": "Search...",
-    "barcode-category": "Barcode"
+    "barcode-category": "Barcode",
+    "show-next": "Show more...",
+    "show-previous": "Show previous",
+    "found-count": "Found items: "
 }

+ 2 - 2
application/assets/languages/index.json

@@ -1,4 +1,4 @@
 {
-    "pl_PL": "polish.json",
-    "en_EN": "english.json"
+    "pl_PL": "polish.json?ver=02112025",
+    "en_EN": "english.json?ver=02112025"
 }

+ 4 - 1
application/assets/languages/polish.json

@@ -69,5 +69,8 @@
     "created-new-product-success": "Produkt utworzono pomyślnie!",
     "close": "Zamknij",
     "search": "Wyszukaj...",
-    "barcode-category": "Kod kreskowy"
+    "barcode-category": "Kod kreskowy",
+    "show-next": "Pokaż kolejne...",
+    "show-previous": "Pokaż poprzednie",
+    "found-count": "Znaleziono: "
 }

+ 3 - 2
application/scripts/core.js

@@ -10,7 +10,7 @@ import { color_theme } from "./color_theme.js";
 
 document.addEventListener("DOMContentLoaded", async () => {
     const languages = new cx_libtranslate.languages("app/assets/languages");
-    await languages.load("index.json");
+    await languages.load("index.json?ver=02112025");
 
     const preferences = new cx_libtranslate.preferences(languages);
     preferences.selector.insert().add_listener(() => { location.reload(); });
@@ -32,10 +32,11 @@ document.addEventListener("DOMContentLoaded", async () => {
     const login_space = document.querySelector(".top-bar .right");
     const scroll_up_button = document.querySelector(".scroll-up-button");
     const reverse_colors = document.querySelector(".reverse-colors");
+    const counter = document.querySelector(".products-counter");
     const manager = new product_containers(container);
 
     new login_bar(login_space);
     new scroll_up(scroll_up_button);
     new color_theme(reverse_colors);
-    new searcher(search_bar, manager, search_title).show_all();
+    new searcher(search_bar, manager, search_title, counter).show_all();
 });

+ 82 - 7
application/scripts/product_containers.js

@@ -5,11 +5,40 @@ export class product_containers {
     #content;
     #where;
     #inserted;
+    #counter;
+    #count;
+    #next_button;
+    #previous_button;
 
     constructor(where) {
-        this.#where = where;
+        this.#counter = 0;
+        this.#count = 24;
+        
         this.#content = new Array();
         this.#inserted = new Array();
+
+        this.#where = document.createElement("div");
+        this.#where.classList.add("products-list");
+        
+        this.#next_button = document.createElement("input");
+        this.#next_button.type = "button";
+        this.#next_button.value = _("show-next");
+
+        this.#previous_button = document.createElement("input");
+        this.#previous_button.type = "button";
+        this.#previous_button.value = _("show-previous");
+
+        this.#next_button.addEventListener("click", () => {
+            this.#next();
+        });
+
+        this.#previous_button.addEventListener("click", () => {
+            this.#previous();
+        });
+
+        where.appendChild(this.#previous_button);
+        where.appendChild(this.#where);
+        where.appendChild(this.#next_button);
     }   
     
     add_list(target) {
@@ -28,29 +57,75 @@ export class product_containers {
     }
 
     clean() {
+        this.#counter = 0;
         this.#content = new Array();
 
         return this;
     }
 
+    #update_buttons() {
+        if (this.previous_avairable) {
+            this.#previous_button.style.opacity = "1";
+        } else {
+            this.#previous_button.style.opacity = "0";
+        }
+
+        if (this.next_avairable) {
+            this.#next_button.style.opacity = "1";
+        } else {
+            this.#next_button.style.opacity = "0";
+        }
+    }
+
     update() {
+        this.#update_buttons();
         this.#hide();
 
         setTimeout(() => {
-            this.#content.forEach(count => {
-                this.#inserted.push(count);
-                count.add(this.#where);
+            const first = this.#counter;
+            const last = this.#counter + this.#count;
+            const current = this.#content.slice(first, last);
+            
+            current.forEach(count => { 
+                this.#show_sigle(count); 
             });
         }, 500);
 
         return this;
     }
 
+    get next_avairable() {
+        return (this.#counter + this.#count) <= this.#content.length;
+    }
+
+    get previous_avairable() {
+        return this.#counter >= this.#count;
+    }
+
+    #next() {
+        if (!this.next_avairable) return;
+
+        this.#counter += this.#count;
+        this.update();
+    }
+
+    #previous() {
+        if (!this.previous_avairable) return;
+
+        this.#counter -= this.#count;
+        this.#counter = this.#counter < 0 ? 0 : this.#counter;
+
+        this.update();
+    }
+
+    #show_sigle(target) {
+        this.#inserted.push(target);
+        target.add(this.#where);
+    }
+
     #hide() {
         this.#inserted.forEach(count => {
-            if (!this.#content.includes(count)) {
-                count.drop();
-            }
+            count.drop();
         });
 
         this.#inserted = new Array();

+ 13 - 1
application/scripts/searcher.js

@@ -6,6 +6,7 @@ export class searcher {
     #category;
     #manager;
     #result;
+    #counter;
 
     static #instances;
 
@@ -27,11 +28,12 @@ export class searcher {
         });
     }
     
-    constructor(search_form, manager, result) {
+    constructor(search_form, manager, result, counter) {
         this.#input = search_form.querySelector("input[type=\"text\"]");
         this.#category = search_form.querySelector("select");
         this.#manager = manager;
         this.#result = result;
+        this.#counter = counter;
 
         this.#selector_complete();
         search_form.addEventListener("submit", (target) => {
@@ -96,6 +98,14 @@ export class searcher {
         this.#insert(await this.#loader(this.phrase));
     }
 
+    set #how_many(target) { 
+        this.#counter.innerText = _("found-count") + target;
+    }
+
+    get #how_many() {
+        return this.#counter.innerText;
+    }
+
     #insert(list) {
         if (list.length === 0) {
             this.#result_title = _("not-found-anything");
@@ -103,6 +113,8 @@ export class searcher {
             this.#result_title = _("browse-our-products");
         }
 
+        this.#how_many = list.length;
+
         this.#manager
         .clean()
         .add_list(list)

+ 24 - 3
application/theme/positions.sass

@@ -60,14 +60,35 @@
 
 .products   
     display: flex
-    justify-content: space-evenly
-    align-items: stretch
+    justify-content: center
+    align-items: center
     flex-wrap: wrap
-    flex-direction: row
+    flex-direction: column
     width: calc(100% - 40px)
     margin: 20px
     gap: 20px
 
+    input[type="button"] 
+        background-color: $primary
+        color: $secondary
+        border: 2px solid $secondary
+        padding: 10px
+        border-radius: 10px
+        transition: transform 0.5s
+
+        &:hover
+            transform: scale(0.9)
+
+    .products-list
+        display: flex
+        justify-content: space-evenly
+        align-items: stretch
+        flex-wrap: wrap
+        flex-direction: row
+        width: 100%
+        margin: 0px
+        gap: 20px
+
     .top-bar-spacing
         width: 100%
 

+ 3 - 2
application/views/core.html

@@ -14,9 +14,9 @@
         <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap">
         <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
 
-        <script src="app/bundle/app.js" type="text/javascript"></script>
+        <script src="app/bundle/app.js?ver=02112025" type="text/javascript"></script>
         <script src="app/assets/cx-libtranslate.debug.js" type="text/javascript"></script>
-        <link rel="stylesheet" type="text/css" href="app/bundle/theme.css">
+        <link rel="stylesheet" type="text/css" href="app/bundle/theme.css?ver=02112025">
     </head>
 
     <body>
@@ -41,6 +41,7 @@
 
                 <div class="title">
                     <h1 class="search-title"></h1>
+                    <h3 class="products-counter"></h3>
                 </div>
             </div>
         </main>

+ 4 - 1
static/assets/languages/english.json

@@ -69,5 +69,8 @@
     "created-new-product-success": "Product created successfully!",
     "close": "Close",
     "search": "Search...",
-    "barcode-category": "Barcode"
+    "barcode-category": "Barcode",
+    "show-next": "Show more...",
+    "show-previous": "Show previous",
+    "found-count": "Found items: "
 }

+ 2 - 2
static/assets/languages/index.json

@@ -1,4 +1,4 @@
 {
-    "pl_PL": "polish.json",
-    "en_EN": "english.json"
+    "pl_PL": "polish.json?ver=02112025",
+    "en_EN": "english.json?ver=02112025"
 }

+ 4 - 1
static/assets/languages/polish.json

@@ -69,5 +69,8 @@
     "created-new-product-success": "Produkt utworzono pomyślnie!",
     "close": "Zamknij",
     "search": "Wyszukaj...",
-    "barcode-category": "Kod kreskowy"
+    "barcode-category": "Kod kreskowy",
+    "show-next": "Pokaż kolejne...",
+    "show-previous": "Pokaż poprzednie",
+    "found-count": "Znaleziono: "
 }

+ 194 - 188
static/bundle/app.js

@@ -1,27 +1,4 @@
 (() => {
-  var __accessCheck = (obj, member, msg) => {
-    if (!member.has(obj))
-      throw TypeError("Cannot " + msg);
-  };
-  var __privateGet = (obj, member, getter) => {
-    __accessCheck(obj, member, "read from private field");
-    return getter ? getter.call(obj) : member.get(obj);
-  };
-  var __privateAdd = (obj, member, value) => {
-    if (member.has(obj))
-      throw TypeError("Cannot add the same private member more than once");
-    member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
-  };
-  var __privateSet = (obj, member, value, setter) => {
-    __accessCheck(obj, member, "write to private field");
-    setter ? setter.call(obj, value) : member.set(obj, value);
-    return value;
-  };
-  var __privateMethod = (obj, member, method) => {
-    __accessCheck(obj, member, "access private method");
-    return method;
-  };
-
   // application/scripts/height_equaler.js
   var height_equaler = class {
     #to;
@@ -50,7 +27,7 @@
   };
 
   // application/scripts/product.js
-  var product = class {
+  var product = class _product {
     name;
     description;
     author;
@@ -68,22 +45,14 @@
       this.barcode = null;
       this.thumbnail = null;
       this.on_stock = null;
-      if ("name" in target)
-        this.name = target["name"];
-      if ("description" in target)
-        this.description = target["description"];
-      if ("author" in target)
-        this.author = target["author"];
-      if ("image" in target)
-        this.image = target["image"];
-      if ("stock_count" in target)
-        this.stock_count = target["stock_count"];
-      if ("barcode" in target)
-        this.barcode = target["barcode"];
-      if ("thumbnail" in target)
-        this.thumbnail = target["thumbnail"];
-      if ("on_stock" in target)
-        this.on_stock = target["on_stock"];
+      if ("name" in target) this.name = target["name"];
+      if ("description" in target) this.description = target["description"];
+      if ("author" in target) this.author = target["author"];
+      if ("image" in target) this.image = target["image"];
+      if ("stock_count" in target) this.stock_count = target["stock_count"];
+      if ("barcode" in target) this.barcode = target["barcode"];
+      if ("thumbnail" in target) this.thumbnail = target["thumbnail"];
+      if ("on_stock" in target) this.on_stock = target["on_stock"];
       try {
         this.stock_count = Number(this.stock_count);
       } catch {
@@ -111,80 +80,70 @@
       return dumped;
     }
     get ready() {
-      if (this.name === null || this.description === null)
-        return false;
-      if (this.author === null || this.image === null)
-        return false;
-      if (this.stock_count === null || this.barcode === null)
-        return false;
-      if (this.thumbnail === null)
-        return false;
+      if (this.name === null || this.description === null) return false;
+      if (this.author === null || this.image === null) return false;
+      if (this.stock_count === null || this.barcode === null) return false;
+      if (this.thumbnail === null) return false;
       return true;
     }
     copy() {
-      return new product(this.dump);
+      return new _product(this.dump);
     }
   };
 
   // application/scripts/products_loader.js
-  var _response_to_collection, response_to_collection_fn, _single_response_to_collection, single_response_to_collection_fn, _list_response_to_collection, list_response_to_collection_fn, _search, search_fn;
-  var _products_loader = class {
+  var products_loader = class _products_loader {
     static async all() {
-      var _a;
       const request2 = await fetch("/products/");
       const response = await request2.json();
-      return __privateMethod(_a = _products_loader, _response_to_collection, response_to_collection_fn).call(_a, response);
+      return _products_loader.#response_to_collection(response);
+    }
+    static #response_to_collection(response) {
+      if (response.result !== "success") {
+        return new Array();
+      }
+      if ("collection" in response) {
+        return this.#list_response_to_collection(response);
+      }
+      return this.#single_response_to_collection(response);
+    }
+    static #single_response_to_collection(response) {
+      const result = new Array();
+      result.push(new product(response.product));
+      return result;
+    }
+    static #list_response_to_collection(response) {
+      const result = new Array();
+      response.collection.forEach((serialized) => {
+        result.push(new product(serialized));
+      });
+      return result;
     }
     static async search_name(name) {
-      var _a;
-      return await __privateMethod(_a = _products_loader, _search, search_fn).call(_a, "/product/search/name", name);
+      return await _products_loader.#search(
+        "/product/search/name",
+        name
+      );
     }
     static async search_author(author) {
-      var _a;
-      return await __privateMethod(_a = _products_loader, _search, search_fn).call(_a, "/product/search/author", author);
+      return await _products_loader.#search(
+        "/product/search/author",
+        author
+      );
     }
     static async search_barcode(barcode) {
-      var _a;
-      return await __privateMethod(_a = _products_loader, _search, search_fn).call(_a, "/product/get/barcode", barcode);
-    }
-  };
-  var products_loader = _products_loader;
-  _response_to_collection = new WeakSet();
-  response_to_collection_fn = function(response) {
-    if (response.result !== "success") {
-      return new Array();
+      return await _products_loader.#search(
+        "/product/get/barcode",
+        barcode
+      );
     }
-    if ("collection" in response) {
-      return __privateMethod(this, _list_response_to_collection, list_response_to_collection_fn).call(this, response);
+    static async #search(path, parameter) {
+      const coded = encodeURI(parameter);
+      const request2 = await fetch(path + "/" + coded);
+      const response = await request2.json();
+      return _products_loader.#response_to_collection(response);
     }
-    return __privateMethod(this, _single_response_to_collection, single_response_to_collection_fn).call(this, response);
-  };
-  _single_response_to_collection = new WeakSet();
-  single_response_to_collection_fn = function(response) {
-    const result = new Array();
-    result.push(new product(response.product));
-    return result;
-  };
-  _list_response_to_collection = new WeakSet();
-  list_response_to_collection_fn = function(response) {
-    const result = new Array();
-    response.collection.forEach((serialized) => {
-      result.push(new product(serialized));
-    });
-    return result;
-  };
-  _search = new WeakSet();
-  search_fn = async function(path, parameter) {
-    var _a;
-    const coded = encodeURI(parameter);
-    const request2 = await fetch(path + "/" + coded);
-    const response = await request2.json();
-    return __privateMethod(_a = _products_loader, _response_to_collection, response_to_collection_fn).call(_a, response);
   };
-  __privateAdd(products_loader, _response_to_collection);
-  __privateAdd(products_loader, _single_response_to_collection);
-  __privateAdd(products_loader, _list_response_to_collection);
-  __privateAdd(products_loader, _search);
 
   // application/scripts/fullscreen.js
   var fullscreen = class {
@@ -596,10 +555,32 @@
     #content;
     #where;
     #inserted;
+    #counter;
+    #count;
+    #next_button;
+    #previous_button;
     constructor(where) {
-      this.#where = where;
+      this.#counter = 0;
+      this.#count = 24;
       this.#content = new Array();
       this.#inserted = new Array();
+      this.#where = document.createElement("div");
+      this.#where.classList.add("products-list");
+      this.#next_button = document.createElement("input");
+      this.#next_button.type = "button";
+      this.#next_button.value = _("show-next");
+      this.#previous_button = document.createElement("input");
+      this.#previous_button.type = "button";
+      this.#previous_button.value = _("show-previous");
+      this.#next_button.addEventListener("click", () => {
+        this.#next();
+      });
+      this.#previous_button.addEventListener("click", () => {
+        this.#previous();
+      });
+      where.appendChild(this.#previous_button);
+      where.appendChild(this.#where);
+      where.appendChild(this.#next_button);
     }
     add_list(target) {
       target.forEach((count) => {
@@ -613,24 +594,59 @@
       return this;
     }
     clean() {
+      this.#counter = 0;
       this.#content = new Array();
       return this;
     }
+    #update_buttons() {
+      if (this.previous_avairable) {
+        this.#previous_button.style.opacity = "1";
+      } else {
+        this.#previous_button.style.opacity = "0";
+      }
+      if (this.next_avairable) {
+        this.#next_button.style.opacity = "1";
+      } else {
+        this.#next_button.style.opacity = "0";
+      }
+    }
     update() {
+      this.#update_buttons();
       this.#hide();
       setTimeout(() => {
-        this.#content.forEach((count) => {
-          this.#inserted.push(count);
-          count.add(this.#where);
+        const first = this.#counter;
+        const last = this.#counter + this.#count;
+        const current = this.#content.slice(first, last);
+        current.forEach((count) => {
+          this.#show_sigle(count);
         });
       }, 500);
       return this;
     }
+    get next_avairable() {
+      return this.#counter + this.#count <= this.#content.length;
+    }
+    get previous_avairable() {
+      return this.#counter >= this.#count;
+    }
+    #next() {
+      if (!this.next_avairable) return;
+      this.#counter += this.#count;
+      this.update();
+    }
+    #previous() {
+      if (!this.previous_avairable) return;
+      this.#counter -= this.#count;
+      this.#counter = this.#counter < 0 ? 0 : this.#counter;
+      this.update();
+    }
+    #show_sigle(target) {
+      this.#inserted.push(target);
+      target.add(this.#where);
+    }
     #hide() {
       this.#inserted.forEach((count) => {
-        if (!this.#content.includes(count)) {
-          count.drop();
-        }
+        count.drop();
       });
       this.#inserted = new Array();
       return this;
@@ -638,37 +654,40 @@
   };
 
   // application/scripts/searcher.js
-  var _input, _category, _manager, _result, _instances, _add, add_fn, _selector_complete, selector_complete_fn, _loader, loader_get, _result_title, result_title_get, result_title_set, _insert, insert_fn;
-  var _searcher = class {
-    constructor(search_form, manager, result) {
-      __privateAdd(this, _selector_complete);
-      __privateAdd(this, _loader);
-      __privateAdd(this, _result_title);
-      __privateAdd(this, _insert);
-      __privateAdd(this, _input, void 0);
-      __privateAdd(this, _category, void 0);
-      __privateAdd(this, _manager, void 0);
-      __privateAdd(this, _result, void 0);
-      var _a;
-      __privateSet(this, _input, search_form.querySelector('input[type="text"]'));
-      __privateSet(this, _category, search_form.querySelector("select"));
-      __privateSet(this, _manager, manager);
-      __privateSet(this, _result, result);
-      __privateMethod(this, _selector_complete, selector_complete_fn).call(this);
-      search_form.addEventListener("submit", (target) => {
-        target.preventDefault();
-        this.update();
-      });
-      __privateMethod(_a = _searcher, _add, add_fn).call(_a, this);
+  var searcher = class _searcher {
+    #input;
+    #category;
+    #manager;
+    #result;
+    #counter;
+    static #instances;
+    static #add(instance) {
+      if (typeof _searcher.#instances !== "object") {
+        _searcher.#instances = new Array();
+      }
+      _searcher.#instances.push(instance);
     }
     static reload() {
-      if (typeof __privateGet(_searcher, _instances) !== "object") {
+      if (typeof _searcher.#instances !== "object") {
         return;
       }
-      __privateGet(_searcher, _instances).forEach((instance) => {
+      _searcher.#instances.forEach((instance) => {
         instance.update();
       });
     }
+    constructor(search_form, manager, result, counter) {
+      this.#input = search_form.querySelector('input[type="text"]');
+      this.#category = search_form.querySelector("select");
+      this.#manager = manager;
+      this.#result = result;
+      this.#counter = counter;
+      this.#selector_complete();
+      search_form.addEventListener("submit", (target) => {
+        target.preventDefault();
+        this.update();
+      });
+      _searcher.#add(this);
+    }
     get categories() {
       return {
         "name": _("name-category"),
@@ -676,73 +695,61 @@
         "barcode": _("barcode-category")
       };
     }
+    #selector_complete() {
+      const category = this.#category;
+      const categories = this.categories;
+      Object.keys(categories).forEach((name) => {
+        const option = document.createElement("option");
+        option.value = name;
+        option.innerText = categories[name];
+        category.appendChild(option);
+      });
+    }
+    get #loader() {
+      return {
+        "name": products_loader.search_name,
+        "author": products_loader.search_author,
+        "barcode": products_loader.search_barcode
+      }[this.category];
+    }
     get category() {
-      return __privateGet(this, _category).value;
+      return this.#category.value;
     }
     get phrase() {
-      return __privateGet(this, _input).value.trim();
+      return this.#input.value.trim();
+    }
+    get #result_title() {
+      return this.#result.innerText;
+    }
+    set #result_title(target) {
+      this.#result.innerText = target;
     }
     async update() {
       if (this.phrase.length === 0) {
         this.show_all();
         return;
       }
-      __privateMethod(this, _insert, insert_fn).call(this, await __privateGet(this, _loader, loader_get).call(this, this.phrase));
+      this.#insert(await this.#loader(this.phrase));
+    }
+    set #how_many(target) {
+      this.#counter.innerText = _("found-count") + target;
+    }
+    get #how_many() {
+      return this.#counter.innerText;
+    }
+    #insert(list) {
+      if (list.length === 0) {
+        this.#result_title = _("not-found-anything");
+      } else {
+        this.#result_title = _("browse-our-products");
+      }
+      this.#how_many = list.length;
+      this.#manager.clean().add_list(list).update();
     }
     async show_all() {
-      __privateMethod(this, _insert, insert_fn).call(this, await products_loader.all());
+      this.#insert(await products_loader.all());
     }
   };
-  var searcher = _searcher;
-  _input = new WeakMap();
-  _category = new WeakMap();
-  _manager = new WeakMap();
-  _result = new WeakMap();
-  _instances = new WeakMap();
-  _add = new WeakSet();
-  add_fn = function(instance) {
-    if (typeof __privateGet(_searcher, _instances) !== "object") {
-      __privateSet(_searcher, _instances, new Array());
-    }
-    __privateGet(_searcher, _instances).push(instance);
-  };
-  _selector_complete = new WeakSet();
-  selector_complete_fn = function() {
-    const category = __privateGet(this, _category);
-    const categories = this.categories;
-    Object.keys(categories).forEach((name) => {
-      const option = document.createElement("option");
-      option.value = name;
-      option.innerText = categories[name];
-      category.appendChild(option);
-    });
-  };
-  _loader = new WeakSet();
-  loader_get = function() {
-    return {
-      "name": products_loader.search_name,
-      "author": products_loader.search_author,
-      "barcode": products_loader.search_barcode
-    }[this.category];
-  };
-  _result_title = new WeakSet();
-  result_title_get = function() {
-    return __privateGet(this, _result).innerText;
-  };
-  result_title_set = function(target) {
-    __privateGet(this, _result).innerText = target;
-  };
-  _insert = new WeakSet();
-  insert_fn = function(list) {
-    if (list.length === 0) {
-      __privateSet(this, _result_title, _("not-found-anything"), result_title_set);
-    } else {
-      __privateSet(this, _result_title, _("browse-our-products"), result_title_set);
-    }
-    __privateGet(this, _manager).clean().add_list(list).update();
-  };
-  __privateAdd(searcher, _add);
-  __privateAdd(searcher, _instances, void 0);
 
   // application/scripts/delete_product_window.js
   var delete_product_window = class extends confirm_action {
@@ -1206,7 +1213,7 @@
   };
 
   // application/scripts/reservation.js
-  var reservation = class {
+  var reservation = class _reservation {
     email;
     phone_number;
     product_barcode;
@@ -1240,14 +1247,12 @@
       return dumped;
     }
     get ready() {
-      if (this.product_barcode === null)
-        return false;
-      if (this.email === null && this.phone_number === null)
-        return false;
+      if (this.product_barcode === null) return false;
+      if (this.email === null && this.phone_number === null) return false;
       return true;
     }
     copy() {
-      return new reservation(this.dump);
+      return new _reservation(this.dump);
     }
   };
 
@@ -2556,7 +2561,7 @@
   // application/scripts/core.js
   document.addEventListener("DOMContentLoaded", async () => {
     const languages = new cx_libtranslate.languages("app/assets/languages");
-    await languages.load("index.json");
+    await languages.load("index.json?ver=02112025");
     const preferences = new cx_libtranslate.preferences(languages);
     preferences.selector.insert().add_listener(() => {
       location.reload();
@@ -2575,10 +2580,11 @@
     const login_space = document.querySelector(".top-bar .right");
     const scroll_up_button = document.querySelector(".scroll-up-button");
     const reverse_colors = document.querySelector(".reverse-colors");
+    const counter = document.querySelector(".products-counter");
     const manager = new product_containers(container);
     new login_bar(login_space);
     new scroll_up(scroll_up_button);
     new color_theme(reverse_colors);
-    new searcher(search_bar, manager, search_title).show_all();
+    new searcher(search_bar, manager, search_title, counter).show_all();
   });
 })();

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
static/bundle/theme.css


+ 3 - 2
static/core.html

@@ -14,9 +14,9 @@
         <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap">
         <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
 
-        <script src="app/bundle/app.js" type="text/javascript"></script>
+        <script src="app/bundle/app.js?ver=02112025" type="text/javascript"></script>
         <script src="app/assets/cx-libtranslate.debug.js" type="text/javascript"></script>
-        <link rel="stylesheet" type="text/css" href="app/bundle/theme.css">
+        <link rel="stylesheet" type="text/css" href="app/bundle/theme.css?ver=02112025">
     </head>
 
     <body>
@@ -41,6 +41,7 @@
 
                 <div class="title">
                     <h1 class="search-title"></h1>
+                    <h3 class="products-counter"></h3>
                 </div>
             </div>
         </main>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio