| Server IP : 10.200.247.200 / Your IP : 216.73.217.19 Web Server : Apache System : Linux synergy-usa-sites 6.8.0-138-generic #138-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 31 22:41:49 UTC 2026 x86_64 User : jeremy ( 1001) PHP Version : 8.4.25 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/coaching_sites/usbusinessfundingsolutions.com/js/ |
Upload File : |
/* Site behaviour: mobile nav, accordions, scroll reveals, toasts, forms. */
(function () {
"use strict";
var USBFS = (window.USBFS = window.USBFS || {});
/* ---------------------------------------------------------------- helpers */
function $(selector, root) {
return (root || document).querySelector(selector);
}
function $$(selector, root) {
return Array.prototype.slice.call((root || document).querySelectorAll(selector));
}
/* ------------------------------------------------------------- mobile nav */
function initMobileNav() {
var menu = $("[data-mobile-nav]");
if (!menu) return;
var openers = $$("[data-mobile-nav-open]");
var closers = $$("[data-mobile-nav-close]", menu);
function setOpen(open) {
menu.setAttribute("data-open", open ? "true" : "false");
menu.setAttribute("aria-hidden", open ? "false" : "true");
document.body.style.overflow = open ? "hidden" : "";
openers.forEach(function (button) {
button.setAttribute("aria-expanded", open ? "true" : "false");
});
}
openers.forEach(function (button) {
button.addEventListener("click", function () {
setOpen(true);
});
});
closers.forEach(function (button) {
button.addEventListener("click", function () {
setOpen(false);
});
});
// Any link inside the panel closes the menu on navigation.
$$("a", menu).forEach(function (link) {
link.addEventListener("click", function () {
setOpen(false);
});
});
document.addEventListener("keydown", function (event) {
if (event.key === "Escape" && menu.getAttribute("data-open") === "true") {
setOpen(false);
}
});
}
/* -------------------------------------------------------------- accordion */
function initAccordions() {
$$("[data-accordion]").forEach(function (accordion) {
var triggers = $$(".accordion__trigger", accordion);
triggers.forEach(function (trigger) {
var panel = document.getElementById(trigger.getAttribute("aria-controls"));
if (!panel) return;
trigger.addEventListener("click", function () {
var isOpen = trigger.getAttribute("aria-expanded") === "true";
// Single-select accordion: close the others first.
triggers.forEach(function (other) {
if (other === trigger) return;
var otherPanel = document.getElementById(other.getAttribute("aria-controls"));
other.setAttribute("aria-expanded", "false");
if (otherPanel) otherPanel.setAttribute("data-open", "false");
});
trigger.setAttribute("aria-expanded", isOpen ? "false" : "true");
panel.setAttribute("data-open", isOpen ? "false" : "true");
});
});
});
}
/* --------------------------------------------------------- scroll reveals */
function initReveals() {
var items = $$(".reveal");
if (!items.length) return;
if (!("IntersectionObserver" in window)) {
items.forEach(function (item) {
item.classList.add("is-visible");
});
return;
}
var observer = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
});
},
{ rootMargin: "0px 0px -10% 0px", threshold: 0.05 }
);
items.forEach(function (item) {
// Stagger siblings so grids cascade in, matching the original design.
if (!item.style.getPropertyValue("--reveal-delay")) {
var siblings = $$(".reveal", item.parentNode);
var index = siblings.indexOf(item);
if (index > 0) {
item.style.setProperty("--reveal-delay", Math.min(index, 8) * 80 + "ms");
}
}
observer.observe(item);
});
}
/* ----------------------------------------------------------------- toasts */
function toast(message, variant) {
var region = $(".toast-region");
if (!region) {
region = document.createElement("div");
region.className = "toast-region";
region.setAttribute("role", "status");
region.setAttribute("aria-live", "polite");
document.body.appendChild(region);
}
var node = document.createElement("div");
node.className = "toast toast--" + (variant || "success");
node.textContent = message;
region.appendChild(node);
window.setTimeout(function () {
node.remove();
}, 6000);
}
USBFS.toast = toast;
/* ------------------------------------------------------ password toggling */
var EYE_OPEN =
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">' +
'<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.964-7.178Z" />' +
'<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /></svg>';
var EYE_CLOSED =
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">' +
'<path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243" /></svg>';
function initPasswordToggles() {
$$("[data-password-toggle]").forEach(function (button) {
var input = document.getElementById(button.getAttribute("data-password-toggle"));
if (!input) return;
button.innerHTML = EYE_OPEN;
button.addEventListener("click", function () {
var revealed = input.type === "text";
input.type = revealed ? "password" : "text";
button.innerHTML = revealed ? EYE_OPEN : EYE_CLOSED;
button.setAttribute(
"aria-label",
revealed ? "Show password" : "Hide password"
);
});
});
}
/* ------------------------------------------------------ form validation */
function fieldError(form, name, message) {
var slot = $('[data-error-for="' + name + '"]', form);
var control = form.elements[name];
if (slot) slot.textContent = message || "";
if (control) {
var nodes = control.length && !control.tagName ? control : [control];
Array.prototype.forEach.call(nodes, function (node) {
if (node.setAttribute) {
if (message) node.setAttribute("aria-invalid", "true");
else node.removeAttribute("aria-invalid");
}
});
}
}
function clearErrors(form) {
$$("[data-error-for]", form).forEach(function (slot) {
fieldError(form, slot.getAttribute("data-error-for"), "");
});
}
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
/* Mirrors the rules the original zod schemas enforced. */
function validate(form, rules) {
clearErrors(form);
var values = {};
var errors = 0;
Object.keys(rules).forEach(function (name) {
var rule = rules[name];
var control = form.elements[name];
var raw = control ? (control.value != null ? control.value : "") : "";
var value = rule.trim === false ? raw : raw.trim();
values[name] = value;
var message = "";
if (!value) {
message = rule.required;
} else if (rule.email && !EMAIL_RE.test(value)) {
message = "Invalid email address";
} else if (rule.max && value.length > rule.max) {
message = rule.maxMessage;
}
if (message) {
errors++;
fieldError(form, name, message);
}
});
return errors ? null : values;
}
function submitJson(url, payload) {
return fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
}).then(function (response) {
return response.json();
});
}
function setBusy(form, busy, busyLabel, idleLabel) {
var button = $('button[type="submit"]', form);
if (!button) return;
button.disabled = busy;
var label = $("[data-submit-label]", button);
if (label) label.textContent = busy ? busyLabel : idleLabel;
}
/* --------------------------------------------------------- contact form */
function initContactForm() {
var form = $("[data-contact-form]");
if (!form) return;
form.addEventListener("submit", function (event) {
event.preventDefault();
var values = validate(form, {
firstName: { required: "First name is required", max: 100, maxMessage: "First name must be less than 100 characters" },
lastName: { required: "Last name is required", max: 100, maxMessage: "Last name must be less than 100 characters" },
email: { required: "Email is required", email: true, max: 255, maxMessage: "Email must be less than 255 characters" },
phone: { required: "Phone number is required", max: 20, maxMessage: "Phone number must be less than 20 characters" },
business: { required: "Business name is required", max: 200, maxMessage: "Business name must be less than 200 characters" },
subject: { required: "Please select a subject" },
message: { required: "Message is required", max: 1000, maxMessage: "Message must be less than 1000 characters" },
});
if (!values) return;
values.talkedToAdmissions = form.elements.talkedToAdmissions.value;
values.inProgram = form.elements.inProgram.value;
setBusy(form, true, "Sending...", "Send Message");
submitJson("/ajax/contact.php", values)
.then(function (result) {
if (result && result.status === "success") {
toast("Message sent successfully! We'll get back to you soon.", "success");
form.reset();
} else {
toast(
(result && result.message) || "Failed to send message. Please try again.",
"error"
);
}
})
.catch(function (error) {
toast("An error occurred. Please try again later.", "error");
console.error("Form submission error:", error);
})
.then(function () {
setBusy(form, false, "Sending...", "Send Message");
});
});
}
/* ----------------------------------------------------------- login forms */
function initLoginForms() {
var loginPanel = $("[data-login-panel]");
var resetPanel = $("[data-reset-panel]");
var loginForm = $("[data-login-form]");
var resetForm = $("[data-reset-form]");
if (!loginForm || !resetForm || !loginPanel || !resetPanel) return;
function showReset(show) {
loginPanel.hidden = show;
resetPanel.hidden = !show;
if (show) {
resetForm.reset();
clearErrors(resetForm);
}
}
$$("[data-show-reset]").forEach(function (button) {
button.addEventListener("click", function () {
showReset(true);
});
});
$$("[data-show-login]").forEach(function (button) {
button.addEventListener("click", function () {
showReset(false);
});
});
loginForm.addEventListener("submit", function (event) {
event.preventDefault();
var values = validate(loginForm, {
email: { required: "Email is required", email: true, max: 255, maxMessage: "Email must be less than 255 characters" },
password: { required: "Password is required", trim: false, max: 100, maxMessage: "Password must be less than 100 characters" },
});
if (!values) return;
setBusy(loginForm, true, "Signing In...", "Sign In");
submitJson("/ajax/login.php", values)
.then(function (result) {
if (result && result.status === "success") {
toast("Login successful! Redirecting...", "success");
window.setTimeout(function () {
window.location.href = "/member/";
}, 500);
} else {
toast(
(result && result.message) ||
"Login failed. Please check your credentials.",
"error"
);
}
})
.catch(function (error) {
toast("An error occurred. Please try again later.", "error");
console.error("Login error:", error);
})
.then(function () {
setBusy(loginForm, false, "Signing In...", "Sign In");
});
});
resetForm.addEventListener("submit", function (event) {
event.preventDefault();
var values = validate(resetForm, {
email: { required: "Email is required", email: true, max: 255, maxMessage: "Email must be less than 255 characters" },
});
if (!values) return;
setBusy(resetForm, true, "Sending...", "Send Reset Link");
submitJson("/ajax/forgotPassword.php", values)
.then(function (result) {
if (result && result.status === "success") {
toast(
"Password reset instructions have been sent to your email.",
"success"
);
showReset(false);
} else {
toast(
(result && result.message) ||
"Failed to send reset email. Please try again.",
"error"
);
}
})
.catch(function (error) {
toast("An error occurred. Please try again later.", "error");
console.error("Forgot password error:", error);
})
.then(function () {
setBusy(resetForm, false, "Sending...", "Send Reset Link");
});
});
}
/* -------------------------------------------------------------- bootstrap */
function init() {
initMobileNav();
initAccordions();
initPasswordToggles();
initContactForm();
initLoginForms();
initReveals();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();