website/events/static/app.js
Jimmy Vargo dae67ce653 Update Events (#10)
This update restructures the events page code and provides additional functionality.
- Overwrite old entries on re-submission of previously used emails
- Build data and stats caches on launch for use in submission checks and stats regeneration
- Update to form content
- Move stats function to separate utils file

Reviewed-on: ayo/website#10
Co-authored-by: Jimmy Vargo <james@ayo.tokyo>
Co-committed-by: Jimmy Vargo <james@ayo.tokyo>
2024-05-07 18:59:57 +09:00

113 lines
No EOL
3.5 KiB
JavaScript

const isEmailValid = (email) => {
const match = email.match(/[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+/)
return !!match?.[0] && match.index === 0 ? match?.[0] : null
}
const toggleOtherTopic = () => {
const otherInput = document.getElementById('other-text')
if (document.getElementById('topic-other')?.checked) {
otherInput.style.display = 'block'
}
else {
otherInput.style.display = 'none'
}
}
const send = () => {
const error = document.getElementById('error')
error.style.display = 'none'
const name = document.getElementById('name')
if (!name.value.trim()) {
error.style.display = 'block'
error.innerHTML = 'Please enter your name.&NewLine;名前を入力してください。'
return
}
const email = document.getElementById('email')
if (!isEmailValid(email.value)) {
error.style.display = 'block'
error.innerHTML = 'Please enter a valid email.&NewLine;有効なメールアドレスを入力してください。'
return
}
const times = [...document.querySelectorAll('[id^=time-]')]?.reduce((entries, checkbox) => {
return { ...entries, [checkbox.id]: checkbox.checked }
}, {})
if (Object.values(times).every(item => item == false)) {
error.style.display = 'block'
error.innerHTML = 'Please select at least one convenient time.&NewLine;都合の時間を一つ以上を選択してください。'
return
}
const topics = [...document.querySelectorAll('[id^=topic-]')]?.reduce((entries, checkbox) => {
return { ...entries, [checkbox.id]: checkbox.checked }
}, {})
if (Object.values(topics).every(item => item == false)) {
error.style.display = 'block'
error.innerHTML = 'Please select at least one topic of interest.&NewLine;興味あるテーマを一つ以上を選択してください。'
return
}
const background = [...document.querySelectorAll('[id^=background-]')]?.reduce((entries, checkbox) => {
return { ...entries, [checkbox.id]: checkbox.checked }
}, {})
if (Object.values(background).every(item => item == false)) {
error.style.display = 'block'
error.innerHTML = 'Please select at least one background.&NewLine;履歴・業種を一つ以上を選択してください。'
return
}
const otherText = document.getElementById('other-text')
if (topics['topic-other'] && !otherText.value.trim()) {
error.style.display = 'block'
error.innerHTML = 'Please enter your other topic of interest.&NewLine;その他の興味あるテーマを入力してください。'
return
}
const language = document.getElementById('language')
const presentationInterest = document.getElementById('presentation-interest')
const data = {
name: name.value,
email: email.value,
...times,
...topics,
...background,
'topic-other': topics['topic-other'] ? otherText.value : null,
'presentation-interest': presentationInterest.value,
'language-english': language.value == 'english' || language.value == 'either',
'language-japanese': language.value == 'japanese' || language.value == 'either',
}
fetch('/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(async response => {
return {
ok: response.ok,
status: response.status,
...await response.json()
}
})
.then(response => {
if (!response.ok) {
throw response.error || 'Bad request'
}
window.location.href = '/stats'
if (response.status >= 200 && response.status < 300) {
window.location.href = '/stats'
}
else {
throw response.error || 'Bad request'
}
})
.catch(error => {
console.error(error);
})
}