diff --git a/ts/base/common.ts b/ts/base/common.ts index 90ddad4..696ea68 100644 --- a/ts/base/common.ts +++ b/ts/base/common.ts @@ -41,53 +41,4 @@ document.addEventListener("DOMContentLoaded", function () { }); }, 300); } - - const scrollTop = (target: string, offset: number = 0) => { - const targetElement = document.getElementById(target); - if (!targetElement) throw new Error(`scrollTop requires ${target} to exist`); - const top = targetElement.getBoundingClientRect().top, - t = window.scrollY + top - offset; - scrollTo({ - top: t, - behavior: "smooth" - }); - }; - - const pageUp = document.getElementById("page-up"); - if (pageUp) { - pageUp.addEventListener("click", () => scrollTop("content-container", 250)), - document.addEventListener("scroll", () => { - if (window.scrollY > 250) { - pageUp.classList.add("show"); - return; - } - pageUp.classList.remove("show"); - }); - } -}); - -// * Input Validation. -document.addEventListener("DOMContentLoaded", function () { - document.querySelectorAll("input.is-invalid").forEach((input) => { - let timer: NodeJS.Timeout|null = null; - input.addEventListener("change", () => { - const parent = input.parentElement; - input.classList.remove("is-invalid"); - if (parent && parent.classList.contains("is-invalid")) { - parent.classList.remove("is-invalid"); - } - }); - input.addEventListener("input", () => { - if (timer) { - clearTimeout(timer); - } - timer = setTimeout(() => { - const parent = input.parentElement; - input.classList.remove("is-invalid"); - if (parent && parent.classList.contains("is-invalid")) { - parent.classList.remove("is-invalid"); - } - }, 250); - }); - }); }); diff --git a/ts/fo.ts b/ts/fo.ts index 1b50d30..2877b5f 100644 --- a/ts/fo.ts +++ b/ts/fo.ts @@ -10,6 +10,11 @@ import "./utilities/vue-fo"; // CUSTOM import "./base/common"; +// PARTIALS +import "./partials/input-errors-removal"; +import "./partials/newsletter"; +import "./partials/scroll-to-top"; + // PAGES import "./pages/home"; import "./pages/products"; diff --git a/ts/partials/input-errors-removal.ts b/ts/partials/input-errors-removal.ts new file mode 100644 index 0000000..3b66684 --- /dev/null +++ b/ts/partials/input-errors-removal.ts @@ -0,0 +1,25 @@ +// * Input Validation. +document.addEventListener("DOMContentLoaded", function () { + document.querySelectorAll("input.is-invalid").forEach((input) => { + let timer: NodeJS.Timeout|null = null; + input.addEventListener("change", () => { + const parent = input.parentElement; + input.classList.remove("is-invalid"); + if (parent && parent.classList.contains("is-invalid")) { + parent.classList.remove("is-invalid"); + } + }); + input.addEventListener("input", () => { + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(() => { + const parent = input.parentElement; + input.classList.remove("is-invalid"); + if (parent && parent.classList.contains("is-invalid")) { + parent.classList.remove("is-invalid"); + } + }, 250); + }); + }); +}); diff --git a/ts/partials/newsletter.ts b/ts/partials/newsletter.ts new file mode 100644 index 0000000..9f60eb7 --- /dev/null +++ b/ts/partials/newsletter.ts @@ -0,0 +1,49 @@ +import route from "../../../../ts/modules/route"; +const laravelRoute = route.methods.route; + +document.addEventListener("DOMContentLoaded", function () { +// * NEWSLETTERS +// Subscribe to newsletter + const newsletterSubmitBtn = document.getElementById("newsletter-submit"); + const newsletterEmailInput = document.getElementById("newsletter-email") as HTMLInputElement; + const newsletterMessageDiv = document.getElementById("newsletter-message"); + if (newsletterSubmitBtn && newsletterEmailInput && newsletterMessageDiv) { + + // Submit the request + newsletterSubmitBtn.addEventListener("click", function () { + // Reset error field + newsletterMessageDiv.classList.remove("bg-success-subtle", "border-success", "text-success"); + newsletterMessageDiv.classList.remove("bg-danger-subtle", "border-danger", "text-danger"); + newsletterMessageDiv.textContent = ""; + + const addSingleOptinRoute = laravelRoute("fo.add-single-optin"); + if (addSingleOptinRoute === null) { + return; + } + window.axios.post(addSingleOptinRoute, { + email: newsletterEmailInput.value, + }) + .then(function (response) { + newsletterMessageDiv.classList.remove("d-none"); + newsletterMessageDiv.classList.add("bg-success-subtle", "border-success", "text-success"); + newsletterMessageDiv.textContent = String(response.data); + newsletterEmailInput.value = ""; + }) + .catch(function (error) { + newsletterMessageDiv.classList.remove("d-none"); + newsletterMessageDiv.classList.add("bg-danger-subtle", "border-danger", "text-danger"); + if (error.response.status == 422) { + const errors = error.response.data.errors; + for (const errorKey in errors) { + const errorP = document.createElement("p"); + errorP.classList.add("m-0"); + errorP.textContent = errors[errorKey]; + newsletterMessageDiv.appendChild(errorP); + } + } else { + newsletterMessageDiv.textContent = error.response.data; + } + }); + }); + } +}); diff --git a/ts/partials/scroll-to-top.ts b/ts/partials/scroll-to-top.ts new file mode 100644 index 0000000..bbdc123 --- /dev/null +++ b/ts/partials/scroll-to-top.ts @@ -0,0 +1,25 @@ +// * Scroll to top button. +document.addEventListener("DOMContentLoaded", function () { + const scrollTop = (target: string, offset: number = 0) => { + const targetElement = document.getElementById(target); + if (!targetElement) throw new Error(`scrollTop requires ${target} to exist`); + const top = targetElement.getBoundingClientRect().top, + t = window.scrollY + top - offset; + scrollTo({ + top: t, + behavior: "smooth" + }); + }; + + const pageUp = document.getElementById("page-up"); + if (pageUp) { + pageUp.addEventListener("click", () => scrollTop("content-container", 250)), + document.addEventListener("scroll", () => { + if (window.scrollY > 250) { + pageUp.classList.add("show"); + return; + } + pageUp.classList.remove("show"); + }); + } +}); diff --git a/views/layouts/footer-newsletter.blade.php b/views/layouts/footer-newsletter.blade.php new file mode 100644 index 0000000..698932c --- /dev/null +++ b/views/layouts/footer-newsletter.blade.php @@ -0,0 +1,12 @@ +{{-- Newsletter form --}} +