@meetelise/chat 1.29.0 → 1.30.1

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.
Files changed (228) hide show
  1. package/dist/src/MyPubnub.d.ts +116 -0
  2. package/dist/src/WebComponent/FeeCalculator/components/addon-item/addon-item-styles.d.ts +2 -0
  3. package/dist/src/WebComponent/FeeCalculator/components/addon-item/addon-item.d.ts +22 -0
  4. package/dist/src/WebComponent/FeeCalculator/components/addon-item/index.d.ts +1 -0
  5. package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.d.ts +2 -0
  6. package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.d.ts +34 -0
  7. package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.d.ts +2 -0
  8. package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card.d.ts +21 -0
  9. package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.d.ts +2 -0
  10. package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item.d.ts +13 -0
  11. package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.d.ts +2 -0
  12. package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.d.ts +33 -0
  13. package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.d.ts +2 -0
  14. package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.d.ts +18 -0
  15. package/dist/src/WebComponent/FeeCalculator/components/index.d.ts +5 -0
  16. package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.d.ts +2 -0
  17. package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card.d.ts +13 -0
  18. package/dist/src/WebComponent/FeeCalculator/constants.d.ts +2 -0
  19. package/dist/src/WebComponent/FeeCalculator/fee-calculator-styles.d.ts +1 -0
  20. package/dist/src/WebComponent/FeeCalculator/fee-calculator.d.ts +59 -0
  21. package/dist/src/WebComponent/FeeCalculator/index.d.ts +2 -0
  22. package/dist/src/WebComponent/FeeCalculator/model/building-fee.d.ts +80 -0
  23. package/dist/src/WebComponent/FeeCalculator/model/transaction-category.d.ts +23 -0
  24. package/dist/src/WebComponent/LeadSourceClient.d.ts +46 -0
  25. package/dist/src/WebComponent/OfficeHours.d.ts +21 -0
  26. package/dist/src/WebComponent/Scheduler/date-picker.d.ts +28 -0
  27. package/dist/src/WebComponent/Scheduler/time-picker.d.ts +14 -0
  28. package/dist/src/WebComponent/Scheduler/tour-scheduler.d.ts +100 -0
  29. package/dist/src/WebComponent/Scheduler/tour-type-option.d.ts +13 -0
  30. package/dist/src/WebComponent/Scheduler/tourSchedulerStyles.d.ts +1 -0
  31. package/dist/src/WebComponent/actions/InputStyles.d.ts +1 -0
  32. package/dist/src/WebComponent/actions/action-confirm-button.d.ts +13 -0
  33. package/dist/src/WebComponent/actions/call-us-window.d.ts +37 -0
  34. package/dist/src/WebComponent/actions/collapse-expand-button.d.ts +8 -0
  35. package/dist/src/WebComponent/actions/details-window.d.ts +14 -0
  36. package/dist/src/WebComponent/actions/email-us-window.d.ts +46 -0
  37. package/dist/src/WebComponent/actions/formatPhoneNumber.d.ts +17 -0
  38. package/dist/src/WebComponent/actions/minimize-expand-button.d.ts +8 -0
  39. package/dist/src/WebComponent/chat-additional-actions.d.ts +28 -0
  40. package/dist/src/WebComponent/health-chat.d.ts +47 -0
  41. package/dist/src/WebComponent/healthchat-styles.d.ts +1 -0
  42. package/dist/src/WebComponent/icons/ApplyOutlineIcon.d.ts +2 -0
  43. package/dist/src/WebComponent/icons/BookTourOutlineIcon.d.ts +2 -0
  44. package/dist/src/WebComponent/icons/CalculatorOutlineIcon.d.ts +2 -0
  45. package/dist/src/WebComponent/icons/ChatOutlineIcon.d.ts +2 -0
  46. package/dist/src/WebComponent/icons/ChevronLeftIcon.d.ts +2 -0
  47. package/dist/src/WebComponent/icons/ChevronRightIcon.d.ts +2 -0
  48. package/dist/src/WebComponent/icons/ContactResidentIcon.d.ts +2 -0
  49. package/dist/src/WebComponent/icons/DollarOutlineIcon.d.ts +3 -0
  50. package/dist/src/WebComponent/icons/EmailOutlineIcon.d.ts +2 -0
  51. package/dist/src/WebComponent/icons/HeyThereEmojiIcon.d.ts +2 -0
  52. package/dist/src/WebComponent/icons/PhoneOutlineIcon.d.ts +2 -0
  53. package/dist/src/WebComponent/icons/SendMessageIcon.d.ts +3 -0
  54. package/dist/src/WebComponent/icons/TourSelfGuidedIcon.d.ts +2 -0
  55. package/dist/src/WebComponent/icons/TourVirtuallyIcon.d.ts +2 -0
  56. package/dist/src/WebComponent/icons/TourWithAgentIcon.d.ts +2 -0
  57. package/dist/src/WebComponent/icons/XOutlineIcon.d.ts +2 -0
  58. package/dist/src/WebComponent/index.d.ts +2 -0
  59. package/dist/src/WebComponent/launcher/Launcher.d.ts +98 -0
  60. package/dist/src/WebComponent/launcher/launcherStyles.d.ts +1 -0
  61. package/dist/src/WebComponent/launcher/mobile-launcher.d.ts +27 -0
  62. package/dist/src/WebComponent/launcher/typeEmojiStyles.d.ts +1 -0
  63. package/dist/src/WebComponent/launcher/typeMiniStyles.d.ts +1 -0
  64. package/dist/src/WebComponent/launcher/typeMobileStyles.d.ts +1 -0
  65. package/dist/src/WebComponent/leasing-chat-styles.d.ts +1 -0
  66. package/dist/src/WebComponent/me-chat.d.ts +91 -0
  67. package/dist/src/WebComponent/me-select.d.ts +24 -0
  68. package/dist/src/WebComponent/mega-loader.d.ts +7 -0
  69. package/dist/src/WebComponent/mini-loader.d.ts +5 -0
  70. package/dist/src/WebComponent/pubnub-chat-styles.d.ts +1 -0
  71. package/dist/src/WebComponent/pubnub-chat.d.ts +49 -0
  72. package/dist/src/WebComponent/pubnub-media.d.ts +14 -0
  73. package/dist/src/WebComponent/pubnub-message-styles.d.ts +1 -0
  74. package/dist/src/WebComponent/pubnub-message.d.ts +39 -0
  75. package/dist/src/WebComponent/simple-launcher/simple-launcher-styles.d.ts +1 -0
  76. package/dist/src/WebComponent/simple-launcher/simple-launcher.d.ts +12 -0
  77. package/dist/src/WebComponent/utilities-chat.d.ts +47 -0
  78. package/dist/src/WebComponent/utilities-styles.d.ts +1 -0
  79. package/dist/src/WebComponent/utils.d.ts +31 -0
  80. package/dist/src/analytics.d.ts +64 -0
  81. package/dist/src/disclaimers.d.ts +8 -0
  82. package/dist/src/fetchBuildingABTestType.d.ts +8 -0
  83. package/dist/src/fetchBuildingInfo.d.ts +57 -0
  84. package/dist/src/fetchBuildingWebchatView.d.ts +123 -0
  85. package/dist/src/fetchFeatureFlag.d.ts +14 -0
  86. package/dist/src/fetchLeadSources.d.ts +4 -0
  87. package/dist/src/fetchPhoneNumberFromSource.d.ts +6 -0
  88. package/dist/src/getAvailabilities.d.ts +45 -0
  89. package/dist/src/getBuildingPhoneNumber.d.ts +1 -0
  90. package/dist/src/getShouldAllowScheduling.d.ts +1 -0
  91. package/dist/src/getShouldShowWebchat.d.ts +3 -0
  92. package/dist/src/getTimezoneString.d.ts +1 -0
  93. package/dist/src/globals.d.ts +1 -0
  94. package/dist/src/gtm.d.ts +6 -0
  95. package/dist/src/handleChatId.d.ts +11 -0
  96. package/dist/src/insertDNIIntoWebsite.d.ts +5 -0
  97. package/dist/src/insertLeadSourceIntoSchedulerLinks.d.ts +4 -0
  98. package/dist/src/main/MEChat.d.ts +74 -0
  99. package/dist/src/main/utils.d.ts +2 -0
  100. package/dist/src/postLeadSources.d.ts +3 -0
  101. package/dist/src/rentgrata.d.ts +4 -0
  102. package/dist/src/replaceSelectButtonsWithNewLink.d.ts +5 -0
  103. package/dist/src/services/fees/calculateQuote.d.ts +52 -0
  104. package/dist/src/services/fees/fetchBuildingFees.d.ts +24 -0
  105. package/dist/src/services/fees/fetchBuildingFloorplans.d.ts +21 -0
  106. package/dist/src/services/fees/utils.d.ts +1 -0
  107. package/dist/src/svgIcons.d.ts +5 -0
  108. package/dist/src/themes.d.ts +5 -0
  109. package/dist/src/types/rest-sdk.types.d.ts +11 -0
  110. package/dist/src/types/webchat-no-show-reason.d.ts +1 -0
  111. package/dist/src/utils.d.ts +13 -0
  112. package/package.json +1 -1
  113. package/public/dist/index.js +384 -179
  114. package/src/MyPubnub.ts +792 -0
  115. package/src/WebComponent/FeeCalculator/components/addon-item/addon-item-styles.ts +79 -0
  116. package/src/WebComponent/FeeCalculator/components/addon-item/addon-item.ts +121 -0
  117. package/src/WebComponent/FeeCalculator/components/addon-item/index.ts +1 -0
  118. package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.ts +127 -0
  119. package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.ts +191 -0
  120. package/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.ts +65 -0
  121. package/src/WebComponent/FeeCalculator/components/fee-card/fee-card.ts +91 -0
  122. package/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.ts +44 -0
  123. package/src/WebComponent/FeeCalculator/components/fee-item/fee-item.ts +38 -0
  124. package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.ts +144 -0
  125. package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +241 -0
  126. package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.ts +74 -0
  127. package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.ts +72 -0
  128. package/src/WebComponent/FeeCalculator/components/index.ts +5 -0
  129. package/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.ts +39 -0
  130. package/src/WebComponent/FeeCalculator/components/promo-card/promo-card.ts +39 -0
  131. package/src/WebComponent/FeeCalculator/constants.ts +3 -0
  132. package/src/WebComponent/FeeCalculator/fee-calculator-styles.ts +334 -0
  133. package/src/WebComponent/FeeCalculator/fee-calculator.ts +369 -0
  134. package/src/WebComponent/FeeCalculator/index.ts +4 -0
  135. package/src/WebComponent/FeeCalculator/model/building-fee.ts +120 -0
  136. package/src/WebComponent/FeeCalculator/model/transaction-category.ts +23 -0
  137. package/src/WebComponent/LeadSourceClient.ts +332 -0
  138. package/src/WebComponent/MEChat.css +5 -0
  139. package/src/WebComponent/OfficeHours.ts +73 -0
  140. package/src/WebComponent/Scheduler/date-picker.ts +405 -0
  141. package/src/WebComponent/Scheduler/time-picker.ts +190 -0
  142. package/src/WebComponent/Scheduler/tour-scheduler.ts +1373 -0
  143. package/src/WebComponent/Scheduler/tour-type-option.ts +112 -0
  144. package/src/WebComponent/Scheduler/tourSchedulerStyles.ts +418 -0
  145. package/src/WebComponent/actions/InputStyles.ts +57 -0
  146. package/src/WebComponent/actions/action-confirm-button.ts +125 -0
  147. package/src/WebComponent/actions/call-us-window.ts +445 -0
  148. package/src/WebComponent/actions/collapse-expand-button.ts +65 -0
  149. package/src/WebComponent/actions/details-window.ts +150 -0
  150. package/src/WebComponent/actions/email-us-window.ts +555 -0
  151. package/src/WebComponent/actions/formatPhoneNumber.ts +72 -0
  152. package/src/WebComponent/actions/minimize-expand-button.ts +93 -0
  153. package/src/WebComponent/chat-additional-actions.ts +135 -0
  154. package/src/WebComponent/health-chat.ts +270 -0
  155. package/src/WebComponent/healthchat-styles.ts +119 -0
  156. package/src/WebComponent/icons/ApplyOutlineIcon.ts +22 -0
  157. package/src/WebComponent/icons/BookTourOutlineIcon.ts +13 -0
  158. package/src/WebComponent/icons/CalculatorOutlineIcon.ts +22 -0
  159. package/src/WebComponent/icons/ChatOutlineIcon.ts +10 -0
  160. package/src/WebComponent/icons/ChevronLeftIcon.ts +7 -0
  161. package/src/WebComponent/icons/ChevronRightIcon.ts +7 -0
  162. package/src/WebComponent/icons/ContactResidentIcon.ts +9 -0
  163. package/src/WebComponent/icons/DollarOutlineIcon.ts +18 -0
  164. package/src/WebComponent/icons/EmailOutlineIcon.ts +7 -0
  165. package/src/WebComponent/icons/HeyThereEmojiIcon.ts +12 -0
  166. package/src/WebComponent/icons/PhoneOutlineIcon.ts +7 -0
  167. package/src/WebComponent/icons/SendMessageIcon.ts +17 -0
  168. package/src/WebComponent/icons/TourSelfGuidedIcon.ts +17 -0
  169. package/src/WebComponent/icons/TourVirtuallyIcon.ts +17 -0
  170. package/src/WebComponent/icons/TourWithAgentIcon.ts +17 -0
  171. package/src/WebComponent/icons/XOutlineIcon.ts +8 -0
  172. package/src/WebComponent/index.ts +2 -0
  173. package/src/WebComponent/launcher/Launcher.ts +1282 -0
  174. package/src/WebComponent/launcher/launcherStyles.ts +500 -0
  175. package/src/WebComponent/launcher/mobile-launcher.ts +162 -0
  176. package/src/WebComponent/launcher/typeEmojiStyles.ts +161 -0
  177. package/src/WebComponent/launcher/typeMiniStyles.ts +60 -0
  178. package/src/WebComponent/launcher/typeMobileStyles.ts +50 -0
  179. package/src/WebComponent/leasing-chat-styles.ts +114 -0
  180. package/src/WebComponent/me-chat.ts +1262 -0
  181. package/src/WebComponent/me-select.ts +322 -0
  182. package/src/WebComponent/mega-loader.ts +36 -0
  183. package/src/WebComponent/mini-loader.ts +28 -0
  184. package/src/WebComponent/pubnub-chat-styles.ts +204 -0
  185. package/src/WebComponent/pubnub-chat.ts +928 -0
  186. package/src/WebComponent/pubnub-media.ts +208 -0
  187. package/src/WebComponent/pubnub-message-styles.ts +54 -0
  188. package/src/WebComponent/pubnub-message.ts +431 -0
  189. package/src/WebComponent/simple-launcher/simple-launcher-styles.ts +34 -0
  190. package/src/WebComponent/simple-launcher/simple-launcher.ts +100 -0
  191. package/src/WebComponent/utilities-chat.ts +270 -0
  192. package/src/WebComponent/utilities-styles.ts +110 -0
  193. package/src/WebComponent/utils.ts +82 -0
  194. package/src/analytics.ts +217 -0
  195. package/src/assetUrls.ts +6 -0
  196. package/src/disclaimers.ts +58 -0
  197. package/src/fetchBuildingABTestType.ts +21 -0
  198. package/src/fetchBuildingInfo.ts +87 -0
  199. package/src/fetchBuildingWebchatView.ts +156 -0
  200. package/src/fetchFeatureFlag.ts +250 -0
  201. package/src/fetchLeadSources.ts +98 -0
  202. package/src/fetchPhoneNumberFromSource.ts +31 -0
  203. package/src/fetchWebchatPreferences.ts +54 -0
  204. package/src/getAvailabilities.ts +179 -0
  205. package/src/getBuildingPhoneNumber.ts +26 -0
  206. package/src/getShouldAllowScheduling.ts +16 -0
  207. package/src/getShouldShowWebchat.ts +114 -0
  208. package/src/getTimezoneString.ts +39 -0
  209. package/src/globals.ts +1 -0
  210. package/src/gtm.ts +17 -0
  211. package/src/handleChatId.ts +101 -0
  212. package/src/insertDNIIntoWebsite.ts +146 -0
  213. package/src/insertLeadSourceIntoSchedulerLinks.ts +71 -0
  214. package/src/main/MEChat.test.ts +110 -0
  215. package/src/main/MEChat.ts +404 -0
  216. package/src/main/utils.ts +70 -0
  217. package/src/postLeadSources.ts +44 -0
  218. package/src/rentgrata.ts +74 -0
  219. package/src/replaceSelectButtonsWithNewLink.ts +69 -0
  220. package/src/services/fees/calculateQuote.ts +135 -0
  221. package/src/services/fees/fetchBuildingFees.ts +63 -0
  222. package/src/services/fees/fetchBuildingFloorplans.ts +74 -0
  223. package/src/services/fees/utils.ts +4 -0
  224. package/src/svgIcons.ts +14 -0
  225. package/src/themes.ts +65 -0
  226. package/src/types/rest-sdk.types.ts +13 -0
  227. package/src/types/webchat-no-show-reason.ts +6 -0
  228. package/src/utils.ts +121 -0
@@ -0,0 +1,135 @@
1
+ import axios from "axios";
2
+
3
+ import { LogType, sendLoggingEvent } from "../../analytics";
4
+ import { BASE_DOMAIN } from "../../globals";
5
+ import { RentableItemSummary } from "./fetchBuildingFees";
6
+ import {
7
+ camelize,
8
+ formatCurrency,
9
+ sentenceTitleCase,
10
+ snakify,
11
+ } from "../../utils";
12
+
13
+ type CalculateQuoteRequest = {
14
+ buildingSlug: string;
15
+ unitId: number;
16
+ addons: DesiredAddon[];
17
+ rentableItems: DesiredRentableItem[];
18
+ leaseTerm: number;
19
+ moveInDate: string;
20
+ };
21
+
22
+ export type DesiredAddon = {
23
+ id: number;
24
+ quantity: number;
25
+ type: string;
26
+ };
27
+
28
+ export type DesiredRentableItem = {
29
+ id: number;
30
+ quantity: number;
31
+ type: string;
32
+ };
33
+
34
+ export type CalculateQuoteResponse = {
35
+ units: UnitFeeBundle[];
36
+ };
37
+
38
+ type UnitFeeBundle = {
39
+ unitId: number;
40
+ unitNumber: string;
41
+ rent: number;
42
+ fees: FeeEstimate[];
43
+ feeTotal: number;
44
+ rentableItems: RentableItemSummary[];
45
+ rentableItemTotal: number;
46
+ };
47
+
48
+ export class FeeEstimate {
49
+ name: string;
50
+ description?: string | null;
51
+ amount: number;
52
+ frequency: string;
53
+ addOnType?: string;
54
+ applicable?: boolean;
55
+ required?: boolean;
56
+ adjustments?: FeeAdjustment[];
57
+ comment?: string;
58
+
59
+ constructor(data: FeeEstimate) {
60
+ this.name = data.name;
61
+ this.description = data.description;
62
+ this.amount = data.amount;
63
+ this.frequency = data.frequency;
64
+ this.addOnType = data.addOnType;
65
+ this.applicable = data.applicable;
66
+ this.required = data.required;
67
+ this.adjustments = data.adjustments;
68
+ this.comment = data.comment;
69
+ }
70
+
71
+ get displayAmount(): string {
72
+ return formatCurrency(this.amount);
73
+ }
74
+
75
+ get displayName(): string {
76
+ return sentenceTitleCase(this.name);
77
+ }
78
+
79
+ get isAddOn(): boolean {
80
+ return !!this.addOnType;
81
+ }
82
+ }
83
+
84
+ type FeeAdjustment = {
85
+ reason: string;
86
+ amount: number;
87
+ };
88
+
89
+ export const calculateQuote = async ({
90
+ buildingSlug,
91
+ unitId,
92
+ addons,
93
+ rentableItems,
94
+ leaseTerm,
95
+ moveInDate,
96
+ }: CalculateQuoteRequest): Promise<CalculateQuoteResponse> => {
97
+ try {
98
+ const feesResponse = await axios.post(
99
+ `${BASE_DOMAIN}/platformApi/webchat/${buildingSlug}/fees/calculate`,
100
+ snakify({
101
+ unitId,
102
+ addons,
103
+ rentableItems,
104
+ leaseTerm,
105
+ moveInDate,
106
+ })
107
+ );
108
+
109
+ if (feesResponse.data) {
110
+ const data = camelize<CalculateQuoteResponse>(feesResponse.data);
111
+ return {
112
+ ...data,
113
+ units: data.units.map((unit) => ({
114
+ ...unit,
115
+ fees: unit.fees.map(toFeeEstimateClass),
116
+ })),
117
+ };
118
+ }
119
+ } catch (error) {
120
+ sendLoggingEvent({
121
+ logType: LogType.error,
122
+ buildingSlug,
123
+ logTitle: "[ERROR_CALCULATING_QUOTE]",
124
+ logData: { error },
125
+ });
126
+ }
127
+
128
+ return {
129
+ units: [],
130
+ };
131
+ };
132
+
133
+ const toFeeEstimateClass = (fee: FeeEstimate) => new FeeEstimate(fee);
134
+
135
+ export default calculateQuote;
@@ -0,0 +1,63 @@
1
+ import axios from "axios";
2
+ import { LogType, sendLoggingEvent } from "../../analytics";
3
+ import { BASE_DOMAIN } from "../../globals";
4
+ import { BuildingFee } from "../../WebComponent/FeeCalculator/model/building-fee";
5
+ import { camelize } from "../../utils";
6
+
7
+ type BuildingFeeResponse = {
8
+ fees: BuildingFee[];
9
+ rentableItems: RentableItemSummary[];
10
+ };
11
+
12
+ export type RentFrequency = "monthly" | "annually";
13
+
14
+ type RentableItem = {
15
+ id: string;
16
+ description: string;
17
+ rent: number;
18
+ rentFrequency: RentFrequency;
19
+ available: boolean;
20
+ reservedUntil?: Date;
21
+ };
22
+
23
+ export type RentableItemSummary = {
24
+ description: string;
25
+ type: string;
26
+ minAvailableItem?: RentableItem;
27
+ maxAvailableItem?: RentableItem;
28
+ allItems: RentableItem[];
29
+ rent?: number;
30
+ };
31
+
32
+ const fetchBuildingFees = async (
33
+ buildingSlug: string
34
+ ): Promise<BuildingFeeResponse> => {
35
+ try {
36
+ const feesResponse = await axios.get(
37
+ `${BASE_DOMAIN}/platformApi/webchat/${buildingSlug}/fees`
38
+ );
39
+ if (feesResponse.data) {
40
+ const data = camelize<BuildingFeeResponse>(feesResponse.data);
41
+ return {
42
+ fees: data.fees.map(toBuildingFeeClass),
43
+ rentableItems: data.rentableItems,
44
+ };
45
+ }
46
+ } catch (error) {
47
+ sendLoggingEvent({
48
+ logType: LogType.error,
49
+ buildingSlug,
50
+ logTitle: "[ERROR_GETTING_FEES]",
51
+ logData: { error },
52
+ });
53
+ }
54
+
55
+ return {
56
+ fees: [],
57
+ rentableItems: [],
58
+ };
59
+ };
60
+
61
+ const toBuildingFeeClass = (fee: BuildingFee) => new BuildingFee(fee);
62
+
63
+ export default fetchBuildingFees;
@@ -0,0 +1,74 @@
1
+ import axios from "axios";
2
+ import { LogType, sendLoggingEvent } from "../../analytics";
3
+ import { BASE_DOMAIN } from "../../globals";
4
+ import { camelize } from "../../utils";
5
+
6
+ export type Floorplan = {
7
+ unitId: number;
8
+ name: string;
9
+ bedrooms: number;
10
+ bathrooms: number;
11
+ numAvailable: number;
12
+ startingPrice: number;
13
+ maxPrice: number;
14
+ earliestAvailable: string;
15
+ latestAvailable: string;
16
+ squareFeet: number;
17
+ url: string | null;
18
+ };
19
+
20
+ type FetchFloorplansParams = {
21
+ buildingSlug: string;
22
+ numBedrooms?: number;
23
+ moveInDateEarliest?: Date;
24
+ moveInDateLatest?: Date;
25
+ };
26
+
27
+ const fetchBuildingFloorplans = async ({
28
+ buildingSlug,
29
+ numBedrooms,
30
+ moveInDateEarliest,
31
+ moveInDateLatest,
32
+ }: FetchFloorplansParams): Promise<Floorplan[]> => {
33
+ try {
34
+ const params = new URLSearchParams();
35
+ if (numBedrooms) {
36
+ params.append("num_bedrooms", numBedrooms.toString());
37
+ }
38
+ if (moveInDateEarliest) {
39
+ params.append(
40
+ "move_in_date_earliest",
41
+ moveInDateEarliest.toISOString().split("T")[0]
42
+ );
43
+ }
44
+ if (moveInDateLatest) {
45
+ params.append(
46
+ "move_in_date_latest",
47
+ moveInDateLatest.toISOString().split("T")[0]
48
+ );
49
+ }
50
+
51
+ const queryString = params.toString() ? `?${params.toString()}` : "";
52
+ const floorplansResponse = await axios.get(
53
+ `${BASE_DOMAIN}/platformApi/webchat/${buildingSlug}/floorplans${queryString}`
54
+ );
55
+
56
+ if (floorplansResponse.data) {
57
+ return camelize<Floorplan[]>(floorplansResponse.data);
58
+ }
59
+ } catch (error) {
60
+ sendLoggingEvent({
61
+ logType: LogType.error,
62
+ buildingSlug,
63
+ logTitle: "[ERROR_GETTING_FLOORPLANS]",
64
+ logData: {
65
+ error,
66
+ params: { numBedrooms, moveInDateEarliest, moveInDateLatest },
67
+ },
68
+ });
69
+ }
70
+
71
+ return [];
72
+ };
73
+
74
+ export default fetchBuildingFloorplans;
@@ -0,0 +1,4 @@
1
+ export const layoutToBedrooms = (layout: number): number => {
2
+ if (layout === 0) return 0; // Studio
3
+ return Math.floor(layout / 10);
4
+ };
@@ -0,0 +1,14 @@
1
+ import { svg } from "lit";
2
+
3
+ /**
4
+ * TODO(erol): PLEASE MOVE INTO EACH OWN ICON FILE UNDER /ICONS
5
+ */
6
+
7
+ export const CheckboxEmpty = svg`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
8
+ <rect x="1" y="1" width="22" height="22" stroke="black" stroke-width="2" rx="2"/>
9
+ </svg>
10
+ `;
11
+ export const CheckboxChecked = svg`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
12
+ <rect y="0.09375" width="16" height="16" rx="2" fill="#4719CD"/>
13
+ <path d="M12 5.09375L6.5 10.5938L4 8.09375" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
14
+ </svg>`;
package/src/themes.ts ADDED
@@ -0,0 +1,65 @@
1
+ export const defaultPrimaryColor = "#646987"; // we have a brand color defined in the BE too, but this is a fallback
2
+ export const defaultBackgroundColor = "#ffffff"; // default background color for the chat widget
3
+
4
+ export const tintColor = (
5
+ originalColor: string,
6
+ tintOpacity: number
7
+ ): string => {
8
+ const originalRgb = hexToRgb(originalColor);
9
+ const tintRgb = { r: 0, g: 0, b: 0 };
10
+
11
+ const newRgb = {
12
+ r: originalRgb.r + Math.round((tintRgb.r - originalRgb.r) * tintOpacity),
13
+ g: originalRgb.g + Math.round((tintRgb.g - originalRgb.g) * tintOpacity),
14
+ b: originalRgb.b + Math.round((tintRgb.b - originalRgb.b) * tintOpacity),
15
+ };
16
+
17
+ return rgbToHex(newRgb.r, newRgb.g, newRgb.b);
18
+ };
19
+
20
+ const hexToRgb = (hex: string): { r: number; g: number; b: number } => {
21
+ const r = parseInt(hex.substring(1, 3), 16);
22
+ const g = parseInt(hex.substring(3, 5), 16);
23
+ const b = parseInt(hex.substring(5, 7), 16);
24
+ return { r, g, b };
25
+ };
26
+
27
+ const rgbToHex = (r: number, g: number, b: number): string => {
28
+ return (
29
+ "#" +
30
+ [r, g, b]
31
+ .map((c) => {
32
+ const hex = c.toString(16);
33
+ return hex.length === 1 ? "0" + hex : hex;
34
+ })
35
+ .join("")
36
+ );
37
+ };
38
+
39
+ export const hexToAlmostWhite = (hexColor: string, ratio: number): string => {
40
+ let r = parseInt(hexColor.substr(1, 2), 16);
41
+ let g = parseInt(hexColor.substr(3, 2), 16);
42
+ let b = parseInt(hexColor.substr(5, 2), 16);
43
+
44
+ // the ratio of white to add (1 = white, 0 = no change)
45
+ r = Math.round(r * (1 - ratio) + 255 * ratio);
46
+ g = Math.round(g * (1 - ratio) + 255 * ratio);
47
+ b = Math.round(b * (1 - ratio) + 255 * ratio);
48
+
49
+ return (
50
+ "#" +
51
+ r.toString(16).padStart(2, "0") +
52
+ g.toString(16).padStart(2, "0") +
53
+ b.toString(16).padStart(2, "0")
54
+ );
55
+ };
56
+
57
+ export const shouldUsePrimaryColorForChatFooter = (
58
+ orgId: number,
59
+ buildingId: number
60
+ ): boolean => {
61
+ // Some clients are complaining that we are NOT ADA compliant with our black, default chat footer
62
+ // So we are temporarily adding this flag to allow them to use their brand color for the chat footer
63
+ // Don't want to suddenly change it for our clients so added this flag
64
+ return orgId === 2 || buildingId === 70392;
65
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Redeclare enum from rest-sdk to avoid pulling in entire module.
3
+ */
4
+ export enum TourAvailabilityResponseRankOrderedSupportedTourTypesEnum {
5
+ Unknown = "UNKNOWN",
6
+ SelfGuided = "SELF_GUIDED",
7
+ VirtualShowing = "VIRTUAL_SHOWING",
8
+ WithAgent = "WITH_AGENT",
9
+ MediaTour = "MEDIA_TOUR",
10
+ }
11
+
12
+ // Types are safe to re-export as they are not included in runtime code.
13
+ export type { TourAvailabilityResponse } from "@meetelise/rest-sdk";
@@ -0,0 +1,6 @@
1
+ export type WebchatNoShowReason =
2
+ | "building_does_not_exist"
3
+ | "building_not_launched"
4
+ | "building_not_active"
5
+ | "building_in_maintenance_mode"
6
+ | "building_not_webchat_scope_configured";
package/src/utils.ts ADDED
@@ -0,0 +1,121 @@
1
+ import camelCase from "lodash/camelCase";
2
+ import snakeCase from "lodash/snakeCase";
3
+ import isArray from "lodash/isArray";
4
+ import isObject from "lodash/isObject";
5
+ import transform from "lodash/transform";
6
+ import addHours from "date-fns/addHours";
7
+ import isBefore from "date-fns/isBefore";
8
+ import { BASE_DOMAIN } from "./globals";
9
+
10
+ export const camelize = <T>(
11
+ snakeCasedObject: Record<string, unknown>,
12
+ keysToExclude?: (string | number | symbol)[]
13
+ ): T =>
14
+ transform(
15
+ snakeCasedObject,
16
+ (acc: Record<string, unknown>, value, key, target) => {
17
+ const camelKey = keysToExclude?.includes(key)
18
+ ? key
19
+ : isArray(target)
20
+ ? key
21
+ : camelCase(String(key));
22
+
23
+ acc[camelKey] = isObject(value)
24
+ ? camelize(value as Record<string, unknown>, keysToExclude)
25
+ : value;
26
+ }
27
+ ) as T;
28
+
29
+ export const snakify = <T>(
30
+ snakeCasedObject: Record<string, unknown>,
31
+ keysToExclude?: (string | number | symbol)[]
32
+ ): T =>
33
+ transform(
34
+ snakeCasedObject,
35
+ (acc: Record<string, unknown>, value, key, target) => {
36
+ const snakeKey = keysToExclude?.includes(key)
37
+ ? key
38
+ : isArray(target)
39
+ ? key
40
+ : snakeCase(String(key));
41
+
42
+ acc[snakeKey] = isObject(value)
43
+ ? snakify(value as Record<string, unknown>, keysToExclude)
44
+ : value;
45
+ }
46
+ ) as T;
47
+
48
+ export const isMobile = (): boolean =>
49
+ window.matchMedia("(max-width: 767px)").matches ||
50
+ window.matchMedia("(max-height: 400px)").matches;
51
+
52
+ export const isTimestampExpired = (
53
+ timestamp: Date,
54
+ ttlHours: number
55
+ ): boolean => {
56
+ const expirationDate = addHours(timestamp, ttlHours);
57
+ return isBefore(expirationDate, Date.now());
58
+ };
59
+
60
+ export const getCookieValue = (name: string): string | null => {
61
+ try {
62
+ const cookies = document.cookie.split("; ");
63
+ const cookiePair = cookies
64
+ .map((cookie) => cookie.split("="))
65
+ .find(([cookieName]) => cookieName === name);
66
+
67
+ return cookiePair ? decodeURIComponent(cookiePair[1]) : null;
68
+ } catch (e) {
69
+ // For debugging purposes if something happens on a client website
70
+ // eslint-disable-next-line no-console
71
+ console.warn(`Error getting cookie value for name=${name}`, e);
72
+ return null;
73
+ }
74
+ };
75
+
76
+ export const isValidPhoneNumber = (phoneNumber: string): boolean => {
77
+ const phoneNumberRegex = /^\([2-9][0-8][0-9]\) [2-9][0-9][0-9]-[0-9]{4}$/;
78
+ return phoneNumberRegex.test(phoneNumber);
79
+ };
80
+
81
+ export const isContainingEmail = (message: string): boolean => {
82
+ try {
83
+ const emailRegex = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b/;
84
+ return emailRegex.test(message);
85
+ } catch (e) {
86
+ // eslint-disable-next-line no-console
87
+ console.warn(`Error checking if message contains email`, e);
88
+ return false;
89
+ }
90
+ };
91
+
92
+ /**
93
+ * FooBarBizzBazz -> Foo Bar Bizz Bazz
94
+ */
95
+ export const sentenceTitleCase = (str: string): string => {
96
+ const spaced = str.replace(/([A-Z])/g, " $1").trim();
97
+ return spaced
98
+ .split(" ")
99
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
100
+ .join(" ");
101
+ };
102
+
103
+ export const formatCurrency = (
104
+ amount: number,
105
+ maximumFractionDigits = 0
106
+ ): string => {
107
+ return Intl.NumberFormat("en-US", {
108
+ style: "currency",
109
+ currency: "USD",
110
+ minimumFractionDigits: 0,
111
+ maximumFractionDigits,
112
+ }).format(amount ?? 0);
113
+ };
114
+
115
+ export const isTestEnv = (): boolean => {
116
+ const href = location.href;
117
+ if (href.startsWith(BASE_DOMAIN + "/settings/widgets")) return true;
118
+ if (href.startsWith(BASE_DOMAIN + "/demo")) return true;
119
+ if (href.startsWith("http://localhost")) return true;
120
+ return false;
121
+ };