File size: 8,225 Bytes
efcaa0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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([], "اكتب اسم الباحث أو اختر اسم المفتش");