@meetelise/chat 1.31.0 → 1.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/WebComponent/FeeCalculator/components/{addon-item → addons/addon-item}/addon-item.d.ts +2 -2
- package/dist/src/WebComponent/FeeCalculator/components/addons/rentable-item/rentable-item-styles.d.ts +2 -0
- package/dist/src/WebComponent/FeeCalculator/components/addons/rentable-item/rentable-item.d.ts +25 -0
- package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.d.ts +13 -5
- package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item.d.ts +1 -1
- package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.d.ts +8 -8
- package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.d.ts +3 -3
- package/dist/src/WebComponent/FeeCalculator/components/index.d.ts +1 -1
- package/dist/src/WebComponent/FeeCalculator/constants.d.ts +1 -0
- package/dist/src/WebComponent/FeeCalculator/fee-calculator.d.ts +4 -3
- package/dist/src/globals.d.ts +1 -0
- package/dist/src/services/fees/calculateQuote.d.ts +0 -1
- package/dist/src/services/fees/fetchBuildingUnits.d.ts +29 -0
- package/dist/src/utils/queryParamBuilder.d.ts +8 -0
- package/package.json +1 -1
- package/public/dist/index.js +302 -241
- package/src/WebComponent/FeeCalculator/components/{addon-item → addons/addon-item}/addon-item.ts +33 -35
- package/src/WebComponent/FeeCalculator/components/addons/rentable-item/rentable-item-styles.ts +9 -0
- package/src/WebComponent/FeeCalculator/components/addons/rentable-item/rentable-item.ts +138 -0
- package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.ts +42 -17
- package/src/WebComponent/FeeCalculator/components/fee-item/fee-item.ts +1 -1
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.ts +0 -1
- package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +31 -35
- package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.ts +13 -13
- package/src/WebComponent/FeeCalculator/components/index.ts +1 -1
- package/src/WebComponent/FeeCalculator/constants.ts +2 -0
- package/src/WebComponent/FeeCalculator/fee-calculator.ts +48 -25
- package/src/WebComponent/actions/call-us-window.ts +32 -10
- package/src/WebComponent/launcher/Launcher.ts +0 -1
- package/src/WebComponent/me-chat.ts +4 -7
- package/src/globals.ts +2 -0
- package/src/services/fees/calculateQuote.ts +0 -1
- package/src/services/fees/fetchBuildingUnits.ts +84 -0
- package/src/utils/queryParamBuilder.ts +28 -0
- package/dist/src/WebComponent/FeeCalculator/components/addon-item/index.d.ts +0 -1
- package/dist/src/services/fees/fetchBuildingFloorplans.d.ts +0 -21
- package/src/WebComponent/FeeCalculator/components/addon-item/index.ts +0 -1
- /package/dist/src/WebComponent/FeeCalculator/components/{addon-item/addon-item-styles.d.ts → addons/common-addon-styles.d.ts} +0 -0
- /package/src/WebComponent/FeeCalculator/components/{addon-item/addon-item-styles.ts → addons/common-addon-styles.ts} +0 -0
package/src/WebComponent/FeeCalculator/components/{addon-item → addons/addon-item}/addon-item.ts
RENAMED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { LitElement, html, TemplateResult } from "lit";
|
|
2
2
|
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
-
import { BuildingFee } from "
|
|
4
|
-
import { formatCurrency } from "
|
|
3
|
+
import { BuildingFee } from "../../../model/building-fee";
|
|
4
|
+
import { formatCurrency } from "../../../../../utils";
|
|
5
|
+
import { DesiredAddon } from "../../../../../services/fees/calculateQuote";
|
|
5
6
|
|
|
6
|
-
import
|
|
7
|
-
import { DesiredAddon } from "../../../../services/fees/calculateQuote";
|
|
7
|
+
import commonAddonStyles from "../common-addon-styles";
|
|
8
8
|
|
|
9
9
|
@customElement("add-on-item")
|
|
10
10
|
export class AddonItem extends LitElement {
|
|
11
|
-
static styles =
|
|
11
|
+
static styles = commonAddonStyles;
|
|
12
12
|
|
|
13
13
|
@property({ type: Object })
|
|
14
14
|
feeItem: BuildingFee | null = null;
|
|
@@ -75,38 +75,36 @@ export class AddonItem extends LitElement {
|
|
|
75
75
|
if (!this.feeItem || !this.feeItem.blueprint.addOnInfo) return html``;
|
|
76
76
|
|
|
77
77
|
return html`
|
|
78
|
-
<div>
|
|
79
|
-
<div class="addon-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
<p class="addon-title">${this.feeItem.displayName("Add-On")}</p>
|
|
88
|
-
</div>
|
|
78
|
+
<div class="addon-container">
|
|
79
|
+
<div class="addon-left">
|
|
80
|
+
<input
|
|
81
|
+
type="checkbox"
|
|
82
|
+
?checked=${this.isChecked}
|
|
83
|
+
@click=${this.handleCheckboxClick}
|
|
84
|
+
/>
|
|
85
|
+
<div class="addon-info">
|
|
86
|
+
<p class="addon-title">${this.feeItem.displayName("Add-On")}</p>
|
|
89
87
|
</div>
|
|
88
|
+
</div>
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
</div>
|
|
90
|
+
<div class="addon-right">
|
|
91
|
+
<div class="quantity-control">
|
|
92
|
+
<button
|
|
93
|
+
class="quantity-button"
|
|
94
|
+
@click=${this.handleDecrement}
|
|
95
|
+
?disabled=${this.quantity <= 0}
|
|
96
|
+
aria-label="Decrease quantity"
|
|
97
|
+
>
|
|
98
|
+
<span class="operator-sign">−</span>
|
|
99
|
+
</button>
|
|
100
|
+
<span class="quantity-value">${this.quantity}</span>
|
|
101
|
+
<button
|
|
102
|
+
class="quantity-button"
|
|
103
|
+
@click=${this.handleIncrement}
|
|
104
|
+
aria-label="Increase quantity"
|
|
105
|
+
>
|
|
106
|
+
<span class="operator-sign">+</span>
|
|
107
|
+
</button>
|
|
110
108
|
</div>
|
|
111
109
|
</div>
|
|
112
110
|
</div>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { html, LitElement, TemplateResult } from "lit";
|
|
2
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
+
import { RentableItemSummary } from "../../../../../services/fees/fetchBuildingFees";
|
|
4
|
+
import { DesiredRentableItem } from "../../../../../services/fees/calculateQuote";
|
|
5
|
+
|
|
6
|
+
import commonAddonStyles from "../common-addon-styles";
|
|
7
|
+
|
|
8
|
+
@customElement("rentable-item")
|
|
9
|
+
export class RentableItem extends LitElement {
|
|
10
|
+
static styles = commonAddonStyles;
|
|
11
|
+
|
|
12
|
+
@property({ type: Object })
|
|
13
|
+
rentableItem: RentableItemSummary | null = null;
|
|
14
|
+
|
|
15
|
+
@property({ type: Function })
|
|
16
|
+
onSelect: ((rentableItem: DesiredRentableItem) => void) | null = null;
|
|
17
|
+
|
|
18
|
+
@state()
|
|
19
|
+
private isChecked = false;
|
|
20
|
+
|
|
21
|
+
@state()
|
|
22
|
+
private quantity = 0;
|
|
23
|
+
|
|
24
|
+
@state()
|
|
25
|
+
selectedItemIds: Set<string> = new Set();
|
|
26
|
+
|
|
27
|
+
get totalAvailableItems(): number {
|
|
28
|
+
return (
|
|
29
|
+
this.rentableItem?.allItems.filter((item) => item.available).length ?? 0
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get quantityLeft(): number {
|
|
34
|
+
return this.totalAvailableItems - this.quantity;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get atMaxUnits(): boolean {
|
|
38
|
+
return this.quantity >= this.totalAvailableItems;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get atMinUnits(): boolean {
|
|
42
|
+
return this.quantity <= 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private handleCheckboxClick(): void {
|
|
46
|
+
if (!this.isChecked) {
|
|
47
|
+
this.isChecked = true;
|
|
48
|
+
this.quantity = 1;
|
|
49
|
+
this.emitChange();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.isChecked = false;
|
|
53
|
+
this.quantity = 0;
|
|
54
|
+
this.emitChange();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private handleIncrement(): void {
|
|
58
|
+
if (this.atMaxUnits) return;
|
|
59
|
+
this.isChecked = true;
|
|
60
|
+
this.quantity += 1;
|
|
61
|
+
this.emitChange();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private handleDecrement(): void {
|
|
65
|
+
if (this.atMinUnits) return;
|
|
66
|
+
this.quantity = Math.max(0, this.quantity - 1);
|
|
67
|
+
this.isChecked = this.quantity > 0;
|
|
68
|
+
this.emitChange();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private emitChange(): void {
|
|
72
|
+
if (!this.rentableItem) return;
|
|
73
|
+
|
|
74
|
+
// Find first item that is available
|
|
75
|
+
const firstAvailableItem = this.rentableItem.allItems.find(
|
|
76
|
+
(item) => item.available && !this.selectedItemIds.has(item.id)
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!firstAvailableItem) return;
|
|
80
|
+
|
|
81
|
+
this.selectedItemIds.add(firstAvailableItem.id);
|
|
82
|
+
|
|
83
|
+
this.onSelect?.({
|
|
84
|
+
id: parseInt(firstAvailableItem.id),
|
|
85
|
+
type: this.rentableItem.type,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
render(): TemplateResult {
|
|
90
|
+
if (!this.rentableItem) return html``;
|
|
91
|
+
|
|
92
|
+
const hasAvailableItems = this.totalAvailableItems > 0;
|
|
93
|
+
|
|
94
|
+
return html`
|
|
95
|
+
<div class="addon-container">
|
|
96
|
+
<div class="addon-left">
|
|
97
|
+
<input
|
|
98
|
+
type="checkbox"
|
|
99
|
+
?checked=${this.isChecked}
|
|
100
|
+
?disabled=${!hasAvailableItems}
|
|
101
|
+
@click=${this.handleCheckboxClick}
|
|
102
|
+
/>
|
|
103
|
+
<div class="addon-info">
|
|
104
|
+
<p class="addon-title">${this.rentableItem.description}</p>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div class="addon-right">
|
|
109
|
+
<div class="quantity-control">
|
|
110
|
+
<button
|
|
111
|
+
class="quantity-button"
|
|
112
|
+
@click=${this.handleDecrement}
|
|
113
|
+
?disabled=${this.quantity <= 0}
|
|
114
|
+
aria-label="Decrease quantity"
|
|
115
|
+
>
|
|
116
|
+
<span class="operator-sign">−</span>
|
|
117
|
+
</button>
|
|
118
|
+
<span class="quantity-value">${this.quantity}</span>
|
|
119
|
+
<button
|
|
120
|
+
class="quantity-button"
|
|
121
|
+
@click=${this.handleIncrement}
|
|
122
|
+
?disabled=${!hasAvailableItems || this.atMaxUnits}
|
|
123
|
+
aria-label="Increase quantity"
|
|
124
|
+
>
|
|
125
|
+
<span class="operator-sign">+</span>
|
|
126
|
+
</button>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
declare global {
|
|
135
|
+
interface HTMLElementTagNameMap {
|
|
136
|
+
"rentable-item": RentableItem;
|
|
137
|
+
}
|
|
138
|
+
}
|
package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.ts
CHANGED
|
@@ -7,12 +7,16 @@ import { LayoutOption } from "../../../../fetchBuildingWebchatView";
|
|
|
7
7
|
import {
|
|
8
8
|
CalculateQuoteResponse,
|
|
9
9
|
DesiredAddon,
|
|
10
|
+
DesiredRentableItem,
|
|
10
11
|
FeeEstimate,
|
|
11
12
|
} from "../../../../services/fees/calculateQuote";
|
|
13
|
+
import { RentableItemSummary } from "../../../../services/fees/fetchBuildingFees";
|
|
14
|
+
import { Unit } from "../../../../services/fees/fetchBuildingUnits";
|
|
12
15
|
|
|
13
16
|
import "../floor-plan-selector/floor-plan-selector";
|
|
14
17
|
import "../fee-card/fee-card";
|
|
15
|
-
import "../addon-item/addon-item";
|
|
18
|
+
import "../addons/addon-item/addon-item";
|
|
19
|
+
import "../addons/rentable-item/rentable-item";
|
|
16
20
|
import "../../../loaders/skeleton-loader";
|
|
17
21
|
|
|
18
22
|
@customElement("fee-calculator-layout")
|
|
@@ -25,8 +29,8 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
25
29
|
@property({ type: Boolean })
|
|
26
30
|
isLoading = false;
|
|
27
31
|
|
|
28
|
-
@property({ type:
|
|
29
|
-
|
|
32
|
+
@property({ type: Object })
|
|
33
|
+
selectedUnit: Unit | null = null;
|
|
30
34
|
|
|
31
35
|
@property({ type: Object })
|
|
32
36
|
quote: CalculateQuoteResponse | null = null;
|
|
@@ -48,11 +52,14 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
48
52
|
[RecurrenceFrequency.Unknown]: [],
|
|
49
53
|
};
|
|
50
54
|
|
|
55
|
+
@property({ type: Array })
|
|
56
|
+
rentableItems: RentableItemSummary[] = [];
|
|
57
|
+
|
|
51
58
|
@property()
|
|
52
59
|
onSelectLayout: ((layoutIds: number[]) => void) | null = null;
|
|
53
60
|
|
|
54
61
|
@property()
|
|
55
|
-
onUnitSelect: ((
|
|
62
|
+
onUnitSelect: ((unit: Unit) => void) | null = null;
|
|
56
63
|
|
|
57
64
|
@property()
|
|
58
65
|
onMoveInDateChange: ((moveInDate: Date) => void) | null = null;
|
|
@@ -63,6 +70,10 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
63
70
|
@property()
|
|
64
71
|
onAddonSelect: ((addon: DesiredAddon) => void) | null = null;
|
|
65
72
|
|
|
73
|
+
@property()
|
|
74
|
+
onRentableItemSelect: ((rentableItem: DesiredRentableItem) => void) | null =
|
|
75
|
+
null;
|
|
76
|
+
|
|
66
77
|
get standardFees(): Record<RecurrenceFrequency, BuildingFee[]> {
|
|
67
78
|
const result: Record<RecurrenceFrequency, BuildingFee[]> = {} as Record<
|
|
68
79
|
RecurrenceFrequency,
|
|
@@ -78,15 +89,18 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
78
89
|
return result;
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
/**
|
|
93
|
+
* A "rentable item" is simply a fee which has inventory attached to it.
|
|
94
|
+
*/
|
|
95
|
+
get addOns(): (BuildingFee | RentableItemSummary)[] {
|
|
96
|
+
const addons = Object.values(this.groupedFees)
|
|
83
97
|
.flat()
|
|
84
98
|
.filter((fee) => {
|
|
85
99
|
if (!fee.isAddOn) return false;
|
|
86
100
|
if (!this.quote) return true;
|
|
87
101
|
|
|
88
102
|
const unitLayout = this.quote?.units.find(
|
|
89
|
-
(unit) => unit.unitId === this.
|
|
103
|
+
(unit) => unit.unitId === this.selectedUnit?.id
|
|
90
104
|
)?.unitLayout;
|
|
91
105
|
|
|
92
106
|
// Let the addon through if it's not layout specific
|
|
@@ -94,6 +108,8 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
94
108
|
|
|
95
109
|
return fee.layoutIds.includes(unitLayout);
|
|
96
110
|
});
|
|
111
|
+
|
|
112
|
+
return [...addons, ...this.rentableItems];
|
|
97
113
|
}
|
|
98
114
|
|
|
99
115
|
renderRecurrenceFeeSection(
|
|
@@ -119,7 +135,7 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
119
135
|
];
|
|
120
136
|
|
|
121
137
|
const unitFees =
|
|
122
|
-
this.quote?.units.find((unit) => unit.unitId === this.
|
|
138
|
+
this.quote?.units.find((unit) => unit.unitId === this.selectedUnit?.id)
|
|
123
139
|
?.fees ?? [];
|
|
124
140
|
|
|
125
141
|
const applicableFees = unitFees.filter((fee) => fee.applicable);
|
|
@@ -136,7 +152,7 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
136
152
|
}
|
|
137
153
|
|
|
138
154
|
renderFeesContent(): TemplateResult {
|
|
139
|
-
if (!this.
|
|
155
|
+
if (!this.selectedUnit) {
|
|
140
156
|
return html`
|
|
141
157
|
<div class="fees-container empty-state">
|
|
142
158
|
<p>Select a unit to view estimated costs</p>
|
|
@@ -181,14 +197,23 @@ export class FeeCalculatorLayout extends LitElement {
|
|
|
181
197
|
<div class="sidepanel-section">
|
|
182
198
|
<h5 class="sidepanel-section-title">Add-Ons</h5>
|
|
183
199
|
<div class="sidepanel-addons-container">
|
|
184
|
-
${this.addOns.map(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
200
|
+
${this.addOns.map((addon) => {
|
|
201
|
+
return html`
|
|
202
|
+
${addon instanceof BuildingFee
|
|
203
|
+
? html`
|
|
204
|
+
<add-on-item
|
|
205
|
+
.feeItem=${addon}
|
|
206
|
+
.onQuantityChange=${this.onAddonSelect}
|
|
207
|
+
></add-on-item>
|
|
208
|
+
`
|
|
209
|
+
: html`
|
|
210
|
+
<rentable-item
|
|
211
|
+
.rentableItem=${addon}
|
|
212
|
+
.onSelect=${this.onRentableItemSelect}
|
|
213
|
+
></rentable-item>
|
|
214
|
+
`}
|
|
215
|
+
`;
|
|
216
|
+
})}
|
|
192
217
|
</div>
|
|
193
218
|
</div>
|
|
194
219
|
`
|
|
@@ -2,7 +2,7 @@ import { LitElement, html, TemplateResult } from "lit";
|
|
|
2
2
|
import { customElement, property } from "lit/decorators.js";
|
|
3
3
|
import { FeeEstimate } from "../../../../services/fees/calculateQuote";
|
|
4
4
|
|
|
5
|
-
import "../addon-item/addon-item";
|
|
5
|
+
import "../addons/addon-item/addon-item";
|
|
6
6
|
|
|
7
7
|
import feeItemStyles from "./fee-item-styles";
|
|
8
8
|
|
package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { LitElement, html, TemplateResult } from "lit";
|
|
2
2
|
import { customElement, property, state } from "lit/decorators.js";
|
|
3
3
|
import { LayoutOption } from "../../../../fetchBuildingWebchatView";
|
|
4
|
-
import { ALL_LAYOUTS_OPTION } from "../../constants";
|
|
4
|
+
import { ALL_LAYOUTS_OPTION, DEFAULT_LEASE_TERM } from "../../constants";
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
} from "../../../../services/fees/
|
|
6
|
+
import fetchBuildingUnits, {
|
|
7
|
+
Unit,
|
|
8
|
+
} from "../../../../services/fees/fetchBuildingUnits";
|
|
9
9
|
import { layoutToBedrooms } from "../../../../services/fees/utils";
|
|
10
10
|
import floorPlanSelectorStyles from "./floor-plan-selector-styles";
|
|
11
|
-
import {
|
|
11
|
+
import { TODAY } from "../../../../globals";
|
|
12
12
|
|
|
13
13
|
import "../floorplan-image-card/floorplan-image-card";
|
|
14
14
|
import "../../../loaders/mega-loader";
|
|
15
15
|
|
|
16
|
-
const FIRST_OF_NEXT_MONTH = startOfMonth(addMonths(new Date(), 1));
|
|
17
|
-
|
|
18
16
|
@customElement("floor-plan-selector")
|
|
19
17
|
export class FloorPlanSelector extends LitElement {
|
|
20
18
|
static styles = floorPlanSelectorStyles;
|
|
@@ -32,7 +30,7 @@ export class FloorPlanSelector extends LitElement {
|
|
|
32
30
|
onSelectLayout: ((layoutIds: number[]) => void) | null = null;
|
|
33
31
|
|
|
34
32
|
@property()
|
|
35
|
-
onUnitSelect: ((
|
|
33
|
+
onUnitSelect: ((unit: Unit) => void) | null = null;
|
|
36
34
|
|
|
37
35
|
@property()
|
|
38
36
|
onMoveInDateChange: ((moveInDate: Date) => void) | null = null;
|
|
@@ -41,16 +39,16 @@ export class FloorPlanSelector extends LitElement {
|
|
|
41
39
|
onLeaseTermChange: ((leaseTerm: number) => void) | null = null;
|
|
42
40
|
|
|
43
41
|
@state()
|
|
44
|
-
moveInDate: Date | null =
|
|
42
|
+
moveInDate: Date | null = TODAY;
|
|
45
43
|
|
|
46
44
|
@state()
|
|
47
|
-
leaseTerm =
|
|
45
|
+
leaseTerm = DEFAULT_LEASE_TERM;
|
|
48
46
|
|
|
49
47
|
@state()
|
|
50
|
-
|
|
48
|
+
units: Unit[] = [];
|
|
51
49
|
|
|
52
50
|
@state()
|
|
53
|
-
|
|
51
|
+
selectedUnit: Unit | null = null;
|
|
54
52
|
|
|
55
53
|
@state()
|
|
56
54
|
isLoading = false;
|
|
@@ -97,7 +95,7 @@ export class FloorPlanSelector extends LitElement {
|
|
|
97
95
|
.sort((a, b) => a.value - b.value);
|
|
98
96
|
}
|
|
99
97
|
|
|
100
|
-
private
|
|
98
|
+
private fetchUnits = async (): Promise<Unit[]> => {
|
|
101
99
|
this.isLoading = true;
|
|
102
100
|
|
|
103
101
|
const numBedrooms =
|
|
@@ -106,36 +104,33 @@ export class FloorPlanSelector extends LitElement {
|
|
|
106
104
|
: undefined;
|
|
107
105
|
|
|
108
106
|
try {
|
|
109
|
-
const
|
|
107
|
+
const units = await fetchBuildingUnits({
|
|
110
108
|
buildingSlug: this.buildingSlug,
|
|
111
109
|
moveInDateEarliest: this.moveInDate ? this.moveInDate : undefined,
|
|
112
110
|
...(this.selectedLayoutIds.includes(ALL_LAYOUTS_OPTION)
|
|
113
111
|
? {}
|
|
114
112
|
: { numBedrooms }),
|
|
113
|
+
leaseTermMin: this.leaseTerm,
|
|
115
114
|
});
|
|
116
|
-
return
|
|
115
|
+
return units.filter((unit) => !!unit.floorplanUrl);
|
|
117
116
|
} finally {
|
|
118
117
|
this.isLoading = false;
|
|
119
118
|
}
|
|
120
119
|
};
|
|
121
120
|
|
|
122
121
|
firstUpdated = async (): Promise<void> => {
|
|
123
|
-
this.
|
|
124
|
-
|
|
125
|
-
// Default move-in is 1st of next month
|
|
126
|
-
this.moveInDate = FIRST_OF_NEXT_MONTH;
|
|
127
|
-
this.onMoveInDateChange?.(FIRST_OF_NEXT_MONTH);
|
|
122
|
+
this.units = await this.fetchUnits();
|
|
128
123
|
};
|
|
129
124
|
|
|
130
|
-
handleUnitSelect = (
|
|
131
|
-
this.
|
|
132
|
-
this.onUnitSelect?.(
|
|
125
|
+
handleUnitSelect = (unit: Unit): void => {
|
|
126
|
+
this.selectedUnit = unit;
|
|
127
|
+
this.onUnitSelect?.(unit);
|
|
133
128
|
};
|
|
134
129
|
|
|
135
130
|
handleLayoutChange = async (ids: number[]): Promise<void> => {
|
|
136
131
|
this.selectedLayoutIds = ids;
|
|
137
132
|
this.onSelectLayout?.(this.selectedLayoutIds);
|
|
138
|
-
this.
|
|
133
|
+
this.units = await this.fetchUnits();
|
|
139
134
|
};
|
|
140
135
|
|
|
141
136
|
handleMoveInDateChange = async (e: Event): Promise<void> => {
|
|
@@ -143,19 +138,20 @@ export class FloorPlanSelector extends LitElement {
|
|
|
143
138
|
let newMoveIn;
|
|
144
139
|
|
|
145
140
|
if (!inputValue) {
|
|
146
|
-
newMoveIn =
|
|
141
|
+
newMoveIn = TODAY;
|
|
147
142
|
} else {
|
|
148
143
|
newMoveIn = new Date(inputValue);
|
|
149
144
|
}
|
|
150
145
|
|
|
151
146
|
this.moveInDate = newMoveIn;
|
|
152
147
|
this.onMoveInDateChange?.(newMoveIn);
|
|
153
|
-
this.
|
|
148
|
+
this.units = await this.fetchUnits();
|
|
154
149
|
};
|
|
155
150
|
|
|
156
|
-
handleLeaseTermChange = (e: Event): void => {
|
|
157
|
-
this.leaseTerm = (e.target as HTMLInputElement).value;
|
|
158
|
-
this.onLeaseTermChange?.(
|
|
151
|
+
handleLeaseTermChange = async (e: Event): Promise<void> => {
|
|
152
|
+
this.leaseTerm = parseInt((e.target as HTMLInputElement).value);
|
|
153
|
+
this.onLeaseTermChange?.(this.leaseTerm);
|
|
154
|
+
this.units = await this.fetchUnits();
|
|
159
155
|
};
|
|
160
156
|
|
|
161
157
|
render(): TemplateResult {
|
|
@@ -195,7 +191,7 @@ export class FloorPlanSelector extends LitElement {
|
|
|
195
191
|
<input
|
|
196
192
|
type="number"
|
|
197
193
|
placeholder="Lease term (months)"
|
|
198
|
-
.value=${this.leaseTerm}
|
|
194
|
+
.value=${this.leaseTerm.toString()}
|
|
199
195
|
@input=${this.handleLeaseTermChange}
|
|
200
196
|
/>
|
|
201
197
|
</div>
|
|
@@ -210,19 +206,19 @@ export class FloorPlanSelector extends LitElement {
|
|
|
210
206
|
</div>
|
|
211
207
|
`
|
|
212
208
|
: ""}
|
|
213
|
-
${this.
|
|
209
|
+
${!this.isLoading && this.units?.length === 0
|
|
214
210
|
? html`
|
|
215
211
|
<div class="no-floorplans-container">
|
|
216
212
|
<p>No floorplans found</p>
|
|
217
213
|
</div>
|
|
218
214
|
`
|
|
219
215
|
: ""}
|
|
220
|
-
${this.
|
|
221
|
-
(
|
|
216
|
+
${this.units?.map(
|
|
217
|
+
(unit) => html`
|
|
222
218
|
<floorplan-image-card
|
|
223
|
-
.
|
|
219
|
+
.unit=${unit}
|
|
224
220
|
.onUnitSelect=${this.handleUnitSelect}
|
|
225
|
-
.selected=${this.
|
|
221
|
+
.selected=${this.selectedUnit?.id === unit.id}
|
|
226
222
|
></floorplan-image-card>
|
|
227
223
|
`
|
|
228
224
|
)}
|
package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LitElement, TemplateResult } from "lit";
|
|
2
2
|
import { html } from "lit";
|
|
3
3
|
import { customElement, property } from "lit/decorators.js";
|
|
4
|
-
import {
|
|
4
|
+
import { Unit } from "../../../../services/fees/fetchBuildingUnits";
|
|
5
5
|
|
|
6
6
|
import floorplanImageCardStyles from "./floorplan-image-card-styles";
|
|
7
7
|
|
|
@@ -10,30 +10,30 @@ export class FloorplanImageCard extends LitElement {
|
|
|
10
10
|
static styles = floorplanImageCardStyles;
|
|
11
11
|
|
|
12
12
|
@property({ type: Object })
|
|
13
|
-
|
|
13
|
+
unit: Unit = {} as Unit;
|
|
14
14
|
|
|
15
15
|
@property()
|
|
16
|
-
onUnitSelect: ((
|
|
16
|
+
onUnitSelect: ((unit: Unit) => void) | null = null;
|
|
17
17
|
|
|
18
18
|
@property({ type: Boolean })
|
|
19
19
|
selected = false;
|
|
20
20
|
|
|
21
21
|
get bedAndBathText(): string {
|
|
22
|
-
return `${this.
|
|
22
|
+
return `${this.unit.numberOfBedrooms}bd | ${this.unit.numberOfBathrooms}ba`;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
get priceRange(): string {
|
|
26
|
-
if (this.
|
|
27
|
-
return `$${this.
|
|
26
|
+
if (this.unit.startingPrice === this.unit.maxPrice) {
|
|
27
|
+
return `$${this.unit.startingPrice}`;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
return `$${this.
|
|
30
|
+
return `$${this.unit.startingPrice} - $${this.unit.maxPrice}`;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
handleOnUnitSelect(): void {
|
|
34
34
|
if (this.selected) return;
|
|
35
35
|
this.selected = !this.selected;
|
|
36
|
-
this.onUnitSelect?.(this.
|
|
36
|
+
this.onUnitSelect?.(this.unit);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
handleOnImgClick(event: Event): void {
|
|
@@ -47,17 +47,17 @@ export class FloorplanImageCard extends LitElement {
|
|
|
47
47
|
<div class="section-left">
|
|
48
48
|
<img
|
|
49
49
|
@click=${this.handleOnImgClick}
|
|
50
|
-
src="${this.
|
|
51
|
-
alt="${this.
|
|
50
|
+
src="${this.unit.floorplanUrl ?? ""}"
|
|
51
|
+
alt="${this.unit.floorplanName}"
|
|
52
52
|
/>
|
|
53
53
|
</div>
|
|
54
54
|
<div class="section-right" @click=${this.handleOnUnitSelect}>
|
|
55
55
|
<p class="image-card-title">
|
|
56
|
-
${this.
|
|
56
|
+
${this.unit.floorplanName} | ${this.priceRange}
|
|
57
57
|
</p>
|
|
58
58
|
<p class="image-card-subtitle">
|
|
59
|
-
${this.bedAndBathText} | ${this.
|
|
60
|
-
${this.
|
|
59
|
+
${this.bedAndBathText} | ${this.unit.squareFootage} ft |
|
|
60
|
+
${this.unit.earliestAvailable}
|
|
61
61
|
</p>
|
|
62
62
|
</div>
|
|
63
63
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./promo-card/promo-card";
|
|
2
2
|
export * from "./floor-plan-selector/floor-plan-selector";
|
|
3
3
|
export * from "./fee-card/fee-card";
|
|
4
|
-
export * from "./addon-item/addon-item";
|
|
4
|
+
export * from "./addons/addon-item/addon-item";
|
|
5
5
|
export * from "./fee-calculator-layout/fee-calculator-layout";
|