';}
}
window.acDoLogin=doLogin;
window.acDoLogout=function(){loggedIn=false;renderAdmin();};
function renderAdmin(){
document.getElementById('ac-admin-lock').style.display=loggedIn?'none':'block';
document.getElementById('ac-admin-panel').style.display=loggedIn?'block':'none';
if(loggedIn){renderOrders();renderSMS();}
}
function doTrack(){
var key=document.getElementById('ac-track-input').value.trim().toUpperCase();
var box=document.getElementById('ac-track-result');
box.innerHTML='
Recherche en cours...
';
function showResult(){
var o=orders[key];
if(!o){
fetch(GSHEET+'?action=getOne&id='+key)
.then(function(r){return r.json();})
.then(function(data){
if(data&&data.id){
try{if(typeof data.items==='string')data.items=JSON.parse(data.items);}catch(e){data.items=[];}
orders[key]=data;saveLocal();
}
renderTrackResult(key,box);
})
.catch(function(){renderTrackResult(key,box);});
}else{renderTrackResult(key,box);}
}
showResult();
}
window.acDoTrack=doTrack;
function renderTrackResult(key,box){
var o=orders[key];
if(!o){box.innerHTML='
';
var steps=o.steps||[];
STEPS.forEach(function(s,i){
var done=i
'+
(done?'':'')+
'
'+(i<4?'':'')+'
'+
'
'+s+'
'+
(steps[i]&&steps[i].date?'
'+steps[i].date+'
':'')+
(steps[i]&&steps[i].note?'
'+steps[i].note+'
':'')+
'
';
});
tl+='';
var etaF=o.eta?fmtDate(o.eta):null;
box.innerHTML='
'+
'
'+
'
'+key+'
'+o.customer+'
'+
''+STEPS[o.currentStep]+'
'+
(etaF?'
Livraison estim\u00e9e : '+etaF+'
':'')+
tl+'
';
}
function smsText(id,o,step){
var name=o.customer.split(' ')[0];
var eta=etaAuto(o);
var etaTxt=eta?'\nLivraison pr\u00e9vue le '+eta+'.':'';
var nb=(o.items&&o.items.length)||1;
var art=nb>1?nb+' articles':((o.items&&o.items[0]&&o.items[0].description)||'votre commande');
var link='\n\nSuivi de votre commande :\nhttps://anastasi-couture.ch/suivi-de-votre-commande?order='+id;
var base='Bonjour '+name+',\nN\u00b0 '+id+' \u2014 '+art+'.'+etaTxt;
if(step===0)return base+'\nVotre commande a bien \u00e9t\u00e9 enregistr\u00e9e chez Anastasi Couture.'+link;
if(step===1||step===2)return base+'\nVotre commande est en production.'+link;
if(step===3)return base+'\nVotre commande est en cours de livraison.'+link;
return 'Bonjour '+name+',\nN\u00b0 '+id+' \u2014 '+art+'.\nVotre commande est pr\u00eate \u00e0 \u00eatre r\u00e9cup\u00e9r\u00e9e \u00e0 notre atelier.\nAu plaisir de vous accueillir ! \u2014 Anastasi Couture'+link;
}
window.acSmsText=smsText;
function addSMS(id,o,step){
var now=new Date().toLocaleString('fr-FR',{day:'numeric',month:'short',year:'numeric',hour:'2-digit',minute:'2-digit'});
smsList.unshift({id:id,customer:o.customer,phone:o.phone||'',text:smsText(id,o,step),time:now});
if(smsList.length>100)smsList.pop();
saveLocal();
}
function waUrl(phone,text){
var p=(phone||'').toString().trim().replace(/[\s\-\(\)\.]/g,'');
if(p.startsWith('00'))p=p.slice(2);
if(p.startsWith('+'))p=p.slice(1);
if(p.length===9)p='41'+p;
return 'https://wa.me/'+p+'?text='+encodeURIComponent(text);
}
function renderSMS(){
var box=document.getElementById('ac-sms-list');
var cnt=document.getElementById('ac-sms-count');
if(cnt)cnt.textContent=smsList.length?'('+smsList.length+')':'';
if(!box)return;
if(!smsList.length){box.innerHTML='
';
}).join('');
box.querySelectorAll('.ac-copy-btn').forEach(function(btn){
btn.addEventListener('click',function(){
var i=parseInt(btn.getAttribute('data-i'));
try{navigator.clipboard.writeText(smsList[i].text);}catch(e){}
btn.textContent='Copi\u00e9 !';setTimeout(function(){btn.textContent='Copier';},2000);
});
});
}
function renderOrders(){
var box=document.getElementById('ac-order-list');
if(!box)return;
var keys=Object.keys(orders);
if(!keys.length){box.innerHTML='
Aucune commande.
';return;}
box.innerHTML=keys.map(function(k){
var o=orders[k];
var nb=(o.items&&o.items.length)||1;
var bc=o.currentStep===4?'ac-badge-done':o.currentStep===3?'ac-badge-shipped':'ac-badge-progress';
var wa=o.phone?''+
'WA':'';
return '
';
}).join('');
box.querySelectorAll('.ac-prefill-btn').forEach(function(btn){
btn.addEventListener('click',function(){
var id=btn.getAttribute('data-id');
document.getElementById('ac-upd-id').value=id;
document.getElementById('ac-upd-status').value=orders[id].currentStep;
document.getElementById('ac-upd-note').value='';
document.getElementById('ac-upd-eta').value=orders[id].eta||'';
document.getElementById('ac-upd-id').scrollIntoView({behavior:'smooth',block:'center'});
});
});
box.querySelectorAll('.ac-del-btn').forEach(function(btn){
btn.addEventListener('click',function(){
var id=btn.getAttribute('data-id');
if(!confirm('Supprimer la commande '+id+' ?'))return;
delete orders[id];saveLocal();deleteFromSheet(id);renderOrders();
});
});
}
window.acCreateOrder=function(){
var id=document.getElementById('ac-new-id').value.trim().toUpperCase();
var customer=document.getElementById('ac-new-customer').value.trim();
var item=document.getElementById('ac-new-item').value.trim();
var eta=document.getElementById('ac-new-eta').value;
var phone=document.getElementById('ac-new-phone').value.trim();
var msg=document.getElementById('ac-create-msg');
if(!id||!customer||!item){msg.innerHTML='
Remplissez tous les champs.
';return;}
if(orders[id]){msg.innerHTML='
Ce num\u00e9ro existe d\u00e9j\u00e0.
';return;}
var today=new Date().toLocaleDateString('fr-FR',{day:'numeric',month:'long',year:'numeric'});
var o={id:id,customer:customer,phone:phone,items:[{ref:id,description:item,fabric:''}],placed:today,placedIso:new Date().toISOString(),eta:eta||null,currentStep:0,steps:[{date:today,note:'Commande cr\u00e9\u00e9e.'},{date:null,note:null},{date:null,note:null},{date:null,note:null},{date:null,note:null}]};
orders[id]=o;addSMS(id,o,0);saveLocal();saveLocal();renderOrders();renderSMS();
msg.innerHTML='
Commande '+id+' cr\u00e9\u00e9e.
';
['ac-new-id','ac-new-customer','ac-new-item','ac-new-phone'].forEach(function(f){document.getElementById(f).value='';});
document.getElementById('ac-new-eta').value='';
setTimeout(function(){msg.innerHTML='';},3000);
};
window.acUpdateOrder=function(){
var id=document.getElementById('ac-upd-id').value.trim().toUpperCase();
var step=parseInt(document.getElementById('ac-upd-status').value);
var note=document.getElementById('ac-upd-note').value.trim();
var eta=document.getElementById('ac-upd-eta').value;
var msg=document.getElementById('ac-update-msg');
if(!id||!orders[id]){msg.innerHTML='
Commande introuvable.
';return;}
orders[id].currentStep=step;
if(eta)orders[id].eta=eta;
var today=new Date().toLocaleDateString('fr-FR',{day:'numeric',month:'long',year:'numeric'});
if(!orders[id].steps)orders[id].steps=[{date:today,note:''},{date:null,note:null},{date:null,note:null},{date:null,note:null},{date:null,note:null}];
orders[id].steps[step]={date:today,note:note||null};
addSMS(id,orders[id],step);saveLocal();saveLocal();renderOrders();renderSMS();
msg.innerHTML='
Commande '+id+' mise \u00e0 jour.
';
setTimeout(function(){msg.innerHTML='';},3000);
};
function statusToStep(s){
if(!s)return 0;s=s.toLowerCase().trim();
if(s.includes('stock'))return 4;
if(s.includes('on deliv')||s.includes('delivery'))return 3;
if(s.includes('logist')||s.includes('ship'))return 3;
if(s.includes('produc')||s.includes('sew'))return 2;
if(s.includes('cut')||s.includes('pattern')||s.includes('measure'))return 1;
if(s.includes('arriv')||s.includes('pickup')||s.includes('gva'))return 4;
return 0;
}
window.acHandleFile = handleExcelFile;
window.acProcessExcel = function(rows, msgEl){
var today=new Date().toLocaleDateString('fr-FR',{day:'numeric',month:'long',year:'numeric'});
var byClient={};
rows.forEach(function(r){
var name=(r['Client Name']||r['client name']||'').toString().trim();
if(!name)return;
if(!byClient[name])byClient[name]=[];
byClient[name].push(r);
});
var imported=0,updated=0,toSave=[];
Object.keys(byClient).forEach(function(name){
var clientRows=byClient[name];
var phone=(clientRows[0]['Phone']||clientRows[0]['phone']||'').toString().trim();
var items=clientRows.map(function(r){return{ref:(r['OrderNO.']||'').toString(),description:(r['Clothing Category']||'').toString(),fabric:(r['Fabric']||'').toString()};});
var maxStep=0;
clientRows.forEach(function(r){var s=statusToStep((r['Status']||'').toString());if(s>maxStep)maxStep=s;});
var existingId=null;
Object.keys(orders).forEach(function(k){if(orders[k].customer===name)existingId=k;});
if(existingId){
if(phone&&!orders[existingId].phone)orders[existingId].phone=phone;
if(maxStep>orders[existingId].currentStep){
orders[existingId].currentStep=maxStep;
if(!orders[existingId].steps)orders[existingId].steps=[null,null,null,null,null].map(function(){return{date:null,note:null};});
orders[existingId].steps[maxStep]={date:today,note:'Mis à jour depuis Excel.'};
addSMS(existingId,orders[existingId],maxStep);
}
toSave.push(orders[existingId]);updated++;
}else{
var ini=name.split(' ').map(function(p){return p[0]||'';}).join('').toUpperCase().slice(0,2);
var num=String(Math.floor(Math.random()*9000+1000));
var acId='AC-'+ini+num;
while(orders[acId]){num=String(parseInt(num)+1);acId='AC-'+ini+num;}
var steps=[{date:today,note:'Importé depuis Excel.'},{date:null,note:null},{date:null,note:null},{date:null,note:null},{date:null,note:null}];
if(maxStep>0)steps[maxStep]={date:today,note:"Statut à l'import."};
var o={id:acId,customer:name,phone:phone,items:items,placed:today,placedIso:new Date().toISOString(),eta:null,currentStep:maxStep,steps:steps};
orders[acId]=o;toSave.push(o);imported++;
}
});
saveLocal();
fetch(GSHEET,{method:'POST',body:JSON.stringify({action:'saveAll',orders:toSave})}).catch(function(){});
renderOrders();renderSMS();
if(msgEl)msgEl.innerHTML='
'+imported+' commande'+(imported>1?'s':'')+' importée'+(imported>1?'s':'')+''+(updated?' — '+updated+' mise'+(updated>1?'s':'')+' à jour':'')+' — Sync Google Sheets...
';
setTimeout(function(){if(msgEl)msgEl.innerHTML='';},6000);
};
// Listen for import event from iframe
window.addEventListener('ac_import', function(e){
var msgEl=document.getElementById('ac-import-msg');
if(e.detail&&Array.isArray(e.detail))window.acProcessExcel(e.detail,msgEl);
});
document.addEventListener('ac_import', function(e){
var msgEl=document.getElementById('ac-import-msg');
if(e.detail&&Array.isArray(e.detail))window.acProcessExcel(e.detail,msgEl);
});
function handleExcelFile(file){
var msg=document.getElementById('ac-import-msg');
msg.innerHTML='
Import en cours...
';
var reader=new FileReader();
reader.onload=function(e){
try{
var wb=XLSX.read(e.target.result,{type:'array'});
var orderSheet=wb.SheetNames[0];
wb.SheetNames.forEach(function(sn){if(sn.toLowerCase().includes('order'))orderSheet=sn;});
var rows=XLSX.utils.sheet_to_json(wb.Sheets[orderSheet]);
var today=new Date().toLocaleDateString('fr-FR',{day:'numeric',month:'long',year:'numeric'});
var byClient={};
rows.forEach(function(r){
var name=(r['Client Name']||r['client name']||'').toString().trim();
if(!name)return;
if(!byClient[name])byClient[name]=[];
byClient[name].push(r);
});
var imported=0,updated=0;
var toSave=[];
Object.keys(byClient).forEach(function(name){
var clientRows=byClient[name];
var phone=(clientRows[0]['Phone']||clientRows[0]['phone']||'').toString().trim();
var items=clientRows.map(function(r){
return{ref:(r['OrderNO.']||'').toString(),description:(r['Clothing Category']||'').toString(),fabric:(r['Fabric']||'').toString()};
});
var maxStep=0;
clientRows.forEach(function(r){var s=statusToStep((r['Status']||'').toString());if(s>maxStep)maxStep=s;});
var existingId=null;
Object.keys(orders).forEach(function(k){if(orders[k].customer===name)existingId=k;});
if(existingId){
if(phone&&!orders[existingId].phone)orders[existingId].phone=phone;
if(maxStep>orders[existingId].currentStep){
orders[existingId].currentStep=maxStep;
if(!orders[existingId].steps)orders[existingId].steps=[null,null,null,null,null].map(function(){return{date:null,note:null};});
orders[existingId].steps[maxStep]={date:today,note:'Mis \u00e0 jour depuis Excel.'};
addSMS(existingId,orders[existingId],maxStep);
}
toSave.push(orders[existingId]);
updated++;
}else{
var ini=name.split(' ').map(function(p){return p[0]||'';}).join('').toUpperCase().slice(0,2);
var num=String(Math.floor(Math.random()*9000+1000));
var acId='AC-'+ini+num;
while(orders[acId]){num=String(parseInt(num)+1);acId='AC-'+ini+num;}
var steps=[{date:today,note:'Import\u00e9 depuis Excel.'},{date:null,note:null},{date:null,note:null},{date:null,note:null},{date:null,note:null}];
if(maxStep>0)steps[maxStep]={date:today,note:"Statut \u00e0 l'import."};
var o={id:acId,customer:name,phone:phone,items:items,placed:today,placedIso:new Date().toISOString(),eta:null,currentStep:maxStep,steps:steps};
orders[acId]=o;toSave.push(o);imported++;
}
});
saveLocal();
fetch(GSHEET,{method:'POST',body:JSON.stringify({action:'saveAll',orders:toSave})})
.then(function(){renderOrders();renderSMS();})
.catch(function(){renderOrders();renderSMS();});
msg.innerHTML='
'+imported+' commande'+(imported>1?'s':'')+' import\u00e9e'+(imported>1?'s':'')+''+(updated?' \u2014 '+updated+' mise'+(updated>1?'s':'')+' \u00e0 jour':'')+' \u2014 Synchronisation Google Sheets en cours...