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>
113 lines
No EOL
3.5 KiB
JavaScript
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.
名前を入力してください。'
|
|
return
|
|
}
|
|
|
|
const email = document.getElementById('email')
|
|
if (!isEmailValid(email.value)) {
|
|
error.style.display = 'block'
|
|
error.innerHTML = 'Please enter a valid email.
有効なメールアドレスを入力してください。'
|
|
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.
都合の時間を一つ以上を選択してください。'
|
|
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.
興味あるテーマを一つ以上を選択してください。'
|
|
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.
履歴・業種を一つ以上を選択してください。'
|
|
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.
その他の興味あるテーマを入力してください。'
|
|
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);
|
|
})
|
|
} |