Upload 6 files
Browse files
README.md
CHANGED
|
@@ -25,6 +25,8 @@ short_description: نظام استعلام المنشآت الصناعية
|
|
| 25 |
- إذا كانت الخانة تحتوي على إحداثيات رقمية، يظهر رابط مباشر إلى خرائط Google.
|
| 26 |
- إذا كانت الخانة فارغة، لا يظهر حقل الإحداثيات.
|
| 27 |
- إذا كانت الخانة تحتوي على نص تواصل ورقم جوال، تظهر باسم "إفادة مدن" مع أزرار نسخ الرقم وواتساب ونسخ رسالة مقترحة.
|
|
|
|
|
|
|
| 28 |
|
| 29 |
## تحديث البيانات
|
| 30 |
|
|
|
|
| 25 |
- إذا كانت الخانة تحتوي على إحداثيات رقمية، يظهر رابط مباشر إلى خرائط Google.
|
| 26 |
- إذا كانت الخانة فارغة، لا يظهر حقل الإحداثيات.
|
| 27 |
- إذا كانت الخانة تحتوي على نص تواصل ورقم جوال، تظهر باسم "إفادة مدن" مع أزرار نسخ الرقم وواتساب ونسخ رسالة مقترحة.
|
| 28 |
+
- يتم تمييز الإحداثيات وإفادة مدن بصريًا بألوان مختلفة.
|
| 29 |
+
- يحفظ النظام آخر منطقة ومدينة وبحث تم استخدامها على نفس المتصفح.
|
| 30 |
|
| 31 |
## تحديث البيانات
|
| 32 |
|
app.js
CHANGED
|
@@ -27,6 +27,7 @@ const regionStats = document.getElementById("regionStats");
|
|
| 27 |
const toast = document.getElementById("toast");
|
| 28 |
|
| 29 |
const PAGE_SIZE = 24;
|
|
|
|
| 30 |
const CONTACT_MESSAGE = (name) =>
|
| 31 |
`السلام عليكم ورحمة الله وبركاته\n\nأستاذي الكريم،\nنأمل تزويدنا بموقع منشأة (${name || "العينة"})، وذلك لاستكمال بيانات الزيارة الميدانية.\n\nشاكرين لكم تعاونكم.`;
|
| 32 |
|
|
@@ -34,6 +35,7 @@ let rows = [];
|
|
| 34 |
let visibleRows = [];
|
| 35 |
let renderedCount = 0;
|
| 36 |
let toastTimer;
|
|
|
|
| 37 |
|
| 38 |
function base64ToBytes(value) {
|
| 39 |
const binary = atob(value);
|
|
@@ -89,6 +91,26 @@ function setOptions(select, values, placeholder) {
|
|
| 89 |
values.forEach((value) => select.add(new Option(value, value)));
|
| 90 |
}
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
function updateRegionButtonState() {
|
| 93 |
regionButtons.querySelectorAll(".region-choice").forEach((button) => {
|
| 94 |
const isActive = button.dataset.region === regionSelect.value;
|
|
@@ -190,13 +212,14 @@ function createCoordinatesBlock(row) {
|
|
| 190 |
if (!value) return null;
|
| 191 |
|
| 192 |
const item = document.createElement("div");
|
| 193 |
-
|
|
|
|
| 194 |
const label = document.createElement("span");
|
| 195 |
label.className = "detail-label";
|
| 196 |
-
label.textContent =
|
| 197 |
item.append(label);
|
| 198 |
|
| 199 |
-
if (
|
| 200 |
item.append(
|
| 201 |
createActionLink(
|
| 202 |
"اضغط هنا للذهاب بخرائط Google",
|
|
@@ -321,6 +344,7 @@ function applyFilters() {
|
|
| 321 |
resultsTitle.textContent = city || region || "نتائج البحث";
|
| 322 |
resultsMeta.textContent = `${visibleRows.length} من أصل ${scopedRows.length} منشأة`;
|
| 323 |
renderVisibleRows(true);
|
|
|
|
| 324 |
}
|
| 325 |
|
| 326 |
function initializeDashboard(data) {
|
|
@@ -359,6 +383,22 @@ function initializeDashboard(data) {
|
|
| 359 |
);
|
| 360 |
setOptions(citySelect, [], "اختر المدينة الصناعية");
|
| 361 |
citySelect.disabled = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
applyFilters();
|
| 363 |
}
|
| 364 |
|
|
@@ -411,6 +451,7 @@ searchInput.addEventListener("input", applyFilters);
|
|
| 411 |
loadMoreButton.addEventListener("click", () => renderVisibleRows());
|
| 412 |
clearFiltersButton.addEventListener("click", () => {
|
| 413 |
searchInput.value = "";
|
|
|
|
| 414 |
setRegion("");
|
| 415 |
showToast("تم مسح الاختيارات");
|
| 416 |
});
|
|
|
|
| 27 |
const toast = document.getElementById("toast");
|
| 28 |
|
| 29 |
const PAGE_SIZE = 24;
|
| 30 |
+
const STATE_KEY = "icsInquiryFilters";
|
| 31 |
const CONTACT_MESSAGE = (name) =>
|
| 32 |
`السلام عليكم ورحمة الله وبركاته\n\nأستاذي الكريم،\nنأمل تزويدنا بموقع منشأة (${name || "العينة"})، وذلك لاستكمال بيانات الزيارة الميدانية.\n\nشاكرين لكم تعاونكم.`;
|
| 33 |
|
|
|
|
| 35 |
let visibleRows = [];
|
| 36 |
let renderedCount = 0;
|
| 37 |
let toastTimer;
|
| 38 |
+
let isRestoringState = false;
|
| 39 |
|
| 40 |
function base64ToBytes(value) {
|
| 41 |
const binary = atob(value);
|
|
|
|
| 91 |
values.forEach((value) => select.add(new Option(value, value)));
|
| 92 |
}
|
| 93 |
|
| 94 |
+
function saveFilterState() {
|
| 95 |
+
if (isRestoringState) return;
|
| 96 |
+
localStorage.setItem(
|
| 97 |
+
STATE_KEY,
|
| 98 |
+
JSON.stringify({
|
| 99 |
+
region: regionSelect.value,
|
| 100 |
+
city: citySelect.value,
|
| 101 |
+
search: searchInput.value,
|
| 102 |
+
}),
|
| 103 |
+
);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
function getSavedFilterState() {
|
| 107 |
+
try {
|
| 108 |
+
return JSON.parse(localStorage.getItem(STATE_KEY) || "{}");
|
| 109 |
+
} catch {
|
| 110 |
+
return {};
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
function updateRegionButtonState() {
|
| 115 |
regionButtons.querySelectorAll(".region-choice").forEach((button) => {
|
| 116 |
const isActive = button.dataset.region === regionSelect.value;
|
|
|
|
| 212 |
if (!value) return null;
|
| 213 |
|
| 214 |
const item = document.createElement("div");
|
| 215 |
+
const hasCoordinates = isCoordinate(value);
|
| 216 |
+
item.className = `detail-item coordinates-detail ${hasCoordinates ? "map-detail" : "statement-detail"}`;
|
| 217 |
const label = document.createElement("span");
|
| 218 |
label.className = "detail-label";
|
| 219 |
+
label.textContent = hasCoordinates ? "الإحداثيات" : "إفادة مدن";
|
| 220 |
item.append(label);
|
| 221 |
|
| 222 |
+
if (hasCoordinates) {
|
| 223 |
item.append(
|
| 224 |
createActionLink(
|
| 225 |
"اضغط هنا للذهاب بخرائط Google",
|
|
|
|
| 344 |
resultsTitle.textContent = city || region || "نتائج البحث";
|
| 345 |
resultsMeta.textContent = `${visibleRows.length} من أصل ${scopedRows.length} منشأة`;
|
| 346 |
renderVisibleRows(true);
|
| 347 |
+
saveFilterState();
|
| 348 |
}
|
| 349 |
|
| 350 |
function initializeDashboard(data) {
|
|
|
|
| 383 |
);
|
| 384 |
setOptions(citySelect, [], "اختر المدينة الصناعية");
|
| 385 |
citySelect.disabled = true;
|
| 386 |
+
restoreFilterState();
|
| 387 |
+
}
|
| 388 |
+
|
| 389 |
+
function restoreFilterState() {
|
| 390 |
+
const saved = getSavedFilterState();
|
| 391 |
+
isRestoringState = true;
|
| 392 |
+
searchInput.value = saved.search || "";
|
| 393 |
+
if (saved.region && [...regionSelect.options].some((option) => option.value === saved.region)) {
|
| 394 |
+
setRegion(saved.region);
|
| 395 |
+
if (saved.city && [...citySelect.options].some((option) => option.value === saved.city)) {
|
| 396 |
+
citySelect.value = saved.city;
|
| 397 |
+
}
|
| 398 |
+
} else {
|
| 399 |
+
setRegion("");
|
| 400 |
+
}
|
| 401 |
+
isRestoringState = false;
|
| 402 |
applyFilters();
|
| 403 |
}
|
| 404 |
|
|
|
|
| 451 |
loadMoreButton.addEventListener("click", () => renderVisibleRows());
|
| 452 |
clearFiltersButton.addEventListener("click", () => {
|
| 453 |
searchInput.value = "";
|
| 454 |
+
localStorage.removeItem(STATE_KEY);
|
| 455 |
setRegion("");
|
| 456 |
showToast("تم مسح الاختيارات");
|
| 457 |
});
|
style.css
CHANGED
|
@@ -516,6 +516,81 @@ select:disabled {
|
|
| 516 |
border-left: 0 !important;
|
| 517 |
}
|
| 518 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
.ltr-value .detail-value {
|
| 520 |
direction: ltr;
|
| 521 |
text-align: right;
|
|
|
|
| 516 |
border-left: 0 !important;
|
| 517 |
}
|
| 518 |
|
| 519 |
+
.coordinates-detail {
|
| 520 |
+
position: relative;
|
| 521 |
+
margin-top: 10px;
|
| 522 |
+
padding: 13px 14px !important;
|
| 523 |
+
border: 1px solid transparent !important;
|
| 524 |
+
border-radius: 8px;
|
| 525 |
+
}
|
| 526 |
+
|
| 527 |
+
.coordinates-detail::before {
|
| 528 |
+
content: "";
|
| 529 |
+
position: absolute;
|
| 530 |
+
top: 12px;
|
| 531 |
+
right: 0;
|
| 532 |
+
bottom: 12px;
|
| 533 |
+
width: 4px;
|
| 534 |
+
border-radius: 8px 0 0 8px;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
.map-detail {
|
| 538 |
+
background: #edf9f3;
|
| 539 |
+
border-color: #bfead2 !important;
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
.map-detail::before {
|
| 543 |
+
background: #168a5b;
|
| 544 |
+
}
|
| 545 |
+
|
| 546 |
+
.statement-detail {
|
| 547 |
+
background: #eef7fb;
|
| 548 |
+
border-color: #c7e1ec !important;
|
| 549 |
+
}
|
| 550 |
+
|
| 551 |
+
.statement-detail::before {
|
| 552 |
+
background: #227997;
|
| 553 |
+
}
|
| 554 |
+
|
| 555 |
+
.map-detail .detail-label,
|
| 556 |
+
.statement-detail .detail-label {
|
| 557 |
+
display: inline-flex;
|
| 558 |
+
align-items: center;
|
| 559 |
+
gap: 6px;
|
| 560 |
+
min-height: 24px;
|
| 561 |
+
padding: 3px 8px;
|
| 562 |
+
border-radius: 8px;
|
| 563 |
+
}
|
| 564 |
+
|
| 565 |
+
.map-detail .detail-label {
|
| 566 |
+
color: #116343;
|
| 567 |
+
background: #dff4e9;
|
| 568 |
+
}
|
| 569 |
+
|
| 570 |
+
.statement-detail .detail-label {
|
| 571 |
+
color: #17647d;
|
| 572 |
+
background: #dff0f6;
|
| 573 |
+
}
|
| 574 |
+
|
| 575 |
+
.map-detail .action-link {
|
| 576 |
+
color: #116343;
|
| 577 |
+
background: #ffffff;
|
| 578 |
+
border-color: #b7e3ca;
|
| 579 |
+
}
|
| 580 |
+
|
| 581 |
+
.statement-detail .action-link {
|
| 582 |
+
color: #17647d;
|
| 583 |
+
background: #ffffff;
|
| 584 |
+
border-color: #bddce8;
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
.map-detail .action-link:hover,
|
| 588 |
+
.statement-detail .action-link:hover {
|
| 589 |
+
color: #fff;
|
| 590 |
+
background: var(--primary);
|
| 591 |
+
border-color: var(--primary);
|
| 592 |
+
}
|
| 593 |
+
|
| 594 |
.ltr-value .detail-value {
|
| 595 |
direction: ltr;
|
| 596 |
text-align: right;
|