let calculatedResults = null; function calculatePlan() { const revenueGoal = parseFloat(document.getElementById("revenueGoal").value) || 0; const aov = parseFloat(document.getElementById("aov").value) || 0; const conversionRate = parseFloat(document.getElementById("conversionRate").value) || 0; const cps = parseFloat(document.getElementById("cps").value) || 0; if (revenueGoal > 0 && aov > 0 && conversionRate > 0 && cps > 0) { const sessionsNeeded = revenueGoal / (aov * (conversionRate / 100)); const adSpendNeeded = sessionsNeeded * cps; const estimatedROAS = revenueGoal / adSpendNeeded; calculatedResults = { sessionsNeeded, adSpendNeeded, estimatedROAS, cps, }; // Update UI document.getElementById("resultsPlaceholder").classList.add("hidden"); document.getElementById("resultsCard").classList.remove("hidden"); document.getElementById("channelSection").classList.remove("hidden"); document.getElementById("sessionsNeeded").textContent = Math.round(sessionsNeeded).toLocaleString(); document.getElementById("adSpendNeeded").textContent = "$" + adSpendNeeded.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2, }); document.getElementById("estimatedROAS").textContent = estimatedROAS.toFixed(2) + "x"; updateAllocation(); } } function updateAllocation() { if (!calculatedResults) return; const meta = parseFloat(document.getElementById("metaAlloc").value) || 0; const google = parseFloat(document.getElementById("googleAlloc").value) || 0; const tiktok = parseFloat(document.getElementById("tiktokAlloc").value) || 0; const pinterest = parseFloat(document.getElementById("pinterestAlloc").value) || 0; const other = parseFloat(document.getElementById("otherAlloc").value) || 0; const total = meta + google + tiktok + pinterest + other; const validationEl = document.getElementById("validationMessage"); if (total > 0 && Math.abs(total - 100) > 0.1) { validationEl.className = "validation-message validation-error"; validationEl.textContent = "Allocations must total exactly 100%"; document.getElementById("allocationTable").classList.add("hidden"); } else if (Math.abs(total - 100) <= 0.1) { validationEl.textContent = ""; validationEl.className = ""; // Build table const channels = [ { name: "Meta Ads", percent: meta }, { name: "Google Ads", percent: google }, { name: "TikTok Ads", percent: tiktok }, { name: "Pinterest Ads", percent: pinterest }, { name: "Other", percent: other }, ].filter((c) => c.percent > 0); if (channels.length > 0) { const tbody = document.getElementById("allocationTableBody"); tbody.innerHTML = ""; channels.forEach((channel) => { const spend = calculatedResults.adSpendNeeded * (channel.percent / 100); const sessions = Math.round(spend / calculatedResults.cps); const row = document.createElement("tr"); row.innerHTML = ` ${channel.name} (${ channel.percent }%) $${spend.toLocaleString(undefined, { maximumFractionDigits: 0, })} ${sessions.toLocaleString()} `; tbody.appendChild(row); }); document .getElementById("allocationTable") .classList.remove("hidden"); } } else { validationEl.textContent = ""; validationEl.className = ""; document.getElementById("allocationTable").classList.add("hidden"); } }