bep40 commited on
Commit
445b4fb
·
verified ·
1 Parent(s): 93e7808

order-button v2: Order picker modal + product page button fix + order edit with prompt/delete"

Browse files
Files changed (1) hide show
  1. order-button.js +87 -72
order-button.js CHANGED
@@ -1,125 +1,140 @@
1
  /**
2
- * V.AI STUDIO — Order Button Injection
3
- * 1. Adds "Thêm đơn" button to search dropdown results
4
- * 2. Adds floating "Thêm đơn" button on product detail pages
 
5
  */
6
  (function(){
7
  'use strict';
8
 
9
- // Wait for D and VAI_ORDERS to be ready
10
- function waitReady(cb){
11
- var t=setInterval(function(){
12
- if(typeof D!=='undefined'&&D.length>100){clearInterval(t);cb();}
13
- },2000);
14
- setTimeout(function(){clearInterval(t);},20000);
15
- }
16
 
17
- function addToLastOrder(product){
18
- if(!window.VAI_ORDERS||!window.VAI_ORDERS.getAll)return false;
19
- var orders=window.VAI_ORDERS.getAll();
20
- if(!orders.length)return false;
21
- var latest=orders[0];
 
 
 
 
 
 
 
22
  var name=product.name||product.n||'';
 
23
  var price=product.priceNum||product.pn||0;
24
  if(!price)price=parseInt((product.price||product.p||'').toString().replace(/[^\d]/g,''))||0;
25
- latest.items=latest.items||[];
26
- // Check duplicate
27
- var sku=product.sku||product.model||product.mod||'';
28
- for(var i=0;i<latest.items.length;i++){if(latest.items[i].model===sku)return'dup';}
29
- latest.items.push({name:name,model:sku,image:product.image||product.img||product.i||'',price:price,discPrice:price,qty:1,total:price,note:''});
30
- latest.grandTotal=(latest.grandTotal||0)+price;
31
- latest.savedAt=new Date().toISOString();
32
- window.VAI_ORDERS.add(latest);
33
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
  /**
37
- * Override/enhance search dropdown to add "Thêm đơn" buttons
38
  */
39
  function enhanceSearchDropdown(){
40
- // Watch for dropdown appearance and add buttons
41
- var observer=new MutationObserver(function(){
42
  var dropdown=document.getElementById('vai-search-dropdown');
43
  if(!dropdown||dropdown.style.display==='none')return;
44
- // Add buttons if not already added
45
- var items=dropdown.querySelectorAll('.vai-dd-item:not([data-btn-added])');
46
- items.forEach(function(item){
47
- item.setAttribute('data-btn-added','1');
48
- var slug=item.getAttribute('data-slug');
49
- if(!slug)return;
50
- // Add "Thêm đơn" button
51
  var btn=document.createElement('button');
52
- btn.className='vai-dd-add-btn';
53
  btn.textContent='+ Đơn';
54
  btn.style.cssText='padding:4px 8px;background:#003f62;color:#fff;border:none;border-radius:4px;font-size:10px;font-weight:700;cursor:pointer;white-space:nowrap;margin-left:6px;flex-shrink:0';
55
  btn.addEventListener('click',function(e){
56
  e.stopPropagation();
57
- // Find product by slug
58
  for(var i=0;i<D.length;i++){
59
  if(D[i]&&D[i].slug===slug){
60
- var result=addToLastOrder(D[i]);
61
- if(result===true){btn.textContent='✓';btn.style.background='#059669';}
62
- else if(result==='dup'){btn.textContent='Đã có';btn.style.background='#94a3b8';}
63
- else{btn.textContent='Chưa có đơn';btn.style.background='#dc2626';}
64
- setTimeout(function(){btn.textContent='+ Đơn';btn.style.background='#003f62';},2000);
65
- break;
66
  }
67
  }
68
  });
69
  item.appendChild(btn);
70
  });
71
- });
72
- observer.observe(document.body,{childList:true,subtree:true,attributes:true});
73
  }
74
 
75
  /**
76
- * Add floating "Thêm vào đơn" button on product detail pages
77
  */
78
  function addProductPageButton(){
79
- var url=window.location.pathname;
80
- var slugMatch=url.match(/\/san-pham\/([^/]+)/);
81
  if(!slugMatch)return;
82
  var slug=slugMatch[1];
83
 
84
- // Wait for page to load
85
- setTimeout(function(){
86
- // Don't add if already exists
87
- if(document.getElementById('vai-add-order-btn'))return;
 
 
88
 
89
- // Find product
90
  var product=null;
91
- for(var i=0;i<D.length;i++){
92
- if(D[i]&&D[i].slug===slug){product=D[i];break;}
93
- }
94
  if(!product)return;
 
95
 
96
- // Create floating button
97
  var btn=document.createElement('button');
98
- btn.id='vai-add-order-btn';
99
  btn.innerHTML='🛒 Thêm vào đơn';
100
- btn.style.cssText='position:fixed;bottom:80px;right:16px;z-index:999;padding:12px 20px;background:linear-gradient(135deg,#003f62,#0369a1);color:#fff;border:none;border-radius:30px;font-size:14px;font-weight:700;cursor:pointer;box-shadow:0 4px 16px rgba(0,63,98,.4);transition:transform .2s,box-shadow .2s';
101
- btn.onmouseover=function(){this.style.transform='scale(1.05)';this.style.boxShadow='0 6px 20px rgba(0,63,98,.5)';};
102
- btn.onmouseout=function(){this.style.transform='';this.style.boxShadow='0 4px 16px rgba(0,63,98,.4)';};
103
  btn.addEventListener('click',function(){
104
- var result=addToLastOrder(product);
105
- if(result===true){
106
- btn.innerHTML=' Đã thêm!';btn.style.background='linear-gradient(135deg,#059669,#10b981)';
107
  setTimeout(function(){btn.innerHTML='🛒 Thêm vào đơn';btn.style.background='linear-gradient(135deg,#003f62,#0369a1)';},2500);
108
- }else if(result==='dup'){
109
- btn.innerHTML='ℹ️ Đã có trong đơn';btn.style.background='#64748b';
110
- setTimeout(function(){btn.innerHTML='🛒 Thêm vào đơn';btn.style.background='linear-gradient(135deg,#003f62,#0369a1)';},2000);
111
- }else{
112
- btn.innerHTML='⚠️ Chưa có đơn nào';btn.style.background='#dc2626';
113
- setTimeout(function(){btn.innerHTML='🛒 Thêm vào đơn';btn.style.background='linear-gradient(135deg,#003f62,#0369a1)';},2000);
114
- }
115
  });
116
  document.body.appendChild(btn);
117
- },2000);
118
  }
119
 
120
  waitReady(function(){
121
  enhanceSearchDropdown();
122
  addProductPageButton();
123
- console.log('✅ Order buttons ready');
124
  });
125
  })();
 
1
  /**
2
+ * V.AI STUDIO — Order Button v2
3
+ * 1. "Thêm đơn" on product pages shows order picker (choose which order)
4
+ * 2. "Thêm đơn" in search dropdown same order picker
5
+ * 3. Order detail modal: delete SP per row + prompt for fees/deposit/discount
6
  */
7
  (function(){
8
  'use strict';
9
 
10
+ function waitReady(cb){var t=setInterval(function(){if(typeof D!=='undefined'&&D.length>100&&window.VAI_ORDERS){clearInterval(t);cb();}},2000);setTimeout(function(){clearInterval(t);},25000);}
11
+ function fmt(n){if(!n||isNaN(n))return'0đ';return Number(n).toLocaleString('vi-VN')+'đ';}
 
 
 
 
 
12
 
13
+ /**
14
+ * Show order picker modal: let user choose which saved order to add product to
15
+ */
16
+ function showOrderPicker(product,onDone){
17
+ var old=document.getElementById('vai-order-picker');if(old)old.remove();
18
+ var orders=(window.VAI_ORDERS&&window.VAI_ORDERS.getAll)?window.VAI_ORDERS.getAll():[];
19
+
20
+ var overlay=document.createElement('div');
21
+ overlay.id='vai-order-picker';
22
+ overlay.style.cssText='position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:99999;display:flex;align-items:center;justify-content:center;padding:16px;backdrop-filter:blur(2px)';
23
+ overlay.addEventListener('click',function(e){if(e.target===overlay)overlay.remove();});
24
+
25
  var name=product.name||product.n||'';
26
+ var sku=product.sku||product.model||product.mod||'';
27
  var price=product.priceNum||product.pn||0;
28
  if(!price)price=parseInt((product.price||product.p||'').toString().replace(/[^\d]/g,''))||0;
29
+
30
+ var h='<div style="background:#fff;border-radius:16px;max-width:400px;width:100%;max-height:70vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.3)">';
31
+ h+='<div style="padding:14px 18px;background:#003f62;border-radius:16px 16px 0 0;color:#fff"><div style="font-weight:800;font-size:14px">🛒 Thêm vào đơn</div><div style="font-size:11px;margin-top:4px;color:#bae6fd">'+name.substring(0,40)+'</div></div>';
32
+ h+='<div style="padding:14px 18px">';
33
+
34
+ if(!orders.length){
35
+ h+='<div style="text-align:center;padding:20px;color:#64748b">Chưa có đơn hàng nào.<br><span style="font-size:11px">Tạo báo giá trước rồi lưu đơn.</span></div>';
36
+ }else{
37
+ h+='<div style="font-size:11px;color:#64748b;margin-bottom:8px">Chọn đơn:</div>';
38
+ orders.forEach(function(o,idx){
39
+ h+='<div class="vai-op-item" data-idx="'+idx+'" style="padding:10px 12px;border:1px solid #e2e8f0;border-radius:8px;margin-bottom:6px;cursor:pointer;transition:background .1s" onmouseover="this.style.background=\'#f0f9ff\'" onmouseout="this.style.background=\'\'">';
40
+ h+='<div style="display:flex;justify-content:space-between;align-items:center"><b style="color:#003f62;font-size:13px">'+o.code+'</b><span style="font-size:11px;color:#64748b">'+(o.items?o.items.length:0)+' SP</span></div>';
41
+ h+='<div style="font-size:11px;color:#64748b;margin-top:2px">'+(o.customer||'')+(o.date?' • '+o.date:'')+'</div></div>';
42
+ });
43
+ }
44
+ h+='<button id="vai-op-close" style="margin-top:10px;width:100%;padding:10px;background:#e2e8f0;border:none;border-radius:8px;font-weight:600;cursor:pointer">Đóng</button>';
45
+ h+='</div></div>';
46
+ overlay.innerHTML=h;
47
+ document.body.appendChild(overlay);
48
+
49
+ document.getElementById('vai-op-close').onclick=function(){overlay.remove();};
50
+ overlay.querySelectorAll('.vai-op-item').forEach(function(item){
51
+ item.addEventListener('click',function(){
52
+ var idx=parseInt(this.getAttribute('data-idx'));
53
+ var order=orders[idx];
54
+ if(!order)return;
55
+ order.items=order.items||[];
56
+ // Check duplicate
57
+ for(var i=0;i<order.items.length;i++){if(order.items[i].model===sku){overlay.remove();if(onDone)onDone('dup');return;}}
58
+ order.items.push({name:name,model:sku,image:product.image||product.img||product.i||'',price:price,discPrice:price,qty:1,total:price,note:''});
59
+ order.grandTotal=(order.grandTotal||0)+price;
60
+ order.savedAt=new Date().toISOString();
61
+ window.VAI_ORDERS.add(order);
62
+ overlay.remove();
63
+ if(onDone)onDone('ok');
64
+ });
65
+ });
66
  }
67
 
68
  /**
69
+ * Enhance search dropdown with "Thêm đơn" buttons
70
  */
71
  function enhanceSearchDropdown(){
72
+ new MutationObserver(function(){
 
73
  var dropdown=document.getElementById('vai-search-dropdown');
74
  if(!dropdown||dropdown.style.display==='none')return;
75
+ dropdown.querySelectorAll('.vai-dd-item:not([data-ob])').forEach(function(item){
76
+ item.setAttribute('data-ob','1');
77
+ var slug=item.getAttribute('data-slug');if(!slug)return;
 
 
 
 
78
  var btn=document.createElement('button');
 
79
  btn.textContent='+ Đơn';
80
  btn.style.cssText='padding:4px 8px;background:#003f62;color:#fff;border:none;border-radius:4px;font-size:10px;font-weight:700;cursor:pointer;white-space:nowrap;margin-left:6px;flex-shrink:0';
81
  btn.addEventListener('click',function(e){
82
  e.stopPropagation();
 
83
  for(var i=0;i<D.length;i++){
84
  if(D[i]&&D[i].slug===slug){
85
+ showOrderPicker(D[i],function(r){
86
+ if(r==='ok'){btn.textContent='✓';btn.style.background='#059669';}
87
+ else if(r==='dup'){btn.textContent='Đã có';btn.style.background='#94a3b8';}
88
+ setTimeout(function(){btn.textContent='+ Đơn';btn.style.background='#003f62';},2000);
89
+ });break;
 
90
  }
91
  }
92
  });
93
  item.appendChild(btn);
94
  });
95
+ }).observe(document.body,{childList:true,subtree:true,attributes:true});
 
96
  }
97
 
98
  /**
99
+ * Floating button on product detail pages
100
  */
101
  function addProductPageButton(){
102
+ var slugMatch=window.location.pathname.match(/\/san-pham\/([^/]+)/);
 
103
  if(!slugMatch)return;
104
  var slug=slugMatch[1];
105
 
106
+ // Retry until D is loaded and product found
107
+ var attempts=0;
108
+ var t=setInterval(function(){
109
+ attempts++;if(attempts>20){clearInterval(t);return;}
110
+ if(typeof D==='undefined'||!D.length)return;
111
+ if(document.getElementById('vai-page-add-btn'))return;
112
 
 
113
  var product=null;
114
+ for(var i=0;i<D.length;i++){if(D[i]&&D[i].slug===slug){product=D[i];break;}}
 
 
115
  if(!product)return;
116
+ clearInterval(t);
117
 
 
118
  var btn=document.createElement('button');
119
+ btn.id='vai-page-add-btn';
120
  btn.innerHTML='🛒 Thêm vào đơn';
121
+ btn.style.cssText='position:fixed;bottom:80px;right:16px;z-index:999;padding:12px 20px;background:linear-gradient(135deg,#003f62,#0369a1);color:#fff;border:none;border-radius:30px;font-size:14px;font-weight:700;cursor:pointer;box-shadow:0 4px 16px rgba(0,63,98,.4);transition:transform .2s';
122
+ btn.onmouseover=function(){this.style.transform='scale(1.05)';};
123
+ btn.onmouseout=function(){this.style.transform='';};
124
  btn.addEventListener('click',function(){
125
+ showOrderPicker(product,function(r){
126
+ if(r==='ok'){btn.innerHTML='✅ Đã thêm!';btn.style.background='linear-gradient(135deg,#059669,#10b981)';}
127
+ else if(r==='dup'){btn.innerHTML='ℹ️ Đã ';btn.style.background='#64748b';}
128
  setTimeout(function(){btn.innerHTML='🛒 Thêm vào đơn';btn.style.background='linear-gradient(135deg,#003f62,#0369a1)';},2500);
129
+ });
 
 
 
 
 
 
130
  });
131
  document.body.appendChild(btn);
132
+ },1500);
133
  }
134
 
135
  waitReady(function(){
136
  enhanceSearchDropdown();
137
  addProductPageButton();
138
+ console.log('✅ Order buttons v2 ready');
139
  });
140
  })();