begin
This commit is contained in:
63
ui/_/code/components/EmailJoinForm.js
Normal file
63
ui/_/code/components/EmailJoinForm.js
Normal file
@@ -0,0 +1,63 @@
|
||||
css(`
|
||||
email-join-form {
|
||||
display: flex
|
||||
}
|
||||
`)
|
||||
|
||||
export default class EmailJoinForm extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.querySelector('#submit-button').addEventListener('click', () => this.submitEmail());
|
||||
}
|
||||
|
||||
isValidEmail(email) {
|
||||
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,16}$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
|
||||
showError(message) {
|
||||
$(this).find('#form-message')
|
||||
.css('color', 'red')
|
||||
.text(message);
|
||||
}
|
||||
|
||||
showSuccess(message) {
|
||||
$(this).find('#form-message')
|
||||
.css('color', 'green')
|
||||
.text(message);
|
||||
}
|
||||
|
||||
clearError() {
|
||||
this.querySelector('#form-message').textContent = '';
|
||||
}
|
||||
|
||||
async submitEmail() {
|
||||
const email = this.querySelector('#email-input').value.trim();
|
||||
this.clearError();
|
||||
|
||||
if (!this.isValidEmail(email)) {
|
||||
this.showError('Please enter a valid email address.');
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await fetch('/api/join', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ email }),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
this.showSuccess('Email sent.');
|
||||
} else {
|
||||
const error = await res.text();
|
||||
this.showError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("email-join-form", EmailJoinForm);
|
||||
48
ui/_/code/shared.css
Normal file
48
ui/_/code/shared.css
Normal file
@@ -0,0 +1,48 @@
|
||||
:root {
|
||||
--green: #0B5538;
|
||||
--tan: #FFDFB4;
|
||||
--red: rgb(206, 84, 61);
|
||||
--brown: #c6a476
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Canterbury';
|
||||
src: url('/_/fonts/Canterbury/Canterbury.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'CrimsonText';
|
||||
src: url('/_/fonts/CrimsonText/CrimsonText-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'CrimsonText';
|
||||
src: url('/_/fonts/CrimsonText/CrimsonText-Bold.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'CrimsonText', sans-serif;
|
||||
background-color: var(--tan);
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--green);
|
||||
transition: background .2s, padding .2s, color .2s;
|
||||
padding: 4px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var(--green);
|
||||
color: var(--tan);
|
||||
padding: 1em;
|
||||
box-shadow: none;
|
||||
}
|
||||
41
ui/_/code/util.js
Normal file
41
ui/_/code/util.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user