(function() { // ============================== // 🔹 دالة لإضافة رابط التخفيضات في قائمة الديسكتوب // ============================== function addDesktopSaleLink() { const mainMenu = document.querySelector('.desktop-menu .main-menu'); if (!mainMenu) return; // تأكد أننا لم نضف العنصر مسبقًا if (mainMenu.querySelector('.sale-link-item')) return; const newItem = document.createElement('li'); newItem.className = '!hidden lg:!block root-level lg:!inline-block sale-link-item'; newItem.innerHTML = ` تخفيضات `; mainMenu.appendChild(newItem); } // ============================== // 🔹 دالة لإضافة رابط التخفيضات في تبويبات الموبايل // ============================== function addMobileSaleTab() { const tabsContainer = document.querySelector('.global-tabs'); if (!tabsContainer) return; // تأكد أننا لم نضف العنصر مسبقًا if (tabsContainer.querySelector('.sale-tab-item')) return; const saleTab = document.createElement('div'); saleTab.className = 'global-tabs--item mx-1 sale-tab-item'; saleTab.innerHTML = ` تخفيضات `; tabsContainer.appendChild(saleTab); } // ============================== // 🔹 مراقبة تغييرات الـ DOM // ============================== const observer = new MutationObserver((mutations, obs) => { const desktopReady = document.querySelector('.desktop-menu .main-menu'); const mobileReady = document.querySelector('.global-tabs'); if (desktopReady) addDesktopSaleLink(); if (mobileReady) addMobileSaleTab(); // إذا أضيف الرابطان بنجاح، نوقف المراقبة if ( document.querySelector('.sale-link-item') && document.querySelector('.sale-tab-item') ) { obs.disconnect(); } }); // نراقب كامل الـ body لأن العناصر قد تُضاف بعد التحميل observer.observe(document.body, { childList: true, subtree: true }); // كإجراء احتياطي، نحاول الإضافة بعد تحميل الصفحة document.addEventListener('DOMContentLoaded', function() { addDesktopSaleLink(); addMobileSaleTab(); }); })(); // ✅ Check if we’re on a product page console.log('🔍 Checking page type...'); if (document.body.classList.contains('product-single')) { console.log('✅ This is a product page!'); // Wait helper function waitFor(conditionFn, timeout = 5000, interval = 100) { return new Promise((resolve, reject) => { const start = Date.now(); (function check() { if (conditionFn()) return resolve(true); if (Date.now() - start > timeout) return reject(new Error('Timeout waiting for condition')); setTimeout(check, interval); })(); }); } // ------------------------------ // 🔧 Main init // ------------------------------ async function initDiscountTimer() { try { console.log('🚀 Initializing discount timer...'); await waitFor(() => window.salla && salla.api && salla.api.product, 5000) .catch(() => console.warn('⚠️ salla.api not ready yet, may fail.')); const productId = getProductIdFromPage(); console.log('📦 Product ID:', productId); if (!productId) { console.error('❌ No product ID found.'); return; } if (!salla.api?.product?.getDetails) { console.error('❌ salla.api.product.getDetails not available.'); return; } console.log('📡 Fetching product details...'); const response = await salla.api.product.getDetails(productId); console.log('📥 API Response:', response); const product = response?.data || response?.product || response; if (!product) { console.error('❌ No product data found.'); return; } let discountEnds = product.discount_ends || product.discountEnds || product.sale_end_at; if (!discountEnds) { console.warn('⚠️ No discount end time found.'); return; } // Normalize if (typeof discountEnds === 'number' && discountEnds < 1e12) discountEnds *= 1000; const endTime = new Date(discountEnds); if (isNaN(endTime.getTime())) { console.error('❌ Invalid discount end date.'); return; } if (!document.getElementById('discount-timer')) { createTimerElement(); } console.log('⏱️ Starting countdown...'); startCountdown(endTime); } catch (err) { console.error('💥 Error initializing timer:', err); } } // ------------------------------ // 🧩 Get Product ID // ------------------------------ function getProductIdFromPage() { console.log('🔎 Extracting product ID...'); const productDiv = document.querySelector('[id^="product-"]'); if (productDiv?.id) { const m = productDiv.id.match(/product-(\d+)/); if (m) return Number(m[1]); } const path = window.location.pathname; const urlMatch = path.match(/\/p(\d+)/) || path.match(/\/product\/(\d+)/); if (urlMatch) return Number(urlMatch[1]); const slider = document.querySelector('[id^="details-slider-"]'); if (slider) { const m = slider.id.match(/details-slider-(\d+)/); if (m) return Number(m[1]); } const wishlistBtn = document.querySelector('[data-id]'); if (wishlistBtn?.dataset.id) return Number(wishlistBtn.dataset.id); console.warn('❌ Could not find product ID.'); return null; } // ------------------------------ // 🎨 Create Timer Element (New Style) // ------------------------------ function createTimerElement() { const timerHTML = `
⏰ العرض ينتهي خلال
00
يوم
00
ساعة
00
دقيقة
00
ثانية
`; const insertPoints = [ '.product-main-content', '.main-content', '[id^="product-"]', '.container', 'body' ]; let inserted = false; for (let selector of insertPoints) { const el = document.querySelector(selector); if (el) { el.insertAdjacentHTML('afterend', timerHTML); inserted = true; console.log(`✅ Timer inserted after "${selector}"`); break; } } if (!inserted) { console.warn('⚠️ No valid insertion point found, appending to body.'); document.body.insertAdjacentHTML('beforeend', timerHTML); } } // ------------------------------ // ⏱️ Countdown Logic // ------------------------------ function startCountdown(endTime) { const endMs = new Date(endTime).getTime(); let intervalId; function updateTimer() { const now = Date.now(); const distance = endMs - now; const timerEl = document.getElementById('discount-timer'); if (!timerEl) { if (intervalId) clearInterval(intervalId); return; } if (distance <= 0) { timerEl.innerHTML = `
⏰ انتهى العرض
`; if (intervalId) clearInterval(intervalId); return; } const days = Math.floor(distance / (1000 * 60 * 60 * 24)); const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((distance % (1000 * 60)) / 1000); const update = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = String(val).padStart(2, '0'); }; update('days', days); update('hours', hours); update('minutes', minutes); update('seconds', seconds); } updateTimer(); intervalId = setInterval(updateTimer, 1000); } // ------------------------------ // 🚀 Start on DOM Ready // ------------------------------ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initDiscountTimer); } else { initDiscountTimer(); } } else { console.log('❌ Not a product page — timer won’t run.'); } // ✅ عداد الخصم على بطاقات المنتجات - يظهر فوق الصورة بأسفلها + Responsive async function initCardTimersGlobal() { // 🔄 تأكد من جاهزية API await new Promise((res) => { const check = () => window.salla?.api?.product?.getDetails ? res() : setTimeout(check, 300); check(); }); console.log("🚀 بدء تفعيل عدادات الخصم على بطاقات المنتجات (تصميم جديد)..."); // -------------------------------------------- // دالة مرنة لتحويل أي نوع من تاريخ الانتهاء إلى Date // -------------------------------------------- function parseDiscountDate(value) { if (!value) return null; if (value instanceof Date && !isNaN(value)) return value; if (typeof value === "number") { const ms = value < 1e12 ? value * 1000 : value; const d = new Date(ms); return isNaN(d) ? null : d; } if (typeof value === "string") { let t = Date.parse(value); if (!isNaN(t)) return new Date(t); if (!value.endsWith("Z")) t = Date.parse(value + "Z"); if (!isNaN(t)) return new Date(t); const n = Number(value); if (!isNaN(n)) return new Date(n < 1e12 ? n * 1000 : n); } return null; } // -------------------------------------------- // دالة لإضافة العداد على صورة المنتج في البطاقة // -------------------------------------------- async function addTimerToCard(card) { const idMatch = card.id?.match(/\d+/); if (!idMatch) return; const productId = idMatch[0]; if (card.dataset.timerAdded) return; card.dataset.timerAdded = "true"; try { const res = await salla.api.product.getDetails(productId); const product = res?.data || res?.product || res; const discountEnds = product?.discount_ends ?? product?.discountEnds ?? product?.sale_end_at ?? product?.saleEndsAt; if (!discountEnds) return; const endTime = parseDiscountDate(discountEnds); if (!endTime) return; // -------------------------------------------- // إنشاء عنصر العداد الجديد فوق الصورة // -------------------------------------------- const timerOverlay = document.createElement("div"); timerOverlay.className = "discount-timer-overlay"; timerOverlay.innerHTML = `
00
ي
00
س
00
د `; // حط العداد داخل عنصر الصورة const imageWrapper = card.querySelector(".s-product-card-image"); if (imageWrapper) { imageWrapper.style.position = "relative"; imageWrapper.appendChild(timerOverlay); } else { card.appendChild(timerOverlay); } // -------------------------------------------- // تحديث العد التنازلي // -------------------------------------------- const endMs = endTime.getTime(); const intervalId = setInterval(() => { const diff = endMs - Date.now(); if (diff <= 0) { timerOverlay.innerHTML = '
🔥 انتهى العرض
'; clearInterval(intervalId); return; } const d = Math.floor(diff / (1000 * 60 * 60 * 24)); const h = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const setText = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = String(val).padStart(2, "0"); }; setText(`d-${productId}`, d); setText(`h-${productId}`, h); setText(`m-${productId}`, m); }, 1000); } catch (err) { console.warn(`⚠️ فشل تحميل بيانات المنتج ${productId}`, err); } } // تشغيل على البطاقات الحالية document.querySelectorAll("custom-salla-product-card[id]").forEach(addTimerToCard); // مراقبة DOM لإضافة بطاقات جديدة تلقائيًا const observer = new MutationObserver((mutations) => { for (const m of mutations) { for (const node of m.addedNodes) { if (node.nodeType !== 1) continue; if (node.matches && node.matches("custom-salla-product-card[id]")) { addTimerToCard(node); } else if (node.querySelectorAll) { node.querySelectorAll("custom-salla-product-card[id]").forEach(addTimerToCard); } } } }); observer.observe(document.body, { childList: true, subtree: true }); } // تفعيل عند تحميل الصفحة if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initCardTimersGlobal); } else { initCardTimersGlobal(); }