diff --git a/app/pages/index.vue b/app/pages/index.vue index 26a0909..ccf83ca 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -652,6 +652,15 @@ placeholder="Type the answer" class="w-full rounded-2xl border border-white/10 bg-[#0b1020]/40 px-4 py-3 text-sm text-white placeholder-white/40 outline-none focus:border-cyan-400" /> +
{{ waitlistCaptchaReminder }}
Check the ATC question and try again. @@ -1210,7 +1219,11 @@ const CAPTCHA_CHALLENGES: CaptchaChallenge[] = [ }, ] -const DEFAULT_CAPTCHA = CAPTCHA_CHALLENGES[0] +const DEFAULT_CAPTCHA: CaptchaChallenge = CAPTCHA_CHALLENGES[0] ?? { + id: 'fallback-vfr', + prompt: 'What does the āVā in VFR stand for?', + answers: ['visual', 'visual flight rules'], +} const createCaptchaState = () => reactive({ @@ -1237,11 +1250,11 @@ const isCaptchaAnswerValid = (state: CaptchaState) => { return state.challenge.answers.some((answer) => normaliseCaptchaValue(answer) === response) } -const pickRandomChallenge = (excludeId?: string) => { +const pickRandomChallenge = (excludeId?: string): CaptchaChallenge => { const pool = excludeId ? CAPTCHA_CHALLENGES.filter((challenge) => challenge.id !== excludeId) : CAPTCHA_CHALLENGES const available = pool.length ? pool : CAPTCHA_CHALLENGES const index = Math.floor(Math.random() * available.length) - return available[index] + return available[index] ?? DEFAULT_CAPTCHA } const rotateCaptchaChallenge = (state: CaptchaState) => { @@ -1250,6 +1263,14 @@ const rotateCaptchaChallenge = (state: CaptchaState) => { state.answer = '' } +const cycleCaptchaChallenge = (state: CaptchaState) => { + const currentIndex = CAPTCHA_CHALLENGES.findIndex((challenge) => challenge.id === state.challenge?.id) + const normalizedIndex = currentIndex >= 0 ? currentIndex : 0 + const nextIndex = (normalizedIndex + 1) % CAPTCHA_CHALLENGES.length + state.challenge = CAPTCHA_CHALLENGES[nextIndex] ?? DEFAULT_CAPTCHA + state.answer = '' +} + const numberFormatter = computed(() => new Intl.NumberFormat('en-US')) const formatNumber = (value: number | null | undefined) => numberFormatter.value.format(Math.max(0, Math.round(value ?? 0))) @@ -1295,6 +1316,11 @@ const waitlistLastJoinedFormatted = computed(() => { }) const waitlistCaptchaValid = computed(() => isCaptchaAnswerValid(waitlistCaptcha)) +const tryDifferentWaitlistCaptcha = () => { + cycleCaptchaChallenge(waitlistCaptcha) + waitlistCaptchaReminder.value = '' +} + watch( () => waitlistForm.email, (value) => {