Skip to content

Commit

Permalink
Effective Date and Time for Unit Notes (#1415)
Browse files Browse the repository at this point in the history
* Add EffectiveDateTime component
* Add Expiry Date and Time to Unit Note
* PR review updates. Added more tests.
* Styling update for Effective Date component
  • Loading branch information
dimak1 authored Jul 12, 2023
1 parent 1fcbfaf commit a6788e4
Show file tree
Hide file tree
Showing 7 changed files with 361 additions and 9 deletions.
252 changes: 252 additions & 0 deletions ppr-ui/src/components/unitNotes/EffectiveDateTime.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
<template>
<div id="effective-date-time-container">
<h2>{{ content.title }}</h2>
<p class="mt-2">{{ content.description }}</p>
<v-card id="effective-date-time-card" flat rounded class="mt-8 px-7 pt-10 pb-3">
<v-row no-gutters>
<v-col cols="12" sm="3">
<label class="generic-label" :class="{ 'error-text': false }">
{{ content.sideLabel }}
</label>
</v-col>
<v-col cols="12" sm="9" class="px-1">
<v-radio-group v-model="effectiveDateType" column class="pt-0 mt-0">
<v-radio
:value="EffectiveDateTypes.IMMEDIATE"
label="Immediate (date and time of registration)"
data-test-id="immediate-date-radio"
/>
<v-radio
:value="EffectiveDateTypes.PAST"
label="Date and time in the past"
data-test-id="past-date-radio"
/>
</v-radio-group>
<v-form ref="effectiveDateTimeForm" class="date-time-selectors" v-model="isEffectiveDateTimeFormValid">
<SharedDatePicker
id="effective-date-picker"
ref="effectiveDatePicker"
title="Date"
:initialValue="selectedPastDate"
:disablePicker="isImmediateDateSelected"
:inputRules="required('This field is required')"
:maxDate="maxDate"
@emitDate="selectedPastDate = $event"
@emitCancel="selectedPastDate = ''"
@emitClear="selectedPastDate = ''"
/>

<div class="time-picker" data-test-id="time-picker-fields">
<v-select
id="hour-selector"
ref="hourSelector"
v-model="selectHour"
filled
class="mr-1"
label="Hour"
:items="hours"
:rules="required('This field is required')"
:disabled="isImmediateDateSelected"
/>
<span class="time-separator pt-4" :class="{ disabled: isImmediateDateSelected }"> : </span>

<v-select
id="minute-selector"
ref="minuteSelector"
v-model="selectMinute"
filled
class="mr-1"
label="Minute"
:items="minutes"
:rules="required('This field is required')"
:disabled="isImmediateDateSelected"
/>

<v-select
id="period-selector"
ref="periodSelector"
v-model="selectPeriod"
filled
class="mr-1 period-selector"
:items="[PeriodTypes.AM, PeriodTypes.PM]"
:disabled="isImmediateDateSelected"
/>

<span class="timezone-label pt-4" :class="{ disabled: isImmediateDateSelected }"> Pacific time </span>
</div>
</v-form>

<div
v-if="!isImmediateDateSelected && selectedPastDate && isTimeSelected"
class="ml-8 mb-6"
data-test-id="date-summary-label"
>
Caution on this home effective: <br />
<b>
{{ pacificDate(effectiveDate, true) }}
</b>
</div>
</v-col>
</v-row>
</v-card>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, onBeforeMount, reactive, ref, toRefs, watch } from 'vue-demi'
import { EffectiveDateTypes, PeriodTypes } from '@/enums/'
import { createUtcDate, localTodayDate, pacificDate } from '@/utils'
import { ContentIF, FormIF } from '@/interfaces'
import { useInputRules } from '@/composables'
import SharedDatePicker from '@/components/common/SharedDatePicker.vue'
export default defineComponent({
name: 'EffectiveDateTime',
components: {
SharedDatePicker
},
props: {
validate: {
type: Boolean,
default: false
},
content: {
type: Object as () => ContentIF,
default: () => {}
}
},
emits: ['setStoreProperty'],
setup (props, { emit }) {
const { required } = useInputRules()
const effectiveDatePicker = ref(null) as FormIF
const effectiveDateTimeForm = ref(null) as FormIF
const date = new Date()
const localState = reactive({
isEffectiveDateTimeFormValid: false,
selectHour: null,
selectMinute: null,
selectPeriod: PeriodTypes.AM,
selectedPastDate: '', // date selected from the Date Picker
effectiveDateType: EffectiveDateTypes.IMMEDIATE,
effectiveDate: '',
hours: [...Array(12).keys()].map(num => (num + 1).toString()),
minutes: [...Array(60).keys()].map(num => num.toString().padStart(2, '0')),
maxDate: computed((): string => localTodayDate(new Date(date.setDate(date.getDate() - 1)))),
isImmediateDateSelected: computed((): boolean => localState.effectiveDateType === EffectiveDateTypes.IMMEDIATE),
isTimeSelected: computed((): boolean => localState.selectHour && localState.selectMinute)
})
const buildFullDate = (): Date => {
let hours = parseInt(localState.selectHour)
const minutes = parseInt(localState.selectMinute)
// convert 12 am -> 0
if (localState.selectPeriod === PeriodTypes.AM && localState.selectHour === 12) {
hours = hours - 12
}
// convert 1-11 pm -> 13-23
if (localState.selectPeriod === PeriodTypes.PM && localState.selectHour < 12) {
hours = hours + 12
}
const date = new Date(localState.selectedPastDate)
return createUtcDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), hours, minutes)
}
onBeforeMount((): void => {
// set todays date as Immediate radio button is selected by default
localState.effectiveDate = new Date().toISOString()
})
watch(
() => [localState.effectiveDateType],
() => {
if (localState.isImmediateDateSelected) {
// today's date radio selected
localState.effectiveDate = new Date().toISOString()
} else if (localState.isTimeSelected) {
// past date radio selected and all time dropdowns are selected
localState.effectiveDate = buildFullDate().toISOString()
}
}
)
watch(
() => [localState.selectedPastDate, localState.selectHour, localState.selectMinute, localState.selectPeriod],
() => {
if (localState.isTimeSelected) {
localState.effectiveDate = buildFullDate().toISOString()
}
}
)
watch(
() => localState.effectiveDate,
val => {
emit('setStoreProperty', val)
}
)
return {
required,
effectiveDatePicker,
effectiveDateTimeForm,
EffectiveDateTypes,
PeriodTypes,
pacificDate,
...toRefs(localState)
}
}
})
</script>

<style lang="scss" scoped>
@import '@/assets/styles/theme.scss';
.time-picker {
display: flex;
gap: 5px;
justify-content: space-between;
align-content: center;
max-width: 600px;
.v-select {
max-width: 148px;
}
.time-separator {
margin-right: 2px;
}
.period-selector::v-deep .v-input__slot{
height: 58px;
}
.timezone-label {
white-space: nowrap;
}
}
.v-radio {
padding-bottom: 0.5rem;
}
.date-time-selectors {
margin-left: 2rem;
}
.disabled {
color: $gray6;
}
.v-icon.v-icon.v-icon--disabled {
color: $app-blue !important;
}
.v-input--is-disabled {
opacity: 0.4;
}
</style>
34 changes: 27 additions & 7 deletions ppr-ui/src/components/unitNotes/UnitNoteReview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@
</section>

<section class="mt-15">
<h2>2. Effective Date and Time</h2>
<p class="mt-2">
Select the effective date and time for this {{ unitNoteType.header }}. Custom date and time can
be a date and time in the past. Notice of Caution will expire 90 days after the effective date.
</p>
// Placeholder for the component
<EffectiveDateTime
:content="{
title: '2. Effective Date and Time',
description: `Select the effective date and time for this ${unitNoteType.header}. ` +
'Custom date and time can be a date and time in the past.' + effectiveDateDescForCAU,
sideLabel: 'Effective Date and Time'
}"
:validate="validate"
@setStoreProperty="handleEffectiveDateUpdate($event)"
/>
</section>

<section class="mt-15">
Expand Down Expand Up @@ -87,12 +91,15 @@ import { Attention } from '../mhrRegistration/ReviewConfirm'
import { StaffPayment } from '@bcrs-shared-components/staff-payment'
import { StaffPaymentOptions } from '@bcrs-shared-components/enums'
import { StaffPaymentIF } from '@bcrs-shared-components/interfaces'
import EffectiveDateTime from './EffectiveDateTime.vue'
import { UnitNoteDocTypes } from '@/enums'
export default defineComponent({
name: 'UnitNoteReview',
components: {
UnitNoteReviewDetailsTable,
ContactInformation,
EffectiveDateTime,
Attention,
CertifyInformation,
StaffPayment
Expand All @@ -112,7 +119,7 @@ export default defineComponent({
} = storeToRefs(useStore())
const {
// setMhrUnitNote,
setMhrUnitNote,
setMhrUnitNoteRegistration,
setStaffPayment
} = useStore()
Expand Down Expand Up @@ -147,10 +154,21 @@ export default defineComponent({
setMhrUnitNoteRegistration({ key: 'submittingParty', value: val })
}
const handleEffectiveDateUpdate = (val: string) => {
setMhrUnitNote({ key: 'effectiveDateTime', value: val })
// expiry date is 90 days from effective date
const expiryDateTime = new Date(new Date(val).getTime() + 90 * 24 * 60 * 60 * 1000).toISOString()
setMhrUnitNote({ key: 'expiryDateTime', value: expiryDateTime })
}
const handleComponentValid = (component: MhrCompVal, isValid: boolean) => {
setValidation(MhrSectVal.UNIT_NOTE_VALID, component, isValid)
}
const effectiveDateDescForCAU = getMhrUnitNote.value.documentType === UnitNoteDocTypes.NOTICE_OF_CAUTION
? ' Notice of Caution will expire 90 days after the effective date.'
: ''
const onStaffPaymentDataUpdate = (val: StaffPaymentIF) => {
let staffPaymentData: StaffPaymentIF = {
...val
Expand Down Expand Up @@ -202,8 +220,10 @@ export default defineComponent({
MhrCompVal,
getMhrUnitNote,
setSubmittingParty,
handleEffectiveDateUpdate,
handleComponentValid,
onStaffPaymentDataUpdate,
effectiveDateDescForCAU,
...toRefs(localState)
}
}
Expand Down
1 change: 1 addition & 0 deletions ppr-ui/src/components/unitNotes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as UnitNotePanels } from './UnitNotePanels.vue'
export { default as UnitNoteAdd } from './UnitNoteAdd.vue'
export { default as UnitNoteReview } from './UnitNoteReview.vue'
export { default as UnitNoteReviewDetailsTable } from './UnitNoteReviewDetailsTable.vue'
export { default as EffectiveDateTime } from './EffectiveDateTime.vue'
9 changes: 9 additions & 0 deletions ppr-ui/src/enums/effectiveDateTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export enum EffectiveDateTypes {
PAST = 'past',
IMMEDIATE = 'immediate'
}

export enum PeriodTypes {
AM = 'am',
PM = 'pm'
}
1 change: 1 addition & 0 deletions ppr-ui/src/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export * from './business-types'
export * from './transferTypes'
export * from './homeOwnerPartyTypes'
export * from './unitNoteDocTypes'
export * from './effectiveDateTypes'

// external enums
export { CorpTypeCd } from '@bcrs-shared-components/corp-type-module'
Expand Down
Loading

0 comments on commit a6788e4

Please sign in to comment.