This commit is contained in:
Oliver committed 2025-10-09 08:14:28 -03:00
1 parent 53d61fbaa6
commit bd26988584
5 files changed
+59 -22

No files matched your search

+20 -21
View File
@@ -4,25 +4,32 @@ const CATEGORY_CONFIG = {
4: { showLocation: true, webhook: "https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/c76e6b4e-af2f-4bc3-9875-6460d0ffc8e3" }, // hosting 4: { showLocation: true, webhook: "https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/c76e6b4e-af2f-4bc3-9875-6460d0ffc8e3" }, // hosting
5: { showLocation: false, webhook: "https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/fd20e194-b821-4b1f-814f-7bb93ae16046" }, // Workshops 5: { showLocation: false, webhook: "https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/fd20e194-b821-4b1f-814f-7bb93ae16046" }, // Workshops
7: { showLocation: false, webhook: "" }, // modules 7: { showLocation: false, webhook: "" }, // modules
// Add more categories as needed
}; };
// --- Helper: Get cookie by name ---
// --- Get URL parameters as an object --- function getCookie(name) {
function getUrlParams() { const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return Object.fromEntries(new URLSearchParams(window.location.search).entries()); return match ? decodeURIComponent(match[2]) : null;
} }
// --- Add UTM fields to form with defaults --- // --- Helper: Set cookie if not already set ---
function setCookieIfEmpty(name, value, days = 90) {
if (!value) return;
if (getCookie(name)) return; // Don't overwrite
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${date.toUTCString()}; path=/; SameSite=Lax`;
}
// --- Add UTM fields to form using cookies ---
function addUtmFields(form) { function addUtmFields(form) {
const utmParams = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]; const utmParams = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
const urlParams = getUrlParams();
// Define default values
const defaults = { const defaults = {
utm_source: "homepage", utm_source: "homepage",
utm_medium: "direct", utm_medium: "direct",
utm_campaign: "none" utm_campaign: "none",
utm_term: "",
utm_content: ""
}; };
utmParams.forEach(param => { utmParams.forEach(param => {
@@ -33,8 +40,8 @@ function addUtmFields(form) {
input.name = param; input.name = param;
form.appendChild(input); form.appendChild(input);
} }
// Use URL param if exists, otherwise fallback to default, else empty string // First check cookie, then fallback to default
input.value = urlParams[param] || defaults[param] || ""; input.value = getCookie(param) || defaults[param];
}); });
} }
@@ -111,14 +118,12 @@ function openModal(productHref) {
form.style.display = "flex"; form.style.display = "flex";
confirmation.style.display = "none"; confirmation.style.display = "none";
// Parse URL /<id>/<price>/<category>/<product>
const parts = productHref.split("/").filter(Boolean); const parts = productHref.split("/").filter(Boolean);
const [id, price, category, ...productParts] = parts; const [id, price, category, ...productParts] = parts;
const product = decodeURIComponent(productParts.join("/")); const product = decodeURIComponent(productParts.join("/"));
const categoryNum = parseInt(category, 10); const categoryNum = parseInt(category, 10);
const config = CATEGORY_CONFIG[categoryNum] || { showLocation: false, webhook: "" }; const config = CATEGORY_CONFIG[categoryNum] || { showLocation: false, webhook: "" };
// Handle location field visibility
const locationSelect = document.getElementById("locationSelect"); const locationSelect = document.getElementById("locationSelect");
if (config.showLocation) { if (config.showLocation) {
locationSelect.style.display = "block"; locationSelect.style.display = "block";
@@ -129,20 +134,14 @@ function openModal(productHref) {
locationSelect.value = ""; locationSelect.value = "";
} }
// Update form fields
form.querySelector('input[name="id"]').value = id || ""; form.querySelector('input[name="id"]').value = id || "";
form.querySelector('input[name="price"]').value = price || "0"; form.querySelector('input[name="price"]').value = price || "0";
form.querySelector('input[name="category"]').value = category || ""; form.querySelector('input[name="category"]').value = category || "";
form.querySelector('input[name="product"]').value = product || "Unknown"; form.querySelector('input[name="product"]').value = product || "Unknown";
// Store webhook dynamically for submission
form.dataset.webhook = config.webhook || ""; form.dataset.webhook = config.webhook || "";
// Update display text
modal.querySelector("#productText").textContent = `You will buy ${product} for $${price}.`; modal.querySelector("#productText").textContent = `You will buy ${product} for $${price}.`;
// Add UTM fields addUtmFields(form); // Read from cookie or defaults
addUtmFields(form);
} }
// --- Handle Form Submit --- // --- Handle Form Submit ---
+1 -1
View File
@@ -1 +1 @@
const CATEGORY_CONFIG={3:{showLocation:!1,webhook:""},4:{showLocation:!0,webhook:"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/c76e6b4e-af2f-4bc3-9875-6460d0ffc8e3"},5:{showLocation:!1,webhook:"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/fd20e194-b821-4b1f-814f-7bb93ae16046"},7:{showLocation:!1,webhook:""}};function getUrlParams(){return Object.fromEntries(new URLSearchParams(window.location.search).entries())}function addUtmFields(e){const t=getUrlParams(),o={utm_source:"homepage",utm_medium:"direct",utm_campaign:"none"};["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(n=>{let r=e.querySelector(`input[name="${n}"]`);r||(r=document.createElement("input"),r.type="hidden",r.name=n,e.appendChild(r)),r.value=t[n]||o[n]||""})}function createModal(){const e=document.createElement("div");return e.id="buyNowModal",Object.assign(e.style,{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",backgroundColor:"rgba(0,0,0,0.6)",display:"none",justifyContent:"center",alignItems:"center",zIndex:"1000"}),e.innerHTML='\n <div style="background: #fff; padding: 40px 30px; border-radius: 16px; max-width: 500px; width: 90%; position: relative; font-family: \'Arial\', sans-serif; box-shadow: 0 10px 25px rgba(0,0,0,0.2);">\n <span id="closeModal" style="position: absolute; top: 15px; right: 20px; cursor: pointer; font-weight: bold; font-size: 24px; color: #555;">&times;</span>\n <h2 style="margin-bottom: 15px; font-size: 24px; color: #333;">Order Details</h2>\n <p id="productText" style="margin-bottom: 25px; font-weight: 500; color: #555;"></p>\n\n <form id="buyForm" style="display: flex; flex-direction: column; gap: 15px;">\n <select name="location" id="locationSelect" required style="display: none; padding: 12px 15px; font-size: 16px; border: 1px solid #ccc; border-radius: 8px; outline: none;">\n <option value="">Select Location</option>\n <option value="Boston">Boston</option>\n <option value="Manchester">Manchester</option>\n </select>\n\n <input type="text" name="name" placeholder="Name" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="company" placeholder="Company" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="country" placeholder="Country" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="street" placeholder="Street" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <div style="display: flex; gap: 10px;">\n <input type="text" name="zip" placeholder="ZIP" required style="max-width: 100px; flex: 1 1 0; padding: 12px 10px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="town" placeholder="Town" required style="flex: 2 1 0; padding: 12px 10px; border: 1px solid #ccc; border-radius: 8px;">\n </div>\n <input type="email" name="email" placeholder="Email" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="hidden" name="product">\n <input type="hidden" name="price">\n <input type="hidden" name="id">\n <input type="hidden" name="category">\n\n <button id="submitBuy" type="submit" style="padding: 14px; background: #007BFF; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-size: 18px; font-weight: bold;">Send Order</button>\n </form>\n\n <div id="confirmation" style="display: none; margin-top: 20px; padding: 20px; background-color: #e6ffed; color: #056608; border-radius: 12px; text-align: center; font-weight: 500;">\n <p>Thank you for your purchase! 🎉</p>\n <button id="closeConfirmation" style="margin-top: 10px; padding: 10px 20px; background: #007BFF; color: #fff; border: none; border-radius: 8px; cursor: pointer;">Close</button>\n </div>\n </div>\n ',document.body.appendChild(e),document.getElementById("closeModal").onclick=()=>e.style.display="none",document.getElementById("closeConfirmation").onclick=()=>{document.getElementById("confirmation").style.display="none",e.style.display="none"},e.onclick=t=>{t.target===e&&(e.style.display="none")},e}function openModal(e){const t=document.getElementById("buyNowModal"),o=t.querySelector("#buyForm"),n=t.querySelector("#confirmation");t.style.display="flex",o.style.display="flex",n.style.display="none";const r=e.split("/").filter(Boolean),[d,i,a,...p]=r,l=decodeURIComponent(p.join("/")),c=parseInt(a,10),s=CATEGORY_CONFIG[c]||{showLocation:!1,webhook:""},u=document.getElementById("locationSelect");s.showLocation?(u.style.display="block",u.setAttribute("required","true")):(u.style.display="none",u.removeAttribute("required"),u.value=""),o.querySelector('input[name="id"]').value=d||"",o.querySLine truncated const CATEGORY_CONFIG={3:{showLocation:!1,webhook:""},4:{showLocation:!0,webhook:"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/c76e6b4e-af2f-4bc3-9875-6460d0ffc8e3"},5:{showLocation:!1,webhook:"https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/fd20e194-b821-4b1f-814f-7bb93ae16046"},7:{showLocation:!1,webhook:""}};function getCookie(e){const t=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return t?decodeURIComponent(t[2]):null}function setCookieIfEmpty(e,t,o=90){if(!t)return;if(getCookie(e))return;const n=new Date;n.setTime(n.getTime()+24*o*60*60*1e3),document.cookie=`${e}=${encodeURIComponent(t)}; expires=${n.toUTCString()}; path=/; SameSite=Lax`}function addUtmFields(e){const t={utm_source:"homepage",utm_medium:"direct",utm_campaign:"none",utm_term:"",utm_content:""};["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(o=>{let n=e.querySelector(`input[name="${o}"]`);n||(n=document.createElement("input"),n.type="hidden",n.name=o,e.appendChild(n)),n.value=getCookie(o)||t[o]})}function createModal(){const e=document.createElement("div");return e.id="buyNowModal",Object.assign(e.style,{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",backgroundColor:"rgba(0,0,0,0.6)",display:"none",justifyContent:"center",alignItems:"center",zIndex:"1000"}),e.innerHTML='\n <div style="background: #fff; padding: 40px 30px; border-radius: 16px; max-width: 500px; width: 90%; position: relative; font-family: \'Arial\', sans-serif; box-shadow: 0 10px 25px rgba(0,0,0,0.2);">\n <span id="closeModal" style="position: absolute; top: 15px; right: 20px; cursor: pointer; font-weight: bold; font-size: 24px; color: #555;">&times;</span>\n <h2 style="margin-bottom: 15px; font-size: 24px; color: #333;">Order Details</h2>\n <p id="productText" style="margin-bottom: 25px; font-weight: 500; color: #555;"></p>\n\n <form id="buyForm" style="display: flex; flex-direction: column; gap: 15px;">\n <select name="location" id="locationSelect" required style="display: none; padding: 12px 15px; font-size: 16px; border: 1px solid #ccc; border-radius: 8px; outline: none;">\n <option value="">Select Location</option>\n <option value="Boston">Boston</option>\n <option value="Manchester">Manchester</option>\n </select>\n\n <input type="text" name="name" placeholder="Name" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="company" placeholder="Company" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="country" placeholder="Country" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="street" placeholder="Street" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <div style="display: flex; gap: 10px;">\n <input type="text" name="zip" placeholder="ZIP" required style="max-width: 100px; flex: 1 1 0; padding: 12px 10px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="text" name="town" placeholder="Town" required style="flex: 2 1 0; padding: 12px 10px; border: 1px solid #ccc; border-radius: 8px;">\n </div>\n <input type="email" name="email" placeholder="Email" required style="padding: 12px 15px; border: 1px solid #ccc; border-radius: 8px;">\n <input type="hidden" name="product">\n <input type="hidden" name="price">\n <input type="hidden" name="id">\n <input type="hidden" name="category">\n\n <button id="submitBuy" type="submit" style="padding: 14px; background: #007BFF; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-size: 18px; font-weight: bold;">Send Order</button>\n </form>\n\n <div id="confirmation" style="display: none; margin-top: 20px; padding: 20px; background-color: #e6ffed; color: #056608; border-radius: 12px; text-align: center; font-weight: 500;">\n <p>Thank you for your purchase! 🎉</p>\n <button id="closeConfirmation" style="margin-top: 10px; padding: 10px 20px; background: #007BFF; color: #fff; border: none; border-radius: 8px; cursor: pointer;">Close</button>\n </div>\n </div>\n ',document.body.appendChild(e),document.getElementById("closeModal").onclick=()=>e.style.display="none",document.getElementById("closeConfirmation").onclick=()=>{document.getElementById("confirmation").style.display="none",e.style.display="none"},e.onclick=t=>{t.target===e&&(e.style.display="none")},e}function openModal(e){const t=document.getElementById("buyNowModal"),o=t.querySelector("#buyForm"),n=t.querySelector("#confirmation");t.style.display="flex",o.style.display="flex",n.style.display="none";const i=e.split("/").filter(Boolean),[r,d,a,...p]=i,c=decodeURIComponent(p.join("/")),l=parseInt(a,10),s=CATEGORY_CONFIG[l]||{showLocatiLine truncated
+1
View File
@@ -3,3 +3,4 @@ npm install -g terser
terser buyModal.js -o buyModal.min.js -c -m terser buyModal.js -o buyModal.min.js -c -m
terser tryModal.js -o tryModal.min.js -c -m terser tryModal.js -o tryModal.min.js -c -m
terser setCookie.js -o setCookie.min.js -c -m
+36
View File
@@ -0,0 +1,36 @@
function setUtmCookies() {
// Helper: get query param from URL
function getQueryParam(param) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(param);
}
// Helper: get cookie by name
function getCookie(name) {
const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return match ? decodeURIComponent(match[2]) : null;
}
// Helper: set cookie if not already set
function setCookieIfEmpty(name, value, days = 90) {
if (!value) return;
if (getCookie(name)) return; // Don't overwrite existing cookie
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${date.toUTCString()}; path=/; SameSite=Lax`;
}
// Get UTM params
const utmSource = getQueryParam('utm_source');
const utmMedium = getQueryParam('utm_medium');
const utmCampaign = getQueryParam('utm_campaign');
// Set cookies only if not already present
setCookieIfEmpty('utm_source', utmSource, 90);
setCookieIfEmpty('utm_medium', utmMedium, 90);
setCookieIfEmpty('utm_campaign', utmCampaign, 90);
}
// Run on page load
setUtmCookies();
+1
View File
@@ -0,0 +1 @@
function setUtmCookies(){function e(e){return new URLSearchParams(window.location.search).get(e)}function t(e,t,n=90){if(!t)return;if(function(e){const t=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return t?decodeURIComponent(t[2]):null}(e))return;const o=new Date;o.setTime(o.getTime()+24*n*60*60*1e3),document.cookie=`${e}=${encodeURIComponent(t)}; expires=${o.toUTCString()}; path=/; SameSite=Lax`}const n=e("utm_source"),o=e("utm_medium"),m=e("utm_campaign");t("utm_source",n,90),t("utm_medium",o,90),t("utm_campaign",m,90)}setUtmCookies();