diff options
Diffstat (limited to 'http/public/scripts/contact')
| -rw-r--r-- | http/public/scripts/contact/actions.js | 60 | ||||
| -rw-r--r-- | http/public/scripts/contact/post-error-message.js | 34 | ||||
| -rw-r--r-- | http/public/scripts/contact/resend-otp.js | 31 | ||||
| -rw-r--r-- | http/public/scripts/contact/reset-resend-button.js | 32 | ||||
| -rw-r--r-- | http/public/scripts/contact/selectors.js | 25 | ||||
| -rw-r--r-- | http/public/scripts/contact/submit-contact-form.js | 53 | ||||
| -rw-r--r-- | http/public/scripts/contact/submit-otp-form.js | 77 |
7 files changed, 0 insertions, 312 deletions
diff --git a/http/public/scripts/contact/actions.js b/http/public/scripts/contact/actions.js deleted file mode 100644 index 5a7e32a..0000000 --- a/http/public/scripts/contact/actions.js +++ /dev/null @@ -1,60 +0,0 @@ -export const actions = { - /** - * @param {{type: 'email', name: string, email: string}} - * @returns {Promise<void>} - */ - sendOtp: async ({ type, name, email }) => { - const url = "/do/send_otp.php"; - const req = new Request(url, { - method: "POST", - body: JSON.stringify({ type, name, email }), - }); - const res = await fetch(req); - if (!res.ok) { - throw new Error( - `Request to ${url} failed: ${res.status} ${res.statusText} ${await res.text()}`, - ); - } - }, - - /** - * @param {{guess: string, lenient?: bool, userId: string}} - * @returns {Promise<string | false>} - */ - verifyOtp: async ({ guess, lenient, userId }) => { - const url = "/do/verify_otp.php"; - const req = new Request(url, { - method: "POST", - body: JSON.stringify({ guess, lenient, userId }), - }); - const res = await fetch(req); - - if (res.status === 400) { - return false; - } else if (!res.ok) { - throw new Error( - `Request to ${url} failed: ${res.status} ${res.statusText} ${await res.text()}`, - ); - } - - return res.text(); - }, - - /** - * @param {{email: string, message: string, name: string, userId: string, token: string}} - * @returns {Promise<void>} - */ - sendEmail: async ({ email, message, name, userId, token }) => { - const url = "/do/send_email.php"; - const req = new Request(url, { - method: "POST", - body: JSON.stringify({ email, message, name, userId, token }), - }); - const res = await fetch(req); - if (!res.ok) { - throw new Error( - `Request to ${url} failed: ${res.status} ${res.statusText} ${await res.text()}`, - ); - } - }, -}; diff --git a/http/public/scripts/contact/post-error-message.js b/http/public/scripts/contact/post-error-message.js deleted file mode 100644 index 121cbb6..0000000 --- a/http/public/scripts/contact/post-error-message.js +++ /dev/null @@ -1,34 +0,0 @@ -/** @typedef {import("./selectors.js").Selectors} Selectors */ - -/** - * @param {{contactForm: Selectors}} contactForm - * @param {string} errorMsg - */ -export function postErrorMessageOnContactForm({ contactForm }, errorMsg) { - const errorElem = contactForm.errorElem(); - if (errorElem) { - errorElem.textContent = errorMsg; - errorElem.removeAttribute("hidden"); - } else { - alert(errorMsg); - } -} - -/** - * @param {{otpDialog: Selectors}} otpDialog - * @param {string} errorMsg - */ -export function postErrorMessageOnOtpForm({ otpDialog }, errorMsg) { - const errorElem = otpDialog.errorElem(); - if (errorElem) { - errorElem.textContent = errorMsg; - errorElem.removeAttribute("hidden"); - } else { - alert(errorMsg); - } - /** @type NodeListOf<HTMLInputElement> */ - const inputs = otpDialog.allOtpInputs(); - for (const input of inputs) { - input.value = ""; - } -} diff --git a/http/public/scripts/contact/resend-otp.js b/http/public/scripts/contact/resend-otp.js deleted file mode 100644 index e083d95..0000000 --- a/http/public/scripts/contact/resend-otp.js +++ /dev/null @@ -1,31 +0,0 @@ -/** @typedef {import("./selectors.js").Selectors} Selectors */ - -import { actions } from "./actions.js"; -import { resetResendButton } from "./reset-resend-button.js"; -import { postErrorMessageOnOtpForm } from "./post-error-message.js"; - -/** @typedef {{ resendButtonInterval: NodeJS.Timeout | undefined }} Result */ - -const fallbackErrorMsg = - "No can do. I'm afraid joeac.net is a bit broken right now - sorry about that."; - -/** - * @param {Selectors} selectors - * @param {NodeJS.Timeout | undefined} resetButtonInterval - * @returns {Promise<Result>} - */ -export async function resendOtp(selectors, resetButtonInterval) { - const result = resetResendButton(selectors, resetButtonInterval); - const name = selectors.contactForm.nameElem()?.value; - const email = selectors.contactForm.emailElem().value; - - try { - await actions.sendOtp({ type: "email", name, email }); - } catch (sendOtpError) { - const errorMsg = sendOtpError?.toString() ?? fallbackErrorMsg; - postErrorMessageOnOtpForm(selectors, errorMsg); - throw sendOtpError; - } - - return result; -} diff --git a/http/public/scripts/contact/reset-resend-button.js b/http/public/scripts/contact/reset-resend-button.js deleted file mode 100644 index 47bc9ac..0000000 --- a/http/public/scripts/contact/reset-resend-button.js +++ /dev/null @@ -1,32 +0,0 @@ -/** @typedef {import("./selectors.js").Selectors} Selectors */ - -/** @typedef {{ resendButtonInterval: NodeJS.Timeout | undefined }} Result */ - -/** - * @param {Selectors} selectors - * @param {NodeJS.Timeout | undefined} resetButtonInterval - * @returns {Result} - */ -export function resetResendButton({ otpDialog }, resendButtonInterval) { - clearInterval(resendButtonInterval); - - const resendButton = otpDialog.resendButton(); - if (resendButton) { - resendButton.setAttribute("data-countdown", "60"); - resendButton.setAttribute("disabled", ""); - - resendButtonInterval = setInterval(() => { - const countdown = +(resendButton.getAttribute("data-countdown") ?? 1) - 1; - resendButton.setAttribute("data-countdown", countdown.toString()); - resendButton.textContent = `Resend (${countdown}s)`; - }, 1000); - - setTimeout(() => { - clearInterval(resendButtonInterval); - resendButton.textContent = "Resend"; - resendButton.removeAttribute("disabled"); - }, 1000 * 60); - } - - return { resendButtonInterval }; -} diff --git a/http/public/scripts/contact/selectors.js b/http/public/scripts/contact/selectors.js deleted file mode 100644 index 7676414..0000000 --- a/http/public/scripts/contact/selectors.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @typedef {Object} Selectors - * @property {Object} contactForm - * @property {() => HTMLInputElement} contactForm.emailElem - * @property {() => Element | null} contactForm.errorElem - * @property {() => HTMLInputElement} contactForm.nameElem - * @property {() => HTMLTextAreaElement} contactForm.messageElem - * @property {() => HTMLFormElement | null} contactForm.self - * @property {() => HTMLInputElement | null} contactForm.submitButton - * @property {Object} otpDialog - * @property {() => NodeListOf<HTMLInputElement>} otpDialog.allOtpInputs - * @property {() => Element | null} otpDialog.errorElem - * @property {() => HTMLInputElement | null} otpDialog.firstOtpInput - * @property {() => HTMLFormElement | null} otpDialog.otpForm - * @property {() => Element | null} otpDialog.otpRecipient - * @property {() => Element | null} otpDialog.otpValidUntil - * @property {() => HTMLButtonElement | null} otpDialog.resendButton - * @property {() => HTMLDialogElement} otpDialog.self - * @property {() => HTMLInputElement | null} otpDialog.submitButton - * @property {Object} successSection - * @property {() => Element | null} successSection.email - * @property {() => Element | null} successSection.message - * @property {() => Element | null} successSection.name - * @property {() => Element | null} successSection.self - */ diff --git a/http/public/scripts/contact/submit-contact-form.js b/http/public/scripts/contact/submit-contact-form.js deleted file mode 100644 index a90f420..0000000 --- a/http/public/scripts/contact/submit-contact-form.js +++ /dev/null @@ -1,53 +0,0 @@ -import { actions } from "./actions.js"; -import { postErrorMessageOnContactForm } from "./post-error-message.js"; -import { resetResendButton } from "./reset-resend-button.js"; - -/** @typedef {import("./selectors.js").Selectors} Selectors */ - -const fallbackErrorMsg = - "No can do. I'm afraid joeac.net is a bit broken right now - sorry about that."; - -/** - * @param {Selectors} selectors - * @param {NodeJS.Timeout | undefined} resetButtonInterval - * @returns {Promise<Result>} - */ -export async function submitContactForm(selectors, resendButtonInterval) { - const { contactForm, otpDialog } = selectors; - - const name = contactForm.nameElem()?.value; - const email = contactForm.emailElem().value; - - contactForm.submitButton()?.setAttribute("disabled", ""); - try { - await actions.sendOtp({ type: "email", name, email }); - } catch (sendOtpError) { - const errorMsg = sendOtpError?.toString() ?? fallbackErrorMsg; - postErrorMessageOnContactForm(selectors, errorMsg); - throw sendOtpError; - } - - const otpRecipient = otpDialog.otpRecipient(); - email && otpRecipient && (otpRecipient.textContent = `<${email}>`); - const otpValidUntil = otpDialog.otpValidUntil(); - const validUntil = new Date(Date.now() + 1000 * 60 * 5); - otpValidUntil && - (otpValidUntil.textContent = `until ${validUntil.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`); - - const dialog = otpDialog.self(); - dialog.showModal(); - contactForm.submitButton()?.removeAttribute("disabled"); - dialog.addEventListener("click", function (event) { - const rect = dialog.getBoundingClientRect(); - const isInDialog = - rect.top <= event.clientY && - event.clientY <= rect.top + rect.height && - rect.left <= event.clientX && - event.clientX <= rect.left + rect.width; - if (!isInDialog) { - dialog.close(); - } - }); - - return resetResendButton(selectors, resendButtonInterval); -} diff --git a/http/public/scripts/contact/submit-otp-form.js b/http/public/scripts/contact/submit-otp-form.js deleted file mode 100644 index 8c09314..0000000 --- a/http/public/scripts/contact/submit-otp-form.js +++ /dev/null @@ -1,77 +0,0 @@ -import { actions } from "./actions.js"; -import { postErrorMessageOnOtpForm } from "./post-error-message.js"; - -/** @typedef {import("./selectors.js").Selectors} Selectors */ - -const fallbackErrorMsg = - "No can do. I'm afraid joeac.net is a bit broken right now - sorry about that."; - -/** - * @param {Selectors} selectors - */ -export async function submitOtpForm(selectors) { - const { contactForm, otpDialog, successSection } = selectors; - const otpForm = otpDialog.otpForm(); - otpDialog.submitButton()?.setAttribute("disabled", ""); - - const otpFormData = new FormData(otpForm ?? undefined); - const guess = [ - otpFormData.get("1"), - otpFormData.get("2"), - otpFormData.get("3"), - otpFormData.get("4"), - otpFormData.get("5"), - otpFormData.get("6"), - ].join(""); - - const name = contactForm.nameElem()?.value; - const email = contactForm.emailElem().value; - const message = contactForm.messageElem()?.value; - - let verifyResult; - try { - verifyResult = await actions.verifyOtp({ guess, userId: email }); - } catch (verifyError) { - otpDialog.submitButton()?.removeAttribute("disabled"); - postErrorMessageOnOtpForm( - selectors, - verifyError?.toString() ?? fallbackErrorMsg, - ); - return; - } - - if (verifyResult === false) { - otpDialog.submitButton()?.removeAttribute("disabled"); - postErrorMessageOnOtpForm(selectors, "Incorrect OTP. Check your email?"); - otpDialog.firstOtpInput()?.focus(); - return; - } - const sendmailToken = verifyResult; - - try { - await actions.sendEmail({ - email, - message: message, - name: name, - userId: email, - token: sendmailToken, - }); - } catch (sendEmailError) { - const errorMsg = sendEmailError?.toString() ?? fallbackErrorMsg; - postErrorMessageOnOtpForm(selectors, errorMsg); - otpDialog.submitButton()?.removeAttribute("disabled"); - return; - } - - const sentName = successSection.name(); - const sentEmail = successSection.email(); - const sentMessage = successSection.message(); - sentName && (sentName.textContent = name ?? "???"); - sentEmail && (sentEmail.textContent = email ?? "???"); - sentMessage && (sentMessage.textContent = message ?? "???"); - - contactForm.self()?.remove(); - successSection.self()?.removeAttribute("hidden"); - otpDialog.submitButton()?.removeAttribute("disabled"); - otpDialog.self().close(); -} |
