(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 = `
`;
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();
}