673 lines
25 KiB
JavaScript
673 lines
25 KiB
JavaScript
/**
|
||
* اسکریپت اصلی تم مطیب
|
||
*
|
||
* @package Motayeb
|
||
* @version 1.0.1
|
||
*
|
||
* تغییرات نسخه ۱.۰.۱:
|
||
* - persist شدن سبد خرید و علاقهمندیها در localStorage
|
||
* - persist شدن دارک مود در کوکی (هماهنگ با PHP body_class)
|
||
* - جلوگیری از XSS با escapeHtml روی همه ورودیهای داینامیک
|
||
* - guard کردن motayeb_ajax
|
||
* - بهبود مدیریت خطای fetch
|
||
* - رفع toggleWishlist و setRating
|
||
* - استفاده از کلاسهای Tailwind در renderStars
|
||
*/
|
||
|
||
// ============================================
|
||
// Guard متغیرهای سراسری
|
||
// ============================================
|
||
const MOTAYEB_AJAX = (typeof motayeb_ajax !== 'undefined') ? motayeb_ajax : {
|
||
ajax_url: '/wp-admin/admin-ajax.php',
|
||
nonce: '',
|
||
home_url: '/',
|
||
checkout_url: '/checkout/',
|
||
cart_url: '/cart/'
|
||
};
|
||
|
||
// ============================================
|
||
// مدیریت State با localStorage
|
||
// ============================================
|
||
let cart = loadFromStorage('motayeb_cart', []);
|
||
let wishlist = loadFromStorage('motayeb_wishlist', []);
|
||
let selectedWeightPrice = 295000;
|
||
|
||
function loadFromStorage(key, fallback) {
|
||
try {
|
||
const saved = localStorage.getItem(key);
|
||
return saved ? JSON.parse(saved) : fallback;
|
||
} catch (e) {
|
||
return fallback;
|
||
}
|
||
}
|
||
|
||
function saveToStorage(key, value) {
|
||
try {
|
||
localStorage.setItem(key, JSON.stringify(value));
|
||
} catch (e) {
|
||
// localStorage ممکنه private mode باشه — نادیده میگیریم
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// ابزارهای کمکی
|
||
// ============================================
|
||
|
||
/**
|
||
* Escape کردن HTML برای جلوگیری از XSS
|
||
*/
|
||
function escapeHtml(str) {
|
||
if (str === null || str === undefined) return '';
|
||
return String(str)
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"')
|
||
.replace(/'/g, ''');
|
||
}
|
||
|
||
/**
|
||
* فرمت قیمت — اعداد فارسی + نمایش رایگان برای قیمت صفر
|
||
*/
|
||
function formatPrice(n) {
|
||
n = Number(n) || 0;
|
||
if (n === 0) return 'رایگان';
|
||
return n.toLocaleString('fa-IR');
|
||
}
|
||
|
||
/**
|
||
* درخواست Ajax با مدیریت خطای کامل
|
||
*/
|
||
async function motayebFetch(action, params = {}) {
|
||
const url = new URL(MOTAYEB_AJAX.ajax_url, window.location.origin);
|
||
url.searchParams.set('action', action);
|
||
url.searchParams.set('nonce', MOTAYEB_AJAX.nonce);
|
||
Object.keys(params).forEach(k => url.searchParams.set(k, params[k]));
|
||
|
||
const response = await fetch(url.toString());
|
||
if (!response.ok) {
|
||
throw new Error('HTTP ' + response.status);
|
||
}
|
||
const data = await response.json();
|
||
return data;
|
||
}
|
||
|
||
// ============================================
|
||
// توابع سبد خرید
|
||
// ============================================
|
||
|
||
async function quickAddToCart(id) {
|
||
try {
|
||
const data = await motayebFetch('get_product_data', { id: id });
|
||
if (data.success) {
|
||
const p = data.data;
|
||
const existing = cart.find(x => x.id === p.id);
|
||
if (existing) {
|
||
existing.qty++;
|
||
} else {
|
||
cart.push({ ...p, qty: 1 });
|
||
}
|
||
saveToStorage('motayeb_cart', cart);
|
||
updateCartUI();
|
||
showToast(escapeHtml(p.name) + ' به سبد خرید اضافه شد', 'success');
|
||
} else {
|
||
showToast('محصول یافت نشد', 'error');
|
||
}
|
||
} catch (err) {
|
||
console.error('quickAddToCart:', err);
|
||
showToast('خطا در ارتباط با سرور', 'error');
|
||
}
|
||
}
|
||
|
||
async function addToCartDetail(productId) {
|
||
const qtyEl = document.getElementById('product-qty');
|
||
const qty = parseInt(qtyEl ? qtyEl.textContent : '1') || 1;
|
||
|
||
try {
|
||
const data = await motayebFetch('get_product_data', { id: productId });
|
||
if (data.success) {
|
||
const p = data.data;
|
||
const existing = cart.find(x => x.id === p.id);
|
||
if (existing) {
|
||
existing.qty += qty;
|
||
} else {
|
||
cart.push({ ...p, qty: qty });
|
||
}
|
||
saveToStorage('motayeb_cart', cart);
|
||
updateCartUI();
|
||
showToast(escapeHtml(p.name) + ' به سبد خرید اضافه شد', 'success');
|
||
} else {
|
||
showToast('محصول یافت نشد', 'error');
|
||
}
|
||
} catch (err) {
|
||
console.error('addToCartDetail:', err);
|
||
showToast('خطا در ارتباط با سرور', 'error');
|
||
}
|
||
}
|
||
|
||
function removeFromCart(id) {
|
||
cart = cart.filter(x => x.id !== id);
|
||
saveToStorage('motayeb_cart', cart);
|
||
updateCartUI();
|
||
}
|
||
|
||
function updateCartQty(id, delta) {
|
||
const item = cart.find(x => x.id === id);
|
||
if (!item) return;
|
||
item.qty += delta;
|
||
if (item.qty <= 0) {
|
||
removeFromCart(id);
|
||
return;
|
||
}
|
||
saveToStorage('motayeb_cart', cart);
|
||
updateCartUI();
|
||
}
|
||
|
||
function updateCartUI() {
|
||
const count = cart.reduce((s, i) => s + i.qty, 0);
|
||
const total = cart.reduce((s, i) => s + (Number(i.price) || 0) * i.qty, 0);
|
||
|
||
// Badge روی آیکون سبد
|
||
['cart-count', 'mobile-cart-count', 'cart-drawer-count'].forEach(id => {
|
||
const el = document.getElementById(id);
|
||
if (!el) return;
|
||
if (id === 'cart-drawer-count') {
|
||
el.textContent = count;
|
||
} else {
|
||
if (count > 0) {
|
||
el.textContent = count;
|
||
el.classList.remove('hidden');
|
||
} else {
|
||
el.classList.add('hidden');
|
||
}
|
||
}
|
||
});
|
||
|
||
// محتویات drawer
|
||
const listEl = document.getElementById('cart-items-list');
|
||
const emptyEl = document.getElementById('cart-empty');
|
||
const footerEl = document.getElementById('cart-drawer-footer');
|
||
|
||
if (!listEl) return;
|
||
|
||
if (cart.length === 0) {
|
||
listEl.classList.add('hidden');
|
||
if (emptyEl) emptyEl.classList.remove('hidden');
|
||
if (footerEl) footerEl.classList.add('hidden');
|
||
} else {
|
||
listEl.classList.remove('hidden');
|
||
if (emptyEl) emptyEl.classList.add('hidden');
|
||
if (footerEl) footerEl.classList.remove('hidden');
|
||
|
||
const totalEl = document.getElementById('cart-drawer-total');
|
||
if (totalEl) totalEl.textContent = formatPrice(total) + ' تومان';
|
||
|
||
listEl.innerHTML = cart.map(i => `
|
||
<div class="flex gap-3 bg-cream-50 dark:bg-dark-bg rounded-xl p-3">
|
||
<img src="${escapeHtml(i.img && i.img !== 'default-product' ? i.img : 'https://picsum.photos/seed/' + i.id + '/100/100.jpg')}" alt="${escapeHtml(i.name)}" class="w-16 h-16 rounded-lg object-cover flex-shrink-0">
|
||
<div class="flex-1 min-w-0">
|
||
<h4 class="font-bold text-sm line-clamp-1">${escapeHtml(i.name)}</h4>
|
||
<div class="text-xs text-cream-500 dark:text-dark-muted mt-0.5">${formatPrice(i.price)} تومان</div>
|
||
<div class="flex items-center justify-between mt-2">
|
||
<div class="flex items-center border border-cream-200 dark:border-dark-border rounded-lg overflow-hidden">
|
||
<button onclick="updateCartQty(${i.id},-1)" class="w-7 h-7 flex items-center justify-center hover:bg-cream-200 dark:hover:bg-dark-card transition text-xs" aria-label="کاهش"><iconify-icon icon="lucide:minus" width="12"></iconify-icon></button>
|
||
<span class="w-8 h-7 flex items-center justify-center text-xs font-bold border-x border-cream-200 dark:border-dark-border">${i.qty}</span>
|
||
<button onclick="updateCartQty(${i.id},1)" class="w-7 h-7 flex items-center justify-center hover:bg-cream-200 dark:hover:bg-dark-card transition text-xs" aria-label="افزایش"><iconify-icon icon="lucide:plus" width="12"></iconify-icon></button>
|
||
</div>
|
||
<button onclick="removeFromCart(${i.id})" class="text-red-400 hover:text-red-500 transition" aria-label="حذف"><iconify-icon icon="lucide:trash-2" width="16"></iconify-icon></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
|
||
// صفحه checkout
|
||
const checkoutItems = document.getElementById('checkout-items');
|
||
if (checkoutItems) {
|
||
if (cart.length === 0) {
|
||
checkoutItems.innerHTML = '<p class="text-sm text-cream-500 dark:text-dark-muted text-center py-4">سبد خرید خالی است</p>';
|
||
} else {
|
||
checkoutItems.innerHTML = cart.map(i => `
|
||
<div class="flex items-center gap-3">
|
||
<img src="${escapeHtml(i.img && i.img !== 'default-product' ? i.img : 'https://picsum.photos/seed/' + i.id + '/60/60.jpg')}" alt="${escapeHtml(i.name)}" class="w-12 h-12 rounded-lg object-cover">
|
||
<div class="flex-1 min-w-0">
|
||
<div class="text-sm font-medium line-clamp-1">${escapeHtml(i.name)}</div>
|
||
<div class="text-xs text-cream-500 dark:text-dark-muted">${i.qty} عدد</div>
|
||
</div>
|
||
<div class="text-sm font-bold whitespace-nowrap">${formatPrice(Number(i.price) * i.qty)}</div>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
const subtotalEl = document.getElementById('checkout-subtotal');
|
||
const totalEl = document.getElementById('checkout-total');
|
||
if (subtotalEl) subtotalEl.textContent = formatPrice(total) + ' تومان';
|
||
if (totalEl) totalEl.textContent = formatPrice(total) + ' تومان';
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// توابع UI — جستجو، سبد، منو
|
||
// ============================================
|
||
|
||
function openSearch() {
|
||
const overlay = document.getElementById('search-overlay');
|
||
if (!overlay) return;
|
||
overlay.classList.remove('hidden');
|
||
setTimeout(() => {
|
||
const input = document.getElementById('search-input');
|
||
if (input) input.focus();
|
||
}, 100);
|
||
}
|
||
|
||
function closeSearch() {
|
||
const overlay = document.getElementById('search-overlay');
|
||
if (overlay) overlay.classList.add('hidden');
|
||
const input = document.getElementById('search-input');
|
||
if (input) input.value = '';
|
||
const results = document.getElementById('search-results');
|
||
if (results) results.innerHTML = '';
|
||
const suggestions = document.getElementById('search-suggestions');
|
||
if (suggestions) suggestions.classList.remove('hidden');
|
||
}
|
||
|
||
function openCart() {
|
||
const drawer = document.getElementById('cart-drawer');
|
||
if (drawer) drawer.classList.remove('hidden');
|
||
}
|
||
|
||
function closeCart() {
|
||
const drawer = document.getElementById('cart-drawer');
|
||
if (drawer) drawer.classList.add('hidden');
|
||
}
|
||
|
||
function openMobileMenu() {
|
||
const menu = document.getElementById('mobile-menu');
|
||
if (menu) menu.classList.remove('hidden');
|
||
}
|
||
|
||
function closeMobileMenu() {
|
||
const menu = document.getElementById('mobile-menu');
|
||
if (menu) menu.classList.add('hidden');
|
||
}
|
||
|
||
function toggleLang() {
|
||
showToast('نسخه انگلیسی به زودی اضافه میشود', 'info');
|
||
}
|
||
|
||
function goToCheckout() {
|
||
closeCart();
|
||
if (MOTAYEB_AJAX.checkout_url) {
|
||
window.location.href = MOTAYEB_AJAX.checkout_url;
|
||
} else {
|
||
window.location.href = '/checkout/';
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// دارک مود — هماهنگ با PHP body_class
|
||
// ============================================
|
||
|
||
/**
|
||
* تغییر حالت تاریک.
|
||
* - کلاس dark روی <html> (برای Tailwind dark:)
|
||
* - کلاس dark-mode روی <body> (برای CSS variables قدیمی)
|
||
* - ذخیره در کوکی (برای خواندن سمت سرور در functions.php)
|
||
*/
|
||
function toggleDark() {
|
||
const html = document.documentElement;
|
||
const body = document.body;
|
||
const isDark = html.classList.toggle('dark');
|
||
body.classList.toggle('dark-mode', isDark);
|
||
|
||
// ذخیره در کوکی — ۱ سال اعتبار
|
||
const value = isDark ? 'on' : 'off';
|
||
document.cookie = 'motayeb_darkmode=' + value +
|
||
';path=/;max-age=31536000;SameSite=Lax';
|
||
}
|
||
|
||
// ============================================
|
||
// جستجوی زنده
|
||
// ============================================
|
||
|
||
async function handleSearch(val) {
|
||
const results = document.getElementById('search-results');
|
||
const suggestions = document.getElementById('search-suggestions');
|
||
if (!results) return;
|
||
|
||
if (val.length < 2) {
|
||
results.innerHTML = '';
|
||
if (suggestions) suggestions.classList.remove('hidden');
|
||
return;
|
||
}
|
||
if (suggestions) suggestions.classList.add('hidden');
|
||
|
||
try {
|
||
const data = await motayebFetch('search_products', { term: val });
|
||
if (data.success && data.data.length > 0) {
|
||
results.innerHTML = data.data.map(p => {
|
||
const imgSrc = p.image || p.img || ('https://picsum.photos/seed/' + p.id + '/60/60.jpg');
|
||
const permalink = p.permalink || '#';
|
||
return `
|
||
<a href="${escapeHtml(permalink)}" onclick="closeSearch()" class="flex items-center gap-3 w-full p-3 rounded-xl hover:bg-cream-50 dark:hover:bg-dark-bg transition text-right">
|
||
<img src="${escapeHtml(imgSrc)}" alt="${escapeHtml(p.name)}" class="w-12 h-12 rounded-lg object-cover">
|
||
<div class="flex-1 min-w-0">
|
||
<div class="font-bold text-sm line-clamp-1">${escapeHtml(p.name)}</div>
|
||
<div class="text-xs text-cream-500 dark:text-dark-muted">${escapeHtml(p.category || 'محصول')}</div>
|
||
</div>
|
||
<div class="text-sm font-bold text-forest-500 dark:text-forest-300 whitespace-nowrap">${formatPrice(p.price)}</div>
|
||
</a>
|
||
`;
|
||
}).join('');
|
||
} else {
|
||
results.innerHTML = '<p class="text-sm text-cream-500 dark:text-dark-muted text-center py-6">محصولی یافت نشد</p>';
|
||
}
|
||
} catch (err) {
|
||
console.error('handleSearch:', err);
|
||
results.innerHTML = '<p class="text-sm text-cream-500 dark:text-dark-muted text-center py-6">خطا در جستجو. لطفاً دوباره تلاش کنید.</p>';
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// گالری محصول — زوم و تغییر تصویر
|
||
// ============================================
|
||
|
||
function changeImage(src, btn) {
|
||
const mainImg = document.getElementById('main-product-img');
|
||
if (!mainImg) return;
|
||
|
||
mainImg.src = src;
|
||
mainImg.setAttribute('data-large_image', src);
|
||
mainImg.setAttribute('data-src', src);
|
||
|
||
const parentLink = mainImg.closest('a');
|
||
if (parentLink) parentLink.href = src;
|
||
|
||
document.querySelectorAll('.gallery-thumb').forEach(t => t.classList.remove('active'));
|
||
if (btn) btn.classList.add('active');
|
||
|
||
// بازسازی زوم ووکامرس (اگه jQuery لود شده باشه)
|
||
if (typeof jQuery !== 'undefined' && typeof jQuery.fn.zoom !== 'undefined') {
|
||
const $mainImg = jQuery(mainImg);
|
||
const $wrapper = $mainImg.parent();
|
||
$wrapper.trigger('zoom.destroy');
|
||
$wrapper.zoom({ url: src, touch: false });
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// صفحه محصول — انتخاب وزن و تعداد
|
||
// ============================================
|
||
|
||
function selectWeight(btn, price) {
|
||
document.querySelectorAll('.weight-btn').forEach(b => {
|
||
b.classList.remove('active', 'border-forest-500', 'dark:border-forest-300', 'bg-forest-50', 'dark:bg-forest-900/30', 'text-forest-500', 'dark:text-forest-300');
|
||
b.classList.add('border-cream-200', 'dark:border-dark-border');
|
||
});
|
||
btn.classList.add('active', 'border-forest-500', 'dark:border-forest-300', 'bg-forest-50', 'dark:bg-forest-900/30', 'text-forest-500', 'dark:text-forest-300');
|
||
btn.classList.remove('border-cream-200', 'dark:border-dark-border');
|
||
selectedWeightPrice = price;
|
||
const priceEl = document.getElementById('product-price');
|
||
if (priceEl) priceEl.textContent = formatPrice(price);
|
||
}
|
||
|
||
function changeQty(delta) {
|
||
const el = document.getElementById('product-qty');
|
||
if (!el) return;
|
||
let val = parseInt(el.textContent) + delta;
|
||
if (val < 1) val = 1;
|
||
if (val > 10) val = 10;
|
||
el.textContent = val;
|
||
}
|
||
|
||
function switchTab(tabId, btn) {
|
||
document.querySelectorAll('.tab-content').forEach(t => t.classList.add('hidden'));
|
||
document.querySelectorAll('.tab-btn').forEach(b => {
|
||
b.classList.remove('tab-active');
|
||
b.classList.add('text-cream-500', 'dark:text-dark-muted');
|
||
});
|
||
const target = document.getElementById('tab-' + tabId);
|
||
if (target) target.classList.remove('hidden');
|
||
if (btn) {
|
||
btn.classList.add('tab-active');
|
||
btn.classList.remove('text-cream-500', 'dark:text-dark-muted');
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// علاقهمندیها — با persist در localStorage
|
||
// ============================================
|
||
|
||
function toggleWishlist(btn, productId) {
|
||
if (!btn) return;
|
||
const icon = btn.querySelector('iconify-icon');
|
||
if (!icon) return;
|
||
|
||
productId = productId || parseInt(btn.getAttribute('data-product-id')) || 0;
|
||
|
||
const index = wishlist.indexOf(productId);
|
||
if (index === -1) {
|
||
// افزودن به علاقهمندیها
|
||
wishlist.push(productId);
|
||
icon.setAttribute('icon', 'lucide:heart');
|
||
icon.style.color = '#ef4444';
|
||
icon.style.fill = '#ef4444';
|
||
showToast('به علاقهمندیها اضافه شد', 'success');
|
||
} else {
|
||
// حذف از علاقهمندیها
|
||
wishlist.splice(index, 1);
|
||
icon.setAttribute('icon', 'lucide:heart');
|
||
icon.style.color = '';
|
||
icon.style.fill = '';
|
||
showToast('از علاقهمندیها حذف شد', 'info');
|
||
}
|
||
saveToStorage('motayeb_wishlist', wishlist);
|
||
}
|
||
|
||
// ============================================
|
||
// Toast نوتیفیکیشن
|
||
// ============================================
|
||
|
||
function showToast(msg, type) {
|
||
type = type || 'info';
|
||
const container = document.getElementById('toast-container');
|
||
if (!container) return;
|
||
|
||
const colors = {
|
||
success: 'bg-forest-500',
|
||
info: 'bg-earth-400',
|
||
error: 'bg-red-500'
|
||
};
|
||
const icons = {
|
||
success: 'lucide:check-circle',
|
||
info: 'lucide:info',
|
||
error: 'lucide:alert-circle'
|
||
};
|
||
|
||
const toast = document.createElement('div');
|
||
toast.className = 'toast flex items-center gap-3 px-5 py-3 ' + (colors[type] || 'bg-earth-400') + ' text-white rounded-2xl shadow-xl text-sm font-medium';
|
||
toast.innerHTML = '<iconify-icon icon="' + (icons[type] || 'lucide:info') + '" width="20"></iconify-icon><span>' + escapeHtml(msg) + '</span>';
|
||
container.appendChild(toast);
|
||
|
||
setTimeout(() => {
|
||
toast.style.opacity = '0';
|
||
toast.style.transition = 'opacity 0.3s';
|
||
setTimeout(() => toast.remove(), 300);
|
||
}, 3000);
|
||
}
|
||
|
||
// ============================================
|
||
// فرمها
|
||
// ============================================
|
||
|
||
function handleNewsletter(e) {
|
||
e.preventDefault();
|
||
const email = document.getElementById('newsletter-email');
|
||
if (email && email.value) {
|
||
showToast(email.value + ' با موفقیت ثبت شد!', 'success');
|
||
email.value = '';
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function handleContact(e) {
|
||
e.preventDefault();
|
||
showToast('پیام شما با موفقیت ارسال شد. به زودی پاسخ میدهیم.', 'success');
|
||
e.target.reset();
|
||
return false;
|
||
}
|
||
|
||
// ============================================
|
||
// سیستم امتیازدهی ستارهای
|
||
// ============================================
|
||
|
||
let currentRating = 0;
|
||
|
||
/**
|
||
* تعیین امتیاز با کلیک روی ستاره
|
||
*/
|
||
function setRating(rating) {
|
||
currentRating = rating;
|
||
renderStars(rating);
|
||
|
||
// تنظیم فیلد مخفی برای ارسال با فرم
|
||
const hiddenInput = document.getElementById('rating-input');
|
||
if (hiddenInput) hiddenInput.value = rating;
|
||
}
|
||
|
||
/**
|
||
* نمایش ستارهها با امتیاز دادهشده
|
||
* @param {number} rating - امتیاز از ۱ تا ۵
|
||
* @param {string} containerId - شناسه ظرف (پیشفرض: star-rating)
|
||
*/
|
||
function renderStars(rating, containerId) {
|
||
containerId = containerId || 'star-rating';
|
||
const container = document.getElementById(containerId);
|
||
if (!container) return;
|
||
|
||
container.innerHTML = '';
|
||
|
||
for (let i = 1; i <= 5; i++) {
|
||
const star = document.createElement('i');
|
||
if (i <= rating) {
|
||
// ستاره پر — طلایی (کلاسهای Tailwind/FontAwesome)
|
||
star.className = 'fa-solid fa-star text-honey-400 cursor-pointer transition';
|
||
} else {
|
||
// ستاره خالی — خاکستری
|
||
star.className = 'fa-regular fa-star text-cream-300 dark:text-dark-muted cursor-pointer transition';
|
||
}
|
||
star.dataset.rating = i;
|
||
star.setAttribute('role', 'button');
|
||
star.setAttribute('aria-label', 'امتیاز ' + i + ' از ۵');
|
||
star.addEventListener('click', function() {
|
||
setRating(parseInt(this.dataset.rating));
|
||
});
|
||
star.addEventListener('mouseenter', function() {
|
||
renderStars(parseInt(this.dataset.rating), containerId);
|
||
});
|
||
container.appendChild(star);
|
||
}
|
||
|
||
// وقتی موس از ظرف خارج شد، به امتیاز فعلی برگرد
|
||
container.onmouseleave = function() {
|
||
renderStars(currentRating, containerId);
|
||
};
|
||
}
|
||
|
||
// ============================================
|
||
// رویدادهای صفحه کلید
|
||
// ============================================
|
||
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'Escape') {
|
||
closeSearch();
|
||
closeCart();
|
||
closeMobileMenu();
|
||
}
|
||
// Ctrl/Cmd + K برای باز کردن جستجو
|
||
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
||
e.preventDefault();
|
||
openSearch();
|
||
}
|
||
});
|
||
|
||
// ============================================
|
||
// تغییر هدر هنگام اسکرول
|
||
// ============================================
|
||
|
||
window.addEventListener('scroll', function() {
|
||
const header = document.getElementById('header');
|
||
if (!header) return;
|
||
if (window.scrollY > 100) {
|
||
header.classList.add('shadow-lg');
|
||
} else {
|
||
header.classList.remove('shadow-lg');
|
||
}
|
||
}, { passive: true });
|
||
|
||
// ============================================
|
||
// مقداردهی اولیه — همه در یک listener
|
||
// ============================================
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// ۱. بهروزرسانی UI سبد خرید از localStorage
|
||
updateCartUI();
|
||
|
||
// ۲. تنظیم گالری محصول (اگه در صفحه محصول هستیم)
|
||
const mainImg = document.getElementById('main-product-img');
|
||
if (mainImg) {
|
||
const firstThumb = document.querySelector('.gallery-thumb');
|
||
if (firstThumb) firstThumb.classList.add('active');
|
||
}
|
||
|
||
// ۳. رندر ستارههای امتیازدهی (اگه ظرف وجود داشته باشه)
|
||
const starContainer = document.getElementById('star-rating');
|
||
if (starContainer) {
|
||
// خواندن امتیاز فعلی از فیلد مخفی (اگه ویرایش نظر باشه)
|
||
const hiddenInput = document.getElementById('rating-input');
|
||
currentRating = hiddenInput ? parseInt(hiddenInput.value) || 0 : 0;
|
||
renderStars(currentRating);
|
||
}
|
||
|
||
// ۴. علامتگذاری آیکونهای علاقهمندی که قبلاً انتخاب شدهان
|
||
document.querySelectorAll('[data-wishlist-btn]').forEach(btn => {
|
||
const productId = parseInt(btn.getAttribute('data-product-id')) || 0;
|
||
if (wishlist.indexOf(productId) !== -1) {
|
||
const icon = btn.querySelector('iconify-icon');
|
||
if (icon) {
|
||
icon.style.color = '#ef4444';
|
||
icon.style.fill = '#ef4444';
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
// AJAX Add to Cart برای صفحه محصول
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
var form = document.querySelector('form.cart');
|
||
if (!form) return;
|
||
|
||
form.addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
var formData = new FormData(form);
|
||
var productId = formData.get('add-to-cart');
|
||
var quantity = formData.get('quantity') || 1;
|
||
|
||
fetch(MOTAYEB_AJAX.ajax_url, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
body: 'action=woocommerce_add_to_cart&product_id=' + productId + '&quantity=' + quantity
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.fragments) {
|
||
// بهروزرسانی fragment های ووکامرس (مثل شمارنده سبد)
|
||
Object.keys(data.fragments).forEach(function(key) {
|
||
var el = document.querySelector(key);
|
||
if (el) el.innerHTML = data.fragments[key];
|
||
});
|
||
showToast('به سبد خرید اضافه شد', 'success');
|
||
}
|
||
})
|
||
.catch(err => showToast('خطا در افزودن', 'error'));
|
||
});
|
||
}); |