Files
Hamza-AyedandClaude Opus 5 75b80bd299 refactor(marketing): تفكيك الموقع إلى وحدات + توحيد الباقات الثلاث
- marketing: index.html من 2274 إلى 775 سطراً، والباقي إلى
  styles/ (tokens·base·components·sections·responsive) و
  js/ (app·i18n·calculator·analytics) و i18n/ بخمس لغات
  (ar·en·fr·es·tr) عبر سمة data-i18n.
- docs/05 + docs/33 + لوحة السوبر-أدمن: الباقات صارت ثلاثاً
  (إطلاق · نمو · سيادة) بدل الأربع، وتحديث docs/31 بما يطابقها.
- docs/36: توثيق سيرو إكسبرس للتوصيل.
- تنظيف استيرادات غير مستعملة في apps/rider و apps/driver.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 04:53:19 +03:00

133 lines
5.7 KiB
JavaScript

/* ============ MEASUREMENT (consent-gated) ============ ------------------
⚠️ ضع معرّف البكسل هنا قبل أول دولار إعلاني. ما دام فارغاً لا يُحمَّل شيء.
الأحداث تُسجَّل محلياً دائماً (بلا كوكيز وبلا بيانات شخصية) وتُرسل لميتا
فقط بعد موافقة صريحة — مطلوب لزوّار الاتحاد الأوروبي (الموقع بالفرنسية
والإسبانية). تعريف الأحداث وربطها بأهداف CAC في docs/32 §5. */
const PIXEL_ID = "1360167306316901";
const CAPI_TOKEN = "EAAOFgSTx7pUBSGsw30ZBnx40yTbFJSFW3iZCEf0bHqEai6wZAxDsZCD89VsAtWtvytneZAVECx2EH3s4XM9kIN8dcAC8e9gogk4bzAdAZBuaLPtVZC8ZAe66SCu4ptZCZCAPVLSPD0LBU26Ac0QeX0ILf5dh4uFHKrM8ZCtU2ZCjYlMaM9xULe1ou5GUv8SxyYWLugZDZD";
const CONSENT_KEY = "tripz_consent";
const Track = (() => {
const local = [];
let pixelReady = false;
const standardEvents = new Set(["PageView", "Lead", "Contact", "ViewContent", "Schedule"]);
function sendCAPI(eventName, params = {}){
if (!CAPI_TOKEN || !PIXEL_ID) return;
try {
const payload = {
data: [{
event_name: eventName,
event_time: Math.floor(Date.now() / 1000),
event_source_url: location.href,
action_source: "website",
user_data: {
client_user_agent: navigator.userAgent
},
custom_data: params
}]
};
fetch(`https://graph.facebook.com/v19.0/${PIXEL_ID}/events?access_token=${CAPI_TOKEN}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
}).catch(()=>{});
} catch(e){}
}
function loadPixel(){
if (pixelReady || !PIXEL_ID) return;
pixelReady = true;
/* Meta Pixel base */
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', PIXEL_ID);
fbq('track', 'PageView');
sendCAPI('PageView');
local.forEach(([n,p]) => {
if (standardEvents.has(n)) fbq('track', n, p);
else fbq('trackCustom', n, p);
sendCAPI(n, p);
});
}
function consented(){ return localStorage.getItem(CONSENT_KEY) !== "no"; }
return {
init(){ if (consented()) loadPixel(); },
grant(){ localStorage.setItem(CONSENT_KEY,"yes"); loadPixel(); },
deny(){ localStorage.setItem(CONSENT_KEY,"no"); },
ev(name, params = {}){
const p = Object.assign({ lang: document.documentElement.lang }, params);
local.push([name, p]);
if (pixelReady && window.fbq) {
if (standardEvents.has(name)) fbq('track', name, p);
else fbq('trackCustom', name, p);
}
sendCAPI(name, p);
if (location.protocol === "file:") console.debug("[track]", name, p);
},
seen: new Set()
};
})();
/* شريط الموافقة */
(function(){
const box = document.getElementById("consent");
if (!box) return;
if (!localStorage.getItem(CONSENT_KEY)) setTimeout(()=>box.classList.add("show"), 1600);
document.getElementById("consentYes").onclick = () => { Track.grant(); box.classList.remove("show"); Track.ev("ConsentGranted"); };
document.getElementById("consentNo").onclick = () => { Track.deny(); box.classList.remove("show"); };
Track.init();
})();
/* أحداث القمع — مطابقة لأهداف CAC في docs/32 */
(function(){
// عمق التصفّح: أي قسم وصله الزائر
const secs = document.querySelectorAll("section[id]");
if ("IntersectionObserver" in window){
const io = new IntersectionObserver(es => es.forEach(e => {
if (e.isIntersecting && !Track.seen.has(e.target.id)){
Track.seen.add(e.target.id);
Track.ev("SectionView", { section: e.target.id });
}
}), { threshold: .35 });
secs.forEach(s => io.observe(s));
}
// نية شراء: نقر على باقة / وحدة / مواصلات
document.querySelectorAll("#pricing .plan").forEach(p => p.addEventListener("click", () => {
Track.ev("PlanInterest", { plan: p.querySelector("h3")?.getAttribute("data-i18n") || "?" });
}));
document.querySelectorAll("#addons .addon-card").forEach(c => c.addEventListener("click", () => {
Track.ev("ModuleInterest", { module: c.querySelector("h3")?.getAttribute("data-i18n") || "?" });
}));
// استعمال الحاسبة = أقوى إشارة نية قبل التواصل
let calcTimer;
["trips","fare","cur","plan"].forEach(id => {
const el = document.getElementById(id);
el && el.addEventListener("change", () => {
clearTimeout(calcTimer);
calcTimer = setTimeout(() => Track.ev("CalculatorUsed", {
plan: document.getElementById("plan")?.value,
currency: document.getElementById("cur")?.value?.split(":")[0]
}), 800);
});
});
// التحويل: كل مسارات الاتصال
document.querySelectorAll('a[href*="wa.me"]').forEach(a => a.addEventListener("click", () => {
Track.ev("Lead", { channel: "whatsapp", where: a.closest("section")?.id || "float" });
}));
document.querySelectorAll('a[href*="calendly"]').forEach(a => a.addEventListener("click", () => {
Track.ev("Lead", { channel: "calendly", where: a.closest("section")?.id || "?" });
}));
document.querySelectorAll('a[href*="apps.apple.com"],a[href*="play.google.com"]').forEach(a => a.addEventListener("click", () => {
Track.ev("DemoAppOpened");
}));
})();