MDN2 / script.js
stat2025's picture
Upload 3 files
efcaa0c verified
const rawRows = Array.isArray(window.DATA) ? window.DATA : [];
const selectors = {
total: document.getElementById("totalCount"),
researchers: document.getElementById("researcherCount"),
inspectors: document.getElementById("inspectorCount"),
tabs: document.querySelectorAll(".modeTab"),
panels: document.querySelectorAll(".searchPanel"),
researcherInput: document.getElementById("researcherInput"),
researcherSelect: document.getElementById("researcherSelect"),
inspectorGrid: document.getElementById("inspectorGrid"),
inspectorResearcherSelect: document.getElementById("inspectorResearcherSelect"),
resultEyebrow: document.getElementById("resultEyebrow"),
resultTitle: document.getElementById("resultTitle"),
resultCount: document.getElementById("resultCount"),
results: document.getElementById("results"),
};
let selectedInspector = "";
function clean(value) {
return String(value ?? "").trim();
}
function normalizeArabic(value) {
return clean(value)
.toLowerCase()
.replace(/[\u064B-\u065F\u0670\u06D6-\u06ED]/g, "")
.replace(/\u0640/g, "")
.replace(/[إأآٱ]/g, "ا")
.replace(/ى/g, "ي")
.replace(/ة/g, "ه")
.replace(/\s+/g, " ");
}
function valueOf(row, keys, index) {
if (Array.isArray(row)) return clean(row[index]);
for (const key of keys) {
if (row && Object.prototype.hasOwnProperty.call(row, key)) return clean(row[key]);
}
return "";
}
function mapRow(row) {
return {
establishment: valueOf(row, ["establishment", "name", "sample", "اسم المنشأة", "إسم المنشأة"], 0),
statusMain: valueOf(row, ["statusMain", "status_b", "b", "حالة العينة في المسح", "حالة العينة في المسح "], 1),
statusOther: valueOf(row, ["statusOther", "status_c", "c", "حالة العينة في مسح اخر", "حالة العينة في مسح آخر"], 2),
survey: valueOf(row, ["survey", "surveyName", "اسم المسح"], 3),
researcher: valueOf(row, ["researcher", "researcherName", "اسم الباحث الحالي", "اسم الباحث"], 4),
inspector: valueOf(row, ["inspector", "inspectorName", "المفتش", "اسم المفتش"], 5),
};
}
function unique(values) {
return [...new Set(values.filter(Boolean))].sort((a, b) => a.localeCompare(b, "ar"));
}
function escapeHtml(value) {
return clean(value)
.replaceAll("&", "&")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#039;");
}
function optionHtml(value) {
return `<option value="${escapeHtml(value)}">${escapeHtml(value)}</option>`;
}
const rows = rawRows
.map(mapRow)
.filter((row) => normalizeArabic(row.statusMain) !== normalizeArabic(row.statusOther));
const researchers = unique(rows.map((row) => row.researcher));
const inspectors = unique(rows.map((row) => row.inspector));
selectors.total.textContent = rows.length;
selectors.researchers.textContent = researchers.length;
selectors.inspectors.textContent = inspectors.length;
function setMode(mode) {
selectors.tabs.forEach((tab) => {
const active = tab.dataset.mode === mode;
tab.classList.toggle("active", active);
tab.setAttribute("aria-selected", String(active));
});
selectors.panels.forEach((panel) => panel.classList.toggle("active", panel.id === `${mode}Panel`));
if (mode === "researcher") selectors.researcherInput.focus();
}
function byResearcher(query, sourceRows = rows) {
const tokens = normalizeArabic(query).split(" ").filter(Boolean);
if (!tokens.length) return [];
return sourceRows.filter((row) => {
const name = normalizeArabic(row.researcher);
return tokens.every((token) => name.includes(token));
});
}
function byInspector(name) {
const target = normalizeArabic(name);
return rows.filter((row) => normalizeArabic(row.inspector) === target);
}
function renderControls() {
selectors.researcherSelect.innerHTML = `<option value="">اختر اسم الباحث</option>${researchers.map(optionHtml).join("")}`;
selectors.inspectorGrid.innerHTML = inspectors.map((name) => (
`<button class="inspectorChip" type="button" data-inspector="${escapeHtml(name)}">${escapeHtml(name)}</button>`
)).join("");
}
function renderInspectorResearchers(inspectorName) {
const list = byInspector(inspectorName);
const names = unique(list.map((row) => row.researcher));
selectors.inspectorResearcherSelect.disabled = names.length === 0;
selectors.inspectorResearcherSelect.innerHTML = `<option value="">كل الباحثين للمفتش</option>${names.map(optionHtml).join("")}`;
}
function renderResults(list, title, eyebrow = "النتائج") {
selectors.resultEyebrow.textContent = eyebrow;
selectors.resultTitle.textContent = title;
selectors.resultCount.textContent = list.length;
if (!list.length) {
selectors.results.innerHTML = `<div class="emptyState">لا توجد عينات مختلفة حسب الخيار الحالي</div>`;
return;
}
selectors.results.innerHTML = list.map((row) => `
<article class="sampleCard">
<h3 class="sampleName">${escapeHtml(row.establishment || "بدون اسم منشأة")}</h3>
<div class="metaLine">
<span>الباحث: ${escapeHtml(row.researcher || "-")}</span>
</div>
<div class="statusGrid">
<div class="statusBox">
<strong>حالة العينة في المسح</strong>
<p>${escapeHtml(row.statusMain || "-")}</p>
</div>
<div class="statusBox">
<strong>حالة العينة في مسح آخر</strong>
<p>${escapeHtml(row.statusOther || "-")}</p>
<em>${escapeHtml(row.survey || "بدون اسم مسح")}</em>
</div>
</div>
</article>
`).join("");
}
function resetInspectorResearcherSelect() {
selectedInspector = "";
selectors.inspectorResearcherSelect.disabled = true;
selectors.inspectorResearcherSelect.innerHTML = `<option value="">اختر المفتش أولاً</option>`;
}
function showResearcher(name) {
selectors.researcherInput.value = name;
selectors.researcherSelect.value = name;
renderResults(byResearcher(name), `نتائج الباحث: ${name}`, "بحث الباحث");
}
selectors.tabs.forEach((tab) => {
tab.addEventListener("click", () => setMode(tab.dataset.mode));
});
selectors.researcherInput.addEventListener("input", () => {
const query = selectors.researcherInput.value;
selectors.researcherSelect.value = researchers.includes(query) ? query : "";
if (!query.trim()) {
renderResults([], "اكتب اسم الباحث أو اختر اسم المفتش");
return;
}
renderResults(byResearcher(query), `نتائج الباحث: ${query}`, "بحث الباحث");
});
selectors.researcherSelect.addEventListener("change", () => {
const name = selectors.researcherSelect.value;
if (!name) {
selectors.researcherInput.value = "";
renderResults([], "اكتب اسم الباحث أو اختر اسم المفتش");
return;
}
showResearcher(name);
});
selectors.inspectorGrid.addEventListener("click", (event) => {
const chip = event.target.closest("[data-inspector]");
if (!chip) return;
selectedInspector = chip.dataset.inspector;
document.querySelectorAll(".inspectorChip").forEach((button) => {
button.classList.toggle("selected", button.dataset.inspector === selectedInspector);
});
renderInspectorResearchers(selectedInspector);
renderResults(byInspector(selectedInspector), `مفتش: ${selectedInspector}`, "بحث المفتش");
});
selectors.inspectorResearcherSelect.addEventListener("change", () => {
if (!selectedInspector) return;
const inspectorRows = byInspector(selectedInspector);
const researcherName = selectors.inspectorResearcherSelect.value;
if (!researcherName) {
renderResults(inspectorRows, `مفتش: ${selectedInspector}`, "كل باحثي المفتش");
return;
}
renderResults(byResearcher(researcherName, inspectorRows), `الباحث: ${researcherName}`, `مفتش: ${selectedInspector}`);
});
renderControls();
resetInspectorResearcherSelect();
renderResults([], "اكتب اسم الباحث أو اختر اسم المفتش");