feat: complete email verification flow

This commit is contained in:
Florian Sylvain
2024-05-15 19:16:55 +02:00
parent aabdbfae95
commit a35e7c4283
13 changed files with 228 additions and 124 deletions
@@ -12,12 +12,12 @@
</head>
<body class="d-flex min-vh-100 vw-100 justify-content-center align-items-center text-dark">
<div class="container">
<div class="d-flex flex-column gap-5 m-auto form-container">
<div class="d-flex flex-column m-auto form-container">
<div>
<h1>GohCMS</h1>
<h2>Login</h2>
</div>
<form action="login" method="POST">
<form action="login" method="POST" class="mt-5" id="loginForm">
<div class="d-flex flex-column gap-4">
<div class="form-floating">
<input class="form-control {{ if .PageError.IsError }} is-invalid {{ end }}"
@@ -46,12 +46,18 @@
</button>
</div>
</form>
<form action="register" method="get" class="mt-2 w-100">
<button class="btn btn-outline-primary w-100" type="submit">
Don't have any verified account? Register here.
</button>
</form>
</div>
</div>
<script>
const button = document.querySelector("#loginFormButton")
const inputs = document.querySelectorAll('input')
const form = document.querySelector("#loginForm")
function formFieldsEmpty() {
return Array.from(inputs).some((input) => input.value === "")
@@ -77,7 +83,7 @@
if (event.target.tagName === "INPUT") setButtonDisabled()
}
window.addEventListener('submit', onLoginFormSubmit)
form.addEventListener('submit', onLoginFormSubmit)
window.addEventListener('input', onInput)
setButtonDisabled()
</script>
@@ -1,81 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>GohCMS | Setup</title>
{{.Head}}
<title>GohCMS | Setup</title>
{{.Head}}
<style>
<style>
.form-container {
max-width: 24rem;
}
</style>
</style>
</head>
<body class="d-flex min-vh-100 vw-100 justify-content-center align-items-center text-dark">
<div class="container">
<div class="d-flex flex-column gap-5 m-auto form-container">
<div>
<h1>GohCMS</h1>
<h2>Admin account creation</h2>
</div>
<form action="register" class="" method="POST">
<div class="d-flex flex-column gap-4">
<div class="form-floating">
<input class="form-control {{ if .PageError.IsError }} is-invalid {{ end }}"
id="email"
name="email"
placeholder="E-mail"
required
type="email"
value="{{.Email}}"
onblur="validateEmail()">
<label for="email">E-mail</label>
<div class="invalid-feedback">The e-mail must be a valid e-mail.</div>
</div>
<div class="form-floating">
<input class="form-control {{ if .PageError.IsError }} is-invalid {{ end }}"
id="username"
name="username"
placeholder="Username"
required
type="text"
value="{{.Username}}">
<label for="username">Username</label>
<div class="invalid-feedback">The username must be between 3 and 20 characters long.</div>
</div>
<div class="form-floating">
<input class="form-control {{ if .PageError.IsError }} is-invalid {{ end }}"
id="password"
name="password"
placeholder="Password"
required
type="password">
<label for="password">Password</label>
<div class="invalid-feedback">The password must contain at least 8 characters.</div>
</div>
<div class="form-floating">
<input class="form-control {{ if .PageError.IsError }} is-invalid {{ end }}"
id="confirmPassword"
name="confirmPassword"
placeholder="Password confirmation"
required
type="password"
onblur="validatePasswordMatch()"
oninput="validatePasswordMatch()">
<label for="confirmPassword">Password confirmation</label>
<div class="invalid-feedback">The passwords do not match.</div>
</div>
<button id="registerFormButton" class="btn btn-primary" disabled type="submit">
<div class="d-flex flex-column m-auto form-container">
<div>
<h1>GohCMS</h1>
<h2>Admin account creation</h2>
</div>
<form action="register" method="POST" class="mt-5" id="registerForm">
<div class="d-flex flex-column gap-4">
<div class="form-floating">
<input class="form-control {{ if .PageError.Email }} is-invalid {{ end }}"
id="email"
name="email"
placeholder="E-mail"
required
type="email"
value="{{.Email}}"
onblur="validateEmail()">
<label for="email">E-mail</label>
<div class="invalid-feedback">The e-mail must be a valid e-mail and not already in use.</div>
</div>
<div class="form-floating">
<input class="form-control {{ if .PageError.Username }} is-invalid {{ end }}"
id="username"
name="username"
placeholder="Username"
required
type="text"
value="{{.Username}}">
<label for="username">Username</label>
<div class="invalid-feedback">The username must be between 3 and 20 characters long.</div>
</div>
<div class="form-floating">
<input class="form-control {{ if .PageError.Password }} is-invalid {{ end }}"
id="password"
name="password"
placeholder="Password"
required
type="password">
<label for="password">Password</label>
<div class="invalid-feedback">The password must contain at least 8 characters.</div>
</div>
<div class="form-floating">
<input class="form-control {{ if .PageError.Password }} is-invalid {{ end }}"
id="confirmPassword"
name="confirmPassword"
placeholder="Password confirmation"
required
type="password"
onblur="validatePasswordMatch()"
oninput="validatePasswordMatch()">
<label for="confirmPassword">Password confirmation</label>
<div class="invalid-feedback">The passwords do not match.</div>
</div>
<button id="registerFormButton" class="btn btn-primary" disabled type="submit">
<span class="registerFormButtonLoading visually-hidden spinner-border spinner-border-sm"
role="status"></span>
<span class="registerFormButtonDefault">Next</span>
</button>
</div>
</form>
</div>
role="status"></span>
<span class="registerFormButtonDefault">Next</span>
</button>
</div>
</form>
<form action="login" method="get" class="mt-2 w-100">
<button class="btn btn-outline-primary w-100" type="submit">
Already registered? Log in!
</button>
</form>
</div>
</div>
<script>
const docElems = {
form: document.querySelector("#registerForm"),
button: document.querySelector("#registerFormButton"),
inputs: document.querySelectorAll("input"),
email: document.querySelector("#email"),
@@ -88,8 +94,8 @@
}
function isFormValid() {
return !formSomeFieldsEmpty() && validateEmail() && validatePasswordMatch()
}
return !formSomeFieldsEmpty() && validateEmail() && validatePasswordMatch()
}
function setButtonLoading() {
docElems.button.classList.add("disabled")
@@ -106,7 +112,7 @@
function onInput(event) {
if (event.target.tagName === "INPUT") {
docElems.button.disabled = !isFormValid()
docElems.button.disabled = !isFormValid()
}
}
@@ -133,7 +139,7 @@
}
}
window.addEventListener('submit', onRegisterFormSubmit)
docElems.form.addEventListener('submit', onRegisterFormSubmit)
window.addEventListener('input', onInput)
</script>
@@ -1,32 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>GohCMS | Setup</title>
{{.Head}}
<title>GohCMS | Setup</title>
{{.Head}}
<style>
<style>
.form-container {
max-width: 24rem;
}
</style>
</style>
</head>
<body class="d-flex min-vh-100 vw-100 justify-content-center align-items-center text-dark">
<div class="container">
<div class="d-flex flex-column gap-5 m-auto form-container">
<div>
<h1>GohCMS</h1>
<h2>Verify your email</h2>
</div>
<p>An e-mail with the validation link was sent to the address you just registered.</p>
<button id="finalSetupFormButton" class="btn btn-outline-primary" type="button">
<span class="finalSetupFormButtonLoading visually-hidden spinner-border spinner-border-sm"
role="status"></span>
<span class="finalSetupFormButtonDefault">Cancel</span>
</button>
</div>
<div class="d-flex flex-column m-auto form-container">
<div>
<h1>GohCMS</h1>
<h2>Verify your email</h2>
</div>
<p>An e-mail with the validation link was sent to the address you just registered.</p>
<p>If you misspelled the address or just didn't receive any e-mails, please check your spams or cancel the
account creation.</p>
<form action="" method="post" class="d-flex">
<button class="btn btn-outline-primary w-100" type="submit">
<span class="visually-hidden spinner-border spinner-border-sm"
role="status"></span>
<span>Cancel</span>
</button>
</form>
</div>
</div>
<script>
const button = document.querySelector("button")
function setButtonLoading() {
button.classList.add("disabled")
button.querySelector("button > span + span").classList.add("visually-hidden")
button.querySelector("button > span:first-child").classList.remove("visually-hidden")
}
window.addEventListener('submit', setButtonLoading)
button.addEventListener('click', setButtonLoading)
</script>
</body>
@@ -41,12 +41,8 @@
button.querySelector("button > span:first-child").classList.remove("visually-hidden")
}
function onSubmit(event) {
setButtonLoading()
}
window.addEventListener('submit', onSubmit)
button.addEventListener('click', onSubmit)
window.addEventListener('submit', setButtonLoading)
button.addEventListener('click', setButtonLoading)
</script>
</body>