';
}
function areaField(key, ph, opts) {
opts = opts || {};
return '
' +
'' +
(opts.hint ? '
';
}
function chips(key, options, multi) {
var cur = S.a[key];
var html = '' + esc(opts.hint) + '
' : "") +
'';
options.forEach(function (opt) {
var on = multi ? (cur || []).indexOf(opt) >= 0 : cur === opt;
html += '';
});
return html + "
";
}
function bigOpts(key, options, multi) {
var cur = S.a[key];
var html = '';
options.forEach(function (o) {
var on = multi ? (cur || []).indexOf(o.id) >= 0 : cur === o.id;
html += '';
});
return html + "
";
}
function buildSteps() {
var a = S.a;
var wantsSEO = a.services.indexOf("seo") >= 0;
var wantsAds = a.services.indexOf("ads") >= 0;
var steps = [];
steps.push({ id: "welcome", type: "welcome" });
steps.push({
id: "contact", section: "About you",
q: "First, who are we working with?",
sub: "Just the basics so we know who to reach.",
valid: function () { return (a.name || "").trim() && (a.email || "").trim(); },
render: function () {
return textField("Your name", "name", "Jane Smith", { autofocus: true }) +
textField("Email", "email", "jane@company.com", { type: "email" }) +
textField("Phone (optional)", "phone", "(714) 555-0100");
}
});
steps.push({
id: "business", section: "Your business",
q: "Tell us about the business.",
sub: "Name and website. We'll take a look before our kickoff.",
valid: function () { return (a.bizName || "").trim(); },
render: function () {
return textField("Business name", "bizName", "Acme Plumbing Co.", { autofocus: true }) +
textField("Website URL", "website", "https://yoursite.com", { hint: "No website yet? Leave it blank. We can help with that too." });
}
});
steps.push({
id: "industry", section: "Your business",
q: "What industry are you in?",
sub: "Tap one. This shapes our keyword and audience research.",
valid: function () { return !!a.industry; },
render: function () {
var h = chips("industry", ["Home Services", "Healthcare", "Legal", "Real Estate", "E-commerce", "Restaurant / Food", "Beauty & Wellness", "Professional Services", "Automotive", "Construction", "Education", "Other"], false);
if (a.industry === "Other") {
h += '' + textField("", "industryOther", "Tell us your industry", { autofocus: true }) + "
";
}
return h;
}
});
steps.push({
id: "services", section: "Services",
q: "What are we building together?",
sub: "Pick one or both. Your next questions adapt to this.",
valid: function () { return a.services.length > 0; },
render: function () {
return bigOpts("services", [
{ id: "seo", icon: "🔍", title: "SEO", desc: "Rank higher on Google, grow organic traffic and leads over time." },
{ id: "ads", icon: "🎯", title: "Google Ads", desc: "Paid campaigns that put you in front of buyers right now." }
], true);
}
});
steps.push({
id: "goal", section: "Goals",
q: "What does success look like in 6 months?",
sub: "Pick your top priority. We can chase more than one, but one leads.",
valid: function () { return !!a.goal; },
render: function () {
return chips("goal", ["More phone calls", "More form leads", "More online sales", "More foot traffic", "Brand visibility", "Beat a competitor"], false);
}
});
if (wantsSEO) {
steps.push({
id: "seoAreas", section: "SEO",
q: "Where should customers find you?",
sub: "List the cities or areas you want to rank in.",
valid: function () { return (a.seoAreas || "").trim(); },
render: function () {
return textField("", "seoAreas", "Orange, Anaheim, Santa Ana, all of Orange County…", { autofocus: true, hint: 'Serving customers nationwide? Just say "national."' });
}
});
steps.push({
id: "seoKeywords", section: "SEO",
q: "If you could rank #1 for anything, what would it be?",
sub: "Give us 3 to 5 search phrases your dream customer would type.",
valid: function () { return (a.seoKeywords || "").trim(); },
render: function () {
return areaField("seoKeywords", "emergency plumber orange ca\nwater heater repair near me\n…", { autofocus: true });
}
});
steps.push({
id: "seoCompetitors", section: "SEO",
q: "Who's beating you on Google right now?",
sub: "Name 1 to 3 competitors, websites or business names. We love a target.",
valid: function () { return true; },
render: function () {
return areaField("seoCompetitors", "competitor1.com, Joe's Plumbing…", { autofocus: true, hint: "Optional. Skip if you're not sure, we'll find them." });
}
});
}
if (wantsAds) {
steps.push({
id: "adsHistory", section: "Google Ads",
q: "Have you run Google Ads before?",
valid: function () { return !!a.adsHistory; },
render: function () {
return bigOpts("adsHistory", [
{ id: "current", icon: "🟢", title: "Running now", desc: "We have active campaigns today." },
{ id: "past", icon: "🕐", title: "In the past", desc: "We've tried it before but paused or stopped." },
{ id: "never", icon: "✨", title: "Never", desc: "This would be our first time. Exciting." }
], false);
}
});
steps.push({
id: "adsBudget", section: "Google Ads",
q: "What's your monthly ad budget?",
sub: "Ad spend only, this is what goes to Google. Ballpark is fine.",
valid: function () { return !!a.adsBudget; },
render: function () {
return chips("adsBudget", ["Under $1,000", "$1,000 – $3,000", "$3,000 – $5,000", "$5,000 – $10,000", "$10,000+", "Not sure yet"], false);
}
});
if (a.adsHistory === "current" || a.adsHistory === "past") {
steps.push({
id: "adsAccess", section: "Google Ads",
q: "Can you grant us access to the existing account?",
sub: "We audit before we build. Keeping your history is valuable.",
valid: function () { return !!a.adsAccess; },
render: function () {
return chips("adsAccess", ["Yes, I can grant access", "I'll need help finding it", "It belonged to an old agency"], false) +
'' +
textField("Google Ads Customer ID (optional)", "adsCid", "123-456-7890", { hint: "Top-right corner when you're logged into ads.google.com." }) +
"
";
}
});
}
}
steps.push({
id: "platform", section: "Access",
q: "What's your website built on?",
valid: function () { return !!a.platform; },
render: function () {
return chips("platform", ["WordPress", "Shopify", "Wix", "Squarespace", "Webflow", "Custom / not sure", "No website yet"], false);
}
});
steps.push({
id: "tools", section: "Access",
q: "Which of these do you already have set up?",
sub: "Tap all that apply. Not sure? Skip it, we'll check during setup.",
valid: function () { return true; },
render: function () {
return chips("tools", ["Google Analytics (GA4)", "Google Search Console", "Google Business Profile", "Google Tag Manager", "Facebook / Meta Pixel", "None of these", "Not sure"], true);
}
});
steps.push({
id: "files", section: "Assets",
q: "Upload anything that helps us hit the ground running.",
sub: "Logos, brand guidelines, photos, past ad creative, old reports. Optional but very welcome. Up to " + OWG_CONFIG.MAX_FILES + " files, " + OWG_CONFIG.MAX_TOTAL_MB + "MB total.",
valid: function () { return true; },
render: function () {
var h = '' +
'
';
if (S.a.files.length) {
h += 'Drop files here or click to browse
' +
'Logo, brand guide, photos, ad creative, past reports. Anything helpful.
' +
'';
S.a.files.forEach(function (f, i) {
var sz = f.size > 1048576 ? (f.size / 1048576).toFixed(1) + " MB" : Math.max(1, Math.round(f.size / 1024)) + " KB";
h += '
";
}
h += '';
return h;
}
});
steps.push({
id: "notes", section: "Almost done",
q: "Anything else we should know?",
sub: "Deadlines, promotions coming up, things past agencies got wrong. The floor is yours.",
valid: function () { return true; },
render: function () {
return areaField("notes", "Optional. Anything at all.", { autofocus: true });
}
});
steps.push({ id: "review", type: "review", section: "Review" });
steps.push({ id: "done", type: "done" });
return steps;
}
/* ============================================================
Summary text (what lands in Google Drive)
============================================================ */
function svcLabel() {
return S.a.services.map(function (s) { return s === "seo" ? "SEO" : "Google Ads"; }).join(" + ");
}
function adsHistoryLabel() {
return S.a.adsHistory === "current" ? "Running now" : S.a.adsHistory === "past" ? "Ran in the past" : S.a.adsHistory === "never" ? "Never ran ads" : "";
}
function summaryText() {
var a = S.a;
var L = [];
L.push("ORANGE WEB GROUP — CLIENT ONBOARDING");
L.push("Submitted: " + new Date().toLocaleString());
L.push("");
L.push("== CONTACT ==");
L.push("Name: " + (a.name || ""));
L.push("Email: " + (a.email || ""));
L.push("Phone: " + (a.phone || ""));
L.push("");
L.push("== BUSINESS ==");
L.push("Business: " + (a.bizName || ""));
L.push("Website: " + (a.website || ""));
L.push("Industry: " + (a.industry === "Other" ? (a.industryOther || "Other") : (a.industry || "")));
L.push("");
L.push("== SERVICES & GOALS ==");
L.push("Services: " + svcLabel());
L.push("Top goal: " + (a.goal || ""));
if (a.services.indexOf("seo") >= 0) {
L.push("");
L.push("== SEO ==");
L.push("Target areas: " + (a.seoAreas || ""));
L.push("Dream keywords:");
L.push(a.seoKeywords || "");
L.push("Competitors: " + (a.seoCompetitors || ""));
}
if (a.services.indexOf("ads") >= 0) {
L.push("");
L.push("== GOOGLE ADS ==");
L.push("History: " + adsHistoryLabel());
L.push("Monthly budget: " + (a.adsBudget || ""));
L.push("Account access: " + (a.adsAccess || ""));
L.push("Customer ID: " + (a.adsCid || ""));
}
L.push("");
L.push("== ACCESS & ASSETS ==");
L.push("Platform: " + (a.platform || ""));
L.push("Tools in place: " + (a.tools || []).join(", "));
L.push("Files attached: " + a.files.length + (a.files.length ? " (" + a.files.map(function (f) { return f.name; }).join(", ") + ")" : ""));
L.push("");
L.push("== NOTES ==");
L.push(a.notes || "");
return L.join("\n");
}
/* ============================================================
Submission to Zapier Catch Hook
============================================================ */
function buildFormData() {
var a = S.a;
var fd = new FormData();
fd.append("contact_name", a.name || "");
fd.append("contact_email", a.email || "");
fd.append("contact_phone", a.phone || "");
fd.append("business_name", a.bizName || "");
fd.append("website", a.website || "");
fd.append("industry", a.industry === "Other" ? (a.industryOther || "Other") : (a.industry || ""));
fd.append("services", svcLabel());
fd.append("top_goal", a.goal || "");
fd.append("seo_target_areas", a.seoAreas || "");
fd.append("seo_dream_keywords", a.seoKeywords || "");
fd.append("seo_competitors", a.seoCompetitors || "");
fd.append("ads_history", adsHistoryLabel());
fd.append("ads_monthly_budget", a.adsBudget || "");
fd.append("ads_account_access", a.adsAccess || "");
fd.append("ads_customer_id", a.adsCid || "");
fd.append("website_platform", a.platform || "");
fd.append("tools_in_place", (a.tools || []).join(", "));
fd.append("notes", a.notes || "");
fd.append("file_count", String(a.files.length));
fd.append("submitted_at", new Date().toISOString());
fd.append("summary_text", summaryText());
a.files.slice(0, OWG_CONFIG.MAX_FILES).forEach(function (f, i) {
fd.append("file" + (i + 1), f, f.name);
});
return fd;
}
function submit() {
if (S.submitting) return;
var url = OWG_CONFIG.WEBHOOK_URL;
if (!url || url.indexOf("http") !== 0) {
S.submitError = "This form isn't connected yet. Please email us directly at hello@orangewebgroup.com.";
render();
console.warn("[OWG] WEBHOOK_URL is not configured in OWG_CONFIG.");
return;
}
S.submitting = true;
S.submitError = null;
render();
fetch(url, { method: "POST", body: buildFormData() })
.then(function (res) {
if (!res.ok) throw new Error("HTTP " + res.status);
S.submitting = false;
go(1);
})
.catch(function (err) {
S.submitting = false;
S.submitError = "Something went wrong sending your answers (" + err.message + "). Please try again, or email us at hello@orangewebgroup.com.";
render();
});
}
/* ============================================================
Render
============================================================ */
function render() {
var steps = buildSteps();
if (S.idx >= steps.length) S.idx = steps.length - 1;
var step = steps[S.idx];
var qSteps = steps.filter(function (s) { return !s.type; });
var qIndex = -1;
qSteps.forEach(function (s, i) { if (s.id === step.id) qIndex = i; });
var progress = step.type === "welcome" ? 0 : step.type === "done" ? 100 : step.type === "review" ? 96 : Math.round(((qIndex + 1) / (qSteps.length + 1)) * 100);
document.getElementById("owg-rail-wrap").style.display = (step.type === "welcome" || step.type === "done") ? "none" : "block";
document.getElementById("owg-nav").style.display = (step.type === "welcome" || step.type === "done") ? "none" : "flex";
document.getElementById("owg-rail-fill").style.width = progress + "%";
document.getElementById("owg-section").textContent = step.section || "";
document.getElementById("owg-pct").textContent = progress + "%";
document.getElementById("owg-est").textContent = step.type === "welcome" ? "Client onboarding" : step.type === "done" ? "Complete" : "~" + Math.max(1, Math.ceil((qSteps.length - qIndex) * 0.4)) + " min left";
var html = "";
if (step.type === "welcome") {
html = '' + esc(f.name) + ' ' + sz + '
';
});
h += "' +
'
';
} else if (!step.type) {
html = 'SEO + Google Ads Onboarding
' +
'Let\'s get your growth engine running.
' + 'A few quick questions so our team can start researching your market before we even meet. Tap through it. Most clients finish in about 3 minutes.
' + '' + '' + 'press Enter ↵' +
'
";
} else if (step.type === "review") {
var a = S.a;
function row(k, v) { return v ? 'Question ' + (qIndex + 1) + ' of ' + qSteps.length + '
' +
'' + esc(step.q) + '
' + (step.sub ? '' + esc(step.sub) + '
' : "") + step.render() + "' + esc(k) + '' + esc(v) + "
" : ""; }
html = '' +
'
";
} else if (step.type === "done") {
var a2 = S.a;
html = 'Final check
' +
'Look good, ' + esc((a.name || "").split(" ")[0] || "friend") + '?
' + 'Give it a once-over. Tap Edit on anything you want to change.
' + (S.submitError ? '' + esc(S.submitError) + "
" : "") +
'' +
'" +
'" +
(a.services.indexOf("seo") >= 0 ? '" : "") +
(a.services.indexOf("ads") >= 0 ? '" : "") +
'
Contact & business
' +
row("Name", a.name) + row("Email", a.email) + row("Phone", a.phone) + row("Business", a.bizName) + row("Website", a.website) + row("Industry", a.industry === "Other" ? a.industryOther : a.industry) + "Services & goals
' +
row("Services", svcLabel()) + row("Top goal", a.goal) + "SEO
' + row("Target areas", a.seoAreas) + row("Dream keywords", a.seoKeywords) + row("Competitors", a.seoCompetitors) + "Google Ads
' + row("History", adsHistoryLabel()) + row("Monthly budget", a.adsBudget) + row("Account access", a.adsAccess) + row("Customer ID", a.adsCid) + "Access & assets
' +
row("Platform", a.platform) + row("Tools in place", (a.tools || []).join(", ")) + row("Files", a.files.length ? a.files.length + " file" + (a.files.length > 1 ? "s" : "") + " attached" : "None") + row("Notes", a.notes) + "' +
'
';
}
document.getElementById("owg-stage-inner").innerHTML = html;
var nextBtn = document.getElementById("owg-next");
if (step.type === "review") {
nextBtn.innerHTML = S.submitting ? 'Sending…' : "Submit onboarding";
nextBtn.disabled = S.submitting;
} else if (!step.type) {
nextBtn.textContent = "Continue";
nextBtn.disabled = !step.valid();
}
var af = document.querySelector("#owg-stage-inner [autofocus]");
if (af) try { af.focus(); } catch (e) {}
if (window.__owgRendered) {
try { document.getElementById("owg-onb").scrollIntoView({ behavior: "smooth", block: "start" }); } catch (e) {}
}
window.__owgRendered = true;
wireStep(step);
}
function currentStep() {
var steps = buildSteps();
return steps[Math.min(S.idx, steps.length - 1)];
}
function go(dir) {
var steps = buildSteps();
S.idx = Math.max(0, Math.min(S.idx + dir, steps.length - 1));
S.submitError = null;
render();
}
function jump(id) {
var steps = buildSteps();
for (var i = 0; i < steps.length; i++) { if (steps[i].id === id) { S.idx = i; break; } }
render();
}
function refreshNext() {
var step = currentStep();
var btn = document.getElementById("owg-next");
if (!step.type) btn.disabled = !step.valid();
}
/* ============================================================
Events
============================================================ */
function wireStep(step) {
var stage = document.getElementById("owg-stage-inner");
stage.querySelectorAll("[data-key]").forEach(function (el) {
el.addEventListener("input", function () { set(el.getAttribute("data-key"), el.value); refreshNext(); });
});
stage.querySelectorAll("[data-chip-key]").forEach(function (el) {
el.addEventListener("click", function () {
var k = el.getAttribute("data-chip-key"), v = el.getAttribute("data-chip-val"), multi = el.getAttribute("data-multi") === "1";
if (multi) {
var cur = S.a[k] || [];
var i = cur.indexOf(v);
if (i >= 0) cur.splice(i, 1); else cur.push(v);
set(k, cur);
} else set(k, v);
render();
});
});
stage.querySelectorAll("[data-big-key]").forEach(function (el) {
el.addEventListener("click", function () {
var k = el.getAttribute("data-big-key"), v = el.getAttribute("data-big-val"), multi = el.getAttribute("data-multi") === "1";
if (multi) {
var cur = S.a[k] || [];
var i = cur.indexOf(v);
if (i >= 0) cur.splice(i, 1); else cur.push(v);
set(k, cur);
} else set(k, v);
render();
});
});
stage.querySelectorAll("[data-jump]").forEach(function (el) {
el.addEventListener("click", function () { jump(el.getAttribute("data-jump")); });
});
stage.querySelectorAll("[data-rmfile]").forEach(function (el) {
el.addEventListener("click", function () {
S.a.files.splice(parseInt(el.getAttribute("data-rmfile"), 10), 1);
render();
});
});
var start = document.getElementById("owg-start");
if (start) start.addEventListener("click", function () { go(1); });
var drop = document.getElementById("owg-drop");
if (drop) {
var input = document.getElementById("owg-fileinput");
function addFiles(list) {
var files = S.a.files.concat(Array.prototype.slice.call(list || []));
var warn = "";
if (files.length > OWG_CONFIG.MAX_FILES) {
files = files.slice(0, OWG_CONFIG.MAX_FILES);
warn = "Limit is " + OWG_CONFIG.MAX_FILES + " files. Extra files were not added.";
}
var total = files.reduce(function (s, f) { return s + f.size; }, 0);
while (total > OWG_CONFIG.MAX_TOTAL_MB * 1048576 && files.length) {
var rm = files.pop();
total -= rm.size;
warn = "Total upload limit is " + OWG_CONFIG.MAX_TOTAL_MB + "MB. \"" + rm.name + "\" was not added. Email larger files to us directly.";
}
S.a.files = files;
render();
var w = document.getElementById("owg-filewarn");
if (w) w.textContent = warn;
}
drop.addEventListener("click", function () { input.click(); });
drop.addEventListener("keydown", function (e) { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); input.click(); } });
drop.addEventListener("dragover", function (e) { e.preventDefault(); drop.classList.add("drag"); });
drop.addEventListener("dragleave", function () { drop.classList.remove("drag"); });
drop.addEventListener("drop", function (e) { e.preventDefault(); drop.classList.remove("drag"); addFiles(e.dataTransfer.files); });
input.addEventListener("change", function () { addFiles(input.files); input.value = ""; });
}
}
document.getElementById("owg-back").addEventListener("click", function () { go(-1); });
document.getElementById("owg-next").addEventListener("click", function () {
var step = currentStep();
if (step.type === "review") { submit(); return; }
if (!step.type && !step.valid()) return;
go(1);
});
document.getElementById("owg-onb").addEventListener("keydown", function (e) {
var step = currentStep();
if (e.key === "Enter" && !e.shiftKey && e.target.tagName !== "TEXTAREA" && step.type !== "done") {
e.preventDefault();
if (step.type === "welcome") { go(1); return; }
if (step.type === "review") { submit(); return; }
if (!step.type && step.valid()) go(1);
}
});
render();
✓
' +
'You\'re all set' + (a2.name ? ", " + esc(a2.name.split(" ")[0]) : "") + '. We\'re on it.
' + 'Your onboarding is in. Our team will review everything and reach out' + (a2.email ? " at " + esc(a2.email) : "") + ' within one business day with next steps and access requests.
' + 'Orange Web Group · Orange, CA · orangewebgroup.com

