@axos-web-dev/shared-components 2.2.29 → 2.2.31
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/Auth/ErrorAlert.js +1 -1
- package/dist/Calculators/Calculator.js +1 -1
- package/dist/Chatbot/ChatWindow.css.js +1 -0
- package/dist/Chatbot/ChatWindow.d.ts +1 -0
- package/dist/Chatbot/ChatWindow.js +5 -10
- package/dist/Chatbot/Chatbot.css.js +0 -1
- package/dist/Chatbot/Chatbot.js +75 -42
- package/dist/Chatbot/ChatbotMessage.d.ts +1 -0
- package/dist/Chatbot/ChatbotMessage.js +2 -1
- package/dist/Chatbot/store/messages.d.ts +6 -1
- package/dist/Chatbot/store/messages.js +62 -3
- package/dist/Forms/MortgageRate/MortgageRateForm.js +26 -8
- package/dist/Forms/MortgageRate/MortgageRateQuoteFilters.js +33 -11
- package/dist/Forms/MortgageRate/MortgageRateWatch.d.ts +1 -1
- package/dist/Forms/MortgageRate/MortgageRateWatch.js +90 -17
- package/dist/Forms/SuccesForm.js +1 -1
- package/dist/Input/DownPaymentInput.js +1 -0
- package/dist/assets/ImageBillboard/ImageBillboard.css +12 -0
- package/package.json +1 -1
package/dist/Auth/ErrorAlert.js
CHANGED
|
@@ -73,8 +73,8 @@ import "../Carousel/index.js";
|
|
|
73
73
|
/* empty css */
|
|
74
74
|
import "../Chatbot/store/chat.js";
|
|
75
75
|
import "../Chatbot/Chatbot.js";
|
|
76
|
-
import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
|
|
77
76
|
import "../LoadingIndicator/LoadingIndicator.css.js";
|
|
77
|
+
import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
|
|
78
78
|
/* empty css */
|
|
79
79
|
import "../Chatbot/store/messages.js";
|
|
80
80
|
import { Hyperlink } from "../Hyperlink/index.js";
|
|
@@ -54,9 +54,9 @@ import "../Carousel/index.js";
|
|
|
54
54
|
/* empty css */
|
|
55
55
|
import "../Chatbot/store/chat.js";
|
|
56
56
|
import "../Chatbot/Chatbot.js";
|
|
57
|
-
import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
|
|
58
57
|
import "../LoadingIndicator/LoadingIndicator.css.js";
|
|
59
58
|
import "react-use";
|
|
59
|
+
import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
|
|
60
60
|
/* empty css */
|
|
61
61
|
import "../Chatbot/store/messages.js";
|
|
62
62
|
/* empty css */
|
|
@@ -3,6 +3,7 @@ import '../assets/Chatbot/ChatWindow.css';import '../assets/Typography/Typograph
|
|
|
3
3
|
/* empty css */
|
|
4
4
|
/* empty css */
|
|
5
5
|
/* empty css */
|
|
6
|
+
import "./Chatbot.css.ts.vanilla.css.js";
|
|
6
7
|
/* empty css */
|
|
7
8
|
var windowStyle = "_13n1jqk1";
|
|
8
9
|
var windowExpandedStyle = "_13n1jqk2";
|
|
@@ -18,7 +18,6 @@ import { useOpenChat } from "./store/chat.js";
|
|
|
18
18
|
import { ThankYouMessage } from "./ThankYouMessage.js";
|
|
19
19
|
const ChatWindow = ({
|
|
20
20
|
messages,
|
|
21
|
-
status = "connected",
|
|
22
21
|
onSend,
|
|
23
22
|
inputDisabled = false,
|
|
24
23
|
onClose,
|
|
@@ -43,7 +42,6 @@ const ChatWindow = ({
|
|
|
43
42
|
showThankyouMessage,
|
|
44
43
|
toggleThankyouMessage,
|
|
45
44
|
hasEscalated,
|
|
46
|
-
isBlockedInput,
|
|
47
45
|
isOpen,
|
|
48
46
|
hasOpenedOnce,
|
|
49
47
|
chatStatus,
|
|
@@ -65,7 +63,6 @@ const ChatWindow = ({
|
|
|
65
63
|
const handleSend = (e) => {
|
|
66
64
|
e.preventDefault();
|
|
67
65
|
const cleaned = cleanInput(input);
|
|
68
|
-
if (isBlockedInput) return;
|
|
69
66
|
if (cleaned != "") {
|
|
70
67
|
onSend(cleaned);
|
|
71
68
|
setInput("");
|
|
@@ -460,7 +457,7 @@ const ChatWindow = ({
|
|
|
460
457
|
}
|
|
461
458
|
) }) : null,
|
|
462
459
|
/* @__PURE__ */ jsxs("div", { className: clsx(messagesContainerStyle), children: [
|
|
463
|
-
|
|
460
|
+
!messages.some((msg) => !msg.pending) && /* @__PURE__ */ jsx(
|
|
464
461
|
"div",
|
|
465
462
|
{
|
|
466
463
|
className: clsx(),
|
|
@@ -525,9 +522,7 @@ const ChatWindow = ({
|
|
|
525
522
|
/* @__PURE__ */ jsx(
|
|
526
523
|
"div",
|
|
527
524
|
{
|
|
528
|
-
className: clsx(
|
|
529
|
-
focused && !inputDisabled && !isBlockedInput ? focusAnimation : ""
|
|
530
|
-
),
|
|
525
|
+
className: clsx(focused && !inputDisabled ? focusAnimation : ""),
|
|
531
526
|
style: {
|
|
532
527
|
position: "absolute",
|
|
533
528
|
left: "10%",
|
|
@@ -544,7 +539,7 @@ const ChatWindow = ({
|
|
|
544
539
|
style: {
|
|
545
540
|
display: "flex",
|
|
546
541
|
padding: "12px 16px",
|
|
547
|
-
background:
|
|
542
|
+
background: inputDisabled || escalationDeflected ? "light-dark(rgba(239, 239, 239, 0.3), rgba(59, 59, 59, 0.3))" : "#ffffff",
|
|
548
543
|
borderRadius: 12
|
|
549
544
|
},
|
|
550
545
|
children: [
|
|
@@ -568,7 +563,7 @@ const ChatWindow = ({
|
|
|
568
563
|
"aria-label": "Ask anything...",
|
|
569
564
|
className: clsx(inputStyle, autoResize),
|
|
570
565
|
autoFocus: true,
|
|
571
|
-
disabled:
|
|
566
|
+
disabled: inputDisabled || escalationDeflected,
|
|
572
567
|
rows: 1
|
|
573
568
|
}
|
|
574
569
|
),
|
|
@@ -582,7 +577,7 @@ const ChatWindow = ({
|
|
|
582
577
|
type: "submit",
|
|
583
578
|
title: "Send message",
|
|
584
579
|
"aria-label": "Send message",
|
|
585
|
-
disabled:
|
|
580
|
+
disabled: inputDisabled || !input.trim() || escalationDeflected,
|
|
586
581
|
children: /* @__PURE__ */ jsx(
|
|
587
582
|
"svg",
|
|
588
583
|
{
|
package/dist/Chatbot/Chatbot.js
CHANGED
|
@@ -40,17 +40,34 @@ const Chatbot = ({
|
|
|
40
40
|
hideDisplayThankyouMessage
|
|
41
41
|
} = useOpenChat();
|
|
42
42
|
const isVisible = usePageVisibility();
|
|
43
|
-
const {
|
|
43
|
+
const {
|
|
44
|
+
addMessage,
|
|
45
|
+
addMessages,
|
|
46
|
+
clearMessages,
|
|
47
|
+
messages,
|
|
48
|
+
addPendingMessage,
|
|
49
|
+
resolvePendingMessage
|
|
50
|
+
} = useMessages();
|
|
44
51
|
const clientRef = useRef(null);
|
|
45
52
|
const menuRef = useRef(null);
|
|
46
53
|
const isMountedRef = useRef(false);
|
|
47
54
|
const chatRef = useRef(null);
|
|
48
55
|
const chatLoading = useRef(false);
|
|
49
56
|
const agent_virtual = useRef(null);
|
|
57
|
+
const messageQueueRef = useRef([]);
|
|
58
|
+
const sendInFlightRef = useRef(false);
|
|
59
|
+
const flushingRef = useRef(false);
|
|
60
|
+
const statusRef = useRef("idle");
|
|
50
61
|
const [status, setStatus] = useState("idle");
|
|
51
62
|
const [menusLoaded, setMenusLoaded] = useState(false);
|
|
52
63
|
const [isTyping, setIsTyping] = useState(false);
|
|
53
64
|
const [scalationStarted, setScalationStarted] = useState(false);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
statusRef.current = status;
|
|
67
|
+
if (status === "connected") {
|
|
68
|
+
flushQueuedMessages();
|
|
69
|
+
}
|
|
70
|
+
}, [status]);
|
|
54
71
|
useEffect(() => {
|
|
55
72
|
if (messages.length === 0) return;
|
|
56
73
|
const hasScalation = messages.some(
|
|
@@ -67,6 +84,9 @@ const Chatbot = ({
|
|
|
67
84
|
["axos", 1],
|
|
68
85
|
["ufb", 3]
|
|
69
86
|
]);
|
|
87
|
+
const hasRealReply = () => useMessages.getState().messages.some(
|
|
88
|
+
(m) => !m.pending && m.$userType !== "end_user" && m.type !== "noti" && m.$sid !== "typing-1"
|
|
89
|
+
);
|
|
70
90
|
const typingMessage = {
|
|
71
91
|
$sid: "typing-1",
|
|
72
92
|
type: "system",
|
|
@@ -107,7 +127,7 @@ const Chatbot = ({
|
|
|
107
127
|
menuRef.current = await clientRef.current.getMenus();
|
|
108
128
|
setMenusLoaded(true);
|
|
109
129
|
console.log("menus:", menuRef.current);
|
|
110
|
-
if (menuRef.current !== null) {
|
|
130
|
+
if (menuRef.current !== null && useOpenChat.getState().isOpen) {
|
|
111
131
|
await startChat("onReady");
|
|
112
132
|
}
|
|
113
133
|
}
|
|
@@ -121,10 +141,11 @@ const Chatbot = ({
|
|
|
121
141
|
const onChatMessageHandler = async (message) => {
|
|
122
142
|
console.log("Received message:", message);
|
|
123
143
|
const { event, $userType } = message;
|
|
124
|
-
if (["
|
|
144
|
+
if (["virtual_agent", "user"].includes($userType) && event === void 0) {
|
|
125
145
|
addMessage(message);
|
|
126
146
|
if (!hasEscalated) {
|
|
127
147
|
unblockInput?.();
|
|
148
|
+
flushQueuedMessages();
|
|
128
149
|
}
|
|
129
150
|
return;
|
|
130
151
|
}
|
|
@@ -205,6 +226,7 @@ const Chatbot = ({
|
|
|
205
226
|
startEscalation?.();
|
|
206
227
|
}
|
|
207
228
|
}
|
|
229
|
+
flushQueuedMessages();
|
|
208
230
|
} catch (error) {
|
|
209
231
|
console.error("Error fetching messages on chat connected:", error);
|
|
210
232
|
}
|
|
@@ -226,7 +248,7 @@ const Chatbot = ({
|
|
|
226
248
|
const deregisterEventHandlers = () => {
|
|
227
249
|
clientRef.current?.off("ready", onReadyHandler);
|
|
228
250
|
clientRef.current?.off("authenticated", onAuthenticatedHandler);
|
|
229
|
-
clientRef.current?.off("chat.ongoing",
|
|
251
|
+
clientRef.current?.off("chat.ongoing", onChatOngoingHandler);
|
|
230
252
|
clientRef.current?.off("chat.message", onChatMessageHandler);
|
|
231
253
|
clientRef.current?.off("chat.typingStarted", onChatTypingStartedHandler);
|
|
232
254
|
clientRef.current?.off("chat.typingEnded", onChatTypingEndedHandler);
|
|
@@ -340,6 +362,41 @@ const Chatbot = ({
|
|
|
340
362
|
setChatStarted();
|
|
341
363
|
}
|
|
342
364
|
};
|
|
365
|
+
const sendNow = async (msg) => {
|
|
366
|
+
sendInFlightRef.current = true;
|
|
367
|
+
let success = true;
|
|
368
|
+
try {
|
|
369
|
+
await clientRef.current?.sendTextMessage(msg);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
console.log(error);
|
|
372
|
+
success = false;
|
|
373
|
+
} finally {
|
|
374
|
+
sendInFlightRef.current = false;
|
|
375
|
+
if (!hasEscalated) {
|
|
376
|
+
blockInput?.();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return success;
|
|
380
|
+
};
|
|
381
|
+
const flushQueuedMessages = async () => {
|
|
382
|
+
if (flushingRef.current) return;
|
|
383
|
+
if (messageQueueRef.current.length === 0) return;
|
|
384
|
+
if (!clientRef.current || statusRef.current !== "connected") return;
|
|
385
|
+
if (!hasRealReply()) return;
|
|
386
|
+
flushingRef.current = true;
|
|
387
|
+
try {
|
|
388
|
+
while (messageQueueRef.current.length > 0 && !useOpenChat.getState().isBlockedInput && !sendInFlightRef.current) {
|
|
389
|
+
const next = messageQueueRef.current[0];
|
|
390
|
+
const success = await sendNow(next.text);
|
|
391
|
+
messageQueueRef.current.shift();
|
|
392
|
+
if (!success) {
|
|
393
|
+
resolvePendingMessage(next.id);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
} finally {
|
|
397
|
+
flushingRef.current = false;
|
|
398
|
+
}
|
|
399
|
+
};
|
|
343
400
|
const onSendMessage = async (msg) => {
|
|
344
401
|
const clientChatId = clientRef.current?.chat?.id;
|
|
345
402
|
const refChatId = chatRef.current?.id;
|
|
@@ -351,15 +408,16 @@ const Chatbot = ({
|
|
|
351
408
|
"| chatRef.id:",
|
|
352
409
|
refChatId
|
|
353
410
|
);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
411
|
+
const notReady = !clientRef.current || statusRef.current !== "connected";
|
|
412
|
+
const isThinking = useOpenChat.getState().isBlockedInput;
|
|
413
|
+
const noReplyYet = !hasRealReply();
|
|
414
|
+
if (notReady || isThinking || sendInFlightRef.current || noReplyYet) {
|
|
415
|
+
const id = `pending-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
416
|
+
messageQueueRef.current.push({ id, text: msg });
|
|
417
|
+
addPendingMessage(id, msg);
|
|
418
|
+
return;
|
|
362
419
|
}
|
|
420
|
+
await sendNow(msg);
|
|
363
421
|
};
|
|
364
422
|
const onEndChat = async () => {
|
|
365
423
|
console.log(`Ending chat [end chat]`);
|
|
@@ -373,6 +431,9 @@ const Chatbot = ({
|
|
|
373
431
|
clearMessages();
|
|
374
432
|
chatRef.current = null;
|
|
375
433
|
resetChatStarted();
|
|
434
|
+
messageQueueRef.current = [];
|
|
435
|
+
sendInFlightRef.current = false;
|
|
436
|
+
flushingRef.current = false;
|
|
376
437
|
console.log("Chat ended");
|
|
377
438
|
endEscalation?.();
|
|
378
439
|
} finally {
|
|
@@ -399,6 +460,8 @@ const Chatbot = ({
|
|
|
399
460
|
console.log("Chatbot unmounted");
|
|
400
461
|
deregisterEventHandlers();
|
|
401
462
|
chatLoading.current = false;
|
|
463
|
+
messageQueueRef.current = [];
|
|
464
|
+
sendInFlightRef.current = false;
|
|
402
465
|
reset();
|
|
403
466
|
resetChatStarted();
|
|
404
467
|
setStatus("idle");
|
|
@@ -443,36 +506,6 @@ const Chatbot = ({
|
|
|
443
506
|
}
|
|
444
507
|
}
|
|
445
508
|
}, [isOpen, isVisible]);
|
|
446
|
-
useMount(() => {
|
|
447
|
-
const hasParams = () => {
|
|
448
|
-
return window.location.search.includes("utm_");
|
|
449
|
-
};
|
|
450
|
-
const tryStart = () => {
|
|
451
|
-
if (hasParams()) {
|
|
452
|
-
startChat("utm-ready");
|
|
453
|
-
return true;
|
|
454
|
-
}
|
|
455
|
-
return false;
|
|
456
|
-
};
|
|
457
|
-
if (tryStart()) return;
|
|
458
|
-
const original = history.replaceState;
|
|
459
|
-
history.replaceState = function(...args) {
|
|
460
|
-
original.apply(this, args);
|
|
461
|
-
if (tryStart()) {
|
|
462
|
-
history.replaceState = original;
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
const interval = setInterval(() => {
|
|
466
|
-
if (tryStart()) {
|
|
467
|
-
clearInterval(interval);
|
|
468
|
-
history.replaceState = original;
|
|
469
|
-
}
|
|
470
|
-
}, 100);
|
|
471
|
-
return () => {
|
|
472
|
-
clearInterval(interval);
|
|
473
|
-
history.replaceState = original;
|
|
474
|
-
};
|
|
475
|
-
});
|
|
476
509
|
return menusLoaded && /* @__PURE__ */ jsxs(
|
|
477
510
|
"div",
|
|
478
511
|
{
|
|
@@ -108,6 +108,7 @@ const ChatbotMessage = ({
|
|
|
108
108
|
messageStyle,
|
|
109
109
|
msg.$userType == "end_user" ? user_msg : agent_msg
|
|
110
110
|
),
|
|
111
|
+
style: msg.pending ? { opacity: 0.65 } : void 0,
|
|
111
112
|
children: /* @__PURE__ */ jsxs(
|
|
112
113
|
"div",
|
|
113
114
|
{
|
|
@@ -253,7 +254,7 @@ const ChatbotMessage = ({
|
|
|
253
254
|
textTransform: "capitalize",
|
|
254
255
|
fontFamily: "inherit"
|
|
255
256
|
},
|
|
256
|
-
children: timeText
|
|
257
|
+
children: msg.pending ? "Sending..." : timeText
|
|
257
258
|
}
|
|
258
259
|
)
|
|
259
260
|
]
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { MessageResponse } from '@ujet/websdk-headless';
|
|
2
2
|
|
|
3
|
+
export type PendingMessage = MessageResponse & {
|
|
4
|
+
pending?: boolean;
|
|
5
|
+
};
|
|
3
6
|
interface MessageStore {
|
|
4
|
-
messages: Array<
|
|
7
|
+
messages: Array<PendingMessage>;
|
|
5
8
|
addMessage: (message: MessageResponse) => void;
|
|
6
9
|
removeMessage: (id: string) => void;
|
|
7
10
|
addMessages: (newMessages: MessageResponse[]) => void;
|
|
8
11
|
clearMessages: () => void;
|
|
9
12
|
isEscalated: boolean;
|
|
13
|
+
addPendingMessage: (id: string, text: string) => void;
|
|
14
|
+
resolvePendingMessage: (id: string) => void;
|
|
10
15
|
}
|
|
11
16
|
export interface Message {
|
|
12
17
|
id: string;
|
|
@@ -3,18 +3,77 @@ const useMessages = create((set, get) => ({
|
|
|
3
3
|
messages: [],
|
|
4
4
|
addMessage: (message) => set((state) => {
|
|
5
5
|
const cleaned = state.messages.filter((m) => m.$sid !== "typing-1");
|
|
6
|
-
|
|
6
|
+
const isPending = message.pending;
|
|
7
|
+
if (!isPending && message.$userType === "end_user") {
|
|
8
|
+
const pendingIdx = cleaned.findIndex(
|
|
9
|
+
(m) => m.pending && m.content === message.content
|
|
10
|
+
);
|
|
11
|
+
if (pendingIdx !== -1) {
|
|
12
|
+
return {
|
|
13
|
+
messages: [
|
|
14
|
+
...cleaned.slice(0, pendingIdx),
|
|
15
|
+
message,
|
|
16
|
+
...cleaned.slice(pendingIdx + 1)
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return { messages: [...cleaned, message] };
|
|
21
|
+
}
|
|
22
|
+
const insertBeforeIdx = !isPending ? cleaned.findIndex((m) => m.pending) : -1;
|
|
23
|
+
if (insertBeforeIdx === -1) {
|
|
24
|
+
return { messages: [...cleaned, message] };
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
messages: [
|
|
28
|
+
...cleaned.slice(0, insertBeforeIdx),
|
|
29
|
+
message,
|
|
30
|
+
...cleaned.slice(insertBeforeIdx)
|
|
31
|
+
]
|
|
32
|
+
};
|
|
7
33
|
}),
|
|
8
34
|
removeMessage: (id) => set((state) => ({
|
|
9
35
|
messages: state.messages.filter(
|
|
10
36
|
(msg) => "$sid" in msg && msg.$sid !== id
|
|
11
37
|
)
|
|
12
38
|
})),
|
|
13
|
-
addMessages: (newMessages) => set((state) =>
|
|
39
|
+
addMessages: (newMessages) => set((state) => {
|
|
40
|
+
const pendingIdx = state.messages.findIndex(
|
|
41
|
+
(m) => m.pending
|
|
42
|
+
);
|
|
43
|
+
if (pendingIdx === -1) {
|
|
44
|
+
return { messages: [...state.messages, ...newMessages] };
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
messages: [
|
|
48
|
+
...state.messages.slice(0, pendingIdx),
|
|
49
|
+
...newMessages,
|
|
50
|
+
...state.messages.slice(pendingIdx)
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
}),
|
|
14
54
|
clearMessages: () => set({ messages: [] }),
|
|
15
55
|
isEscalated: get()?.messages?.some(
|
|
16
56
|
(msg) => ["escalationAccepted", "escalationStarted"].includes(msg.event)
|
|
17
|
-
)
|
|
57
|
+
),
|
|
58
|
+
addPendingMessage: (id, text) => set((state) => ({
|
|
59
|
+
messages: [
|
|
60
|
+
...state.messages,
|
|
61
|
+
{
|
|
62
|
+
$sid: id,
|
|
63
|
+
type: "text",
|
|
64
|
+
content: text,
|
|
65
|
+
sender: { id: "end_user", type: "end_user" },
|
|
66
|
+
$timestamp: /* @__PURE__ */ new Date(),
|
|
67
|
+
$userType: "end_user",
|
|
68
|
+
$index: Date.now(),
|
|
69
|
+
$userId: 0,
|
|
70
|
+
pending: true
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
})),
|
|
74
|
+
resolvePendingMessage: (id) => set((state) => ({
|
|
75
|
+
messages: state.messages.filter((msg) => msg.$sid !== id)
|
|
76
|
+
}))
|
|
18
77
|
}));
|
|
19
78
|
export {
|
|
20
79
|
useMessages
|
|
@@ -22,7 +22,7 @@ import clsx from "clsx";
|
|
|
22
22
|
import "../../Accordion/Accordion.js";
|
|
23
23
|
import "../../Accordion/Accordion.css.js";
|
|
24
24
|
import "../../AlertBanner/AlertBanner.css.js";
|
|
25
|
-
import { useState, useEffect } from "react";
|
|
25
|
+
import { useState, useRef, useEffect, useLayoutEffect } from "react";
|
|
26
26
|
import "../../Article/Article.css.js";
|
|
27
27
|
import "../../ArticlesSet/ArticlesSet.css.js";
|
|
28
28
|
import "../../Calculators/calculator.css.js";
|
|
@@ -134,6 +134,7 @@ import "../../StepItemSet/StepItemSet.css.js";
|
|
|
134
134
|
/* empty css */
|
|
135
135
|
/* empty css */
|
|
136
136
|
/* empty css */
|
|
137
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
137
138
|
const MortgageRate = ({
|
|
138
139
|
icon = false,
|
|
139
140
|
children,
|
|
@@ -159,6 +160,8 @@ const MortgageRate = ({
|
|
|
159
160
|
const [_downPayment, setDownPayment] = useState(0);
|
|
160
161
|
const [isTypingDownPayment, setIsTypingDownPayment] = useState(false);
|
|
161
162
|
const [salesPriceVal, setSalesPriceVal] = useState(0);
|
|
163
|
+
const containerRef = useRef(null);
|
|
164
|
+
const restoreScrollOnNextRender = useRef(false);
|
|
162
165
|
const cachedEmailValidator = useCachedEmailValidator(validateEmail);
|
|
163
166
|
const schema = z.object({
|
|
164
167
|
firstName: z.string({ message: "First Name is required." }).regex(/^[A-Za-z][^0-9_!¡?÷?¿/\\+=@#$%ˆ&*,.^(){}|~<>;:[\]]{1,}$/g, {
|
|
@@ -295,6 +298,17 @@ const MortgageRate = ({
|
|
|
295
298
|
methods.setValue("downPayment", calculatedDownPayment);
|
|
296
299
|
}
|
|
297
300
|
}, [salesPrice, downPaymentPercentage]);
|
|
301
|
+
useIsomorphicLayoutEffect(() => {
|
|
302
|
+
if (!restoreScrollOnNextRender.current) return;
|
|
303
|
+
restoreScrollOnNextRender.current = false;
|
|
304
|
+
const anchorViewport = () => {
|
|
305
|
+
const target = showingTables && containerRef.current?.nextElementSibling || containerRef.current;
|
|
306
|
+
target?.scrollIntoView({ block: "start" });
|
|
307
|
+
};
|
|
308
|
+
anchorViewport();
|
|
309
|
+
const raf = requestAnimationFrame(anchorViewport);
|
|
310
|
+
return () => cancelAnimationFrame(raf);
|
|
311
|
+
}, [hideModal, showingTables]);
|
|
298
312
|
const submitForm = async (data) => {
|
|
299
313
|
const processData = {
|
|
300
314
|
...data
|
|
@@ -303,6 +317,7 @@ const MortgageRate = ({
|
|
|
303
317
|
if (setRateWatchSubmitted) {
|
|
304
318
|
setRateWatchSubmitted(false);
|
|
305
319
|
}
|
|
320
|
+
restoreScrollOnNextRender.current = true;
|
|
306
321
|
setHideModal(true);
|
|
307
322
|
};
|
|
308
323
|
const variant = getVariant(fullVariant);
|
|
@@ -366,7 +381,7 @@ const MortgageRate = ({
|
|
|
366
381
|
}
|
|
367
382
|
return value;
|
|
368
383
|
};
|
|
369
|
-
return /* @__PURE__ */ jsxs(
|
|
384
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, children: [
|
|
370
385
|
hideModal && !showingTables && /* @__PURE__ */ jsx(
|
|
371
386
|
"section",
|
|
372
387
|
{
|
|
@@ -442,9 +457,9 @@ const MortgageRate = ({
|
|
|
442
457
|
{
|
|
443
458
|
className: form,
|
|
444
459
|
onSubmit: async (e) => {
|
|
460
|
+
e.preventDefault();
|
|
445
461
|
onValidate && onValidate(e);
|
|
446
462
|
await handleSubmit(submitForm)(e);
|
|
447
|
-
e.preventDefault();
|
|
448
463
|
},
|
|
449
464
|
children: [
|
|
450
465
|
/* @__PURE__ */ jsxs("div", { className: clsx(formWrapper({ variant })), children: [
|
|
@@ -794,12 +809,15 @@ const MortgageRate = ({
|
|
|
794
809
|
{
|
|
795
810
|
id,
|
|
796
811
|
className: `${chevron({ variant })} ${!isValid ? na_cursor : ""}`,
|
|
797
|
-
onClick:
|
|
798
|
-
await onSubmit(data);
|
|
799
|
-
toggleModal();
|
|
800
|
-
setHideModal(false);
|
|
801
|
-
}) : (e) => {
|
|
812
|
+
onClick: (e) => {
|
|
802
813
|
e.preventDefault();
|
|
814
|
+
if (!isValid) return;
|
|
815
|
+
handleSubmit(async (data) => {
|
|
816
|
+
await onSubmit(data);
|
|
817
|
+
restoreScrollOnNextRender.current = true;
|
|
818
|
+
toggleModal();
|
|
819
|
+
setHideModal(false);
|
|
820
|
+
})(e);
|
|
803
821
|
},
|
|
804
822
|
children: "Sign Up For Ratewatch"
|
|
805
823
|
}
|
|
@@ -36,7 +36,7 @@ const MortgageRateFilters = ({
|
|
|
36
36
|
loanPurpose: z.number({ message: "Loan Purpose is required." }),
|
|
37
37
|
propertyType: z.number({ message: "Property Type is required." }).positive({ message: "Property Type is required." }),
|
|
38
38
|
occupancy: z.number({ message: "Property Usage is required." }).positive({ message: "Property Usage is required." }),
|
|
39
|
-
salesPrice: z.number({ message: "Purchase Price is required." }).refine((val) => loanPurpose === 1 ? val != null : true, {
|
|
39
|
+
salesPrice: z.number({ message: "Purchase Price is required." }).optional().refine((val) => loanPurpose === 1 ? val != null : true, {
|
|
40
40
|
message: "Sales Price is required."
|
|
41
41
|
}).refine(
|
|
42
42
|
(val) => {
|
|
@@ -47,7 +47,7 @@ const MortgageRateFilters = ({
|
|
|
47
47
|
},
|
|
48
48
|
{ message: "Value must be between $50,000 and $25,000,000." }
|
|
49
49
|
),
|
|
50
|
-
downPayment: z.number({ message: "Down Payment is required." }).refine((val) => loanPurpose === 1 ? val != null : true, {
|
|
50
|
+
downPayment: z.number({ message: "Down Payment is required." }).optional().refine((val) => loanPurpose === 1 ? val != null : true, {
|
|
51
51
|
message: "Down Payment is required."
|
|
52
52
|
}).refine(
|
|
53
53
|
(val) => {
|
|
@@ -61,8 +61,8 @@ const MortgageRateFilters = ({
|
|
|
61
61
|
}
|
|
62
62
|
),
|
|
63
63
|
creditScore: z.number({ message: "Credit Score is required." }).positive({ message: "Credit Score is required." }),
|
|
64
|
-
zipCode: z.number({ message: "Zip Code is required." }),
|
|
65
|
-
appraisedValue: z.number({ message: "Home Price is required." }).refine(
|
|
64
|
+
zipCode: z.number({ message: "Zip Code is required." }).int({ message: "Zip Code must be a valid 5-digit zip code." }).gte(1e4, { message: "Zip Code must be a valid 5-digit zip code." }).lte(99999, { message: "Zip Code must be a valid 5-digit zip code." }),
|
|
65
|
+
appraisedValue: z.number({ message: "Home Price is required." }).optional().refine(
|
|
66
66
|
(val) => {
|
|
67
67
|
if (loanPurpose === 2) {
|
|
68
68
|
return val != null && val >= 5e4 && val <= 25e6;
|
|
@@ -71,7 +71,7 @@ const MortgageRateFilters = ({
|
|
|
71
71
|
},
|
|
72
72
|
{ message: "Value must be between $50,000 and $25,000,000." }
|
|
73
73
|
),
|
|
74
|
-
mortgageBalance: z.number({ message: "Mortgage Balance is required." }).refine(
|
|
74
|
+
mortgageBalance: z.number({ message: "Mortgage Balance is required." }).optional().refine(
|
|
75
75
|
(val) => {
|
|
76
76
|
if (loanPurpose === 2) {
|
|
77
77
|
return val != null && val >= 5e4 && val <= 25e6;
|
|
@@ -80,7 +80,7 @@ const MortgageRateFilters = ({
|
|
|
80
80
|
},
|
|
81
81
|
{ message: "Value must be between $50,000 and $25,000,000." }
|
|
82
82
|
),
|
|
83
|
-
cashOut: z.number({ message: "Cash Out is required." }).refine(
|
|
83
|
+
cashOut: z.number({ message: "Cash Out is required." }).optional().refine(
|
|
84
84
|
(val) => {
|
|
85
85
|
if (loanPurpose === 2 && val == null) {
|
|
86
86
|
return false;
|
|
@@ -92,7 +92,19 @@ const MortgageRateFilters = ({
|
|
|
92
92
|
});
|
|
93
93
|
const methods = useForm({
|
|
94
94
|
resolver: zodResolver(schema),
|
|
95
|
-
mode: "all"
|
|
95
|
+
mode: "all",
|
|
96
|
+
defaultValues: {
|
|
97
|
+
loanPurpose: formData.loanPurpose,
|
|
98
|
+
propertyType: formData.propertyType,
|
|
99
|
+
occupancy: formData.occupancy,
|
|
100
|
+
salesPrice: formData.salesPrice,
|
|
101
|
+
downPayment: formData.downPayment,
|
|
102
|
+
creditScore: formData.creditScore,
|
|
103
|
+
zipCode: formData.zipCode,
|
|
104
|
+
appraisedValue: formData.appraisedValue,
|
|
105
|
+
mortgageBalance: formData.mortgageBalance,
|
|
106
|
+
cashOut: formData.cashOut
|
|
107
|
+
}
|
|
96
108
|
});
|
|
97
109
|
const {
|
|
98
110
|
handleSubmit,
|
|
@@ -102,10 +114,10 @@ const MortgageRateFilters = ({
|
|
|
102
114
|
} = methods;
|
|
103
115
|
const salesPrice = watch("salesPrice");
|
|
104
116
|
useEffect(() => {
|
|
105
|
-
setSalesPriceVal(salesPrice);
|
|
117
|
+
setSalesPriceVal(salesPrice ?? 0);
|
|
106
118
|
});
|
|
107
119
|
useEffect(() => {
|
|
108
|
-
if (salesPrice > 0 && !isTypingDownPayment) {
|
|
120
|
+
if (salesPrice != null && salesPrice > 0 && !isTypingDownPayment) {
|
|
109
121
|
const calculatedDownPayment = Math.round(
|
|
110
122
|
salesPrice * downPaymentPercentage / 100
|
|
111
123
|
);
|
|
@@ -115,7 +127,16 @@ const MortgageRateFilters = ({
|
|
|
115
127
|
}, [salesPrice, downPaymentPercentage]);
|
|
116
128
|
const submitForm = async (data) => {
|
|
117
129
|
const processData = {
|
|
118
|
-
|
|
130
|
+
loanPurpose: data.loanPurpose,
|
|
131
|
+
propertyType: data.propertyType,
|
|
132
|
+
occupancy: data.occupancy,
|
|
133
|
+
creditScore: data.creditScore,
|
|
134
|
+
zipCode: data.zipCode,
|
|
135
|
+
salesPrice: data.salesPrice ?? 0,
|
|
136
|
+
downPayment: data.downPayment ?? 0,
|
|
137
|
+
appraisedValue: data.appraisedValue ?? 0,
|
|
138
|
+
mortgageBalance: data.mortgageBalance ?? 0,
|
|
139
|
+
cashOut: data.cashOut ?? 0
|
|
119
140
|
};
|
|
120
141
|
await onSubmit(processData);
|
|
121
142
|
};
|
|
@@ -391,7 +412,8 @@ const MortgageRateFilters = ({
|
|
|
391
412
|
inputMode: "numeric",
|
|
392
413
|
...register("zipCode", {
|
|
393
414
|
required: true,
|
|
394
|
-
pattern: /^\d{5}
|
|
415
|
+
pattern: /^\d{5}$/,
|
|
416
|
+
setValueAs: (value) => Number(value)
|
|
395
417
|
}),
|
|
396
418
|
label: "Zip Code",
|
|
397
419
|
sizes: "medium",
|
|
@@ -136,12 +136,34 @@ const RateWatchForm = ({
|
|
|
136
136
|
toggleModal,
|
|
137
137
|
setRateWatchSubmitted
|
|
138
138
|
}) => {
|
|
139
|
+
const desiredRateFields = [
|
|
140
|
+
"tR1DesiredRate",
|
|
141
|
+
"tR2DesiredRate",
|
|
142
|
+
"tR3DesiredRate"
|
|
143
|
+
];
|
|
144
|
+
const sanitizeDesiredRate = (value) => {
|
|
145
|
+
if (!value) return "";
|
|
146
|
+
const normalizedValue = value.replace(/[^\d.]/g, "");
|
|
147
|
+
if (!normalizedValue || normalizedValue === ".") return "";
|
|
148
|
+
const [wholePart, decimalPart = ""] = normalizedValue.split(".");
|
|
149
|
+
const trimmedDecimal = decimalPart.slice(0, 4);
|
|
150
|
+
const formattedValue = trimmedDecimal ? `${wholePart || "0"}.${trimmedDecimal}` : wholePart || "0";
|
|
151
|
+
const numericValue = Number(formattedValue);
|
|
152
|
+
if (!Number.isFinite(numericValue)) return "";
|
|
153
|
+
return Number.isInteger(numericValue) ? String(numericValue) : numericValue.toFixed(4).replace(/\.0+$|(?<=\.\d*)(0+)$/, "").replace(/\.$/, "");
|
|
154
|
+
};
|
|
155
|
+
const isDesiredRateOutOfRange = (value) => {
|
|
156
|
+
if (!value) return false;
|
|
157
|
+
const numericValue = Number(value);
|
|
158
|
+
if (!Number.isFinite(numericValue)) return false;
|
|
159
|
+
return numericValue < 2 || numericValue > 10;
|
|
160
|
+
};
|
|
139
161
|
const [updateType, setUpdateType] = useState(
|
|
140
162
|
"Target Rate"
|
|
141
163
|
);
|
|
142
164
|
const schema = z.object({
|
|
143
165
|
updateType: z.string().min(1, { message: "Update type is required." }),
|
|
144
|
-
updateCadence: z.string().refine((val) => !(updateType === "Frequency" && !val), {
|
|
166
|
+
updateCadence: z.string().optional().refine((val) => !(updateType === "Frequency" && !val), {
|
|
145
167
|
message: "Frequency is required."
|
|
146
168
|
}),
|
|
147
169
|
loanTerms: z.string().optional().refine((val) => !(updateType === "Frequency" && !val), {
|
|
@@ -150,11 +172,13 @@ const RateWatchForm = ({
|
|
|
150
172
|
hasSmsConsent: z.boolean().refine((val) => val === true, {
|
|
151
173
|
message: "You must agree to receive SMS messages."
|
|
152
174
|
}),
|
|
153
|
-
tR1DesiredRate: z.string().optional().refine(
|
|
175
|
+
tR1DesiredRate: z.string().optional().refine((val) => updateType === "Target Rate" ? !!val : true, {
|
|
176
|
+
message: "Desired Rate is required."
|
|
177
|
+
}).refine(
|
|
154
178
|
(val) => {
|
|
155
179
|
if (val && updateType === "Target Rate") {
|
|
156
180
|
const numericValue = +val;
|
|
157
|
-
return
|
|
181
|
+
return numericValue >= 2 && numericValue <= 10;
|
|
158
182
|
}
|
|
159
183
|
return true;
|
|
160
184
|
},
|
|
@@ -193,15 +217,21 @@ const RateWatchForm = ({
|
|
|
193
217
|
email: z.string()
|
|
194
218
|
});
|
|
195
219
|
const methods = useForm({
|
|
196
|
-
resolver: zodResolver(schema)
|
|
220
|
+
resolver: zodResolver(schema),
|
|
221
|
+
mode: "onChange"
|
|
197
222
|
});
|
|
198
223
|
const {
|
|
199
224
|
handleSubmit,
|
|
200
225
|
register,
|
|
201
226
|
formState: { errors, isSubmitting, isValid },
|
|
202
227
|
setValue,
|
|
203
|
-
clearErrors
|
|
228
|
+
clearErrors,
|
|
229
|
+
watch
|
|
204
230
|
} = methods;
|
|
231
|
+
const watchedDesiredRates = watch(desiredRateFields);
|
|
232
|
+
const hasDesiredRateWarning = desiredRateFields.some(
|
|
233
|
+
(_, index) => isDesiredRateOutOfRange(watchedDesiredRates[index])
|
|
234
|
+
);
|
|
205
235
|
const submitForm = async (data) => {
|
|
206
236
|
const processedData = {
|
|
207
237
|
...data,
|
|
@@ -240,12 +270,22 @@ const RateWatchForm = ({
|
|
|
240
270
|
const handleTypeChange = (event) => {
|
|
241
271
|
const value = event.target.value;
|
|
242
272
|
setUpdateType(value);
|
|
273
|
+
methods.setValue("updateType", value, { shouldValidate: true });
|
|
274
|
+
};
|
|
275
|
+
const handleDesiredRateChange = (fieldName) => (event) => {
|
|
276
|
+
const sanitizedValue = sanitizeDesiredRate(event.target.value);
|
|
277
|
+
event.target.value = sanitizedValue;
|
|
278
|
+
setValue(fieldName, sanitizedValue, {
|
|
279
|
+
shouldValidate: true,
|
|
280
|
+
shouldDirty: true,
|
|
281
|
+
shouldTouch: true
|
|
282
|
+
});
|
|
243
283
|
};
|
|
244
284
|
const handleSubmitClick = () => {
|
|
245
285
|
handleSubmit(submitForm)();
|
|
246
286
|
};
|
|
247
287
|
useEffect(() => {
|
|
248
|
-
methods.reset();
|
|
288
|
+
methods.reset({ updateType });
|
|
249
289
|
}, [updateType]);
|
|
250
290
|
return /* @__PURE__ */ jsx("section", { className: "rate-watch-form", children: /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx(
|
|
251
291
|
SuccesFormWrapper,
|
|
@@ -323,7 +363,7 @@ const RateWatchForm = ({
|
|
|
323
363
|
/* @__PURE__ */ jsx("p", { className: mt1Rem, children: "You can establish up to three different targets with one rate watch." }),
|
|
324
364
|
/* @__PURE__ */ jsxs("div", { className: threeColRow, children: [
|
|
325
365
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
326
|
-
/* @__PURE__ */ jsx("label", { className: resposiveLabel, children: "Select a Loan Type
|
|
366
|
+
/* @__PURE__ */ jsx("label", { className: resposiveLabel, children: "Select a Loan Type" }),
|
|
327
367
|
/* @__PURE__ */ jsxs(
|
|
328
368
|
Dropdown,
|
|
329
369
|
{
|
|
@@ -342,18 +382,24 @@ const RateWatchForm = ({
|
|
|
342
382
|
)
|
|
343
383
|
] }),
|
|
344
384
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
345
|
-
/* @__PURE__ */
|
|
385
|
+
/* @__PURE__ */ jsxs("label", { className: resposiveLabel, children: [
|
|
386
|
+
"Desired Rate",
|
|
387
|
+
/* @__PURE__ */ jsx("sup", { children: "*" })
|
|
388
|
+
] }),
|
|
346
389
|
/* @__PURE__ */ jsx(
|
|
347
390
|
Input,
|
|
348
391
|
{
|
|
349
392
|
className: dynPH,
|
|
350
393
|
...register("tR1DesiredRate", {
|
|
351
|
-
setValueAs: (value) => value
|
|
394
|
+
setValueAs: (value) => sanitizeDesiredRate(String(value ?? ""))
|
|
352
395
|
}),
|
|
396
|
+
onChange: handleDesiredRateChange("tR1DesiredRate"),
|
|
353
397
|
type: "number",
|
|
398
|
+
min: "2",
|
|
399
|
+
max: "10",
|
|
354
400
|
placeholder: "Desired Rate",
|
|
355
401
|
error: !!errors.tR1DesiredRate,
|
|
356
|
-
helperText: errors.tR1DesiredRate?.message
|
|
402
|
+
helperText: isDesiredRateOutOfRange(watch("tR1DesiredRate")) ? "Desired Rate must be between 2 and 10." : errors.tR1DesiredRate?.message
|
|
357
403
|
}
|
|
358
404
|
)
|
|
359
405
|
] }),
|
|
@@ -404,9 +450,16 @@ const RateWatchForm = ({
|
|
|
404
450
|
Input,
|
|
405
451
|
{
|
|
406
452
|
className: dynPH,
|
|
407
|
-
...register("tR2DesiredRate"
|
|
408
|
-
|
|
409
|
-
|
|
453
|
+
...register("tR2DesiredRate", {
|
|
454
|
+
setValueAs: (value) => sanitizeDesiredRate(String(value ?? ""))
|
|
455
|
+
}),
|
|
456
|
+
onChange: handleDesiredRateChange("tR2DesiredRate"),
|
|
457
|
+
type: "number",
|
|
458
|
+
min: "2",
|
|
459
|
+
max: "10",
|
|
460
|
+
placeholder: "Desired Rate",
|
|
461
|
+
error: isDesiredRateOutOfRange(watch("tR2DesiredRate")),
|
|
462
|
+
helperText: isDesiredRateOutOfRange(watch("tR2DesiredRate")) ? "Desired Rate must be between 2 and 10." : errors.tR2DesiredRate?.message
|
|
410
463
|
}
|
|
411
464
|
) }),
|
|
412
465
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
|
|
@@ -452,10 +505,17 @@ const RateWatchForm = ({
|
|
|
452
505
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
453
506
|
Input,
|
|
454
507
|
{
|
|
455
|
-
...register("tR3DesiredRate"
|
|
456
|
-
|
|
508
|
+
...register("tR3DesiredRate", {
|
|
509
|
+
setValueAs: (value) => sanitizeDesiredRate(String(value ?? ""))
|
|
510
|
+
}),
|
|
511
|
+
onChange: handleDesiredRateChange("tR3DesiredRate"),
|
|
512
|
+
type: "number",
|
|
513
|
+
min: "2",
|
|
514
|
+
max: "10",
|
|
457
515
|
placeholder: "Desired Rate",
|
|
458
|
-
className: dynPH
|
|
516
|
+
className: dynPH,
|
|
517
|
+
error: isDesiredRateOutOfRange(watch("tR3DesiredRate")),
|
|
518
|
+
helperText: isDesiredRateOutOfRange(watch("tR3DesiredRate")) ? "Desired Rate must be between 2 and 10." : errors.tR3DesiredRate?.message
|
|
459
519
|
}
|
|
460
520
|
) }),
|
|
461
521
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
|
|
@@ -480,7 +540,20 @@ const RateWatchForm = ({
|
|
|
480
540
|
}
|
|
481
541
|
) })
|
|
482
542
|
] }),
|
|
483
|
-
/* @__PURE__ */
|
|
543
|
+
/* @__PURE__ */ jsxs(
|
|
544
|
+
"p",
|
|
545
|
+
{
|
|
546
|
+
className: mt1Rem,
|
|
547
|
+
style: {
|
|
548
|
+
color: hasDesiredRateWarning ? "#d92d20" : void 0,
|
|
549
|
+
fontWeight: hasDesiredRateWarning ? 600 : void 0
|
|
550
|
+
},
|
|
551
|
+
children: [
|
|
552
|
+
/* @__PURE__ */ jsx("sup", { children: "*" }),
|
|
553
|
+
" Please enter a desired rate between 2% and 10%"
|
|
554
|
+
]
|
|
555
|
+
}
|
|
556
|
+
)
|
|
484
557
|
] }),
|
|
485
558
|
/* @__PURE__ */ jsxs("div", { className: modalCheckboxContainer, children: [
|
|
486
559
|
/* @__PURE__ */ jsx(
|
package/dist/Forms/SuccesForm.js
CHANGED
|
@@ -69,9 +69,9 @@ import "../Carousel/index.js";
|
|
|
69
69
|
/* empty css */
|
|
70
70
|
import "../Chatbot/store/chat.js";
|
|
71
71
|
import "../Chatbot/Chatbot.js";
|
|
72
|
-
import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
|
|
73
72
|
import "../LoadingIndicator/LoadingIndicator.css.js";
|
|
74
73
|
import "react-use";
|
|
74
|
+
import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
|
|
75
75
|
/* empty css */
|
|
76
76
|
import "../Chatbot/store/messages.js";
|
|
77
77
|
/* empty css */
|
|
@@ -293,6 +293,12 @@ main > div:nth-last-child(2) > ._1m7m2a0:not(._1m7m2ax) {
|
|
|
293
293
|
.page_body_contents > div:has(._1m7m2ax._1m7m2a4) + div:has(._1m7m2ax._1m7m2a4) {
|
|
294
294
|
padding-top: 0;
|
|
295
295
|
}
|
|
296
|
+
.page_body_contents > div:has(.stacked) {
|
|
297
|
+
padding-bottom: 40px;
|
|
298
|
+
}
|
|
299
|
+
.page_body_contents > div:has(> ._1m7m2ax) {
|
|
300
|
+
padding-block: 56px;
|
|
301
|
+
}
|
|
296
302
|
.page_body_contents > div:has(._1m7m2ax) + div:has(._1m7m2ax) {
|
|
297
303
|
margin-top: 0;
|
|
298
304
|
}
|
|
@@ -459,6 +465,9 @@ main > div:nth-last-child(2) > ._1m7m2a0:not(._1m7m2ax) {
|
|
|
459
465
|
.stacked:first-child {
|
|
460
466
|
padding-top: 42px;
|
|
461
467
|
}
|
|
468
|
+
.page_body_contents > div:has(> ._1m7m2ax) {
|
|
469
|
+
padding-block: 42px;
|
|
470
|
+
}
|
|
462
471
|
}
|
|
463
472
|
@media screen and (max-width: 768px) {
|
|
464
473
|
._1m7m2av {
|
|
@@ -476,6 +485,9 @@ main > div:nth-last-child(2) > ._1m7m2a0:not(._1m7m2ax) {
|
|
|
476
485
|
.stacked:first-child {
|
|
477
486
|
padding-top: 2rem;
|
|
478
487
|
}
|
|
488
|
+
.page_body_contents > div:has(> ._1m7m2ax) {
|
|
489
|
+
padding-block: 2rem;
|
|
490
|
+
}
|
|
479
491
|
}
|
|
480
492
|
@media screen and (max-width: 327px) {
|
|
481
493
|
._1m7m2av {
|