Spaces:
Paused
Paused
Upload src/app.js
#6
by bep40 - opened
- src/app.js +45 -14
src/app.js
CHANGED
|
@@ -127,7 +127,7 @@ const chatMessages = /** @type {HTMLElement} */ ($("#chat-messages"));
|
|
| 127 |
const chatInput = /** @type {HTMLInputElement} */ ($("#chat-input"));
|
| 128 |
const chatSendBtn = /** @type {HTMLButtonElement} */ ($("#chat-send-btn"));
|
| 129 |
const chatCloseBtn = /** @type {HTMLButtonElement} */ ($("#chat-close-btn"));
|
| 130 |
-
const chatResizeHandle = /** @type {HTMLElement} */ ($("#
|
| 131 |
const chatAvatarSelect = /** @type {HTMLSelectElement} */ ($("#chat-avatar-select"));
|
| 132 |
const settingsAvatarSelect = /** @type {HTMLSelectElement} */ ($("#settings-avatar-select"));
|
| 133 |
|
|
@@ -644,17 +644,19 @@ async function loadVaistudioProducts(loadMore = false) {
|
|
| 644 |
}
|
| 645 |
}
|
| 646 |
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
|
|
|
|
|
|
|
| 658 |
}
|
| 659 |
|
| 660 |
function clientSearch(q) { const norm=_sd(q),terms=norm.split(/\s+/).filter(t=>t.length>1); const r=vaistudioAllProducts.filter(p=>{const s=[_sd(p.title_clean||""),_sd(p.sku||""),_sd(p.brand||""),_sd(p.category||"")].join(" "); return terms.every(t=>s.includes(t));}); _lastSearchResults=r; renderPaginated(r); if(vaistudioCount) vaistudioCount.textContent=r.length+" kết quả"; }
|
|
@@ -667,9 +669,38 @@ function initVAISTUDIO() {
|
|
| 667 |
const cb = document.getElementById("vaistudio-close"); if (cb) cb.addEventListener("click", () => { vaistudioPanelOpen = false; vaistudioPanel.classList.remove("open"); vaistudioToggle.classList.remove("active"); });
|
| 668 |
const rb = document.getElementById(VAISTUDIO_RETRY_ID); if (rb) rb.addEventListener("click", () => { vaistudioProductsLoaded = false; vaistudioVisibleCount = 0; vaistudioAllProducts = []; if (vaistudioLoading) vaistudioLoading.classList.remove("hidden"); if (vaistudioErrorEl) vaistudioErrorEl.style.display = "none"; loadVaistudioProducts(); });
|
| 669 |
const si = document.getElementById("vaix-search"); if (si) { let st = null; si.addEventListener("input", () => { if (st) clearTimeout(st); st = setTimeout(() => searchP(si.value), 300); }); si.addEventListener("keydown", (e) => { if (e.key === "Enter") { if (st) clearTimeout(st); searchP(si.value); } }); }
|
| 670 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 671 |
}
|
|
|
|
| 672 |
async function vaistudioOpenCatalog(cat) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Opened"+(cat?": "+cat:"")}; }
|
| 673 |
async function vaistudioOpenProduct(pid) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Opened product "+pid}; }
|
| 674 |
async function vaistudioSearch(query) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); await searchP(query); if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Searching: "+query}; }
|
| 675 |
-
async function vaistudioNavigate(page) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); if(page==="products"){vaistudioCurrentSearch="";_lastSearchResults=[];renderPaginated(vaistudioAllProducts);} if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Navigated to "+page}; }
|
|
|
|
| 127 |
const chatInput = /** @type {HTMLInputElement} */ ($("#chat-input"));
|
| 128 |
const chatSendBtn = /** @type {HTMLButtonElement} */ ($("#chat-send-btn"));
|
| 129 |
const chatCloseBtn = /** @type {HTMLButtonElement} */ ($("#chat-close-btn"));
|
| 130 |
+
const chatResizeHandle = /** @type {HTMLElement} */ ($("#chatResizeHandle"));
|
| 131 |
const chatAvatarSelect = /** @type {HTMLSelectElement} */ ($("#chat-avatar-select"));
|
| 132 |
const settingsAvatarSelect = /** @type {HTMLSelectElement} */ ($("#settings-avatar-select"));
|
| 133 |
|
|
|
|
| 644 |
}
|
| 645 |
}
|
| 646 |
|
| 647 |
+
function searchP(q) {
|
| 648 |
+
return new Promise((resolve) => {
|
| 649 |
+
if (!q || !q.trim()) { _lastSearchResults = []; vaistudioCurrentSearch = ""; if (vaistudioAllProducts.length > 0 && vaistudioProductsLoaded) { renderPaginated(vaistudioAllProducts); if (vaistudioCount) vaistudioCount.textContent = vaistudioAllProducts.length + " sản phẩm"; } resolve(); return; }
|
| 650 |
+
vaistudioCurrentSearch = q.trim();
|
| 651 |
+
if (vaistudioProducts) { vaistudioProducts.innerHTML = ""; vaistudioProducts.style.display = "block"; }
|
| 652 |
+
if (vaistudioCount) vaistudioCount.textContent = "Đang tìm...";
|
| 653 |
+
fetch("/api/vaix/search?q=" + encodeURIComponent(q.trim())).then(r => r.json()).then(json => {
|
| 654 |
+
_lastSearchResults = (json.results || []).map(r => r.product); renderPaginated(_lastSearchResults);
|
| 655 |
+
if (vaistudioCount) vaistudioCount.textContent = _lastSearchResults.length + " kết quả";
|
| 656 |
+
if (!_lastSearchResults.length) clientSearch(q);
|
| 657 |
+
resolve();
|
| 658 |
+
}).catch(() => { clientSearch(q); resolve(); });
|
| 659 |
+
});
|
| 660 |
}
|
| 661 |
|
| 662 |
function clientSearch(q) { const norm=_sd(q),terms=norm.split(/\s+/).filter(t=>t.length>1); const r=vaistudioAllProducts.filter(p=>{const s=[_sd(p.title_clean||""),_sd(p.sku||""),_sd(p.brand||""),_sd(p.category||"")].join(" "); return terms.every(t=>s.includes(t));}); _lastSearchResults=r; renderPaginated(r); if(vaistudioCount) vaistudioCount.textContent=r.length+" kết quả"; }
|
|
|
|
| 669 |
const cb = document.getElementById("vaistudio-close"); if (cb) cb.addEventListener("click", () => { vaistudioPanelOpen = false; vaistudioPanel.classList.remove("open"); vaistudioToggle.classList.remove("active"); });
|
| 670 |
const rb = document.getElementById(VAISTUDIO_RETRY_ID); if (rb) rb.addEventListener("click", () => { vaistudioProductsLoaded = false; vaistudioVisibleCount = 0; vaistudioAllProducts = []; if (vaistudioLoading) vaistudioLoading.classList.remove("hidden"); if (vaistudioErrorEl) vaistudioErrorEl.style.display = "none"; loadVaistudioProducts(); });
|
| 671 |
const si = document.getElementById("vaix-search"); if (si) { let st = null; si.addEventListener("input", () => { if (st) clearTimeout(st); st = setTimeout(() => searchP(si.value), 300); }); si.addEventListener("keydown", (e) => { if (e.key === "Enter") { if (st) clearTimeout(st); searchP(si.value); } }); }
|
| 672 |
+
|
| 673 |
+
// Expose all VAISTUDIO state on window.vaistudio so browser console / tools can access it
|
| 674 |
+
window.vaistudio = {
|
| 675 |
+
send: (a,d={}) => {
|
| 676 |
+
if (a==="navigate" && d.page==="products") {
|
| 677 |
+
vaistudioCurrentSearch="";_lastSearchResults=[];loadVaistudioProducts();if(!vaistudioPanelOpen) vaistudioToggle.click();return{success:true};
|
| 678 |
+
}
|
| 679 |
+
if(a==="search") return searchP(d.query)||Promise.resolve();
|
| 680 |
+
return{success:false};
|
| 681 |
+
},
|
| 682 |
+
open: () => { if(!vaistudioPanelOpen) vaistudioToggle.click(); },
|
| 683 |
+
close: () => { if(vaistudioPanelOpen) vaistudioToggle.click(); },
|
| 684 |
+
isOpen: () => vaistudioPanelOpen,
|
| 685 |
+
products: () => vaistudioAllProducts,
|
| 686 |
+
search: (q) => searchP(q),
|
| 687 |
+
// Pagination state — these were previously module-scoped only
|
| 688 |
+
vaistudioCurrentPage: vaistudioCurrentPage,
|
| 689 |
+
vaistudioTotalProducts: vaistudioTotalProducts,
|
| 690 |
+
vaistudioTotalPages: vaistudioTotalPages,
|
| 691 |
+
vaistudioVisibleCount: vaistudioVisibleCount,
|
| 692 |
+
vaistudioCurrentSearch: vaistudioCurrentSearch,
|
| 693 |
+
vaistudioProductsLoaded: vaistudioProductsLoaded,
|
| 694 |
+
vaistudioAllProducts: vaistudioAllProducts,
|
| 695 |
+
_lastSearchResults: _lastSearchResults,
|
| 696 |
+
// Methods
|
| 697 |
+
_loadMoreProducts: () => loadVaistudioProducts(true),
|
| 698 |
+
_resetPage: () => { vaistudioCurrentPage = 0; vaistudioAllProducts = []; vaistudioProductsLoaded = false; if(vaistudioLoading) vaistudioLoading.classList.remove("hidden"); loadVaistudioProducts(false); },
|
| 699 |
+
_reload: () => { vaistudioProductsLoaded = false; if(vaistudioLoading) vaistudioLoading.classList.remove("hidden"); loadVaistudioProducts(false); },
|
| 700 |
+
};
|
| 701 |
}
|
| 702 |
+
|
| 703 |
async function vaistudioOpenCatalog(cat) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Opened"+(cat?": "+cat:"")}; }
|
| 704 |
async function vaistudioOpenProduct(pid) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Opened product "+pid}; }
|
| 705 |
async function vaistudioSearch(query) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); await searchP(query); if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Searching: "+query}; }
|
| 706 |
+
async function vaistudioNavigate(page) { if(!vaistudioProductsLoaded) await loadVaistudioProducts(); if(page==="products"){vaistudioCurrentSearch="";_lastSearchResults=[];renderPaginated(vaistudioAllProducts);} if(!vaistudioPanelOpen) vaistudioToggle.click(); return{success:true,message:"Navigated to "+page}; }
|