Spaces:
Running
Running
RESTORE to dbc396f5 (before quote/CK/image fixes)
Browse files- index.html +41 -8
index.html
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="vi">
|
| 3 |
-
<head><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 6 |
<title>V.AI STUDIO | Niềm tin khách hàng là tài sản của chúng tôi</title>
|
|
@@ -498,7 +498,7 @@ textarea.form-input{height:120px;resize:vertical}
|
|
| 498 |
<input type="text" id="aiSearch" placeholder="🔍 AI tìm kiếm: bếp từ đôi dưới 15 triệu, máy hút mùi tốt nhất..." style="width:100%;padding:11px 14px 11px 36px;border:2px solid #003f62;border-radius:10px;font-size:.85rem;font-family:inherit;outline:none" onkeypress="if(event.key==='Enter')doAISearch()">
|
| 499 |
</div>
|
| 500 |
<button onclick="doAISearch()" style="padding:11px 20px;background:#003f62;color:#fff;border:none;border-radius:10px;font-weight:700;font-size:.85rem;cursor:pointer;white-space:nowrap"><i class="fas fa-search"></i> Tìm AI</button>
|
| 501 |
-
|
| 502 |
</div>
|
| 503 |
<div id="aiResults" style="max-width:900px;margin:12px auto 0;display:none;background:#f8fafc;border-radius:10px;padding:14px;font-size:.82rem"></div>
|
| 504 |
</div>
|
|
@@ -670,7 +670,7 @@ textarea.form-input{height:120px;resize:vertical}
|
|
| 670 |
<div id="aiPromptBox" style="display:none">
|
| 671 |
<div style="display:flex;gap:8px">
|
| 672 |
<textarea id="qcAiPrompt" placeholder="Nhập yêu cầu chiết khấu... Ví dụ: Giảm 15% tất cả sản phẩm, hoặc: SP1 giảm 2 triệu, SP2 giảm 10%..." style="flex:1;padding:8px 10px;border:1.5px solid var(--p);border-radius:8px;font-size:.82rem;font-family:inherit;outline:none;resize:none;height:48px;background:#fff"></textarea>
|
| 673 |
-
<button onclick="applyAiDiscount()" style="padding:8px 16px;background:var(--p);color:#fff;border:none;border-radius:8px;font-size:.8rem;font-weight:700;cursor:pointer;font-family:inherit;white-space:nowrap;display:flex;align-items:center;gap:6px" id="aiDiscBtn"><i class="fas fa-robot"></i> Áp dụng</button>
|
| 674 |
</div>
|
| 675 |
<div id="aiDiscStatus" style="font-size:.72rem;color:var(--g);margin-top:4px"></div>
|
| 676 |
</div>
|
|
@@ -2105,7 +2105,7 @@ let discStyle='width:80px;padding:5px 6px;border:1.5px solid var(--gl);border-ra
|
|
| 2105 |
discStyle+=locked?'background:var(--l);cursor:not-allowed':'background:#fff';
|
| 2106 |
return `<tr>
|
| 2107 |
<td style="text-align:center">${i+1}</td>
|
| 2108 |
-
<td><img class="qt-img" src="${c.image}" alt="${c.name}"
|
| 2109 |
<td class="qt-name">${c.name}</td>
|
| 2110 |
<td style="text-align:center">${model}</td>
|
| 2111 |
<td style="font-size:.72rem;color:var(--g);max-width:160px">${specs}</td>
|
|
@@ -2132,6 +2132,36 @@ total+=lineTotal;
|
|
| 2132 |
document.getElementById('quoteTotalCell').textContent=total.toLocaleString('vi-VN')+'đ';
|
| 2133 |
}
|
| 2134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2135 |
function getQuoteData(){
|
| 2136 |
let customer={
|
| 2137 |
name:document.getElementById('qcName').value||'',
|
|
@@ -2379,7 +2409,7 @@ div.id='pdfRender';
|
|
| 2379 |
div.style.cssText='position:fixed;top:-9999px;left:0;width:1100px;background:#fff;padding:40px;font-family:Inter,Arial,sans-serif';
|
| 2380 |
let itemsHtml=qd.items.map(it=>`<tr style="border-bottom:1px solid #e2e8f0">
|
| 2381 |
<td style="padding:10px 6px;text-align:center;font-size:13px">${it.stt}</td>
|
| 2382 |
-
<td style="padding:10px 6px"><img src="${it.image}" style="width:80px;height:80px;object-fit:contain;border-radius:6px;border:1px solid #e2e8f0;background:#f8fafc"
|
| 2383 |
<td style="padding:10px 6px;font-size:12px;font-weight:600">${it.name}</td>
|
| 2384 |
<td style="padding:10px 6px;text-align:center;font-size:12px">${it.model}</td>
|
| 2385 |
<td style="padding:10px 6px;font-size:11px;color:#64748b;max-width:180px">${it.specs}</td>
|
|
@@ -2616,7 +2646,7 @@ async function shareQuoteImage(){
|
|
| 2616 |
div.style.cssText='position:fixed;top:-9999px;left:0;width:1100px;background:#fff;padding:40px;font-family:Inter,Arial,sans-serif';
|
| 2617 |
let itemsHtml=qd.items.map(it=>`<tr style="border-bottom:1px solid #e2e8f0">
|
| 2618 |
<td style="padding:10px 6px;text-align:center;font-size:13px">${it.stt}</td>
|
| 2619 |
-
<td style="padding:10px 6px"><img src="${it.image}" style="width:80px;height:80px;object-fit:contain;border-radius:6px;border:1px solid #e2e8f0;background:#f8fafc"
|
| 2620 |
<td style="padding:10px 6px;font-size:12px;font-weight:600">${it.name}</td>
|
| 2621 |
<td style="padding:10px 6px;text-align:center;font-size:12px">${it.model}</td>
|
| 2622 |
<td style="padding:10px 6px;font-size:11px;color:#64748b;max-width:180px">${it.specs}</td>
|
|
@@ -2782,6 +2812,7 @@ function doAISearch(){
|
|
| 2782 |
h+='<div style="font-size:.88rem;font-weight:800;color:#003f62;margin-top:4px">'+(p.price||'Liên hệ')+'</div>';
|
| 2783 |
const specs=p.specs||{};const sk=Object.entries(specs).slice(0,3);
|
| 2784 |
if(sk.length){h+='<div style="margin-top:4px;padding-top:4px;border-top:1px solid #eee;font-size:.58rem;color:#555">';sk.forEach(([k,v])=>{h+='<div>'+k+': <b>'+v+'</b></div>'});h+='</div>'}
|
|
|
|
| 2785 |
h+='</div>';
|
| 2786 |
});
|
| 2787 |
h+='</div>';
|
|
@@ -2824,9 +2855,11 @@ async function _aiSelectProducts(q,res){
|
|
| 2824 |
});
|
| 2825 |
// Call AI to select best combo
|
| 2826 |
const aiPrompt=`Khách yêu cầu: "${q}"\nNgân sách: ${budget.toLocaleString('vi')}đ\nDanh sách SP có sẵn:\n${catalog.map((p,i)=>i+1+'. ['+p.sku+'] '+p.name+' | '+p.brand+' | '+p.price.toLocaleString('vi')+'đ | Loại: '+p.type).join('\n')}\n\nChọn combo TỐT NHẤT (1 SP mỗi loại, ưu tiên Malloca/Grob, tổng ≤ ngân sách). Trả lời CHỈ JSON: {"picks":[{"sku":"...","reason":"lý do chọn ngắn"}]}`;
|
| 2827 |
-
|
|
|
|
|
|
|
| 2828 |
method:'POST',
|
| 2829 |
-
headers:{'Content-Type':'application/json','Authorization':'Bearer '+
|
| 2830 |
body:JSON.stringify({model:'Qwen/Qwen2.5-72B-Instruct',messages:[{role:'user',content:aiPrompt}],max_tokens:300,temperature:0.7})
|
| 2831 |
});
|
| 2832 |
if(!aiRes.ok){
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="vi">
|
| 3 |
+
<head><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 6 |
<title>V.AI STUDIO | Niềm tin khách hàng là tài sản của chúng tôi</title>
|
|
|
|
| 498 |
<input type="text" id="aiSearch" placeholder="🔍 AI tìm kiếm: bếp từ đôi dưới 15 triệu, máy hút mùi tốt nhất..." style="width:100%;padding:11px 14px 11px 36px;border:2px solid #003f62;border-radius:10px;font-size:.85rem;font-family:inherit;outline:none" onkeypress="if(event.key==='Enter')doAISearch()">
|
| 499 |
</div>
|
| 500 |
<button onclick="doAISearch()" style="padding:11px 20px;background:#003f62;color:#fff;border:none;border-radius:10px;font-weight:700;font-size:.85rem;cursor:pointer;white-space:nowrap"><i class="fas fa-search"></i> Tìm AI</button>
|
| 501 |
+
|
| 502 |
</div>
|
| 503 |
<div id="aiResults" style="max-width:900px;margin:12px auto 0;display:none;background:#f8fafc;border-radius:10px;padding:14px;font-size:.82rem"></div>
|
| 504 |
</div>
|
|
|
|
| 670 |
<div id="aiPromptBox" style="display:none">
|
| 671 |
<div style="display:flex;gap:8px">
|
| 672 |
<textarea id="qcAiPrompt" placeholder="Nhập yêu cầu chiết khấu... Ví dụ: Giảm 15% tất cả sản phẩm, hoặc: SP1 giảm 2 triệu, SP2 giảm 10%..." style="flex:1;padding:8px 10px;border:1.5px solid var(--p);border-radius:8px;font-size:.82rem;font-family:inherit;outline:none;resize:none;height:48px;background:#fff"></textarea>
|
| 673 |
+
<button onclick="applyAiDiscount()" style="padding:8px 16px;background:var(--p);color:#fff;border:none;border-radius:8px;font-size:.8rem;font-weight:700;cursor:pointer;font-family:inherit;white-space:nowrap;display:flex;align-items:center;gap:6px" id="aiDiscBtn" onclick="applyLocalCK()"><i class="fas fa-robot"></i> Áp dụng</button>
|
| 674 |
</div>
|
| 675 |
<div id="aiDiscStatus" style="font-size:.72rem;color:var(--g);margin-top:4px"></div>
|
| 676 |
</div>
|
|
|
|
| 2105 |
discStyle+=locked?'background:var(--l);cursor:not-allowed':'background:#fff';
|
| 2106 |
return `<tr>
|
| 2107 |
<td style="text-align:center">${i+1}</td>
|
| 2108 |
+
<td><img class="qt-img" src="${c.image}" crossorigin="anonymous" alt="${c.name}" onerror="this.style.display='none'" style="width:72px;height:72px;object-fit:contain"></td>
|
| 2109 |
<td class="qt-name">${c.name}</td>
|
| 2110 |
<td style="text-align:center">${model}</td>
|
| 2111 |
<td style="font-size:.72rem;color:var(--g);max-width:160px">${specs}</td>
|
|
|
|
| 2132 |
document.getElementById('quoteTotalCell').textContent=total.toLocaleString('vi-VN')+'đ';
|
| 2133 |
}
|
| 2134 |
|
| 2135 |
+
function applyLocalCK(){
|
| 2136 |
+
// Read CK% from input (no API needed)
|
| 2137 |
+
let ckInput=document.getElementById('ckInput')||document.querySelector('[placeholder*="chiết khấu"]')||document.querySelector('[placeholder*="CK"]');
|
| 2138 |
+
if(!ckInput){
|
| 2139 |
+
// Create CK input if not exists
|
| 2140 |
+
let qtBody=document.querySelector('.quote-body');
|
| 2141 |
+
if(qtBody){
|
| 2142 |
+
let div=document.createElement('div');
|
| 2143 |
+
div.style.cssText='padding:8px;background:#fff3e0;border-radius:6px;margin:8px 0;display:flex;align-items:center;gap:8px';
|
| 2144 |
+
div.innerHTML='<label style="font-size:.78rem;font-weight:600">Chiết khấu %:</label><input id="ckInput" type="number" min="0" max="90" value="0" style="width:60px;padding:4px 8px;border:1.5px solid #ddd;border-radius:4px;font-size:.82rem" oninput="applyLocalCK()"><span id="ckStatus" style="font-size:.7rem;color:#28a745"></span>';
|
| 2145 |
+
qtBody.insertBefore(div,qtBody.firstChild);
|
| 2146 |
+
ckInput=document.getElementById('ckInput');
|
| 2147 |
+
}
|
| 2148 |
+
if(!ckInput)return;
|
| 2149 |
+
}
|
| 2150 |
+
let ckPercent=parseFloat(ckInput.value)||0;
|
| 2151 |
+
if(ckPercent<0||ckPercent>90)return;
|
| 2152 |
+
let status=document.getElementById('ckStatus');
|
| 2153 |
+
// Apply CK to all qt-disc inputs
|
| 2154 |
+
cart.forEach((c,i)=>{
|
| 2155 |
+
let discInput=document.querySelector('.qt-disc[data-idx="'+i+'"]');
|
| 2156 |
+
if(discInput&&c.priceNum>0){
|
| 2157 |
+
let discPrice=Math.round(c.priceNum*(1-ckPercent/100));
|
| 2158 |
+
discInput.value=discPrice.toLocaleString('vi-VN');
|
| 2159 |
+
}
|
| 2160 |
+
});
|
| 2161 |
+
if(status)status.textContent=ckPercent>0?'Áp dụng CK '+ckPercent+'%':'';
|
| 2162 |
+
updateQuoteTotal();
|
| 2163 |
+
}
|
| 2164 |
+
|
| 2165 |
function getQuoteData(){
|
| 2166 |
let customer={
|
| 2167 |
name:document.getElementById('qcName').value||'',
|
|
|
|
| 2409 |
div.style.cssText='position:fixed;top:-9999px;left:0;width:1100px;background:#fff;padding:40px;font-family:Inter,Arial,sans-serif';
|
| 2410 |
let itemsHtml=qd.items.map(it=>`<tr style="border-bottom:1px solid #e2e8f0">
|
| 2411 |
<td style="padding:10px 6px;text-align:center;font-size:13px">${it.stt}</td>
|
| 2412 |
+
<td style="padding:10px 6px"><img src="${it.image}" style="width:80px;height:80px;object-fit:contain;border-radius:6px;border:1px solid #e2e8f0;background:#f8fafc" onerror="this.style.display='none'"></td>
|
| 2413 |
<td style="padding:10px 6px;font-size:12px;font-weight:600">${it.name}</td>
|
| 2414 |
<td style="padding:10px 6px;text-align:center;font-size:12px">${it.model}</td>
|
| 2415 |
<td style="padding:10px 6px;font-size:11px;color:#64748b;max-width:180px">${it.specs}</td>
|
|
|
|
| 2646 |
div.style.cssText='position:fixed;top:-9999px;left:0;width:1100px;background:#fff;padding:40px;font-family:Inter,Arial,sans-serif';
|
| 2647 |
let itemsHtml=qd.items.map(it=>`<tr style="border-bottom:1px solid #e2e8f0">
|
| 2648 |
<td style="padding:10px 6px;text-align:center;font-size:13px">${it.stt}</td>
|
| 2649 |
+
<td style="padding:10px 6px"><img src="${it.image}" style="width:80px;height:80px;object-fit:contain;border-radius:6px;border:1px solid #e2e8f0;background:#f8fafc" onerror="this.style.display='none'"></td>
|
| 2650 |
<td style="padding:10px 6px;font-size:12px;font-weight:600">${it.name}</td>
|
| 2651 |
<td style="padding:10px 6px;text-align:center;font-size:12px">${it.model}</td>
|
| 2652 |
<td style="padding:10px 6px;font-size:11px;color:#64748b;max-width:180px">${it.specs}</td>
|
|
|
|
| 2812 |
h+='<div style="font-size:.88rem;font-weight:800;color:#003f62;margin-top:4px">'+(p.price||'Liên hệ')+'</div>';
|
| 2813 |
const specs=p.specs||{};const sk=Object.entries(specs).slice(0,3);
|
| 2814 |
if(sk.length){h+='<div style="margin-top:4px;padding-top:4px;border-top:1px solid #eee;font-size:.58rem;color:#555">';sk.forEach(([k,v])=>{h+='<div>'+k+': <b>'+v+'</b></div>'});h+='</div>'}
|
| 2815 |
+
h+='<button onclick="event.stopPropagation();addToCart('+D.indexOf(p)+')" style="margin-top:5px;width:100%;padding:5px 0;background:#003f62;color:#fff;border:none;border-radius:5px;font-size:.68rem;cursor:pointer;font-weight:600">\u{1F6D2} Th\u00eam gi\u1ECF</button>';
|
| 2816 |
h+='</div>';
|
| 2817 |
});
|
| 2818 |
h+='</div>';
|
|
|
|
| 2855 |
});
|
| 2856 |
// Call AI to select best combo
|
| 2857 |
const aiPrompt=`Khách yêu cầu: "${q}"\nNgân sách: ${budget.toLocaleString('vi')}đ\nDanh sách SP có sẵn:\n${catalog.map((p,i)=>i+1+'. ['+p.sku+'] '+p.name+' | '+p.brand+' | '+p.price.toLocaleString('vi')+'đ | Loại: '+p.type).join('\n')}\n\nChọn combo TỐT NHẤT (1 SP mỗi loại, ưu tiên Malloca/Grob, tổng ≤ ngân sách). Trả lời CHỈ JSON: {"picks":[{"sku":"...","reason":"lý do chọn ngắn"}]}`;
|
| 2858 |
+
// AI disabled (no token) - use random fallback
|
| 2859 |
+
_doQuoteFallback(wantTypes,perBudget,budget,res);return;
|
| 2860 |
+
const aiRes=null&&await fetch('https://router.huggingface.co/v1/chat/completions',{
|
| 2861 |
method:'POST',
|
| 2862 |
+
headers:{'Content-Type':'application/json','Authorization':'Bearer '+''},
|
| 2863 |
body:JSON.stringify({model:'Qwen/Qwen2.5-72B-Instruct',messages:[{role:'user',content:aiPrompt}],max_tokens:300,temperature:0.7})
|
| 2864 |
});
|
| 2865 |
if(!aiRes.ok){
|