PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.0
ووسلام – همگام سازی ووکامرس و باسلام v1.10.0
1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.2 1.9.1 1.9.0 1.8.8 1.8.5 1.8.6 All 53 releases
sync-basalam / assets / js / admin.js

admin.js in ووسلام – همگام سازی ووکامرس و باسلام 1.10.0, at assets/js/admin.js

1,121 lines 31.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 document.addEventListener("DOMContentLoaded", function () {
2 const modalConfig = [
3 {
4 key: "add",
5 modalId: "basalamAddProductsModal",
6 openBtnId: "basalamOpenAddProductsModal",
7 formId: "basalamAddProductsForm",
8 action: "create_products_to_basalam",
9 },
10 {
11 key: "update",
12 modalId: "BasalamUpdateProductsModal",
13 openBtnId: "BasalamOpenUpdateProductsModal",
14 formId: "BasalamUpdateProductsForm",
15 action: "update_products_in_basalam",
16 },
17 {
18 key: "connect",
19 modalId: "BasalamConnectProductsModal",
20 openBtnId: "BasalamOpenConnectProductsModal",
21 formId: "BasalamConnectProductsForm",
22 action: "connect_products_with_basalam",
23 },
24 ];
25
26 const closeModal = () => {
27 document.querySelectorAll(".basalam-modal").forEach((modal) => {
28 modal.style.display = "none";
29 });
30 document.body.style.overflow = "auto";
31 };
32
33 modalConfig.forEach(({ modalId, openBtnId, formId, action }) => {
34 const modal = document.getElementById(modalId);
35 const openBtn = document.getElementById(openBtnId);
36 const form = document.getElementById(formId);
37
38 if (openBtn && modal) {
39 openBtn.addEventListener("click", () => {
40 modal.style.display = "block";
41 document.body.style.overflow = "hidden";
42
43 if (modalId === "BasalamUpdateProductsModal") {
44 const selectionDiv = document.getElementById("update-type-selection");
45 const quickConfirm = document.getElementById("quick-update-confirm");
46 const fullConfirm = document.getElementById("full-update-confirm");
47
48 if (selectionDiv) selectionDiv.style.display = "block";
49 if (quickConfirm) quickConfirm.style.display = "none";
50 if (fullConfirm) fullConfirm.style.display = "none";
51 }
52 });
53 }
54
55 if (form) {
56 form.addEventListener("submit", function (e) {
57 e.preventDefault();
58
59 if (action === "create_products_to_basalam") {
60 const confirmModal = document.getElementById("BasalamConfirmModal");
61 confirmModal.style.display = "block";
62 document.body.style.overflow = "hidden";
63
64 const confirmButton = document.getElementById("confirmSubmitBtn");
65
66 const newConfirmBtn = confirmButton.cloneNode(true);
67 confirmButton.parentNode.replaceChild(newConfirmBtn, confirmButton);
68
69 newConfirmBtn.addEventListener("click", function () {
70 confirmModal.style.display = "none";
71
72 submitToServer(form, action);
73 });
74 } else {
75 submitToServer(form, action);
76 }
77 });
78 }
79 });
80
81 setTimeout(() => {
82 const quickUpdateBtn = document.getElementById("quick-update-btn");
83 const fullUpdateBtn = document.getElementById("full-update-btn");
84
85 if (quickUpdateBtn) {
86 quickUpdateBtn.addEventListener("click", (e) => {
87 e.preventDefault();
88
89 const formData = new FormData();
90 formData.append("update_type", "quick");
91 formData.append("action", "update_products_in_basalam");
92 formData.append(
93 "_wpnonce",
94 document.querySelector(
95 '#BasalamUpdateProductsModal input[name="_wpnonce"]'
96 )?.value || ""
97 );
98
99 submitUpdateRequest(formData, "quick");
100 });
101 }
102
103 if (fullUpdateBtn) {
104 fullUpdateBtn.addEventListener("click", (e) => {
105 e.preventDefault();
106
107 const formData = new FormData();
108 formData.append("update_type", "full");
109 formData.append("action", "update_products_in_basalam");
110 formData.append(
111 "_wpnonce",
112 document.querySelector(
113 '#BasalamUpdateProductsModal input[name="_wpnonce"]'
114 )?.value || ""
115 );
116
117 submitUpdateRequest(formData, "full");
118 });
119 }
120 }, 100);
121
122 function submitUpdateRequest(formData, updateType) {
123 const quickBtn = document.getElementById("quick-update-btn");
124 const fullBtn = document.getElementById("full-update-btn");
125
126 if (quickBtn) quickBtn.disabled = true;
127 if (fullBtn) fullBtn.disabled = true;
128
129 const clickedBtn = updateType === "quick" ? quickBtn : fullBtn;
130 if (clickedBtn) {
131 const originalText = clickedBtn.innerHTML;
132 clickedBtn.innerHTML =
133 '<span class="basalam-loading-text">در حال ارسال...</span>';
134
135 fetch(ajaxurl, {
136 method: "POST",
137 body: formData,
138 })
139 .then((response) => response.json())
140 .then((data) => {
141 closeModal();
142 if (data.success) {
143 window.BasalamToast.success(data.data?.message || "ع�
144 لیات با �
145 وفقیت آغاز شد.");
146 } else {
147 window.BasalamToast.error(data.data?.message || "خطایی رخ داده است.");
148 }
149 location.reload();
150 })
151 .catch((error) => {
152 console.error("Error:", error);
153 window.BasalamToast.error("خطایی در ارسال رخ داده است.");
154
155 if (quickBtn) quickBtn.disabled = false;
156 if (fullBtn) fullBtn.disabled = false;
157 if (clickedBtn) clickedBtn.innerHTML = originalText;
158 });
159 }
160 }
161
162 function submitToServer(form, action, updateType = null) {
163 const formData = new FormData(form);
164 formData.append("action", action);
165
166 const submitButton = form.querySelector('button[type="submit"]');
167 submitButton.disabled = true;
168 submitButton.innerHTML =
169 '<span class="dashicons dashicons-update"></span> در حال ارسال...';
170
171 fetch(ajaxurl, {
172 method: "POST",
173 body: formData,
174 })
175 .then((response) => response.json())
176 .then((data) => {
177 closeModal();
178 if (data.success) {
179 window.BasalamToast.success(data.data?.message || "ع�
180 لیات با �
181 وفقیت آغاز شد.");
182 } else {
183 window.BasalamToast.error(data.data?.message || "خطایی رخ داده است.");
184 }
185 location.reload();
186 })
187 .catch((error) => {
188 console.error("Error:", error);
189 window.BasalamToast.error("خطایی در ارسال رخ داده است.");
190 })
191 .finally(() => {
192 submitButton.disabled = false;
193 submitButton.innerHTML =
194 '<span class="dashicons dashicons-plus-alt"></span> انجا�
195 شد';
196 });
197 }
198
199 document.querySelectorAll(".basalam-modal-close").forEach((btn) => {
200 btn.addEventListener("click", closeModal);
201 });
202
203 window.addEventListener("click", (event) => {
204 if (event.target.classList.contains("basalam-modal")) {
205 closeModal();
206 }
207 });
208
209 document.addEventListener("keydown", (event) => {
210 if (event.key === "Escape") {
211 closeModal();
212 }
213 });
214
215 const select = document.getElementById("basalam-sync-type");
216 if (select) {
217 const toggleFields = (val) => {
218 document.getElementById("Basalam-custom-fields").style.display =
219 val === "custom" ? "block" : "none";
220 };
221 toggleFields(select.value);
222 select.addEventListener("change", (e) => toggleFields(e.target.value));
223 }
224
225 // Tab functionality for settings modal
226 const initTabs = () => {
227 const tabBtns = document.querySelectorAll(".basalam-tab-btn");
228 const tabContents = document.querySelectorAll(".basalam-tab-content");
229
230 tabBtns.forEach((btn) => {
231 btn.addEventListener("click", () => {
232 const tabId = btn.getAttribute("data-tab");
233
234 // Remove active class from all buttons and contents
235 tabBtns.forEach((b) => b.classList.remove("active"));
236 tabContents.forEach((c) => c.classList.remove("active"));
237
238 // Add active class to clicked button and corresponding content
239 btn.classList.add("active");
240 const content = document.getElementById(tabId);
241 if (content) {
242 content.classList.add("active");
243 }
244 });
245 });
246 };
247
248 initTabs();
249
250 const initPointerOnboarding = () => {
251 const pointerTour = window.basalamPointerTour;
252
253 if (
254 !pointerTour ||
255 !Array.isArray(pointerTour.steps) ||
256 pointerTour.steps.length === 0
257 ) {
258 return;
259 }
260
261 if (
262 typeof window.jQuery === "undefined" ||
263 typeof window.jQuery.fn.pointer !== "function"
264 ) {
265 return;
266 }
267
268 const steps = pointerTour.steps.filter(
269 (step) =>
270 step &&
271 typeof step.selector === "string" &&
272 document.querySelector(step.selector)
273 );
274
275 if (steps.length === 0) {
276 return;
277 }
278
279 let completionRequested = false;
280
281 const markTourCompleted = () => {
282 if (completionRequested) {
283 return;
284 }
285
286 completionRequested = true;
287
288 if (!pointerTour.completeAction || !pointerTour.nonce) {
289 return;
290 }
291
292 const formData = new FormData();
293 formData.append("action", pointerTour.completeAction);
294 formData.append("nonce", pointerTour.nonce);
295
296 fetch(ajaxurl, {
297 method: "POST",
298 body: formData,
299 }).catch(() => {});
300 };
301
302 const openStep = (index) => {
303 if (index >= steps.length) {
304 markTourCompleted();
305 return;
306 }
307
308 const step = steps[index];
309 const $target = window.jQuery(step.selector).first();
310
311 if (!$target.length) {
312 openStep(index + 1);
313 return;
314 }
315
316 const targetElement = $target.get(0);
317 if (targetElement && typeof targetElement.scrollIntoView === "function") {
318 targetElement.scrollIntoView({ behavior: "smooth", block: "center" });
319 }
320
321 let shouldAdvance = false;
322 let shouldStop = false;
323
324 $target
325 .pointer({
326 pointerClass: "sync-basalam-pointer",
327 content: step.content || "",
328 position: step.position || { edge: "right", align: "middle" },
329 buttons: function (event, t) {
330 const isLastStep = index === steps.length - 1;
331 const skipLabel = step.skipLabel || "بستن";
332 const nextLabel = isLastStep
333 ? step.doneLabel || "ات�
334 ا�
335 "
336 : step.nextLabel || "بعدی";
337
338 const $skipButton = window.jQuery(
339 '<button type="button" class="button button-secondary"></button>'
340 ).text(skipLabel);
341
342 const $nextButton = window.jQuery(
343 '<button type="button" class="button button-primary"></button>'
344 ).text(nextLabel);
345
346 $skipButton.on("click", function () {
347 shouldStop = true;
348 t.element.pointer("close");
349 });
350
351 $nextButton.on("click", function () {
352 shouldAdvance = true;
353 t.element.pointer("close");
354 });
355
356 return window.jQuery('<div class="wp-pointer-buttons" />')
357 .append($skipButton)
358 .append($nextButton);
359 },
360 close: function () {
361 if (shouldStop) {
362 markTourCompleted();
363 return;
364 }
365
366 if (shouldAdvance) {
367 openStep(index + 1);
368 return;
369 }
370
371 markTourCompleted();
372 },
373 })
374 .pointer("open");
375 };
376
377 openStep(0);
378 };
379
380 initPointerOnboarding();
381
382 const initAnnouncementsPanel = () => {
383 const announcementsConfig = window.basalamAnnouncements;
384
385 if (
386 !announcementsConfig ||
387 !Array.isArray(announcementsConfig.items) ||
388 announcementsConfig.items.length === 0
389 ) {
390 return;
391 }
392
393 const root = document.getElementById("sync-basalam-announcement-root");
394 const trigger = document.getElementById("sync-basalam-announcement-trigger");
395 const panel = document.getElementById("sync-basalam-announcement-panel");
396 const overlay = document.getElementById("sync-basalam-announcement-overlay");
397 const closeBtn = document.getElementById("sync-basalam-announcement-close");
398 const counter = document.getElementById("sync-basalam-announcement-counter");
399 const list = document.getElementById("sync-basalam-announcement-list");
400 const pageIndicator = document.getElementById("sync-basalam-announcement-page");
401 const prevBtn = document.getElementById("sync-basalam-announcement-prev");
402 const nextBtn = document.getElementById("sync-basalam-announcement-next");
403
404 if (
405 !root ||
406 !trigger ||
407 !panel ||
408 !overlay ||
409 !closeBtn ||
410 !counter ||
411 !list ||
412 !pageIndicator ||
413 !prevBtn ||
414 !nextBtn
415 ) {
416 return;
417 }
418
419 const normalizeItems = (rawItems) =>
420 rawItems
421 .map((item) => {
422 const files = Array.isArray(item?.files) ? item.files : [];
423 const imageFile = files.find((f) => f?.url && /\.(png|jpe?g|gif|webp|svg)/i.test(f.url));
424
425 return {
426 id: String(item?.id || ""),
427 description: String(item?.description || ""),
428 link: String(item?.link || "#"),
429 linkText: String(item?.linkText || "ادا�
430 ه"),
431 image: imageFile ? String(imageFile.url) : (item?.image ? String(item.image) : ""),
432 };
433 })
434 .filter((item) => item.id && item.description);
435
436 let items = normalizeItems(announcementsConfig.items);
437
438 if (items.length === 0) {
439 root.remove();
440 return;
441 }
442
443 let currentPage = 1;
444 let totalPages = Math.max(parseInt(announcementsConfig.totalPage, 10) || 1, 1);
445 let isFetching = false;
446
447 let seenIds = new Set(
448 Array.isArray(announcementsConfig.seenIds)
449 ? announcementsConfig.seenIds.map((id) => String(id))
450 : []
451 );
452 let seenRequested = false;
453
454 const getUnreadCount = () =>
455 items.reduce((total, item) => total + (seenIds.has(item.id) ? 0 : 1), 0);
456
457 const updateCounter = () => {
458 const unreadCount = getUnreadCount();
459 counter.textContent = String(unreadCount);
460 counter.classList.toggle(
461 "sync-basalam-announcement-counter-hidden",
462 unreadCount === 0
463 );
464 };
465
466 const renderItems = (pageItems) => {
467 list.innerHTML = "";
468
469 pageItems.forEach((item) => {
470 const card = document.createElement("article");
471 card.className =
472 "sync-basalam-announcement-card" +
473 (item.image ? "" : " sync-basalam-announcement-card-no-image") +
474 (seenIds.has(item.id) ? " is-seen" : " is-unread");
475
476 if (item.image) {
477 const imageWrapper = document.createElement("div");
478 imageWrapper.className = "sync-basalam-announcement-image-wrap";
479
480 const image = document.createElement("img");
481 image.className = "sync-basalam-announcement-image";
482 image.src = item.image;
483 image.alt = "خبر ووسلا�
484 ";
485 image.loading = "lazy";
486
487 imageWrapper.appendChild(image);
488 card.appendChild(imageWrapper);
489 }
490
491 const content = document.createElement("div");
492 content.className = "sync-basalam-announcement-content";
493
494 const description = document.createElement("p");
495 description.className = "sync-basalam-announcement-text";
496 description.textContent = item.description;
497
498 const link = document.createElement("a");
499 link.className = "sync-basalam-announcement-link";
500 link.href = item.link;
501 link.textContent = item.linkText || "ادا�
502 ه";
503 link.target = "_blank";
504 link.rel = "noopener noreferrer";
505
506 content.appendChild(description);
507 if (item.link && item.link !== "#") {
508 content.appendChild(link);
509 }
510 card.appendChild(content);
511 list.appendChild(card);
512 });
513 };
514
515 const updatePagination = () => {
516 pageIndicator.textContent = `${currentPage} / ${totalPages}`;
517 prevBtn.disabled = currentPage <= 1 || isFetching;
518 nextBtn.disabled = currentPage >= totalPages || isFetching;
519 };
520
521 const renderPage = () => {
522 renderItems(items);
523 updatePagination();
524 };
525
526 const fetchPage = (page) => {
527 if (isFetching) {
528 return;
529 }
530
531 isFetching = true;
532 prevBtn.disabled = true;
533 nextBtn.disabled = true;
534 list.innerHTML = '<div class="sync-basalam-announcement-loading">در حال بارگذاری...</div>';
535
536 const formData = new FormData();
537 formData.append("action", announcementsConfig.fetchPageAction || "");
538 formData.append("nonce", announcementsConfig.fetchPageNonce || "");
539 formData.append("page", String(page));
540
541 fetch(ajaxurl, {
542 method: "POST",
543 body: formData,
544 })
545 .then((response) => response.json())
546 .then((data) => {
547 if (!data?.success) {
548 return;
549 }
550
551 const newItems = normalizeItems(data.data.items || []);
552 items = newItems;
553 currentPage = parseInt(data.data.page, 10) || page;
554 totalPages = parseInt(data.data.totalPage, 10) || totalPages;
555
556 renderPage();
557 })
558 .catch(() => {
559 updatePagination();
560 })
561 .finally(() => {
562 isFetching = false;
563 updatePagination();
564 });
565 };
566
567 const markAllSeen = () => {
568 if (seenRequested || getUnreadCount() === 0) {
569 return;
570 }
571
572 seenRequested = true;
573
574 const formData = new FormData();
575 formData.append("action", announcementsConfig.markSeenAction || "");
576 formData.append("nonce", announcementsConfig.nonce || "");
577
578 fetch(ajaxurl, {
579 method: "POST",
580 body: formData,
581 })
582 .then((response) => response.json())
583 .then((data) => {
584 if (!data?.success) {
585 return;
586 }
587
588 seenIds = new Set(items.map((item) => item.id));
589 updateCounter();
590 renderPage();
591 })
592 .catch(() => {})
593 .finally(() => {
594 seenRequested = false;
595 });
596 };
597
598 const openPanel = () => {
599 root.classList.add("is-open");
600 panel.setAttribute("aria-hidden", "false");
601 document.body.classList.add("sync-basalam-announcement-open");
602 markAllSeen();
603 };
604
605 const closePanel = () => {
606 root.classList.remove("is-open");
607 panel.setAttribute("aria-hidden", "true");
608 document.body.classList.remove("sync-basalam-announcement-open");
609 };
610
611 trigger.addEventListener("click", openPanel);
612 closeBtn.addEventListener("click", closePanel);
613 overlay.addEventListener("click", closePanel);
614
615 document.addEventListener("mousedown", (event) => {
616 if (!root.classList.contains("is-open")) {
617 return;
618 }
619
620 const target = event.target;
621 if (!(target instanceof Node)) {
622 return;
623 }
624
625 if (panel.contains(target) || trigger.contains(target)) {
626 return;
627 }
628
629 closePanel();
630 });
631
632 prevBtn.addEventListener("click", () => {
633 if (currentPage <= 1 || isFetching) {
634 return;
635 }
636 fetchPage(currentPage - 1);
637 });
638
639 nextBtn.addEventListener("click", () => {
640 if (currentPage >= totalPages || isFetching) {
641 return;
642 }
643 fetchPage(currentPage + 1);
644 });
645
646 document.addEventListener("keydown", (event) => {
647 if (event.key === "Escape" && root.classList.contains("is-open")) {
648 closePanel();
649 }
650 });
651
652 updateCounter();
653 renderPage();
654 };
655
656 initAnnouncementsPanel();
657
658 const advancedSettingsForm = document.getElementById(
659 "basalam-advanced-settings-form"
660 );
661 const advancedSubmitSection = document.getElementById(
662 "basalam-advanced-submit-section"
663 );
664
665 const isTrackedAdvancedSettingField = (fieldName) =>
666 typeof fieldName === "string" &&
667 fieldName.startsWith("sync_basalam_settings[");
668
669 if (advancedSettingsForm && advancedSubmitSection) {
670 const serializeAdvancedSettings = () => {
671 const formData = new FormData(advancedSettingsForm);
672 const entries = [];
673
674 formData.forEach((value, key) => {
675 if (isTrackedAdvancedSettingField(key)) {
676 entries.push(`${key}=${String(value)}`);
677 }
678 });
679
680 return entries.join("&");
681 };
682
683 let initialSettingsSnapshot = "";
684
685 const toggleAdvancedSubmitVisibility = () => {
686 const currentSnapshot = serializeAdvancedSettings();
687 const hasChanges = currentSnapshot !== initialSettingsSnapshot;
688
689 advancedSubmitSection.classList.toggle(
690 "basalam-submit-section-hidden",
691 !hasChanges
692 );
693 };
694
695 const captureInitialSnapshot = () => {
696 initialSettingsSnapshot = serializeAdvancedSettings();
697 toggleAdvancedSubmitVisibility();
698 };
699
700 const handleSettingsFieldMutation = (event) => {
701 const fieldName = event.target?.name || "";
702
703 if (!isTrackedAdvancedSettingField(fieldName)) {
704 return;
705 }
706
707 window.requestAnimationFrame(toggleAdvancedSubmitVisibility);
708 };
709
710 advancedSettingsForm.addEventListener("input", handleSettingsFieldMutation);
711 advancedSettingsForm.addEventListener(
712 "change",
713 handleSettingsFieldMutation
714 );
715
716 captureInitialSnapshot();
717 window.requestAnimationFrame(captureInitialSnapshot);
718 }
719
720 const infoTriggers = document.querySelectorAll(".basalam-info-trigger");
721
722 const moveModalsToBody = () => {
723 const allModals = document.querySelectorAll(".basalam-info-modal");
724 allModals.forEach((modal) => {
725 if (modal.parentNode !== document.body) {
726 document.body.appendChild(modal);
727 }
728 });
729 };
730
731 moveModalsToBody();
732
733 const closeAllModals = () => {
734 const allModals = document.querySelectorAll(".basalam-info-modal");
735 allModals.forEach((modal) => {
736 modal.style.display = "none";
737 modal.classList.remove("show");
738 });
739 document.body.style.overflow = "auto";
740 };
741
742 const openModal = (modalId) => {
743 const modal = document.getElementById(modalId);
744 if (modal) {
745 if (modal.parentNode !== document.body) {
746 document.body.appendChild(modal);
747 }
748
749 modal.style.display = "block";
750 modal.classList.add("show");
751 document.body.style.overflow = "hidden";
752
753 modal.focus();
754 }
755 };
756
757 infoTriggers.forEach((trigger) => {
758 trigger.addEventListener("click", (e) => {
759 e.preventDefault();
760 e.stopPropagation();
761
762 const modalId = trigger.getAttribute("data-modal-id");
763 if (modalId) {
764 openModal(modalId);
765 }
766 });
767 });
768
769 document.addEventListener("click", (e) => {
770 if (e.target.classList.contains("basalam-info-modal-close")) {
771 e.preventDefault();
772 closeAllModals();
773 }
774
775 if (e.target.classList.contains("basalam-info-modal-overlay")) {
776 closeAllModals();
777 }
778
779 if (e.target.classList.contains("basalam-info-modal")) {
780 closeAllModals();
781 }
782 });
783
784 document.addEventListener("keydown", (e) => {
785 if (e.key === "Escape") {
786 closeAllModals();
787 }
788 });
789
790 document.addEventListener("click", (e) => {
791 if (e.target.closest(".basalam-info-modal-content")) {
792 e.stopPropagation();
793 }
794 });
795
796 const tasksAutoToggle = document.querySelector(".basalam-tasks-auto-toggle");
797 const tasksManualContainer = document.querySelector(
798 ".basalam-tasks-manual-container"
799 );
800 const tasksManualInput = document.querySelector(
801 ".basalam-tasks-manual-input"
802 );
803 const tasksAutoHidden = document.querySelector(".basalam-tasks-auto-hidden");
804
805 const toggleTasksManualInput = () => {
806 if (tasksAutoToggle && tasksManualInput) {
807 const isAuto = tasksAutoToggle.checked;
808
809 if (isAuto) {
810 tasksManualInput.disabled = true;
811 if (tasksAutoHidden) tasksAutoHidden.disabled = true;
812 } else {
813 tasksManualInput.disabled = false;
814 if (tasksAutoHidden) tasksAutoHidden.disabled = false;
815 }
816 }
817 };
818
819 if (tasksAutoToggle) {
820 tasksAutoToggle.addEventListener("change", toggleTasksManualInput);
821 }
822
823 // Attribute suffix toggle handler
824 const attributeSuffixToggle = document.querySelector(
825 ".basalam-attribute-suffix-toggle"
826 );
827 const attributeSuffixPriority = document.querySelector(
828 ".basalam-attribute-suffix-priority"
829 );
830 const attributeSuffixContainer = document.querySelector(
831 ".basalam-attribute-suffix-container"
832 );
833 const attributeSuffixHidden = document.querySelector(
834 ".basalam-attribute-suffix-hidden"
835 );
836
837 const toggleAttributeSuffixPriority = () => {
838 if (attributeSuffixToggle) {
839 const isEnabled = attributeSuffixToggle.checked;
840
841 if (attributeSuffixPriority) {
842 attributeSuffixPriority.disabled = !isEnabled;
843 }
844
845 if (attributeSuffixContainer) {
846 attributeSuffixContainer.style.display = isEnabled ? "block" : "none";
847 }
848
849 if (attributeSuffixHidden) {
850 attributeSuffixHidden.disabled = isEnabled;
851 }
852 }
853 };
854
855 if (attributeSuffixToggle) {
856 attributeSuffixToggle.addEventListener(
857 "change",
858 toggleAttributeSuffixPriority
859 );
860 // Initialize on page load
861 toggleAttributeSuffixPriority();
862 }
863
864 const initBulkEditFields = () => {
865 const SYNC_BASALAM_BULK_ACTION = "sync_basalam_bulk_edit";
866
867 const syncTypeVisibility = () => {
868 document
869 .querySelectorAll('select[name="sync_basalam_bulk_product_type_action"]')
870 .forEach((select) => {
871 const container = select
872 .closest(".sync-basalam-bulk-edit")
873 ?.querySelector(".sync-basalam-bulk-type-fields");
874
875 if (container) {
876 container.style.display = select.value === "yes" ? "flex" : "none";
877 }
878 });
879 };
880
881 const syncIncreaseVisibility = () => {
882 document
883 .querySelectorAll('select[name="sync_basalam_bulk_increase_action"]')
884 .forEach((select) => {
885 const field = select
886 .closest(".sync-basalam-bulk-edit")
887 ?.querySelector(".sync-basalam-bulk-increase-value");
888
889 if (field) {
890 field.style.display = select.value === "set" ? "block" : "none";
891 }
892 });
893 };
894
895 const setBulkEditMode = (mode) => {
896 const bulkRow = document.getElementById("bulk-edit");
897 if (!bulkRow) {
898 return;
899 }
900
901 bulkRow.classList.remove("sync-basalam-bulk-mode", "sync-basalam-default-bulk-mode");
902 bulkRow.classList.add(mode === "basalam" ? "sync-basalam-bulk-mode" : "sync-basalam-default-bulk-mode");
903 };
904
905 const openBasalamBulkEditor = (sourceSelect) => {
906 if (!window.inlineEditPost || typeof window.inlineEditPost.setBulk !== "function") {
907 return;
908 }
909
910 setBulkEditMode("basalam");
911
912 sourceSelect.value = "edit";
913 window.inlineEditPost.setBulk();
914 sourceSelect.value = SYNC_BASALAM_BULK_ACTION;
915
916 window.requestAnimationFrame(() => {
917 setBulkEditMode("basalam");
918 syncTypeVisibility();
919 syncIncreaseVisibility();
920 });
921 };
922
923 document.addEventListener("change", (event) => {
924 const target = event.target;
925 if (!(target instanceof HTMLSelectElement)) {
926 return;
927 }
928
929 if (target.name === "sync_basalam_bulk_product_type_action") {
930 syncTypeVisibility();
931 }
932
933 if (target.name === "sync_basalam_bulk_increase_action") {
934 syncIncreaseVisibility();
935 }
936 });
937
938 document.addEventListener("click", (event) => {
939 const button = event.target instanceof Element
940 ? event.target.closest("#doaction, #doaction2")
941 : null;
942
943 if (!button) {
944 return;
945 }
946
947 const selectorId = button.id === "doaction2" ? "bulk-action-selector-bottom" : "bulk-action-selector-top";
948 const actionSelect = document.getElementById(selectorId);
949
950 if (!(actionSelect instanceof HTMLSelectElement)) {
951 return;
952 }
953
954 if (actionSelect.value === SYNC_BASALAM_BULK_ACTION) {
955 event.preventDefault();
956 event.stopImmediatePropagation();
957 openBasalamBulkEditor(actionSelect);
958 return;
959 }
960
961 if (actionSelect.value === "edit") {
962 setBulkEditMode("default");
963 }
964 }, true);
965
966 document.addEventListener("click", (event) => {
967 const cancelButton = event.target instanceof Element
968 ? event.target.closest("#bulk-edit .cancel")
969 : null;
970
971 if (!cancelButton) {
972 return;
973 }
974
975 setBulkEditMode("default");
976 });
977
978 setBulkEditMode("default");
979
980 syncTypeVisibility();
981 syncIncreaseVisibility();
982 };
983
984 initBulkEditFields();
985
986 var modal = document.getElementById("sync_basalam_support_modal");
987 var btn = document.getElementById("sync_basalam_support_btn");
988 var cancelBtn = document.getElementById("sync_basalam_cancel_btn");
989
990 if (btn) {
991 btn.addEventListener("click", function () {
992 if (modal) {
993 modal.style.display = "flex";
994 }
995 });
996 }
997
998 if (cancelBtn) {
999 cancelBtn.addEventListener("click", function () {
1000 if (modal) {
1001 modal.style.display = "none";
1002 }
1003 });
1004 }
1005
1006 if (modal) {
1007 modal.addEventListener("click", function (e) {
1008 if (e.target === modal) {
1009 modal.style.display = "none";
1010 }
1011 });
1012 }
1013
1014 // Star rating functionality
1015 var currentRating = 5;
1016
1017 function updateStars(rating) {
1018 var stars = document.querySelectorAll('#basalam_rating_stars .basalam-star');
1019 stars.forEach(function(star) {
1020 var starRating = parseInt(star.getAttribute('data-rating'));
1021 if (starRating <= rating) {
1022 star.style.color = '#f5a623';
1023 } else {
1024 star.style.color = '#ddd';
1025 }
1026 });
1027 }
1028
1029 updateStars(5);
1030
1031 var starsContainer = document.getElementById('basalam_rating_stars');
1032 if (starsContainer) {
1033 starsContainer.addEventListener('mouseover', function(e) {
1034 if (e.target.classList.contains('basalam-star')) {
1035 var hoverRating = parseInt(e.target.getAttribute('data-rating'));
1036 updateStars(hoverRating);
1037 }
1038 });
1039
1040 starsContainer.addEventListener('mouseout', function() {
1041 updateStars(currentRating);
1042 });
1043
1044 starsContainer.addEventListener('click', function(e) {
1045 if (e.target.classList.contains('basalam-star')) {
1046 currentRating = parseInt(e.target.getAttribute('data-rating'));
1047 document.getElementById('sync_basalam_rating').value = currentRating;
1048 updateStars(currentRating);
1049 }
1050 });
1051 }
1052
1053 // Remind Later button
1054 var remindLaterBtn = document.getElementById('sync_basalam_remind_later_review_btn');
1055 if (remindLaterBtn) {
1056 remindLaterBtn.addEventListener('click', function() {
1057 var nonceEl = document.getElementById('sync_basalam_remind_later_review_nonce');
1058 jQuery.ajax({
1059 url: ajaxurl,
1060 type: 'POST',
1061 data: {
1062 action: 'sync_basalam_remind_later_review',
1063 _wpnonce: nonceEl ? nonceEl.value : ''
1064 },
1065 success: function() {
1066 document.getElementById('sync_basalam_like_alert').style.display = 'none';
1067 }
1068 });
1069 });
1070 }
1071
1072 // Never Remind button
1073 var neverRemindBtn = document.getElementById('sync_basalam_never_remind_review_btn');
1074 if (neverRemindBtn) {
1075 neverRemindBtn.addEventListener('click', function() {
1076 var nonceEl = document.getElementById('sync_basalam_never_remind_review_nonce');
1077 jQuery.ajax({
1078 url: ajaxurl,
1079 type: 'POST',
1080 data: {
1081 action: 'sync_basalam_never_remind_review',
1082 _wpnonce: nonceEl ? nonceEl.value : ''
1083 },
1084 success: function() {
1085 document.getElementById('sync_basalam_like_alert').style.display = 'none';
1086 }
1087 });
1088 });
1089 }
1090
1091 // Submit Review form
1092 var supportForm = document.getElementById('sync_basalam_support_form');
1093 if (supportForm) {
1094 supportForm.addEventListener('submit', function(e) {
1095 e.preventDefault();
1096 var nonceEl = document.getElementById('sync_basalam_submit_review_nonce');
1097 var ratingEl = document.getElementById('sync_basalam_rating');
1098 var commentEl = document.getElementById('sync_basalam_comment');
1099
1100 jQuery.ajax({
1101 url: ajaxurl,
1102 type: 'POST',
1103 data: {
1104 action: 'sync_basalam_submit_review',
1105 _wpnonce: nonceEl ? nonceEl.value : '',
1106 sync_basalam_rating: ratingEl ? ratingEl.value : '5',
1107 sync_basalam_comment: commentEl ? commentEl.value : ''
1108 },
1109 success: function(response) {
1110 if (response.success) {
1111 document.getElementById('sync_basalam_like_alert').style.display = 'none';
1112 if (modal) modal.style.display = 'none';
1113 } else {
1114 window.BasalamToast.error(response.data && response.data.message ? response.data.message : 'خطا در ارسال نظر');
1115 }
1116 }
1117 });
1118 });
1119 }
1120 });
1121