11<script setup lang="ts">
2- import { ref , onMounted , useTemplateRef } from ' vue' ;
2+ import { ref , onMounted , useTemplateRef , nextTick } from ' vue' ;
33import { useI18n } from ' vue-i18n' ;
4+ import { useDebounceFn } from ' @vueuse/core' ;
45import { NoticeBar , TextInput , TextArea , SelectInput , PrimaryButton , NoticeBarTypes , CheckboxInput , LoadingSkeleton } from ' @thunderbirdops/services-ui' ;
56import CsrfToken from ' @/components/forms/CsrfToken.vue' ;
67import NativeInputWrapper from ' ./NativeInputWrapper.vue' ;
8+ import { isEmailInAllowList } from ' ../api' ;
79
810// Types
911import { ContactFieldsAPIResponse , TicketField } from ' ../types' ;
@@ -30,14 +32,16 @@ const { t } = useI18n();
3032
3133const csrfTokenVal = ref (window ._page .csrfToken );
3234const errorText = ref (window ._page .formError );
35+ const userEmailInAllowList = ref (true );
3336const successText = ref (' ' );
3437const isSubmitting = ref (false );
38+ const tbProWaitListUrl = window ._page ?.tbProWaitListUrl ;
3539const form = ref ({
3640 email: window ._page ?.userEmail || ' ' ,
3741 name: window ._page ?.userFullName || ' ' ,
3842 attachments: [],
3943});
40- const formRef = ref (null );
44+ const formRef = ref < HTMLFormElement | null > (null );
4145const fileInput = ref (null );
4246const isLoadingFormFields = ref (true );
4347
@@ -144,9 +148,26 @@ const resetForm = () => {
144148 formRef .value .reset ();
145149};
146150
151+ const checkEmailInAllowList = useDebounceFn (async () => {
152+ await nextTick ();
153+
154+ const emailField = formRef .value ?.elements .namedItem (' email' ) as HTMLInputElement | null ;
155+
156+ if (emailField ?.checkValidity ()) {
157+ const { is_on_allow_list } = await isEmailInAllowList (emailField .value .trim ());
158+ userEmailInAllowList .value = is_on_allow_list ;
159+ }
160+ }, 250 );
161+
147162const handleSubmit = async () => {
148163 if (isSubmitting .value ) return ;
149164
165+ await checkEmailInAllowList ();
166+
167+ if (! userEmailInAllowList .value ) {
168+ return ;
169+ }
170+
150171 errorText .value = ' ' ;
151172 successText .value = ' ' ;
152173
@@ -224,11 +245,27 @@ onMounted(() => {
224245<template >
225246 <notice-bar :type =" NoticeBarTypes.Critical" v-if =" errorText" class =" notice" >{{ errorText }}</notice-bar >
226247 <notice-bar :type =" NoticeBarTypes.Success" v-if =" successText" class =" notice" >{{ successText }}</notice-bar >
248+ <notice-bar :type =" NoticeBarTypes.Warning" v-if =" !userEmailInAllowList" class =" notice" >
249+ <i18n-t keypath =" views.contact.emailNotOnAllowList" tag =" span" >
250+ <template #joinWaitlist >
251+ <a :href =" tbProWaitListUrl" target =" _blank" >
252+ {{ t('views.contact.joinWaitlist') }}
253+ </a >
254+ </template >
255+ </i18n-t >
256+ </notice-bar >
227257
228258 <form @submit.prevent =" handleSubmit" method =" post" action =" /contact/submit" ref =" formRef" >
229259 <!-- Email (always present) -->
230- <text-input ref =" emailInput" name =" email" type =" email" v-model =" form.email" :required =" true"
231- data-testid =" contact-email-input" >
260+ <text-input
261+ ref =" emailInput"
262+ name =" email"
263+ type =" email"
264+ v-model =" form.email"
265+ :required =" true"
266+ data-testid =" contact-email-input"
267+ @input =" checkEmailInAllowList"
268+ >
232269 {{ t('views.contact.emailAddressLabel') }}
233270 </text-input >
234271
@@ -287,7 +324,11 @@ onMounted(() => {
287324 </ul >
288325
289326 <div class =" form-group" >
290- <primary-button @click.capture =" handleSubmit" data-testid =" contact-submit-btn" :disabled =" isSubmitting" >
327+ <primary-button
328+ @click.capture =" handleSubmit"
329+ data-testid =" contact-submit-btn"
330+ :disabled =" isSubmitting"
331+ >
291332 {{ isSubmitting ? t('views.contact.submitting') : t('views.contact.submit') }}
292333 </primary-button >
293334 </div >
@@ -385,6 +426,10 @@ form {
385426
386427.notice {
387428 margin-block : 1rem ;
429+
430+ a {
431+ color : var (--colour-ti-highlight );
432+ }
388433}
389434
390435.attachment-list {
0 commit comments