Skip to content

Commit

Permalink
Platform - UI: UAT updates (#361)
Browse files Browse the repository at this point in the history
* fix stepper scrolling

* redirect on 401 error

* prevent multiple applications middleware

* add override option to middleware

* generic error page

* update href

* update info collection notice modal content for platforms

* platforms text update

* update stepper to match figma styling

* hide overflow on stepper

* updates from pr comments
  • Loading branch information
deetz99 authored Dec 9, 2024
1 parent 14e40f2 commit 7522dc7
Show file tree
Hide file tree
Showing 20 changed files with 186 additions and 30 deletions.
73 changes: 52 additions & 21 deletions strr-base-web/app/components/connect/Stepper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ const activeStepIndexModel = defineModel<number>('activeStepIndex', { default: 0
const activeStepModel = defineModel<Step>('activeStep', { default: () => {} })
const buttonRefs = ref<HTMLButtonElement[]>([])
const stepperOlRef = ref<HTMLOListElement | null>(null)
const stepImageRefs = ref<HTMLDivElement[] | null>(null)
const separatorPosition = ref<{ top: string, left: string, width: string }>({ top: '0px', left: '0px', width: '0px' })
const activeBorderPosition = ref<{ left: string, width: string }>({ left: '0px', width: '0px' })
const stepperVisible = useElementVisibility(stepperOlRef)
async function setActiveStep (newStep: number) {
activeStepModel.value.complete = true // set currently active step to complete
Expand Down Expand Up @@ -70,9 +75,35 @@ function createStepAriaLabel (index: number) {
return `${stepCount} ${label}, ${validity}`
}
function updateActiveBorderPosition () {
if (stepperOlRef.value) {
activeBorderPosition.value = {
left: `${(stepperOlRef.value.offsetWidth / stepsModel.value.length) * activeStepIndexModel.value}px`,
width: `${stepperOlRef.value.offsetWidth / stepsModel.value.length}px`
}
}
}
watch(activeStepIndexModel, (newIndex) => {
buttonRefs.value[newIndex]?.focus()
window.scrollTo({ top: 0, behavior: 'smooth' })
if (!stepperVisible.value) { // only scroll if stepper outside of viewport
stepperOlRef.value?.scrollIntoView(true) // aligns top of stepper container to top of viewport
}
updateActiveBorderPosition()
})
// update separator position as stepper size changes
useResizeObserver(stepperOlRef, () => {
if (stepImageRefs.value && stepImageRefs.value[0] && buttonRefs.value && buttonRefs.value[0]) {
separatorPosition.value = {
top: `${stepImageRefs.value[0].offsetHeight / 2}px`,
left: `${buttonRefs.value[0].offsetWidth / 2}px`,
width: `${buttonRefs.value[0].offsetWidth * 3}px`
}
}
updateActiveBorderPosition()
})
defineExpose({ setActiveStep, setNextStep, setPreviousStep, setStepValidity, buttonRefs })
Expand All @@ -85,29 +116,38 @@ onMounted(() => {
</script>
<template>
<ol
ref="stepperOlRef"
:aria-label="stepperLabel"
class="
flex w-full flex-row justify-between
rounded-[4px] bg-transparent px-0 pt-0
sm:bg-white sm:px-5 sm:pt-5
"
class="relative flex w-full flex-row justify-between overflow-hidden rounded-[4px] bg-transparent sm:bg-white"
data-testid="stepper"
>
<div
class="absolute z-[1] w-full -translate-y-1/2 border-[0.5px] border-bcGovGray-500"
:style="separatorPosition"
/>

<div
class="absolute bottom-0 hidden h-[3px] bg-blue-500
transition-all duration-300 motion-reduce:transition-none sm:block"
:style="activeBorderPosition"
/>

<li
v-for="(step, index) in stepsModel"
:key="'step' + index"
class="flex flex-row"
:class="index == stepsModel.length - 1 ? 'shrink grow-0': 'shrink-0 grow'"
class="z-[2] w-full grow"
>
<button
ref="buttonRefs"
class="flex cursor-pointer flex-col items-center border-b-0 border-blue-500 pb-5"
:class="index === activeStepIndexModel ? 'sm:border-b-[3px]' : ''"
class="mx-auto flex w-full cursor-pointer flex-col items-center"
:aria-label="createStepAriaLabel(index)"
:aria-current="index === activeStepIndexModel ? 'step' : undefined"
@click="setActiveStep(index)"
>
<div class="flex justify-center pt-2 ">
<div
ref="stepImageRefs"
class="flex justify-center bg-gray-100 p-4 pt-5 sm:bg-white"
>
<div
class="
relative size-8 rounded-full p-[5px]
Expand Down Expand Up @@ -141,21 +181,12 @@ onMounted(() => {
</div>
</div>
<p
class="
mt-2 hidden max-w-[95px] text-center
text-[14px] leading-5 sm:block
"
class="hidden w-full px-2 pb-4 text-center text-sm leading-5 sm:block"
:class="index === activeStepIndexModel ? 'font-bold text-black' : 'text-blue-500'"
>
{{ step.label ? $t(step.label) : $t(`${step.i18nPrefix}.description.${index}`) }}
</p>
</button>
<div
v-if="index < stepsModel.length - 1"
class="mb-2 shrink-0 grow self-center sm:mb-10 md:mb-10"
>
<div class="h-px bg-gray-600" />
</div>
</li>
</ol>
<div v-if="stepsModel[activeStepIndexModel]?.i18nPrefix" class="space-y-5 py-5">
Expand Down
4 changes: 2 additions & 2 deletions strr-base-web/app/components/modal/help/RegisterStr.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
<i18n-t keypath="modal.help.registerStr.content" tag="p" scope="global">
<template #link>
<a
href="https://www.STRregistry.gov.bc.ca"
:href="useRuntimeConfig().public.bcGovStrrUrl"
target="_blank"
class="text-bcGovColor-activeBlue underline"
>
STRregistry.gov.bc.ca
www.gov.bc.ca/STRRegistry
</a>
</template>
</i18n-t>
Expand Down
38 changes: 38 additions & 0 deletions strr-base-web/app/error.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script setup lang="ts">
import type { NuxtError } from '#app'
const { t } = useI18n()
const localePath = useLocalePath()
const props = defineProps({
error: { type: Object as () => NuxtError, default: undefined }
})
// TODO: update with other error codes?
const errorKey: string | number = props.error?.statusCode === 404 ? 404 : 'unknown'
// cant use definePageMeta in error.vue
useRoute().meta.hideBreadcrumbs = true
useHead({
title: errorKey === 404 ? t('page.error.404.title') : t('page.error.unknown.title')
})
</script>

<template>
<NuxtLayout>
<div class="m-auto flex flex-col items-center gap-4">
<h1>
{{ $t(`page.error.${errorKey}.h1`) }}
</h1>
<p>{{ $t(`page.error.${errorKey}.content`) }}</p>
<UButton
:label="$t('btn.goHome')"
icon="i-mdi-home"
size="bcGov"
:to="localePath('/')"
/>
</div>
</NuxtLayout>
</template>
12 changes: 12 additions & 0 deletions strr-base-web/app/locales/en-CA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,18 @@ export default {
Invalid: 'Invalid'
},
page: {
error: {
404: {
title: 'Page Not Found - Short-Term Rental Registry',
h1: '404 Page Not Found',
content: 'This page could not be found or does not exist.'
},
unknown: {
title: 'Unknown Error - Short-Term Rental Registry',
h1: 'Unknown Error',
content: 'An unknown error occured, please refresh the page or try again later.'
}
},
notFound: {
h1: 'Page Not Found'
},
Expand Down
6 changes: 6 additions & 0 deletions strr-base-web/app/plugins/pay-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export default defineNuxtPlugin(() => {
const payApiUrl = useRuntimeConfig().public.payApiURL
const { $keycloak } = useNuxtApp()
const localePath = useLocalePath()

const api = $fetch.create({
baseURL: payApiUrl,
Expand All @@ -13,6 +14,11 @@ export default defineNuxtPlugin(() => {
} else {
headers.Authorization = `Bearer ${$keycloak.token}`
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await navigateTo(localePath('/auth/login'))
}
}
})

Expand Down
6 changes: 6 additions & 0 deletions strr-base-web/app/plugins/strr-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export default defineNuxtPlugin(() => {
const strrApiUrl = useRuntimeConfig().public.strrApiURL
const accountStore = useConnectAccountStore()
const localePath = useLocalePath()

const { $keycloak } = useNuxtApp()

Expand All @@ -18,6 +19,11 @@ export default defineNuxtPlugin(() => {
headers.Authorization = `Bearer ${$keycloak.token}`
headers['Account-Id'] = accountStore.currentAccount.id
}
},
async onResponseError ({ response }) {
if (response.status === 401) {
await navigateTo(localePath('/auth/login'))
}
}
})

Expand Down
3 changes: 2 additions & 1 deletion strr-base-web/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ export default defineNuxtConfig({
version: `STRR Base UI v${process.env.npm_package_version}`,
housingStrrUrl: process.env.NUXT_REGISTRY_HOME_URL, // TODO: update to NUXT_HOUSING_STRR_URL once we get the housing strr url set
// TODO: move to app config for core layer ?
declineTosRedirectUrl: process.env.NUXT_REGISTRY_HOME_URL // TODO: update to NUXT_HOUSING_STRR_URL once we get the housing strr url set,
declineTosRedirectUrl: process.env.NUXT_REGISTRY_HOME_URL, // TODO: update to NUXT_HOUSING_STRR_URL once we get the housing strr url set,
bcGovStrrUrl: process.env.NUXT_BCGOV_STRR_URL
// set by layer - still required in .env
// keycloakAuthUrl - NUXT_KEYCLOAK_AUTH_URL
// keycloakClientId - NUXT_KEYCLOAK_CLIENTID
Expand Down
1 change: 1 addition & 0 deletions strr-host-pm-web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ NUXT_HOUSING_ALL_RULES_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/s
NUXT_HOUSING_REQUIRED_DOCS_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals"
NUXT_HOUSING_PROOF_OF_PR_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/host-registration#documents"
NUXT_HOST_TAC_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/registry-toc-hosts"
NUXT_BCGOV_STRR_URL="https://www.gov.bc.ca/STRRegistry"

#vaults keycloak
NUXT_KEYCLOAK_AUTH_URL="https://dev.loginproxy.gov.bc.ca/auth"
Expand Down
1 change: 1 addition & 0 deletions strr-host-pm-web/devops/vaults.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ NUXT_HOUSING_ALL_RULES_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/s
NUXT_HOUSING_REQUIRED_DOCS_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals"
NUXT_HOUSING_PROOF_OF_PR_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/host-registration#documents"
NUXT_HOST_TAC_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/registry-toc-hosts"
NUXT_BCGOV_STRR_URL="https://www.gov.bc.ca/STRRegistry"
NUXT_HOST_ACC_ACT_SUMMARY="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/short-term-rental-legislation#act"

# vaults api
Expand Down
1 change: 1 addition & 0 deletions strr-platform-web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NUXT_AUTH_WEB_URL="https://dev.account.bcregistry.gov.bc.ca/"
NUXT_BASE_URL="http://localhost:3000/" # app base url
NUXT_HOUSING_STRR_URL="" # TODO: add housing strr base url here for redirects
NUXT_PLATFORMS_TAC_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/registry-toc-platforms"
NUXT_BCGOV_STRR_URL="https://www.gov.bc.ca/STRRegistry"

#vaults keycloak
NUXT_KEYCLOAK_AUTH_URL="https://dev.loginproxy.gov.bc.ca/auth"
Expand Down
2 changes: 1 addition & 1 deletion strr-platform-web/app/components/form/platform/Details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ onMounted(async () => {
>
<template #legend>
<span class="sr-only">{{ $t('validation.required') }}</span>
<span>{{ $t('strr.text.listingSize', { year: new Date().getFullYear() - 1 }) }}</span>
<span>{{ $t('strr.text.listingSize') }}</span>
</template>
</URadioGroup>
</UFormGroup>
Expand Down
25 changes: 25 additions & 0 deletions strr-platform-web/app/components/modal/info/CollectionNotice.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<ModalBase :title="$t('modal.info.collectionNotice.title')">
<div class="space-y-8">
<i18n-t keypath="modal.info.collectionNotice.content" tag="p" scope="global">
<template #straAct>
<em class="italic">{{ $t('act.strrAccomodations') }}</em>
</template>

<template #fippaAct>
<em class="italic">{{ $t('act.fippa') }}</em>
</template>

<template #email>
<a
class="text-blue-500 underline"
href="mailto:[email protected]"
target="_blank"
>
[email protected]
</a>
</template>
</i18n-t>
</div>
</ModalBase>
</template>
16 changes: 14 additions & 2 deletions strr-platform-web/app/locales/en-CA.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
/* eslint-disable max-len */
export default {
act: {
fippa: 'Freedom of Information and Protection of Privacy Act'
},
feeSummary: {
itemLabels: {
PLATREG_SM: 'Platform Application Fee',
PLATREG_LG: 'Platform Application Fee',
PLATREG_WV: 'Platform Application Fee'
}
},
modal: {
info: {
collectionNotice: {
triggerBtn: 'Information collection notice',
title: 'Information Collection Notice',
content: 'This personal information is being collected by the Ministry of Housing and Municipal Affairs under s. 33(1) of the {straAct} and s. 33(2)(e) of the {fippaAct} for the purpose of registering a platform service provider. If you have any questions about the collection of this personal information, please contact the Executive Director of the Short-Term Rental Branch, at {email}'
}
}
},
strr: {
title: {
application: 'Short-Term Rental Platform Service Provider Application'
Expand Down Expand Up @@ -80,9 +92,9 @@ export default {
brandNames: 'If your platform operates under distinct brand names, please enter each of them here.',
brandNames2: 'If the business provides the same listings on multiple websites with different brand names, provide those as well. ',
brandNamesNote: 'NOTE: if the listings are different, each brand should be a separate registration',
hasCpbc: 'Does the business have an active number with Consumer Protection BC (CPBC)?',
hasCpbc: 'Is the business licensed as a travel wholesaler under Consumer Protection BC (CPBC)?',
isUserRep: 'Are you the platform service provider representative? ',
listingSize: 'What is the total number of listings offered by the Platform Service Provider across all platforms on June 1, {year}?',
listingSize: 'What is the total number of listings offered by the Platform Service Provider across all platforms as of today’s date?',
nonComplianceEmail: 'Provide an email address to receive Notices of Non-Compliance.',
nonComplianceEmailLong: 'This message will be sent to the supplier host and platform service provider by a local government to inform both parties that a listing is not compliant with a local government business licence requirement. No action is required from the platform service provider.',
primaryContact: 'This is the primary contact person for the platform service provider.',
Expand Down
15 changes: 15 additions & 0 deletions strr-platform-web/app/middleware/application-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default defineNuxtRouteMiddleware(async (to) => {
const localePath = useLocalePath()
const { application, loadPermitData } = useStrrBasePermit()

// TODO: update with unique code check for renewals?
if (to.query.override === 'true') {
return
}

await loadPermitData(undefined, ApplicationType.PLATFORM)

if (application.value !== undefined) {
return navigateTo(localePath('/platform/dashboard'))
}
})
2 changes: 1 addition & 1 deletion strr-platform-web/app/pages/platform/application.vue
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ useHead({
definePageMeta({
layout: 'connect-form',
path: '/platform/application',
middleware: ['auth', 'check-tos', 'require-premium-account']
middleware: ['auth', 'check-tos', 'require-premium-account', 'application-page']
})
setBreadcrumbs([
Expand Down
3 changes: 3 additions & 0 deletions strr-platform-web/devops/vaults.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ NUXT_REGISTRY_HOME_URL="op://web-url/$APP_ENV/registry/REGISTRY_HOME_URL"
NUXT_PAYMENT_PORTAL_URL="op://web-url/$APP_ENV/pay/PAYMENT_PORTAL_URL"
NUXT_AUTH_WEB_URL="op://web-url/$APP_ENV/auth-web/AUTH_WEB_URL"
NUXT_BASE_URL="op://web-url/$APP_ENV/strr/STRR_PLATFORM_URL"
NUXT_HOUSING_STRR_URL="" # TODO: add housing strr base url here for redirects
NUXT_PLATFORMS_TAC_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/registry-toc-platforms"
NUXT_BCGOV_STRR_URL="https://www.gov.bc.ca/STRRegistry"

# vaults api
NUXT_PAY_API_URL="op://API/$APP_ENV/pay-api/PAY_API_URL"
Expand Down
2 changes: 1 addition & 1 deletion strr-platform-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "strr-platform-web",
"private": true,
"type": "module",
"version": "0.0.13",
"version": "0.0.14",
"scripts": {
"build-check": "nuxt build",
"build": "nuxt generate",
Expand Down
2 changes: 2 additions & 0 deletions strr-strata-web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ NUXT_REGISTRY_HOME_URL="https://dev.bcregistry.gov.bc.ca/"
NUXT_PAYMENT_PORTAL_URL="https://dev.account.bcregistry.gov.bc.ca/makepayment/"
NUXT_AUTH_WEB_URL="https://dev.account.bcregistry.gov.bc.ca/"
NUXT_BASE_URL="http://localhost:3000/" # app base url
NUXT_HOUSING_STRR_URL="" # TODO: add housing strr base url here for redirects
NUXT_STRATA_TAC_URL="https://www2.gov.bc.ca/gov/content/housing-tenancy/short-term-rentals/registry/registry-toc-strataplatforms"
NUXT_BCGOV_STRR_URL="https://www.gov.bc.ca/STRRegistry"

#vaults keycloak
NUXT_KEYCLOAK_AUTH_URL="https://dev.loginproxy.gov.bc.ca/auth"
Expand Down
Loading

0 comments on commit 7522dc7

Please sign in to comment.