`).join("");
}
function generateReviewSummary() {
updateFormDataFromFields();
const serviceMap = {
web: "Web Design",
graphic: "Graphic Design",
branding: "Branding & Brand Identity",
marketing: "Lead Generation & Digital Marketing",
guidance: "Not Sure — I Need Guidance"
};
const reviewService = [
["Service", serviceMap[formData.service] || "—"],
["Selected", formData.service ? "Confirmed" : "Not selected"]
];
const reviewBusiness = [
["Business / Brand Name", formData.business.name || "—"],
["Website / Social", formData.business.website || "—"],
["Business Description", formData.business.description || "—"],
["Location", formData.business.location || "—"],
["Business Stage", formData.business.stage || "—"]
];
let projectRows = [["Project details", "No service questions available"]];
const projectObj = formData.project || {};
if (formData.service === "web") {
projectRows = [
["Need", projectObj.type?.join(", ") || "—"],
["Pages", projectObj.pages || "—"],
["Already have website?", projectObj.hasWebsite || "—"],
["Current URL", projectObj.currentWebsiteUrl || "—"],
["Main goal", projectObj.goal || "—"],
["Assets", projectObj.assets?.join(", ") || "—"],
["References", projectObj.references || "—"],
["Launch date", projectObj.launchDate || "—"]
];
} else if (formData.service === "graphic") {
projectRows = [
["Designs needed", projectObj.designsNeeded?.join(", ") || "—"],
["How many", projectObj.designCount || "—"],
["Where used", projectObj.usage?.join(", ") || "—"],
["Existing guidelines", projectObj.existingBrandGuidelines || "—"],
["Content ready", projectObj.copyReady || "—"],
["Inspiration", projectObj.inspiration || "—"],
["Deadline", projectObj.deadline || "—"]
];
} else if (formData.service === "branding") {
projectRows = [
["Looking for", projectObj.lookFor?.join(", ") || "—"],
["Has existing logo?", projectObj.hasLogo || "—"],
["Deliverables", projectObj.deliverables?.join(", ") || "—"],
["Brand in 3–5 words", projectObj.brandWords || "—"],
["Target audience", projectObj.targetAudience || "—"],
["Visual style inspiration", projectObj.styleInspiration || "—"],
["Brand message", projectObj.brandMessage || "—"]
];
} else if (formData.service === "marketing") {
projectRows = [
["Main goal", projectObj.goal || "—"],
["Platforms", projectObj.platforms?.join(", ") || "—"],
["Services", projectObj.services?.join(", ") || "—"],
["Budget", projectObj.budget || "—"],
["Current leads", projectObj.currentLeads || "—"],
["Successful campaign", projectObj.successDefinition || "—"]
];
} else if (formData.service === "guidance") {
projectRows = [
["Trying to achieve", projectObj.goals || "—"],
["What is not working", projectObj.problem || "—"],
["What Desigfo can help with", projectObj.help || "—"]
];
}
const reviewGoals = [
["Estimated budget", formData.goals.budget || "—"],
["Start timeline", formData.goals.startTime || "—"],
["Deadline", formData.goals.deadline || "—"],
["Additional info", formData.goals.additionalInfo || "—"],
["Attachments", formData.goals.briefFile || "—"]
];
const reviewContact = [
["Full Name", formData.contact.name || "—"],
["Email", formData.contact.email || "—"],
["WhatsApp", formData.contact.whatsapp || "—"],
["Company / Brand", formData.contact.company || "—"],
["Preferred Contact", formData.contact.preferredContact || "—"],
["Meeting Time", formData.contact.meetingTime || "—"],
["Meeting Date", formData.contact.meetingDate || "—"]
];
renderReviewSection("reviewService", reviewService);
renderReviewSection("reviewBusiness", reviewBusiness);
renderReviewSection("reviewProject", projectRows);
renderReviewSection("reviewGoals", reviewGoals);
renderReviewSection("reviewContact", reviewContact);
}
function bindServiceCards() {
serviceCards.forEach((card) => {
card.addEventListener("click", () => {
selectService(card.dataset.service);
updateFormDataFromFields();
});
card.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
selectService(card.dataset.service);
updateFormDataFromFields();
}
if (event.key === "Escape") {
card.blur();
}
});
card.setAttribute("tabindex", "0");
card.setAttribute("role", "radio");
card.setAttribute("aria-checked", "false");
});
}
function bindInputEvents() {
document.querySelectorAll("input, textarea, select").forEach((field) => {
field.addEventListener("input", () => {
updateFormDataFromFields();
if (field.dataset.required === "true") {
if (!field.value.trim()) {
setErrorState(field, "This field is required.");
} else {
clearErrorForInput(field);
}
}
if (field.type === "email" && field.value.trim()) {
if (!validateEmail(field.value.trim())) {
setErrorState(field, "Please enter a valid email address.");
} else {
clearErrorForInput(field);
}
}
if (field.type === "url" && field.value.trim()) {
if (!validateUrl(field.value.trim())) {
setErrorState(field, "Please enter a valid URL.");
} else {
clearErrorForInput(field);
}
}
if (field.id === "businessWebsite" && field.value.trim()) {
if (!validateUrl(field.value.trim())) {
setErrorState(field, "Please enter a valid website or social URL.");
} else {
clearErrorForInput(field);
}
}
if (field.id === "currentWebsiteUrl" && field.value.trim()) {
if (!validateUrl(field.value.trim())) {
setErrorState(field, "Please enter a valid website URL.");
} else {
clearErrorForInput(field);
}
}
if (field.name) {
const radios = document.querySelectorAll(`input[name="${field.name}"]`);
if (radios.length) {
radios.forEach((radio) => {
const pill = radio.closest(".pill-option");
if (pill) pill.classList.toggle("selected", radio.checked);
});
}
}
});
field.addEventListener("blur", () => {
if (field.dataset.required === "true" && !field.value.trim()) {
setErrorState(field, "This field is required.");
} else if (field.type === "email" && field.value.trim() && !validateEmail(field.value.trim())) {
setErrorState(field, "Please enter a valid email address.");
} else if (field.type === "url" && field.value.trim() && !validateUrl(field.value.trim())) {
setErrorState(field, "Please enter a valid URL.");
} else {
clearErrorForInput(field);
}
});
});
document.querySelectorAll('input[type="radio"]').forEach((radio) => {
radio.addEventListener("change", () => {
syncPillSelection(radio.name);
updateFormDataFromFields();
if (radio.name === "webHasSite" && radio.value === "Yes") {
document.getElementById("currentWebsiteGroup").classList.remove("hidden");
} else if (radio.name === "webHasSite" && radio.value === "No") {
document.getElementById("currentWebsiteGroup").classList.add("hidden");
document.getElementById("currentWebsiteUrl").value = "";
clearErrorForInput(document.getElementById("currentWebsiteUrl"));
}
});
});
document.querySelectorAll('input[type="checkbox"]').forEach((checkbox) => {
checkbox.addEventListener("change", () => updateFormDataFromFields());
});
document.querySelectorAll("select").forEach((select) => {
select.addEventListener("change", () => updateFormDataFromFields());
});
}
function bindFileUpload() {
if (projectBriefInput) {
projectBriefInput.addEventListener("change", () => {
const file = projectBriefInput.files && projectBriefInput.files[0];
fileNameLabel.textContent = file ? file.name : "No file selected";
});
}
}
function bindReviewEditButtons() {
document.querySelectorAll(".edit-link").forEach((button) => {
button.addEventListener("click", () => {
const targetStep = Number(button.dataset.editStep);
showStep(targetStep);
});
});
}
function bindNavigation() {
backBtn.addEventListener("click", previousStep);
nextBtn.addEventListener("click", nextStep);
restartBtn.addEventListener("click", restartForm);
}
function restartForm() {
form.reset();
form.style.display = "block";
successScreen.classList.remove("visible");
serviceCards.forEach((card) => {
card.classList.remove("selected");
card.setAttribute("aria-checked", "false");
});
document.querySelectorAll(".pill-option").forEach((option) => option.classList.remove("selected"));
document.querySelectorAll(".service-question-group-inner").forEach((group) => group.classList.add("hidden"));
document.querySelectorAll(".field-error").forEach((error) => { error.textContent = ""; });
document.querySelectorAll(".has-error").forEach((item) => item.classList.remove("has-error"));
document.getElementById("serviceError").textContent = "";
document.getElementById("currentWebsiteGroup").classList.add("hidden");
fileNameLabel.textContent = "No file selected";
formData.service = "";
formData.business = { name: "", website: "", description: "", location: "", stage: "" };
formData.project = {};
formData.goals = { budget: "", startTime: "", deadline: "", additionalInfo: "", briefFile: "" };
formData.contact = { name: "", email: "", whatsapp: "", company: "", preferredContact: "", meetingTime: "", meetingDate: "" };
showStep(1);
}
function handleEscapeClose() {
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && successScreen.classList.contains("visible")) {
successScreen.classList.remove("visible");
form.style.display = "block";
}
});
}
function init() {
bindServiceCards();
bindInputEvents();
bindFileUpload();
bindReviewEditButtons();
bindNavigation();
handleEscapeClose();
document.querySelectorAll(".pill-option").forEach((label) => {
label.addEventListener("click", () => {
const input = label.querySelector("input");
if (!input) return;
if (input.type === "radio") {
input.checked = true;
input.dispatchEvent(new Event("change"));
} else if (input.type === "checkbox") {
input.checked = !input.checked;
input.dispatchEvent(new Event("change"));
}
});
});
showStep(1);
backBtn.style.visibility = "hidden";
}
init();
// FUTURE BACKEND INTEGRATION
// Connect this form to Formspree, Web3Forms, a custom API, email service, CRM, or Google Sheets here.
// Example:
// fetch("/api/submit-inquiry", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(formData) });
// or use Formspree/Web3Forms POST request after successful validation.