2RE03-Design/js/main.js
2RE 53ca1fb834 Initial commit: 2RE03 portfolio site
Static HTML/CSS/JS portfolio for the design studio 2RE03: locally vendored Bootstrap 5.3.3, self-hosted Inter + Space Grotesk fonts, six pages, Collins-style scroll-snap carousels, a case-studies index with 10 detail pages, and a Web3Forms contact form.
2026-09-10 19:06:52 +08:00

95 lines
2.8 KiB
JavaScript

/* ==========================================================================
2RE03 site scripts
- Footer year
- Contact form: client-side validation + AJAX submit to Web3Forms
========================================================================== */
(function () {
"use strict";
/* --- Footer year ------------------------------------------------------- */
document.querySelectorAll("[data-year]").forEach(function (el) {
el.textContent = String(new Date().getFullYear());
});
/* --- Contact form ------------------------------------------------------ */
var form = document.getElementById("contactForm");
if (!form) {
return;
}
var status = document.getElementById("formStatus");
var submitBtn = form.querySelector('button[type="submit"]');
var submitLabel = submitBtn ? submitBtn.innerHTML : "";
function showStatus(message, variant) {
if (!status) {
return;
}
status.textContent = message;
status.className = "alert mt-3 mb-0 alert-" + variant;
status.hidden = false;
status.focus();
}
function clearStatus() {
if (!status) {
return;
}
status.textContent = "";
status.hidden = true;
}
function setBusy(isBusy) {
if (!submitBtn) {
return;
}
submitBtn.disabled = isBusy;
submitBtn.innerHTML = isBusy ? "Sending…" : submitLabel;
}
form.addEventListener("submit", function (event) {
event.preventDefault();
clearStatus();
// Basic validation: required fields + email format (via input[type=email]).
if (!form.checkValidity()) {
form.classList.add("was-validated");
var firstInvalid = form.querySelector(":invalid");
if (firstInvalid) {
firstInvalid.focus();
}
showStatus("Please fix the highlighted fields and try again.", "danger");
return;
}
setBusy(true);
fetch(form.action, {
method: "POST",
body: new FormData(form),
headers: { Accept: "application/json" }
})
.then(function (response) {
return response
.json()
.catch(function () { return {}; })
.then(function (data) { return { ok: response.ok, data: data }; });
})
.then(function (result) {
var data = result.data || {};
if (result.ok && data.success) {
form.reset();
form.classList.remove("was-validated");
showStatus("Thanks, your message is on its way. We'll get back to you soon.", "success");
} else {
showStatus(data.message || "Something went wrong. Please try again, or email us directly.", "danger");
}
})
.catch(function () {
showStatus("Network error. Please check your connection and try again.", "danger");
})
.finally(function () {
setBusy(false);
});
});
})();