(function(){ var MODE="day",WEEK=null,LAST=null,TOK=0; var C={DO:"var(--red)",VANG:"var(--brass)",XANH:"var(--teal)",CHO:"var(--muted)"}; var ST={sent:"Chưa xem",seen:"Đã xem",approved:"Đã duyệt",reviewed:"Đã nhận xét",needimprove:"Đã nhận xét",replied:"Đã phản hồi"}; var BT="padding:6px 14px;border-radius:8px;border:1px solid var(--line);background:none;color:var(--txt);cursor:pointer;font-size:13px;white-space:nowrap;font-family:inherit"; function two(n){return n<10?"0"+n:""+n;} function ymd(d){return d.getFullYear()+"-"+two(d.getMonth()+1)+"-"+two(d.getDate());} function parse(s){var a=String(s).split("-");return new Date(+a[0],+a[1]-1,+a[2]);} function monOf(d){var x=new Date(d.getFullYear(),d.getMonth(),d.getDate());x.setDate(x.getDate()-((x.getDay()+6)%7));return x;} function shiftW(s,n){var d=parse(s);d.setDate(d.getDate()+7*n);return ymd(d);} function label(s){var a=parse(s),b=parse(s);b.setDate(b.getDate()+5);return "Tuần "+two(a.getDate())+"/"+two(a.getMonth()+1)+" – "+two(b.getDate())+"/"+two(b.getMonth()+1)+"/"+b.getFullYear();} function E(s){return String(s==null?"":s).replace(/[&<>"']/g,function(c){return {"&":"&","<":"<",">":">","\"":""","'":"'"}[c];});} function nm(s){return String(s||"").toLowerCase().replace(/\s+/g," ").trim();} function fdate(s){var a=String(s||"").split("-");return a.length===3?a[2]+"/"+a[1]+"/"+a[0]:String(s||"");} function tw(m){try{if(typeof toast==="function")toast(m);}catch(e){}} function tabBtn(m,l){return "";} function paintTabs(){var tb=document.getElementById("aiTabs");if(!tb)return;if(tb.getAttribute("data-m")===MODE&&tb.firstChild)return;tb.innerHTML="
"+tabBtn("day","Báo cáo ngày")+tabBtn("week","Báo cáo tuần")+"
";tb.setAttribute("data-m",MODE);} function kp(emo,cls,col,lb,val,pct){return "
"+emo+"
"+lb+"
"+val+"
"+pct+"%
";} function sec(emo,col,title,n,extra){return "
"+emo+" "+title+"• "+n+""+(extra||"")+"
";} function row(x,bulkOn){ var lv=x.level,col=C[lv]||C.CHO,st=ST[x.status]||"",rs=[]; (x.issues||[]).forEach(function(i){rs.push(i.reason);}); (x.rules||[]).forEach(function(q){rs.push(q);}); var line=(lv==="XANH")?(x.summary||""):(rs.join(" · ")||x.summary||(lv==="CHO"?"Chờ AI chấm (tối đa 15 phút)":"")); var chk=(lv==="XANH"&&bulkOn&&x.status!=="approved")?"":""; var wr=(lv==="CHO")?"":""; return "
"+chk+"
"+E(x.dept)+" · "+E(x.sender)+(st?" · "+st:"")+"
"+E(line)+"
"+wr+"›
"; } function draw(w,D,depts){ var rows=D.rows||[],by={DO:[],VANG:[],XANH:[],CHO:[]}; rows.forEach(function(x){(by[x.level]||by.CHO).push(x);}); var have={};rows.forEach(function(x){have[nm(x.dept)]=1;}); var miss=[],total=0; depts.forEach(function(d){var n=d.dept||d.company||"";if(!n||/test/i.test(n))return;total++;if(!have[nm(n)])miss.push(n);}); var tot=Math.max(total,rows.length); function pc(n){return tot?Math.round(n*100/tot):0;} var h="
"; h+="
"+label(WEEK)+"
"; h+="
"+kp("📄","i-blue","var(--blue)","Đã gửi",rows.length+"/"+tot,pc(rows.length))+kp("✅","i-teal","var(--teal)","Bình thường",by.XANH.length,pc(by.XANH.length))+kp("⚠️","i-gold","var(--brass)","Cần chú ý",by.VANG.length,pc(by.VANG.length))+kp("⛔","i-red","var(--red)","Bất thường",by.DO.length,pc(by.DO.length))+(by.CHO.length?kp("⏳","i-slate","var(--muted)","Chờ chấm",by.CHO.length,pc(by.CHO.length)):"")+"
"; if(!D.bulkOn)h+="
⚡ Đang chạy song song: duyệt như cũ, nút Duyệt tất cả mở từ "+fdate(D.bulkFrom)+".Thấy AI chấm sai thì bấm ⚑ trên dòng đó.
"; if(!rows.length)h+="
Chưa có báo cáo tuần nào trong tuần này.
"; if(by.DO.length)h+=sec("⛔",C.DO,"Bất thường",by.DO.length)+by.DO.map(function(x){return row(x,D.bulkOn);}).join(""); if(by.VANG.length)h+=sec("⚠️",C.VANG,"Cần chú ý",by.VANG.length)+by.VANG.map(function(x){return row(x,D.bulkOn);}).join(""); if(by.CHO.length)h+=sec("⏳",C.CHO,"Chờ chấm",by.CHO.length)+by.CHO.map(function(x){return row(x,D.bulkOn);}).join(""); if(by.XANH.length){ var na=by.XANH.filter(function(x){return x.status!=="approved";}).length; var lab=(na===0)?"✔ Đã duyệt hết":(D.bulkOn?"✔ Duyệt tất cả":"🔒 Duyệt tất cả · mở "+fdate(D.bulkFrom)); h+=sec("✅",C.XANH,"Bình thường",by.XANH.length,"")+by.XANH.map(function(x){return row(x,D.bulkOn);}).join(""); } if(miss.length)h+=sec("⏳",C.CHO,"Chưa gửi",miss.length)+"
"+miss.map(function(n){return ""+E(n)+"";}).join("")+"
"; w.innerHTML=h+"
"; } async function load(){ var my=++TOK,w=document.getElementById("aiWk");if(!w)return; w.innerHTML="
Đang tải…
"; var r=null,dr=null; try{r=await apiPost("aiFlags",{day:WEEK,kind:"weekly"});dr=await apiPost("boardDepts",{});}catch(e){} if(my!==TOK)return; if(!r||r.status!==200||!r.data||!r.data.ok){w.innerHTML="
Không tải được dữ liệu, thử lại sau.
";return;} LAST=r.data; var depts=(dr&&dr.status===200&&dr.data&&dr.data.depts)?dr.data.depts:[]; draw(w,r.data,depts); } async function onWk(e){ var t=e.target&&e.target.closest?e.target.closest("button"):null;if(!t)return; if(t.classList.contains("v2wNav")){WEEK=shiftW(WEEK,+t.getAttribute("data-d"));load();return;} if(t.classList.contains("v2wOpen")){if(typeof openBoardReport==="function")openBoardReport(t.getAttribute("data-id"));return;} if(t.classList.contains("v2wWrong")){ var note=window.prompt("AI chấm chưa đúng ở đâu? (ví dụ: nên là Đỏ; hoặc không cần báo)");if(note===null)return; var rr=await apiPost("aiFlagWrong",{id:t.getAttribute("data-id"),note:note});tw(rr&&rr.status===200?"Đã ghi nhận, cảm ơn":"Không ghi nhận được");return; } if(t.classList.contains("v2wBulk")){ if(!LAST||!LAST.bulkOn){tw("🔒 Đang chạy song song, mở từ "+fdate(LAST?LAST.bulkFrom:""));return;} var ids=[];document.querySelectorAll("#aiWk .v2wChk").forEach(function(c){if(c.checked)ids.push(c.getAttribute("data-id"));}); if(!ids.length){tw("Chưa chọn báo cáo nào");return;} if(!window.confirm("Duyệt "+ids.length+" báo cáo bình thường?"))return; var rb=await apiPost("aiBulkApprove",{ids:ids}); if(rb&&rb.status===200&&rb.data&&rb.data.ok)tw("✅ Đã duyệt "+rb.data.approved+" báo cáo"+(rb.data.skipped?(" · bỏ qua "+rb.data.skipped):""));else tw("Không duyệt được, thử lại"); load(); } } function onTab(e){ var b=e.target&&e.target.closest?e.target.closest("button"):null;if(!b||!b.getAttribute("data-m"))return; var m=b.getAttribute("data-m");if(m===MODE)return; MODE=m;if(m==="week"){if(!WEEK)WEEK=ymd(monOf(new Date()));load();} paintTabs();tick(); } function ensure(p){ if(document.getElementById("aiWk"))return true; var par=p.parentNode;if(!par)return false; var cs=getComputedStyle(p); var tb=document.createElement("div");tb.id="aiTabs";tb.style.cssText="display:none;text-align:center;padding:10px "+cs.paddingRight+" 0 "+cs.paddingLeft; var w=document.createElement("div");w.id="aiWk";w.className=p.className.replace(/\bhidden\b/g,"").trim();w.style.display="none"; par.insertBefore(tb,p);par.insertBefore(w,p.nextSibling); tb.addEventListener("click",onTab);w.addEventListener("click",onWk); return true; } function tick(){ var p=document.getElementById("panelAi");if(!p||!ensure(p))return; var on=document.body.classList.contains("ai-mode"); if(!on&&MODE!=="day")MODE="day"; paintTabs(); var tb=document.getElementById("aiTabs"),w=document.getElementById("aiWk"),wkOn=on&&MODE==="week"; tb.style.display=on?"":"none"; w.style.display=wkOn?"":"none"; p.style.display=wkOn?"none":""; } setInterval(tick,250); })();