let COLS = []; const qEl = document.getElementById("q"); const btnSearch = document.getElementById("btnSearch"); const btnClear = document.getElementById("btnClear"); const resultsEl = document.getElementById("results"); const totalChip = document.getElementById("totalChip"); const countPill = document.getElementById("countPill"); const summaryPill = document.getElementById("summaryPill"); const FIELD_MAP = { researcher: ["اسم الباحث", "اسم الباحث/ة", "الباحث", "الاسم", "K"], facility: ["اسم المنشأة", "إسم المنشأة", "المنشأة", "اسم المنشاه", "C"], description: ["الوصف", "الوصف.1", "S"], completion: ["حالة اكتمال البيانات", "حالة الاكتمال", "U"], collection: ["حالة الاستيفاء", "T"], approval: ["الوصف.1", "حالة الاعتماد", "اعتماد", "الوصف"], }; const DISPLAY_COLUMNS = [ { key: "researcher", label: "اسم الباحث" }, { key: "facility", label: "اسم المنشأة" }, { key: "collection", label: "حالة الاستيفاء" }, { key: "completion", label: "حالة اكتمال البيانات" }, { key: "description", label: "الوصف" }, ]; const RESOLVED = { researcher: null, facility: null, description: null, completion: null, collection: null, approval: null, }; function escHtml(value) { return String(value ?? "") .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function cleanHeader(value) { return String(value ?? "") .replace(/[\u200E\u200F\u202A-\u202E]/g, "") .replace(/\u00A0/g, " ") .replace(/\s+/g, " ") .trim(); } function normalizeArabic(value) { if (value == null) return ""; return String(value) .toLowerCase() .trim() .replace(/[إأآا]/g, "ا") .replace(/ى/g, "ي") .replace(/ة/g, "ه") .replace(/[\u064B-\u065F\u0670]/g, "") .replace(/\s+/g, " "); } function safeGet(obj, key) { if (!obj || !key) return ""; return Object.prototype.hasOwnProperty.call(obj, key) ? obj[key] : ""; } function findColumn(cols, wantedList) { const wanted = Array.isArray(wantedList) ? wantedList : [wantedList]; const cleanedCols = cols.map((col) => ({ original: col, clean: cleanHeader(col), norm: normalizeArabic(cleanHeader(col)), })); for (const candidate of wanted) { const cleanCandidate = cleanHeader(candidate); const normCandidate = normalizeArabic(cleanCandidate); let hit = cleanedCols.find((c) => c.clean === cleanCandidate); if (hit) return hit.original; hit = cleanedCols.find((c) => c.norm === normCandidate); if (hit) return hit.original; hit = cleanedCols.find((c) => c.clean.includes(cleanCandidate) || c.norm.includes(normCandidate)); if (hit) return hit.original; } return null; } function tagClass(value) { const v = normalizeArabic(value); if ( v.includes("تم") || (v.includes("مكتمل") && !v.includes("غير")) || (v.includes("مكتمله") && !v.includes("غير")) || (v.includes("مستوفي") && !v.includes("غير")) ) { return "ok"; } if ( v.includes("غير") || v.includes("ناقص") || v.includes("مرفوض") || v.includes("تعذر") || v.includes("لم يتم") ) { return "warn"; } return "info"; } function renderEmpty(message) { resultsEl.innerHTML = `
${escHtml(message)}
`; } function resolveColumns() { RESOLVED.researcher = findColumn(COLS, FIELD_MAP.researcher); RESOLVED.facility = findColumn(COLS, FIELD_MAP.facility); RESOLVED.description = findColumn(COLS, FIELD_MAP.description); RESOLVED.completion = findColumn(COLS, FIELD_MAP.completion); RESOLVED.collection = findColumn(COLS, FIELD_MAP.collection); RESOLVED.approval = findColumn(COLS, FIELD_MAP.approval); } function resolveApprovalStatus(row) { const direct = normalizeArabic(getDisplayValue(row, "approval")); if (direct.includes("غير معتمد") || (direct.includes("معتمد") && direct.includes("غير"))) return "غير معتمد"; if (direct === "معتمد" || (direct.includes("معتمد") && !direct.includes("غير"))) return "معتمد"; const description = normalizeArabic(getDisplayValue(row, "description")); if (description.includes("غير معتمد") || (description.includes("معتمد") && description.includes("غير"))) return "غير معتمد"; if (description === "معتمد" || (description.includes("معتمد") && !description.includes("غير"))) return "معتمد"; return ""; } function getDisplayValue(row, key) { const col = RESOLVED[key]; return safeGet(row, col); } function renderSummary(rows) { const approved = rows.filter((row) => resolveApprovalStatus(row) === "معتمد").length; const notApproved = rows.filter((row) => resolveApprovalStatus(row) === "غير معتمد").length; summaryPill.innerHTML = [ `إجمالي العينات: ${rows.length}`, `معتمد: ${approved}`, `غير معتمد: ${notApproved}`, ].join(" "); } function renderTable(rows) { if (!rows.length) { renderEmpty("لا توجد نتائج مطابقة."); countPill.textContent = "النتائج: 0"; summaryPill.textContent = "—"; return; } countPill.textContent = `النتائج: ${rows.length}`; renderSummary(rows); const thead = ` ${DISPLAY_COLUMNS.map((col) => `${escHtml(col.label)}`).join("")} `; const tbody = ` ${rows.map((row) => ` ${DISPLAY_COLUMNS.map((col) => { const value = getDisplayValue(row, col.key); if (col.key === "collection" || col.key === "completion") { return `${escHtml(value || "—")}`; } return `${escHtml(value || "—")}`; }).join("")} `).join("")} `; resultsEl.innerHTML = `
${thead}${tbody}
`; } function doSearch() { const q = normalizeArabic(qEl.value); if (!q) { renderEmpty("اكتب اسم الباحث ثم اضغط (بحث)."); countPill.textContent = "النتائج: 0"; summaryPill.textContent = "—"; return; } if (!RESOLVED.researcher) { renderEmpty("⚠️ لم يتم التعرف على عمود اسم الباحث."); countPill.textContent = "النتائج: 0"; summaryPill.textContent = "—"; return; } const rows = DATA.filter((row) => normalizeArabic(getDisplayValue(row, "researcher")).includes(q)); renderTable(rows); } function clearAll() { qEl.value = ""; renderEmpty("اكتب اسمك للبحث"); countPill.textContent = "النتائج: 0"; summaryPill.textContent = "—"; qEl.focus(); } function validateRequiredColumns() { const missing = DISPLAY_COLUMNS .filter((col) => !RESOLVED[col.key]) .map((col) => col.label); return missing; } function init() { if (!Array.isArray(DATA) || !DATA.length) { totalChip.innerHTML = `إجمالي السجلات: 0`; renderEmpty("⚠️ لا توجد بيانات داخل ملف data.js"); return; } COLS = Object.keys(DATA[0]).map(cleanHeader); const originalCols = Object.keys(DATA[0]); COLS = originalCols; resolveColumns(); totalChip.innerHTML = `إجمالي السجلات: ${DATA.length}`; const missing = validateRequiredColumns(); if (missing.length) { renderEmpty(`⚠️ تعذر العثور على الأعمدة التالية في البيانات:\n${missing.join("\n")}`); return; } clearAll(); } btnSearch.addEventListener("click", doSearch); btnClear.addEventListener("click", clearAll); qEl.addEventListener("keydown", (ev) => { if (ev.key === "Enter") doSearch(); }); qEl.addEventListener("input", () => { const value = normalizeArabic(qEl.value); if (value.length >= 2) doSearch(); if (!qEl.value.trim()) clearAll(); }); init();