Files
customerTicket/static/js/ticket-unit-options.js
T
2026-09-10 11:34:19 +03:30

63 lines
4.0 KiB
JavaScript

(() => {
const form = document.querySelector("[data-unit-options-url]");
if (!form) return;
const unit = form.querySelector("[data-ticket-unit]");
const category = form.querySelector("[data-ticket-category]");
const picker = form.querySelector("[data-expert-picker]");
if (!unit || !category || !picker) return;
let requestController;
const addGeneralQueue = (queue) => {
const label = document.createElement("label"); label.className = "expert-card";
label.dataset.generalQueue = ""; label.dataset.unitId = String(queue.unit_id);
const radio = document.createElement("input"); radio.type = "radio"; radio.name = "selected_expert"; radio.value = ""; radio.checked = true;
const avatar = document.createElement("span"); avatar.className = "expert-avatar"; avatar.textContent = "⌁";
const title = document.createElement("strong"); title.textContent = queue.label;
const detail = document.createElement("small"); detail.textContent = "اولین کارشناس آزاد همین واحد";
label.append(radio, avatar, title, detail); picker.append(label);
};
const render = (payload) => {
category.replaceChildren(new Option("انتخاب دسته‌بندی", ""));
payload.categories.forEach((item) => category.add(new Option(item.label, item.id)));
const selectedUnitLabel=unit.options[unit.selectedIndex]?.textContent?.trim() || "واحد";
const queue=payload.queue || {unit_id:unit.value,label:`صف عمومی ${selectedUnitLabel}`};
picker.replaceChildren(); addGeneralQueue(queue);
payload.experts.forEach((item) => {
const label=document.createElement("label"); label.className="expert-card";
const radio=document.createElement("input"); radio.type="radio"; radio.name="selected_expert"; radio.value=item.id;
const image=document.createElement("img"); image.src=item.avatar_url; image.alt=`تصویر ${item.name}`; image.width=56; image.height=56; image.loading="lazy";
const title=document.createElement("strong"); title.textContent=item.name;
const detail=document.createElement("small"); detail.textContent=item.job_title;
label.append(radio,image,title,detail); picker.append(label);
});
if (!payload.experts.length) {
const empty=document.createElement("p"); empty.className="muted expert-empty";
empty.textContent="برای این واحد کارشناس قابل انتخابی ثبت نشده است؛ درخواست به صف عمومی می‌رود.";
picker.append(empty);
}
};
unit.addEventListener("change", async () => {
requestController?.abort(); requestController=new AbortController();
const requestedUnit=unit.value;
category.disabled=true;
try {
const optionsUrl=new URL(form.dataset.unitOptionsUrl,window.location.origin);
optionsUrl.searchParams.set("unit",requestedUnit);
optionsUrl.searchParams.set("v",document.documentElement.dataset.staticVersion || "1");
const response=await fetch(optionsUrl, {headers:{Accept:"application/json"},credentials:"same-origin",cache:"no-store",signal:requestController.signal});
if (!response.ok) throw new Error("options request failed");
const payload=await response.json();
if (unit.value!==requestedUnit) return;
render(payload);
category.dispatchEvent(new CustomEvent("ticket-options-loaded",{detail:{ok:true,unitId:requestedUnit}}));
} catch (error) {
if (error.name==="AbortError") return;
console.error("Failed to update ticket unit options", error);
picker.replaceChildren();
const message=document.createElement("p"); message.className="muted expert-empty"; message.setAttribute("role","alert");
message.textContent="دریافت کارشناسان این واحد ناموفق بود؛ لطفاً دوباره تلاش کنید."; picker.append(message);
category.dispatchEvent(new CustomEvent("ticket-options-loaded",{detail:{ok:false,unitId:requestedUnit}}));
} finally { if (unit.value===requestedUnit) category.disabled=false; }
});
})();