Skip to content

Commit

Permalink
Merge pull request #451 from dimak1/feat/examiner-details-host
Browse files Browse the repository at this point in the history
Update Host Details Page
  • Loading branch information
dimak1 authored Jan 13, 2025
2 parents 52f292a + d31ff16 commit 5cfa7b4
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 178 deletions.
7 changes: 5 additions & 2 deletions strr-base-web/app/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,19 @@ export function dateToStringPacific (date: Date | string, format = 'y-MM-dd') {

/**
* Calculates the number of full days remaining until a given end date.
* If isElapsed is true, it calculates the number of full days since the end date.
*
* @param end - The ISO datestring for the end value.
* @returns The number of full days remaining until the end date.
*/
export function dayCountdown (end: string): number {
export function dayCountdown (end: string, isElapsed: boolean = false): number {
const startDate = DateTime.utc() // get current utc date
const endDate = DateTime.fromISO(end, { setZone: true }).toUTC() // get given end date and convert to utc

// get difference in days https://moment.github.io/luxon/#/math?id=diffs
const diff = endDate.diff(startDate, 'days').toObject().days
const diff = isElapsed
? startDate.diff(endDate, 'days').toObject().days ?? 0
: endDate.diff(startDate, 'days').toObject().days

// round difference down
return Math.floor(diff)
Expand Down
50 changes: 0 additions & 50 deletions strr-examiner-web/app/components/ApplicationDetails.vue

This file was deleted.

23 changes: 3 additions & 20 deletions strr-examiner-web/app/components/ApplicationDetailsSection.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
<script setup lang="ts">
const props = defineProps<{ label: string, hideCheckbox?: boolean, hideChecklist?: boolean }>()
const props = defineProps<{ label: string }>()
</script>

<template>
<div class="flex items-center py-4 text-sm">
<div class="flex py-4 text-sm">
<div class="flex w-1/5 items-start justify-start">
<UCheckbox v-if="!hideCheckbox" name="checkbox">
<template #label>
<span class="text-sm font-bold">{{ props.label }}</span>
</template>
</UCheckbox>
<span class="text-sm font-bold">{{ props.label }}</span>
</div>
<div class="flex-auto">
<slot />
</div>
<div
v-if="!hideChecklist"
class="flex"
>
<UButton
label="Checklist"
variant="link"
class="p-0 text-sm"
icon="i-mdi-chevron-down"
size="sm"
trailing
/>
</div>
</div>
</template>

Expand Down
34 changes: 34 additions & 0 deletions strr-examiner-web/app/components/ApplicationInfoHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script setup lang="ts">
const props = defineProps<{ application: ApiApplicationBaseResp }>()
const { t } = useI18n()
const { header, registration } = props.application
const displayApplicationType = {
[ApplicationType.HOST]: t('strr.label.host'),
[ApplicationType.PLATFORM]: t('strr.label.platform'),
[ApplicationType.STRATA_HOTEL]: t('strr.label.strataHotel')
}
</script>

<template>
<div class="border-b py-6">
<div class="mb-2 text-2xl">
<strong>
{{ header?.applicationNumber }} |
</strong>
{{ registration.unitAddress.nickname }}
</div>
<div class="text-sm">
<UBadge class="mr-3 font-bold" :label="header.examinerStatus" color="primary" />
<strong>Type:</strong>
{{ displayApplicationType[registration?.registrationType as keyof typeof displayApplicationType] }} |
<strong>Submitted:</strong> {{ dateToString(header.applicationDateTime, 'y-MM-dd t') }}
({{ dayCountdown(header.applicationDateTime.toString(), true) }} days ago)
</div>
</div>
</template>

<style scoped></style>
183 changes: 108 additions & 75 deletions strr-examiner-web/app/components/HostDetailsView.vue
Original file line number Diff line number Diff line change
@@ -1,116 +1,149 @@
<script setup lang="ts">
import { useExaminerStore } from '~/store/examiner'
const props = defineProps<{ application: HostApplicationResp }>()
const { t } = useI18n()
const { header, registration } = props.application
const { unitDetails } = registration
const emit = defineEmits<{
approveApplication: [],
rejectApplication: []
approveApplication: [],
rejectApplication: []
}>()
const { getDocument } = useExaminerStore()
const openDocInNewTab = async (supportingDocument: ApiDocument) => {
const file = await getDocument(header.applicationNumber, supportingDocument.fileKey)
const blob = new Blob([file], { type: 'application/pdf' })
const url = URL.createObjectURL(blob)
window.open(url, '_blank')
URL.revokeObjectURL(url)
}
</script>

<template>
<div>
<div class="mb-2 align-middle text-lg">
<strong>
{{ header?.applicationNumber }}
</strong>
<UButton label="View History" variant="link" size="sm" class="mx-2 underline" />
</div>
<div
v-if="registration?.registrationType === ApplicationType.HOST"
class="flex flex-row gap-x-5 divide-x text-sm"
>
<div>
<dl class="grid grid-cols-[repeat(2,auto)] gap-x-4">
<dt>Status:</dt>
<dd>{{ header?.hostStatus }}</dd>

<dt>Submitted:</dt>
<dd>{{ dateToString(header?.applicationDateTime || '') }}</dd>

<dt>Registration Type:</dt>
<dd>{{ registration?.registrationType }}</dd>
</dl>
</div>
<div>
<dl class="grid grid-cols-[repeat(2,auto)] gap-x-4 pl-5">
<dt>Unit Address:</dt>
<dd class="w-[150px]">
{{ displayFullUnitAddress(registration?.unitAddress) }}
</dd>

<dt>Municipality:</dt>
<dd>{{ registration?.strRequirements?.organizationNm }}</dd>
</dl>
<div class="text-bcGovColor-midGray grid grid-cols-4 gap-x-5 divide-x text-sm">
<div class="space-y-2">
<strong>RENTAL UNIT</strong>
<div class="w-[150px]">
<UIcon name="i-mdi-map-marker-outline" />
{{ displayFullUnitAddress(registration?.unitAddress) }}
</div>
<div v-if="registration?.strRequirements?.organizationNm">
<UIcon name="i-mdi-map-outline" />
{{ registration?.strRequirements?.organizationNm }}
</div>
</div>
<div>
<dl class="grid grid-cols-[repeat(2,auto)] gap-x-4 pl-5">
<dt>Host Address:</dt>
<dd class="w-[150px]">
{{ displayFullAddress(registration?.primaryContact.mailingAddress) }}
</dd>

<dt>Address Type:</dt>
<dd>Mailing</dd>

<dt>Same as Unit Address:</dt>
<dd>{{ registration?.unitDetails.hostResidence }}</dd>

<dt>Host Name:</dt>
<dd>{{ displayContactFullName(registration?.primaryContact || {}) }}</dd>

<dt>Host Type:</dt>
<dd>{{ registration?.primaryContact.contactType }}</dd>
<div class="space-y-2 pl-5">
<strong>HOST</strong>
<div class="w-[150px]">
<UIcon name="i-mdi-map-marker-outline" />
{{ displayFullAddress(registration?.primaryContact.mailingAddress) }}
</div>
<div>
<UIcon name="i-mdi-account" />
{{ displayContactFullName(registration?.primaryContact) }}
</div>
<div>
<UIcon name="i-mdi-at" />
{{ registration?.primaryContact.emailAddress }}
</div>
<div>
<strong>Host Type:</strong>
{{ registration?.primaryContact.contactType }}
</div>
<div>
<strong>Owner / Renter:</strong>
{{ unitDetails.ownershipType }}
</div>
</div>

<dt>Ownership Type:</dt>
<dd>{{ registration?.unitDetails.ownershipType }}</dd>
</dl>
<div class="space-y-2 pl-5">
<div>
{{ t(`propertyType.${unitDetails.propertyType}`) }}
</div>
<div>
{{ t(`rentalUnitType.${unitDetails.rentalUnitSpaceType}`) }} ({{ unitDetails.numberOfRoomsForRent }} Rooms)
</div>
<div>{{ t(`hostResidence.${unitDetails.hostResidence}`) }}</div>
<div><strong>PID:</strong> {{ unitDetails.parcelIdentifier }}</div>
<div>
<strong>PR Registered Rentals:</strong>
<!-- TODO: Get number of registered rentals for the host -->
</div>
</div>
<div>
<dl class="grid grid-cols-[repeat(2,auto)] gap-x-4 pl-5">
<dt>Property Type:</dt>
<dd>{{ registration?.unitDetails.propertyType }}</dd>

<dt>Configuration:</dt>
<dd>{{ registration?.unitDetails.rentalUnitSpaceType }}</dd>
<div class="space-y-2 pl-5">
<div>
<UIcon name="i-mdi-account-multiple-outline" />
{{ registration?.secondaryContact?.contactType === OwnerType.INDIVIDUAL
? displayContactFullName(registration?.secondaryContact) :
registration?.secondaryContact?.businessLegalName }}
</div>

<dt>Rooms:</dt>
<dd>{{ registration?.unitDetails.numberOfRoomsForRent }}</dd>
</dl>
<div>
<UIcon name="i-mdi-at" />
{{ registration?.propertyManager?.propertyManagerType === OwnerType.INDIVIDUAL
? displayContactFullName(registration?.propertyManager.contact) :
registration?.propertyManager?.business?.legalName }}
</div>
</div>
</div>

<!-- APPLICATION SECTIONS -->
<div class="mt-6 divide-y">
<ApplicationDetailsSection label="Short-term rentals prohibited" hide-checklist>
<ApplicationDetailsSection label="Short-term rentals prohibited">
<div class="flex items-center justify-between">
<div class="flex">
{{ registration?.strRequirements?.isStrProhibited ? 'Yes' : 'No' }}
</div>
<div class="flex items-start justify-end gap-x-2">
<UButton label="Quick send to supervisor" color="primary" />
</div>
</div>
</ApplicationDetailsSection>

<ApplicationDetailsSection label="Principal Residence">
<div>
{{ registration?.strRequirements?.isPrincipalResidenceRequired ?
'Required' : 'Not Required' }}
'Required.' : 'Not Required.' }} {{ registration?.strRequirements?.isStraaExempt ?
'Exempt.' : 'Not Exempt.' }}
</div>
<div>
<strong>STR Accommodations Act: </strong>
{{ registration?.strRequirements?.isStraaExempt ?
'Exempt' : 'Not Exempt' }}

<div class="mt-2">
<UButton
v-for="document in registration.documents"
:key="document.fileKey"
class="mr-4 gap-x-1 p-0"
variant="link"
icon="mdi-file-document-outline"
@click="openDocInNewTab(document)"
>
{{ t(`documentLabels.${document.documentType}`) }}
</UButton>
</div>
</ApplicationDetailsSection>

<ApplicationDetailsSection label="" hide-checkbox hide-checklist class="pt-8">
<ApplicationDetailsSection label="" hide-checkbox class="pt-8">
<div class="flex justify-end gap-x-2">
<UButton label="Approve" color="primary" @click="emit('approveApplication')" />
<UButton label="Reject" color="gray" @click="emit('rejectApplication')" />
<UButton
icon="i-mdi-close"
:label="t('btn.decline')"
color="red"
variant="outline"
size="lg"
@click="emit('rejectApplication')"
/>
<UButton
icon="i-mdi-check"
:label="t('btn.approve')"
color="green"
variant="outline"
size="lg"
@click="emit('approveApplication')"
/>
</div>
</ApplicationDetailsSection>
</div>
Expand Down
13 changes: 0 additions & 13 deletions strr-examiner-web/app/components/PlatformDetailsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ const { header, registration } = props.application

<template>
<div>
<div class="mb-2 align-middle text-lg">
<strong>
{{ header?.applicationNumber }}
</strong>
<UButton
label="View History"
variant="link"
size="sm"
class="mx-2 underline"
/>
</div>

<div
class="flex flex-row gap-x-5 divide-x text-sm"
>
Expand Down Expand Up @@ -69,7 +57,6 @@ const { header, registration } = props.application
<div class="mt-6 divide-y">
<ApplicationDetailsSection
label="Business Details"
hide-checklist
>
<div class="flex items-center justify-between">
<div class="flex">
Expand Down
Loading

0 comments on commit 5cfa7b4

Please sign in to comment.