-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from deetz99/manage-nr-modal-layout
BRD -UI: Manage nr initial modal layout
- Loading branch information
Showing
15 changed files
with
540 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
177 changes: 177 additions & 0 deletions
177
business-registry-dashboard/app/components/Form/AddNameRequest/Base.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
<script setup lang="ts"> | ||
import type { MaskInputOptions } from 'maska' | ||
import { z } from 'zod' | ||
import type { FormError, FormSubmitEvent, Form } from '#ui/types' | ||
const brdModal = useBrdModals() | ||
const toast = useToast() | ||
const { t } = useI18n() | ||
const emit = defineEmits<{ | ||
showHelp: [void] | ||
nameRequestError: [void] | ||
}>() | ||
const props = defineProps<{ | ||
nrNum: string | ||
}>() | ||
const alertText = ref('') | ||
const formRef = ref<Form<NRSchema>>() | ||
const formLoading = ref(false) | ||
const state = reactive({ | ||
email: '', | ||
phone: '' | ||
}) | ||
const phoneMask: MaskInputOptions = ({ | ||
mask: '###-###-####', | ||
eager: true | ||
}) | ||
const nrSchema = z.object({ | ||
email: z.string(), | ||
phone: z.string() | ||
}) | ||
type NRSchema = z.infer<typeof nrSchema> | ||
const validate = (state: NRSchema): FormError[] => { | ||
alertText.value = '' | ||
const errors = [] | ||
const phoneValid = z.string().regex(/^\d{3}-\d{3}-\d{4}$/).safeParse(state.phone).success | ||
const emailValid = z.string().email().safeParse(state.email).success | ||
if (!state.phone && !state.email) { // show alert if both fields are empty | ||
alertText.value = t('form.manageNR.fields.alert.bothEmpty') | ||
} else if (state.phone && !state.email) { // show phone error if phone populated but invalid | ||
if (!phoneValid) { | ||
errors.push({ path: 'phone', message: t('form.manageNR.fields.phone.error.invalid') }) | ||
} | ||
} else if (!state.phone && state.email) { // show email error if email populated but invalid | ||
if (!emailValid) { | ||
errors.push({ path: 'email', message: t('form.manageNR.fields.email.error.invalid') }) | ||
} | ||
} else if (state.phone && state.email) { // show alert and error text if both fields populated and both are invalid | ||
if (!phoneValid && !emailValid) { | ||
alertText.value = t('form.manageNR.fields.alert.bothInvalid') | ||
errors.push({ path: 'phone', message: t('form.manageNR.fields.phone.error.invalid') }) | ||
errors.push({ path: 'email', message: t('form.manageNR.fields.email.error.invalid') }) | ||
} | ||
} | ||
return errors | ||
} | ||
async function onSubmit (event: FormSubmitEvent<NRSchema>) { | ||
// emit('nameRequestError') | ||
// Do something with data | ||
try { | ||
formLoading.value = true | ||
const emailValid = z.string().email().safeParse(event.data.email).success | ||
const phoneValid = z.string().regex(/^\d{3}-\d{3}-\d{4}$/).safeParse(event.data.phone).success | ||
if (phoneValid) { | ||
// make api request | ||
console.log('submitting phone: ', event.data.phone) | ||
await new Promise<void>((resolve) => { | ||
setTimeout(() => { | ||
// emit('nameRequestError') | ||
toast.add({ title: t('form.manageNR.successToast', { nrNum: props.nrNum }) }) | ||
brdModal.manageNameRequest(false) | ||
resolve() | ||
}, 500) | ||
}) | ||
} else if (emailValid) { | ||
// make api request | ||
console.log('submitting email: ', event.data.email) | ||
await new Promise<void>((resolve) => { | ||
setTimeout(() => { | ||
emit('nameRequestError') | ||
resolve() | ||
}, 500) | ||
}) | ||
} | ||
} catch (e) { | ||
emit('nameRequestError') // pass error? | ||
} finally { | ||
formLoading.value = false | ||
} | ||
} | ||
</script> | ||
<template> | ||
<UForm | ||
ref="formRef" | ||
:state | ||
:validate-on="['submit']" | ||
:validate="validate" | ||
class="space-y-4" | ||
@submit="onSubmit" | ||
@error="handleFormErrorEvent" | ||
> | ||
<fieldset> | ||
<legend class="py-4"> | ||
{{ $t('form.manageNR.legend') }} | ||
</legend> | ||
|
||
<div class="flex flex-col gap-4"> | ||
<UFormGroup | ||
name="phone" | ||
:help="$t('form.manageNR.fields.phone.help')" | ||
> | ||
<UInput | ||
v-model="state.phone" | ||
v-maska="phoneMask" | ||
:placeholder="$t('form.manageNR.fields.phone.placeholder')" | ||
:aria-label="$t('form.manageNR.fields.phone.arialabel')" | ||
variant="bcGovLg" | ||
/> | ||
</UFormGroup> | ||
|
||
<span class="font-semibold">{{ $t('words.Or') }}</span> | ||
|
||
<UFormGroup | ||
name="email" | ||
:help="$t('form.manageNR.fields.email.help')" | ||
> | ||
<UInput | ||
v-model="state.email" | ||
:placeholder="$t('form.manageNR.fields.email.placeholder')" | ||
:aria-label="$t('form.manageNR.fields.email.arialabel')" | ||
variant="bcGovLg" | ||
/> | ||
</UFormGroup> | ||
</div> | ||
</fieldset> | ||
|
||
<UAlert | ||
v-if="alertText !== ''" | ||
icon="i-mdi-alert" | ||
color="red" | ||
variant="error" | ||
:description="alertText" | ||
/> | ||
|
||
<div class="flex justify-between"> | ||
<UButton | ||
:label="$t('btn.help')" | ||
variant="ghost" | ||
icon="i-mdi-help-circle-outline" | ||
@click="$emit('showHelp')" | ||
/> | ||
|
||
<div class="flex gap-2"> | ||
<UButton | ||
:label="$t('btn.cancel')" | ||
variant="outline" | ||
@click="brdModal.manageNameRequest(false)" | ||
/> | ||
<UButton | ||
type="submit" | ||
:label="$t('form.manageNR.submitBtn')" | ||
:loading="formLoading" | ||
/> | ||
</div> | ||
</div> | ||
</UForm> | ||
</template> |
27 changes: 27 additions & 0 deletions
27
business-registry-dashboard/app/components/Form/AddNameRequest/Error.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<script setup lang="ts"> | ||
defineEmits<{ | ||
retryNameRequest: [void] | ||
}>() | ||
const brdModal = useBrdModals() | ||
</script> | ||
<template> | ||
<div class="flex flex-col items-center gap-4 text-center"> | ||
<UIcon name="i-mdi-alert-circle-outline" class="mt-10 size-8 text-red-500" /> | ||
<h2 class="text-xl font-semibold"> | ||
{{ $t('form.manageNR.error.general.heading') }} | ||
</h2> | ||
<p>{{ $t('form.manageNR.error.general.description') }}</p> | ||
<div class="flex gap-2"> | ||
<UButton | ||
:label="$t('btn.cancel')" | ||
variant="outline" | ||
@click="brdModal.manageNameRequest(false)" | ||
/> | ||
<UButton | ||
:label="$t('btn.tryAgain')" | ||
@click="$emit('retryNameRequest')" | ||
/> | ||
</div> | ||
</div> | ||
</template> |
29 changes: 29 additions & 0 deletions
29
business-registry-dashboard/app/components/Form/AddNameRequest/Help.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<script setup lang="ts"> | ||
defineEmits<{ | ||
hideHelp: [void] | ||
}>() | ||
</script> | ||
<template> | ||
<div class="flex flex-col gap-4"> | ||
<h2 class="mt-4 text-lg font-semibold"> | ||
{{ $t('form.manageNR.help.heading') }} | ||
</h2> | ||
<p>{{ $t('form.manageNR.help.description') }}</p> | ||
<ul> | ||
<li>{{ $t('contactInfo.bcRegGeneral.tollFree.title') }} <a class="text-blue-500 underline" href="tel:+1-877-370-1033">1-877-370-1033</a></li> | ||
<li>{{ $t('contactInfo.bcRegGeneral.victoriaOffice.title') }} <a class="text-blue-500 underline" href="tel:+1-250-370-1033">1-250-370-1033</a></li> | ||
<li>{{ $t('contactInfo.bcRegGeneral.email.title') }} <a class="text-blue-500 underline" href="mailto:[email protected]?subject=BC Registries and Online Services - Support Request">[email protected]</a></li> | ||
</ul> | ||
<div class="flex flex-col"> | ||
<span class="font-semibold">{{ $t('contactInfo.bcRegGeneral.hours.title') }}</span> | ||
<span>{{ $t('contactInfo.bcRegGeneral.hours.value') }}</span> | ||
</div> | ||
<UButton | ||
class="self-start" | ||
:label="$t('btn.hideHelp')" | ||
variant="ghost" | ||
icon="i-mdi-help-circle-outline" | ||
@click="$emit('hideHelp')" | ||
/> | ||
</div> | ||
</template> |
44 changes: 44 additions & 0 deletions
44
business-registry-dashboard/app/components/Form/AddNameRequest/index.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<script setup lang="ts"> | ||
import { FormAddNameRequestBase, FormAddNameRequestHelp, FormAddNameRequestError } from '#components' | ||
defineProps<{ | ||
nrNum: string | ||
}>() | ||
type Form = typeof FormAddNameRequestBase | ||
type Help = typeof FormAddNameRequestHelp | ||
type Error = typeof FormAddNameRequestError | ||
type Comp = Form | Help | Error | ||
const state: Record<string, Comp> = { | ||
FormAddNameRequestBase, | ||
FormAddNameRequestHelp, | ||
FormAddNameRequestError | ||
} | ||
const currentState = ref('FormAddNameRequestBase') | ||
</script> | ||
<template> | ||
<!-- TODO: add state for when name is already added to table --> | ||
<transition name="fade" mode="out-in"> | ||
<component | ||
:is="state[currentState]" | ||
:nr-num="nrNum" | ||
@show-help="currentState = 'FormAddNameRequestHelp'" | ||
@hide-help="currentState = 'FormAddNameRequestBase'" | ||
@retry-name-request="currentState = 'FormAddNameRequestBase'" | ||
@name-request-error="currentState = 'FormAddNameRequestError'" | ||
/> | ||
</transition> | ||
</template> | ||
<style scoped> | ||
.fade-enter-active, | ||
.fade-leave-active { | ||
transition: opacity 0.2s ease-out; | ||
} | ||
.fade-enter-from, | ||
.fade-leave-to { | ||
opacity: 0; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
business-registry-dashboard/app/components/Modal/ManageNameRequest.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<script setup lang="ts"> | ||
defineProps<{ | ||
nameRequest: { | ||
names: string[] | ||
nrNum: string | ||
} | ||
}>() | ||
</script> | ||
<template> | ||
<ModalBase | ||
:title="$t('form.manageNR.heading')" | ||
> | ||
<!-- nr info section --> | ||
<div class="-mt-4 flex flex-col gap-2"> | ||
<!-- nr names display --> | ||
<div class="flex gap-8"> | ||
<span class="font-semibold">{{ $t('form.manageNR.requestedNames', nameRequest.names.length) }}</span> | ||
<ul> | ||
<li v-for="name in nameRequest.names" :key="name"> | ||
{{ name }} | ||
</li> | ||
</ul> | ||
</div> | ||
<!-- nr number display --> | ||
<div class="flex gap-8"> | ||
<span class="font-semibold">{{ $t('form.manageNR.nrNum') }}</span> | ||
<span>{{ nameRequest.nrNum }}</span> | ||
</div> | ||
</div> | ||
<FormAddNameRequest :nr-num="nameRequest.nrNum" /> | ||
</ModalBase> | ||
</template> |
Oops, something went wrong.