/* ======================================================== غمبولة بيوتي — App Logic ⚠️ منطق الأعمال (الكتالوج / الأسعار / صيغة نص الأوردر / الأرقام الثابتة / طريقة الحفظ في localStorage) منقول زي ما هو من النسخة السابقة بدون أي تغيير. ممنوع تتغير القيم دي إلا لو طُلب صراحة. ======================================================== */ // ========================================================= // 1) الكتالوج (زي ما هو بالظبط — الأسماء والأحجام والأسعار) // ========================================================= // ⚠️ سعر البخاخ هنا 365 ج (زي الكتالوج الرسمي). لو الرقم الصح فعليًا 356، // غيّري الرقم في السطر اللي فيه "بخاخ علاج التساقط" تحت. const CATALOG = [ { cat: "روتين العناية بالشعر", items: [ { name: "بخاخ علاج التساقط", sizes: [["125 مل", 365]] }, { name: "تركيبة روبانزل", sizes: [["125 مل", 225]] }, { name: "شامبو", sizes: [["125 مل", 110], ["200 مل", 190]] }, { name: "بلسم", sizes: [["125 مل", 110], ["200 مل", 190]] }, { name: "حمام كريم", sizes: [["200 مل", 175], ["350 مل", 275]] }, { name: "سيرم", sizes: [["125 مل", 275]] }, { name: "كريم تسريح", sizes: [["125 مل", 165], ["250 مل", 265]] }, { name: "الروتين الكامل (باقة)", sizes: [["كل المنتجات", 1425]] }, ]}, { cat: "زيوت ومكملات فردية", items: [ { name: "خلطة مساج", sizes: [["-", 265]] }, { name: "جوز هند", sizes: [["125 مل", 205]] }, { name: "نبتة شيا", sizes: [["50 مل", 140]] }, { name: "أرجان بجوجوبا", sizes: [["-", 265]] }, { name: "جوجوبا", sizes: [["125 مل", 185]] }, { name: "هير سول (ماء ورد)", sizes: [["200 مل", 100]] }, ]}, { cat: "العناية بالبشرة والجسم", items: [ { name: "كريم تفتيح الجسم", sizes: [["300 مل", 350]] }, { name: "الشمعة المنورة", sizes: [["-", 285]] }, ]}, { cat: "الرموش والحواجب", items: [ { name: "ماسكرا الرموش والحواجب", sizes: [["10 مل", 265]] }, ]}, { cat: "شامبو القشرة", items: [ { name: "شامبو القشرة", sizes: [["-", 275]] }, ]}, ]; let customRows = []; let customIdCounter = 0; let orderLog = []; // ========================================================= // 2) Navigation (Bottom Nav + Screens) // ========================================================= const SCREEN_TITLES = { home: 'إدارة الأوردرات', products: 'اختيار المنتجات', order: 'مراجعة الأوردر', customer: 'بيانات العميل', preview: 'إرسال الأوردر', earnings: 'الأرباح', }; function showScreen(name){ document.querySelectorAll('.screen').forEach(s => s.classList.toggle('active', s.dataset.screen === name)); document.querySelectorAll('.nav-btn[data-screen-btn]').forEach(b => { b.classList.toggle('active', b.dataset.screenBtn === name); }); document.getElementById('headerSubtitle').textContent = SCREEN_TITLES[name] || ''; document.getElementById('app').scrollTop = 0; window.scrollTo(0,0); updateStickyBar(); if(name === 'earnings') renderCounter(); // ملحوظة: render() بيتنادى من كل الـ inputs عند أي تغيير، وبيحدّث // الداشبورد ونص المعاينة أوتوماتيك، فمش محتاجين ننادي حاجة تانية هنا // (تجنّبًا لأي استدعاء متبادل بين الدوال). render(); } function initNav(){ document.querySelectorAll('[data-screen-btn]').forEach(btn => { btn.addEventListener('click', () => showScreen(btn.dataset.screenBtn)); }); document.querySelectorAll('[data-goto]').forEach(btn => { btn.addEventListener('click', () => showScreen(btn.dataset.goto)); }); } // ========================================================= // 3) بناء قايمة المنتجات (Accordion + Cards) // ========================================================= function buildCategories(){ const container = document.getElementById('categoriesContainer'); container.innerHTML = ''; CATALOG.forEach((catObj, ci) => { const catDiv = document.createElement('div'); catDiv.className = 'cat' + (ci === 0 ? ' open' : ''); catDiv.innerHTML = `
${catObj.cat} ${catObj.items.length} ▾
`; container.appendChild(catDiv); const body = catDiv.querySelector(`#catBody${ci}`); catObj.items.forEach((item, ii) => { const row = document.createElement('div'); row.className = 'prod-card'; row.id = `prodCard_${ci}_${ii}`; const sizeOptions = item.sizes.map((s, si) => ``).join(''); row.innerHTML = `
${item.name}✔
0 ج
0
`; body.appendChild(row); }); }); container.querySelectorAll('[data-toggle-cat]').forEach(header => { header.addEventListener('click', () => { header.closest('.cat').classList.toggle('open'); }); }); container.querySelectorAll('[data-render-on-change]').forEach(sel => { sel.addEventListener('change', render); }); container.querySelectorAll('[data-qty-step]').forEach(btn => { btn.addEventListener('click', () => { const targetId = btn.dataset.qtyTarget; const el = document.getElementById(targetId); const step = Number(btn.dataset.qtyStep); let current = Number(el.textContent) || 0; current = Math.max(0, current + step); el.textContent = current; render(); }); }); } function getQty(ci, ii){ const el = document.getElementById(`qty_${ci}_${ii}`); return el ? (Number(el.textContent) || 0) : 0; } // ========================================================= // 4) منتج مخصص // ========================================================= function addCustomRow(){ const id = customIdCounter++; customRows.push({ id, name: '', size: '', price: 0, qty: 0 }); renderCustomRows(); } function removeCustomRow(id){ customRows = customRows.filter(r => r.id !== id); renderCustomRows(); render(); } function renderCustomRows(){ const el = document.getElementById('customList'); if(customRows.length === 0){ el.innerHTML = '
مفيش منتجات مخصصة مضافة
'; return; } el.innerHTML = customRows.map(r => `
${r.qty}
`).join(''); el.querySelectorAll('[data-rm-custom]').forEach(b => { b.addEventListener('click', () => removeCustomRow(Number(b.dataset.rmCustom))); }); el.querySelectorAll('[data-custom-field]').forEach(inp => { inp.addEventListener('input', () => { const id = Number(inp.dataset.customId); const field = inp.dataset.customField; updateCustom(id, field, inp.value); }); }); el.querySelectorAll('[data-custom-qty-step]').forEach(b => { b.addEventListener('click', () => { const id = Number(b.dataset.customQtyId); const row = customRows.find(r => r.id === id); if(!row) return; row.qty = Math.max(0, (row.qty || 0) + Number(b.dataset.customQtyStep)); const span = el.querySelector(`[data-custom-qty-value="${id}"]`); if(span) span.textContent = row.qty; render(); }); }); } function updateCustom(id, field, value){ const row = customRows.find(r => r.id === id); if(!row) return; row[field] = (field === 'price') ? Number(value) : value; render(); } // ========================================================= // 5) localStorage — نفس المفاتيح القديمة بالظبط // ========================================================= function saveManagerPhone(){ try { localStorage.setItem('gamboola_manager_phone', document.getElementById('managerPhone').value); } catch(e){} } function loadManagerPhone(){ try { const v = localStorage.getItem('gamboola_manager_phone'); if(v) document.getElementById('managerPhone').value = v; } catch(e){} } function saveAgentName(){ try { localStorage.setItem('gamboola_agent_name', document.getElementById('agentName').value); } catch(e){} } function loadAgentName(){ try { const v = localStorage.getItem('gamboola_agent_name'); if(v) document.getElementById('agentName').value = v; } catch(e){} } function saveRate(){ try { localStorage.setItem('gamboola_rate', document.getElementById('rate').value); } catch(e){} } function loadRate(){ try { const v = localStorage.getItem('gamboola_rate'); if(v) document.getElementById('rate').value = v; } catch(e){} } function saveNotifyPhone(){ try { localStorage.setItem('gamboola_notify_phone', document.getElementById('notifyPhone').value); } catch(e){} } function loadNotifyPhone(){ try { const v = localStorage.getItem('gamboola_notify_phone'); if(v) document.getElementById('notifyPhone').value = v; } catch(e){} } function loadOrderLog(){ try { const v = localStorage.getItem('gamboola_order_log'); orderLog = v ? JSON.parse(v) : []; } catch(e){ orderLog = []; } } function saveOrderLog(){ try { localStorage.setItem('gamboola_order_log', JSON.stringify(orderLog)); } catch(e){} } function todayStr(){ const d = new Date(); return `${d.getDate()}/${d.getMonth()+1}/${d.getFullYear()}`; } // ========================================================= // 6) الحساب الرئيسي + بناء نص الأوردر (منطق الأعمال الأصلي) // ========================================================= function collectItems(){ let items = []; let productsTotal = 0; CATALOG.forEach((catObj, ci) => { catObj.items.forEach((item, ii) => { const sizeSel = document.getElementById(`size_${ci}_${ii}`); const qty = getQty(ci, ii); const sizeIdx = Number(sizeSel.value); const [sizeLabel, price] = item.sizes[sizeIdx]; const lineTotal = qty * price; const ltEl = document.getElementById(`lt_${ci}_${ii}`); if(ltEl) ltEl.textContent = lineTotal + ' ج'; const card = document.getElementById(`prodCard_${ci}_${ii}`); if(card) card.classList.toggle('selected', qty > 0); if(qty > 0){ items.push({ name: item.name, size: sizeLabel, qty, price, lineTotal }); productsTotal += lineTotal; } }); }); customRows.forEach(r => { const lineTotal = (r.qty || 0) * (r.price || 0); if(r.qty > 0 && r.name){ items.push({ name: r.name, size: r.size || '', qty: r.qty, price: r.price, lineTotal }); productsTotal += lineTotal; } }); return { items, productsTotal }; } function render(){ const { items, productsTotal } = collectItems(); const shipping = Number(document.getElementById('shipping').value) || 0; const grandTotal = productsTotal + shipping; document.getElementById('productsTotal').textContent = productsTotal + ' ج'; document.getElementById('grandTotal').textContent = grandTotal + ' ج'; // ملخص شاشة "الأوردر" const summaryEl = document.getElementById('orderSummaryList'); if(items.length === 0){ summaryEl.innerHTML = '
🛒مفيش منتجات متضافة للطلب لسه
'; } else { summaryEl.innerHTML = items.map(it => `
${it.name}
${it.size ? it.size + ' • ' : ''}الكمية ${it.qty}
${it.lineTotal} ج
`).join(''); } const totalQty = items.reduce((s,it)=>s+it.qty,0); updateStickyBar(totalQty, grandTotal); updateNavBadge(totalQty); // بنحدّث الداشبورد ونص الأوردر النهائي دايمًا (حسابات رخيصة)، // من غير أي استدعاء متبادل بين الدوال عشان نتجنب أي تكرار لا نهائي. renderHome(items, productsTotal); buildOutputText(items, shipping, grandTotal); return { items, productsTotal, shipping, grandTotal }; } // ⚠️ صيغة نص الأوردر — الأرقام الثابتة (1500 / 000000) والفواصل والترتيب // منقولين حرفيًا زي ما اتأكد عليهم. ممنوع تتغير إلا بطلب صريح. function buildOutputText(items, shipping, grandTotal){ let productsLine = ''; if(items.length === 0){ productsLine = '(لسه مفيش منتجات مختارة)'; } else { const parts = items.map(it => { const qtyPart = it.qty > 1 ? `×${it.qty}` : ''; const sizePart = it.size ? ` ${it.size}` : ''; return `${it.name}${sizePart}${qtyPart} ${it.lineTotal}`; }); parts.push(`شحن ${shipping}`); productsLine = parts.join('+'); } const name = document.getElementById('custName').value || ''; const phone1 = document.getElementById('phone1').value || ''; const phone2 = document.getElementById('phone2').value || ''; const address = document.getElementById('address').value || ''; const agentName = document.getElementById('agentName').value || ''; const date = document.getElementById('orderDate').value || todayStr(); const text = `الاوردر /${productsLine} 1500 000000 ${grandTotal} 000000 ${name} ${phone1} ${phone2} العنوان بالتفصيل / ${address} ${agentName} ${date}`; document.getElementById('outputText').value = text; } // ========================================================= // 7) نسخ + واتساب (نفس المنطق الأصلي، مع fallback للموبايل) // ========================================================= function copyText(){ const ta = document.getElementById('outputText'); const btn = document.getElementById('copyBtn'); const orig = btn.innerHTML; const done = () => { btn.innerHTML = 'تم النسخ ✓'; btn.style.background = 'linear-gradient(135deg, #4CAF7D, #3d9469)'; showToast('تم نسخ النص ✓'); setTimeout(() => { btn.innerHTML = orig; btn.style.background = ''; }, 1500); }; if(navigator.clipboard && navigator.clipboard.writeText){ navigator.clipboard.writeText(ta.value).then(done).catch(() => fallbackCopy(ta, done)); } else { fallbackCopy(ta, done); } } function fallbackCopy(ta, done){ ta.removeAttribute('readonly'); ta.focus(); ta.select(); try { document.execCommand('copy'); done(); } catch(e){ showToast('انسخي النص يدويًا بالضغط المطول عليه'); } ta.setAttribute('readonly', true); } function sendWhatsapp(){ const text = encodeURIComponent(document.getElementById('outputText').value); const phone = document.getElementById('managerPhone').value.replace(/[^0-9]/g, ''); const url = phone ? `https://wa.me/${phone}?text=${text}` : `https://wa.me/?text=${text}`; window.open(url, '_blank'); } // ========================================================= // 8) عداد الأوردرات والأرباح (نفس المنطق الأصلي) // ========================================================= function registerOrder(){ const name = document.getElementById('custName').value || '(بدون اسم)'; const grand = document.getElementById('grandTotal').textContent; const date = document.getElementById('orderDate').value || todayStr(); orderLog.push({ name, grand, date, ts: Date.now() }); saveOrderLog(); renderCounter(); renderHome(); showToast('تم تسجيل الأوردر ✅'); } function undoLastOrder(){ if(orderLog.length === 0) return; if(!confirm('متأكدة تمسحي آخر أوردر مسجل؟')) return; orderLog.pop(); saveOrderLog(); renderCounter(); renderHome(); } function clearLog(){ if(!confirm('متأكدة تمسحي كل السجل والعدّاد يرجع صفر؟')) return; orderLog = []; saveOrderLog(); renderCounter(); renderHome(); } function renderCounter(){ const rate = Number(document.getElementById('rate').value) || 0; const count = orderLog.length; const earned = count * rate; document.getElementById('earnCount').textContent = count; document.getElementById('earnRateDisplay').textContent = rate + ' ج'; document.getElementById('earnTotal').textContent = earned + ' ج'; const logEl = document.getElementById('orderLog'); if(count === 0){ logEl.innerHTML = '
🗒️مفيش أوردرات مسجلة لسه
'; } else { const last15 = orderLog.slice(-15).reverse(); logEl.innerHTML = last15.map((o, i) => `
${o.grand}
#${count - i} — ${o.name}
${o.date}
`).join(''); } } function notifyWhatsapp(){ const rate = Number(document.getElementById('rate').value) || 0; const count = orderLog.length; const earned = count * rate; const msg = `تحديث أوردرات غمبولة 📊\nعدد الأوردرات: ${count}\nالمستحق: ${earned} جنيه`; const text = encodeURIComponent(msg); const phone = document.getElementById('notifyPhone').value.replace(/[^0-9]/g, ''); const url = phone ? `https://wa.me/${phone}?text=${text}` : `https://wa.me/?text=${text}`; window.open(url, '_blank'); } // ========================================================= // 9) واجهة إضافية: Home dashboard / Sticky bar / Badge / Toast // ========================================================= // items/productsTotal اختياريين — لو معدّياش، بتتحسب من تاني (بدون ما تنادي render()). function renderHome(items, productsTotal){ if(items === undefined){ const collected = collectItems(); items = collected.items; productsTotal = collected.productsTotal; } const rate = Number(document.getElementById('rate').value) || 0; document.getElementById('homeOrderCount').textContent = orderLog.length; document.getElementById('homeEarned').textContent = (orderLog.length * rate) + ' ج'; const shipping = Number(document.getElementById('shipping').value) || 0; document.getElementById('homeCartItems').textContent = items.reduce((s,it)=>s+it.qty,0); document.getElementById('homeCartTotal').textContent = (items.length ? productsTotal + shipping : 0) + ' ج'; } // totalQty/grandTotal اختياريين — لو معدّياش، بيتحسبوا من تاني. function updateStickyBar(totalQty, grandTotal){ const bar = document.getElementById('stickyOrderBar'); const productsScreenActive = document.querySelector('.screen[data-screen="products"]').classList.contains('active'); if(!productsScreenActive){ bar.classList.remove('show'); return; } if(totalQty === undefined){ const collected = collectItems(); totalQty = collected.items.reduce((s,it)=>s+it.qty,0); const shipping = Number(document.getElementById('shipping').value) || 0; grandTotal = collected.productsTotal + shipping; } if(!totalQty){ bar.classList.remove('show'); return; } document.getElementById('stickyText').textContent = `${totalQty} منتجات — ${grandTotal} ج`; bar.classList.add('show'); } function updateNavBadge(count){ const badge = document.getElementById('productsBadge'); if(count > 0){ badge.textContent = count; badge.classList.remove('hidden'); } else { badge.classList.add('hidden'); } } let toastTimer = null; function showToast(msg){ const toast = document.getElementById('toast'); toast.textContent = msg; toast.classList.add('show'); clearTimeout(toastTimer); toastTimer = setTimeout(() => toast.classList.remove('show'), 1800); } function resetCurrentOrder(){ CATALOG.forEach((catObj, ci) => { catObj.items.forEach((item, ii) => { const qtyEl = document.getElementById(`qty_${ci}_${ii}`); if(qtyEl) qtyEl.textContent = '0'; const sizeEl = document.getElementById(`size_${ci}_${ii}`); if(sizeEl) sizeEl.value = '0'; }); }); customRows = []; renderCustomRows(); document.getElementById('custName').value = ''; document.getElementById('phone1').value = ''; document.getElementById('phone2').value = ''; document.getElementById('address').value = ''; document.getElementById('orderDate').value = todayStr(); render(); renderHome(); } // ========================================================= // 10) PWA: تسجيل Service Worker + زرار التثبيت // ========================================================= function registerServiceWorker(){ if('serviceWorker' in navigator){ window.addEventListener('load', () => { navigator.serviceWorker.register('sw.js').catch(() => {}); }); } } let deferredInstallPrompt = null; function initInstallPrompt(){ const installBtn = document.getElementById('installBtn'); window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredInstallPrompt = e; installBtn.classList.add('show'); }); installBtn.addEventListener('click', async () => { if(!deferredInstallPrompt) return; deferredInstallPrompt.prompt(); await deferredInstallPrompt.userChoice; deferredInstallPrompt = null; installBtn.classList.remove('show'); }); window.addEventListener('appinstalled', () => { installBtn.classList.remove('show'); showToast('تم تثبيت التطبيق 🎉'); }); // iOS Safari: مفيش beforeinstallprompt، فبنعرض تلميح بسيط بدل ما نضايق المستخدم const isIos = /iphone|ipad|ipod/i.test(navigator.userAgent); const isStandalone = window.navigator.standalone === true || window.matchMedia('(display-mode: standalone)').matches; const dismissed = localStorage.getItem('gamboola_ios_hint_dismissed') === '1'; if(isIos && !isStandalone && !dismissed){ document.getElementById('iosHint').classList.remove('hidden'); } document.getElementById('closeIosHint').addEventListener('click', () => { document.getElementById('iosHint').classList.add('hidden'); try { localStorage.setItem('gamboola_ios_hint_dismissed', '1'); } catch(e){} }); } // ========================================================= // 11) ربط الأحداث العامة + التشغيل الأول // ========================================================= function initFieldListeners(){ ['shipping'].forEach(id => document.getElementById(id).addEventListener('input', render)); ['custName','phone1','phone2','address'].forEach(id => document.getElementById(id).addEventListener('input', render)); document.getElementById('agentName').addEventListener('input', () => { saveAgentName(); render(); }); document.getElementById('orderDate').addEventListener('input', render); document.getElementById('managerPhone').addEventListener('input', saveManagerPhone); document.getElementById('rate').addEventListener('input', () => { saveRate(); renderCounter(); renderHome(); }); document.getElementById('notifyPhone').addEventListener('input', saveNotifyPhone); document.getElementById('addCustomBtn').addEventListener('click', addCustomRow); document.getElementById('copyBtn').addEventListener('click', copyText); document.getElementById('sendWaBtn').addEventListener('click', sendWhatsapp); document.getElementById('registerOrderBtn').addEventListener('click', registerOrder); document.getElementById('undoOrderBtn').addEventListener('click', undoLastOrder); document.getElementById('clearLogBtn').addEventListener('click', clearLog); document.getElementById('notifyWaBtn').addEventListener('click', notifyWhatsapp); document.getElementById('startNewOrderBtn').addEventListener('click', () => { resetCurrentOrder(); showScreen('products'); }); document.getElementById('goToCustomerBtn').addEventListener('click', () => showScreen('customer')); document.getElementById('goToPreviewBtn').addEventListener('click', () => showScreen('preview')); } function init(){ document.getElementById('orderDate').value = todayStr(); buildCategories(); renderCustomRows(); loadManagerPhone(); loadAgentName(); loadRate(); loadNotifyPhone(); loadOrderLog(); initFieldListeners(); initNav(); registerServiceWorker(); initInstallPrompt(); render(); renderCounter(); renderHome(); showScreen('home'); } document.addEventListener('DOMContentLoaded', init);