Commit 9940f32a authored by Mahmoud Aglan's avatar Mahmoud Aglan

Rewrite pricing page: 3-tier model + Saudi geo-detection

- Replace 4 old plans with 3 tiers (Small/Medium/Large)
- Egypt: 699+7%, 1499+5%, 3499+3%
- Saudi: 299SAR+5%, 699SAR+3.5%, 1499SAR+2%
- Add IP-based geo-detection (ipapi.co) to auto-show SAR prices
- Add "250K system / support fees only" value framing
- Add academy website + custom domain messaging
- Update calculator with dual-market plans
- Rewrite comparison table and FAQ for new model
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 900c5017
...@@ -3,6 +3,65 @@ ...@@ -3,6 +3,65 @@
* main.js — Vanilla ES6+, no external dependencies * main.js — Vanilla ES6+, no external dependencies
*/ */
/* ═══════════════════════════════════════════════
GEO-DETECTION & PRICING LOCALIZATION
Detects visitor country and swaps pricing to SAR if Saudi Arabia
═══════════════════════════════════════════════ */
let detectedCountry = 'EG'; // default
async function detectCountry() {
try {
const res = await fetch('https://ipapi.co/json/', { signal: AbortSignal.timeout(3000) });
const data = await res.json();
return data.country_code || 'EG'; // 'SA', 'EG', etc.
} catch {
return 'EG'; // default Egypt
}
}
function applyGeoPricing(country) {
detectedCountry = country;
const isSA = country === 'SA';
const currency = isSA ? 'ر.س' : 'ج.م';
// Swap plan card amounts
document.querySelectorAll('.plan-card[data-plan]').forEach(card => {
const flat = isSA ? card.dataset.saFlat : card.dataset.egFlat;
const pct = isSA ? card.dataset.saPct : card.dataset.egPct;
const amountEl = card.querySelector('.plan-card__amount-number');
if (amountEl) amountEl.textContent = Number(flat).toLocaleString('en-US');
const currencyEl = card.querySelector('.plan-card__amount-currency');
if (currencyEl) currencyEl.textContent = currency;
const pctEl = card.querySelector('.plan-card__pct-number');
if (pctEl) pctEl.textContent = pct + '%';
});
// Swap setup fee displays
document.querySelectorAll('[data-eg-setup]').forEach(el => {
el.textContent = isSA ? el.dataset.saSetup : el.dataset.egSetup;
});
document.querySelectorAll('.setup-currency').forEach(el => {
el.textContent = currency;
});
// Swap comparison table values
document.querySelectorAll('[data-eg-compare]').forEach(el => {
el.textContent = isSA ? el.dataset.saCompare : el.dataset.egCompare;
});
document.querySelectorAll('[data-eg-pct-compare]').forEach(el => {
el.textContent = isSA ? el.dataset.saPctCompare : el.dataset.egPctCompare;
});
document.querySelectorAll('.compare-currency').forEach(el => {
el.textContent = currency;
});
// Re-initialize pricing calculator with correct plans
initPricingCalc();
}
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initNav(); initNav();
initMobileMenu(); initMobileMenu();
...@@ -21,6 +80,13 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -21,6 +80,13 @@ document.addEventListener('DOMContentLoaded', () => {
initSocialProof(); initSocialProof();
injectRevealStyles(); injectRevealStyles();
injectDynamicStyles(); injectDynamicStyles();
// Detect country and apply geo-pricing
detectCountry().then(country => {
if (country !== 'EG') {
applyGeoPricing(country);
}
});
}); });
/* ═══════════════════════════════════════════════ /* ═══════════════════════════════════════════════
...@@ -626,41 +692,46 @@ function initBackToTop() { ...@@ -626,41 +692,46 @@ function initBackToTop() {
/* ═══════════════════════════════════════════════ /* ═══════════════════════════════════════════════
12. PRICING CALCULATOR 12. PRICING CALCULATOR
Range slider for monthly collections (10,000–500,000 EGP). Range slider for monthly collections.
Shows calculated cost per plan. Highlights cheapest. Shows calculated cost per plan. Highlights cheapest.
Supports geo-switching (Egypt / Saudi Arabia).
Only activates if #pricing-calculator exists. Only activates if #pricing-calculator exists.
═══════════════════════════════════════════════ */ ═══════════════════════════════════════════════ */
function initPricingCalc() { function initPricingCalc() {
const container = document.getElementById('pricing-calculator'); const container = document.getElementById('pricing-calculator');
if (!container) return; if (!container) return;
// Plan definitions: { name, monthlyFee (EGP), platformPercent } // Egypt plans
const plans = [ const plansEG = [
{ id: 'free', name: 'نسبة فقط', monthlyFee: 0, platformPercent: 12.0 }, { id: 'small', name: 'حتى ١٠٠ لاعب', monthlyFee: 699, platformPercent: 7.0 },
{ id: 'starter', name: 'المبتدئ', monthlyFee: 1000, platformPercent: 7.5 }, { id: 'medium', name: '١٠٠-٣٠٠ لاعب', monthlyFee: 1499, platformPercent: 5.0 },
{ id: 'institutional',name: 'المؤسسي', monthlyFee: 3500, platformPercent: 5.0 }, { id: 'large', name: '٣٠٠+ لاعب', monthlyFee: 3499, platformPercent: 3.0 },
{ id: 'professional', name: 'الاحترافي', monthlyFee: 10000, platformPercent: 3.5 },
]; ];
// Allow overriding plans via data attribute // Saudi Arabia plans
if (container.dataset.plans) { const plansSA = [
try { { id: 'small', name: 'حتى ١٠٠ لاعب', monthlyFee: 299, platformPercent: 5.0 },
const customPlans = JSON.parse(container.dataset.plans); { id: 'medium', name: '١٠٠-٣٠٠ لاعب', monthlyFee: 699, platformPercent: 3.5 },
if (Array.isArray(customPlans) && customPlans.length) { { id: 'large', name: '٣٠٠+ لاعب', monthlyFee: 1499, platformPercent: 2.0 },
plans.length = 0; ];
plans.push(...customPlans);
} const isSA = detectedCountry === 'SA';
} catch (e) { /* use defaults */ } const plans = isSA ? plansSA : plansEG;
} const currencyCode = isSA ? 'SAR' : 'EGP';
const currencyLabel = isSA ? 'ر.س' : 'ج.م';
const minCollections = 10000; const minCollections = 10000;
const maxCollections = 500000; const maxCollections = 500000;
const step = 5000; const step = 5000;
function formatAmount(amount) {
return new Intl.NumberFormat('ar-EG', { style: 'currency', currency: currencyCode, maximumFractionDigits: 0 }).format(amount);
}
container.innerHTML = ` container.innerHTML = `
<div class="pricing-calc"> <div class="pricing-calc">
<label class="pricing-calc__label" for="collectionsSlider"> <label class="pricing-calc__label" for="collectionsSlider">
حجم التحصيلات الشهرية: <strong class="pricing-calc__value" id="calcValue">${formatEGP(minCollections)}</strong> حجم التحصيلات الشهرية: <strong class="pricing-calc__value" id="calcValue">${formatAmount(minCollections)}</strong>
</label> </label>
<input <input
type="range" type="range"
...@@ -673,8 +744,8 @@ function initPricingCalc() { ...@@ -673,8 +744,8 @@ function initPricingCalc() {
dir="ltr" dir="ltr"
/> />
<div class="pricing-calc__range-labels"> <div class="pricing-calc__range-labels">
<span>${formatEGP(minCollections)}</span> <span>${formatAmount(minCollections)}</span>
<span>${formatEGP(maxCollections)}</span> <span>${formatAmount(maxCollections)}</span>
</div> </div>
<div class="pricing-calc__results" id="calcResults"></div> <div class="pricing-calc__results" id="calcResults"></div>
</div> </div>
...@@ -684,10 +755,6 @@ function initPricingCalc() { ...@@ -684,10 +755,6 @@ function initPricingCalc() {
const valueDisplay = container.querySelector('#calcValue'); const valueDisplay = container.querySelector('#calcValue');
const resultsContainer = container.querySelector('#calcResults'); const resultsContainer = container.querySelector('#calcResults');
function formatEGP(amount) {
return new Intl.NumberFormat('ar-EG', { style: 'currency', currency: 'EGP', maximumFractionDigits: 0 }).format(amount);
}
function calculate(collections) { function calculate(collections) {
const results = plans.map(plan => ({ const results = plans.map(plan => ({
...plan, ...plan,
...@@ -701,10 +768,10 @@ function initPricingCalc() { ...@@ -701,10 +768,10 @@ function initPricingCalc() {
<div class="pricing-calc__plan ${r.totalCost === minCost ? 'pricing-calc__plan--cheapest' : ''}"> <div class="pricing-calc__plan ${r.totalCost === minCost ? 'pricing-calc__plan--cheapest' : ''}">
<div class="pricing-calc__plan-name">${r.name}</div> <div class="pricing-calc__plan-name">${r.name}</div>
<div class="pricing-calc__plan-breakdown"> <div class="pricing-calc__plan-breakdown">
<span>اشتراك: ${formatEGP(r.monthlyFee)}</span> <span>اشتراك: ${formatAmount(r.monthlyFee)}</span>
<span>عمولة: ${formatEGP(collections * r.platformPercent / 100)} (${r.platformPercent}%)</span> <span>نسبة تشغيل: ${formatAmount(collections * r.platformPercent / 100)} (${r.platformPercent}%)</span>
</div> </div>
<div class="pricing-calc__plan-total">${formatEGP(r.totalCost)}</div> <div class="pricing-calc__plan-total">${formatAmount(r.totalCost)}</div>
${r.totalCost === minCost ? '<span class="pricing-calc__badge">الأوفر</span>' : ''} ${r.totalCost === minCost ? '<span class="pricing-calc__badge">الأوفر</span>' : ''}
</div> </div>
`).join(''); `).join('');
...@@ -712,7 +779,7 @@ function initPricingCalc() { ...@@ -712,7 +779,7 @@ function initPricingCalc() {
slider.addEventListener('input', () => { slider.addEventListener('input', () => {
const val = parseInt(slider.value); const val = parseInt(slider.value);
valueDisplay.textContent = formatEGP(val); valueDisplay.textContent = formatAmount(val);
calculate(val); calculate(val);
}); });
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment