@axos-web-dev/shared-components 2.0.0-dev.33 → 2.0.0-dev.34

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 (64) hide show
  1. package/dist/ATMLocator/ATMLocator.js +1 -1
  2. package/dist/Auth/ErrorAlert.js +1 -1
  3. package/dist/Button/Button.js +1 -1
  4. package/dist/Calculators/ApyCalculator/index.js +76 -4
  5. package/dist/Calculators/Calculator.js +1 -1
  6. package/dist/Calculators/MarginTradingCalculator/index.js +1 -1
  7. package/dist/Carousel/index.js +1 -1
  8. package/dist/Chatbot/Bubble.css.js +1 -0
  9. package/dist/Chatbot/Chatbot.css.js +0 -1
  10. package/dist/Chevron/index.js +1 -1
  11. package/dist/Comparison/Comparison.js +1 -1
  12. package/dist/ExecutiveBio/ExecutiveBio.js +1 -1
  13. package/dist/FaqAccordion/index.js +1 -1
  14. package/dist/FooterSiteMap/AxosBank/FooterSiteMap.js +1 -1
  15. package/dist/Forms/ApplyNow.js +1 -1
  16. package/dist/Forms/ContactUsBusiness.js +1 -1
  17. package/dist/Forms/ContactUsBusinessNameEmail.js +1 -1
  18. package/dist/Forms/ContactUsNMLSId.js +1 -1
  19. package/dist/Forms/CpraRequest.js +1 -1
  20. package/dist/Forms/CraPublicFile.js +1 -1
  21. package/dist/Forms/EmailOnly.js +1 -1
  22. package/dist/Forms/MortgageRate/MortgageRateForm.js +1 -1
  23. package/dist/Forms/MortgageRate/MortgageRateWatch.d.ts +1 -1
  24. package/dist/Forms/MortgageRate/MortgageRateWatch.js +91 -18
  25. package/dist/Forms/MortgageWarehouseLending.js +1 -1
  26. package/dist/Forms/SuccesForm.js +1 -1
  27. package/dist/Hyperlink/index.js +1 -1
  28. package/dist/ImageLink/ImageLink.js +1 -1
  29. package/dist/ImageLink/ImageLinkSet.js +1 -1
  30. package/dist/ImageLink/index.js +1 -1
  31. package/dist/ImageToast/index.js +1 -1
  32. package/dist/Input/DownPaymentInput.js +1 -0
  33. package/dist/Insight/Featured/CategorySelector.js +1 -1
  34. package/dist/Insight/Featured/Featured.js +1 -1
  35. package/dist/Insight/Featured/Header.js +1 -1
  36. package/dist/LandingPageHeader/WithLogin.js +1 -1
  37. package/dist/Modal/Modal.js +1 -1
  38. package/dist/NavigationMenu/AxosALTS/index.js +1 -1
  39. package/dist/NavigationMenu/AxosAdvisor/NavBar.module.js +52 -52
  40. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.js +1 -1
  41. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.module.js +1 -1
  42. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileNavData.js +1 -1
  43. package/dist/NavigationMenu/AxosBank/SubNavBar.js +2 -2
  44. package/dist/NavigationMenu/AxosBank/index.js +1 -1
  45. package/dist/NavigationMenu/LaVictoire/index.js +1 -1
  46. package/dist/NavigationMenu/NavItem/index.js +1 -1
  47. package/dist/NavigationMenu/ServerNavigation/DropwdownButton.js +1 -1
  48. package/dist/NavigationMenu/ServerNavigation/Menu.js +1 -1
  49. package/dist/NavigationMenu/ServerNavigation/MobileMenu/MobileMenu.js +1 -1
  50. package/dist/NavigationMenu/ServerNavigation/MobileMenu/MobileMenu.module.js +27 -27
  51. package/dist/NavigationMenu/ServerNavigation/NavBar.module.js +40 -40
  52. package/dist/NavigationMenu/ServerNavigation/SubNavBar.js +1 -1
  53. package/dist/NavigationMenu/ServerNavigation/SubNavItem.js +1 -1
  54. package/dist/NavigationMenu/ServerNavigation/index.js +1 -1
  55. package/dist/SetContainer/SetContainer.js +1 -1
  56. package/dist/SocialMediaBar/iconsRepository.js +1 -1
  57. package/dist/VideoTile/VideoTile.js +1 -1
  58. package/dist/VideoWrapper/index.js +1 -1
  59. package/dist/assets/NavigationMenu/AxosAdvisor/NavBar.css +609 -609
  60. package/dist/assets/NavigationMenu/AxosBank/MobileMenu/MobileMenu.css +353 -0
  61. package/dist/assets/NavigationMenu/ServerNavigation/MobileMenu/MobileMenu.css +353 -353
  62. package/dist/assets/NavigationMenu/ServerNavigation/NavBar.css +483 -483
  63. package/dist/utils/allowedAxosDomains.js +2 -1
  64. package/package.json +1 -1
@@ -75,10 +75,10 @@ import "../Calculators/MonthlyPaymentCalculator/MonthlyPaymentCalculator.css.js"
75
75
  /* empty css */
76
76
  import "../Carousel/index.js";
77
77
  /* empty css */
78
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
78
79
  /* empty css */
79
80
  import "../Chatbot/store/chat.js";
80
81
  import "../Chatbot/Chatbot.js";
81
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
82
82
  /* empty css */
83
83
  import "../Chatbot/store/messages.js";
84
84
  /* empty css */
@@ -71,10 +71,10 @@ import "./SignInPassword.js";
71
71
  /* empty css */
72
72
  import "../Carousel/index.js";
73
73
  /* empty css */
74
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
74
75
  /* empty css */
75
76
  import "../Chatbot/store/chat.js";
76
77
  import "../Chatbot/Chatbot.js";
77
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
78
78
  import "../LoadingIndicator/LoadingIndicator.css.js";
79
79
  /* empty css */
80
80
  import "../Chatbot/store/messages.js";
@@ -80,10 +80,10 @@ import "../Auth/SignInPassword.js";
80
80
  /* empty css */
81
81
  import "../Carousel/index.js";
82
82
  /* empty css */
83
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
83
84
  /* empty css */
84
85
  import "../Chatbot/store/chat.js";
85
86
  import "../Chatbot/Chatbot.js";
86
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
87
87
  /* empty css */
88
88
  import "../Chatbot/store/messages.js";
89
89
  /* empty css */
@@ -24,6 +24,10 @@ const CALCULATOR_DEFINITIONS = [
24
24
  term: "APY (Annual Percentage Yield)",
25
25
  description: "The rate your money earns in a year, with compounding included."
26
26
  },
27
+ {
28
+ term: "APR (Annual Percentage Rate)",
29
+ description: "The rate your money earns in a year, without compounding."
30
+ },
27
31
  {
28
32
  term: "Months",
29
33
  description: "How long you plan to keep your money in the account."
@@ -143,6 +147,14 @@ const ApyCalculator = ({
143
147
  },
144
148
  [compounding]
145
149
  );
150
+ const getAPY = useCallback(
151
+ (apr) => {
152
+ return Number.parseFloat(
153
+ (((1 + apr / 100 / compounding) ** compounding - 1) * 100).toFixed(2)
154
+ );
155
+ },
156
+ [compounding]
157
+ );
146
158
  const AXOS_ONE_APY = Number(domains.AXOS_ONE_APY) || 4.21;
147
159
  const [initialDeposit, setInitialDeposit] = useState(1e4);
148
160
  const [initialDepositDisplay, setInitialDepositDisplay] = useState(
@@ -150,6 +162,8 @@ const ApyCalculator = ({
150
162
  );
151
163
  const [APY, setAPY] = useState(AXOS_ONE_APY);
152
164
  const [APYDisplay, setAPYDisplay] = useState(APY.toString());
165
+ const [APR, setAPR] = useState(() => getAPR(AXOS_ONE_APY));
166
+ const [APRDisplay, setAPRDisplay] = useState(APR.toString());
153
167
  const [months, setMonths] = useState(12);
154
168
  const [monthsDisplay, setMonthsDisplay] = useState(months.toString());
155
169
  const [monthlyDeposits, setMonthlyDeposits] = useState(100);
@@ -182,10 +196,29 @@ const ApyCalculator = ({
182
196
  };
183
197
  const handleAPYChange = (e) => {
184
198
  const raw = e.target.value;
185
- const num = parseFloat(raw.replace(/[^0-9.]/g, ""));
199
+ const cleaned = raw.replace(/[^0-9.]/g, "");
200
+ const num = parseFloat(cleaned);
186
201
  setAPY(num);
187
- setAPYDisplay(raw.replace(/[^0-9.]/g, ""));
202
+ setAPYDisplay(cleaned);
203
+ const newAPR = Number.isNaN(num) ? NaN : getAPR(num);
204
+ setAPR(newAPR);
205
+ setAPRDisplay(Number.isNaN(newAPR) ? "" : newAPR.toString());
188
206
  };
207
+ const handleAPRChange = (e) => {
208
+ const raw = e.target.value;
209
+ const cleaned = raw.replace(/[^0-9.]/g, "");
210
+ const num = parseFloat(cleaned);
211
+ setAPR(num);
212
+ setAPRDisplay(cleaned);
213
+ const newAPY = Number.isNaN(num) ? NaN : getAPY(num);
214
+ setAPY(newAPY);
215
+ setAPYDisplay(Number.isNaN(newAPY) ? "" : newAPY.toString());
216
+ };
217
+ useEffect(() => {
218
+ const newAPR = Number.isNaN(APY) ? NaN : getAPR(APY);
219
+ setAPR(newAPR);
220
+ setAPRDisplay(Number.isNaN(newAPR) ? "" : newAPR.toString());
221
+ }, [compounding]);
189
222
  const [endingBalanceRaw, setEndingBalanceRaw] = useState(0);
190
223
  const [totalDepositsRaw, setTotalDepositsRaw] = useState(0);
191
224
  const [interestEarnedRaw, setInterestEarnedRaw] = useState(0);
@@ -215,9 +248,11 @@ const ApyCalculator = ({
215
248
  if (!APY || APY <= 0 || Number.isNaN(APY)) {
216
249
  newErrors.APY = "Please enter a valid APY greater than 0.";
217
250
  }
251
+ if (!APR || APR <= 0 || Number.isNaN(APR)) {
252
+ newErrors.APR = "Please enter a valid APR greater than 0.";
253
+ }
218
254
  setFieldErrors(newErrors);
219
255
  if (Object.keys(newErrors).length > 0) return false;
220
- const APR = getAPR(APY);
221
256
  const interestRate = 0.01 * APR;
222
257
  let total;
223
258
  if (compounding === 360) {
@@ -243,7 +278,7 @@ const ApyCalculator = ({
243
278
  setTotalDepositsRaw(deposits);
244
279
  setInterestEarnedRaw(interest > 0 ? interest : 0);
245
280
  return true;
246
- }, [initialDeposit, APY, months, monthlyDeposits, compounding, getAPR]);
281
+ }, [initialDeposit, APY, APR, months, monthlyDeposits, compounding]);
247
282
  const handleCalculateClick = useCallback(() => {
248
283
  const didCalculate = calculate();
249
284
  if (!didCalculate || !isStackedLayout) return;
@@ -347,6 +382,43 @@ const ApyCalculator = ({
347
382
  }
348
383
  )
349
384
  ] }),
385
+ /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
386
+ /* @__PURE__ */ jsx(Label, { className: field_label, children: "APR (Annual Percentage Rate)" }),
387
+ /* @__PURE__ */ jsx(
388
+ "span",
389
+ {
390
+ className: `${label_symbol} ${percent}`,
391
+ "aria-hidden": "true",
392
+ children: "%"
393
+ }
394
+ ),
395
+ /* @__PURE__ */ jsx(
396
+ Input,
397
+ {
398
+ className: `${field_row_input} ${fieldErrors.APR ? ` ${field_row_input_error}` : ""}`,
399
+ id: "apr",
400
+ type: "text",
401
+ inputMode: "decimal",
402
+ pattern: "[0-9.]*",
403
+ name: "apr",
404
+ value: APRDisplay,
405
+ onChange: handleAPRChange,
406
+ onWheel: (e) => e.currentTarget.blur(),
407
+ "aria-invalid": !!fieldErrors.APR,
408
+ "aria-describedby": fieldErrors.APR ? "apr-error" : void 0
409
+ }
410
+ ),
411
+ fieldErrors.APR && /* @__PURE__ */ jsx(
412
+ Description,
413
+ {
414
+ as: "span",
415
+ id: "apr-error",
416
+ className: field_error,
417
+ role: "alert",
418
+ children: fieldErrors.APR
419
+ }
420
+ )
421
+ ] }),
350
422
  /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
351
423
  /* @__PURE__ */ jsx(Label, { className: field_label, children: "Months" }),
352
424
  /* @__PURE__ */ jsx(
@@ -51,10 +51,10 @@ import { SummitApyCalculator } from "./SummitApyCalculator/index.js";
51
51
  /* empty css */
52
52
  import "../Carousel/index.js";
53
53
  /* empty css */
54
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
54
55
  /* empty css */
55
56
  import "../Chatbot/store/chat.js";
56
57
  import "../Chatbot/Chatbot.js";
57
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
58
58
  import "../LoadingIndicator/LoadingIndicator.css.js";
59
59
  import "react-use";
60
60
  /* empty css */
@@ -80,10 +80,10 @@ import "../../Auth/SignInPassword.js";
80
80
  /* empty css */
81
81
  import "../../Carousel/index.js";
82
82
  /* empty css */
83
+ import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
83
84
  /* empty css */
84
85
  import "../../Chatbot/store/chat.js";
85
86
  import "../../Chatbot/Chatbot.js";
86
- import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
87
87
  /* empty css */
88
88
  import "../../Chatbot/store/messages.js";
89
89
  /* empty css */
@@ -81,10 +81,10 @@ import "../Auth/SignInPassword.js";
81
81
  /* empty css */
82
82
  /* empty css */
83
83
  /* empty css */
84
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
84
85
  /* empty css */
85
86
  import "../Chatbot/store/chat.js";
86
87
  import "../Chatbot/Chatbot.js";
87
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
88
88
  /* empty css */
89
89
  import "../Chatbot/store/messages.js";
90
90
  /* empty css */
@@ -2,6 +2,7 @@ import '../assets/Chatbot/Bubble.css';import '../assets/themes/victorie.css';imp
2
2
  /* empty css */
3
3
  /* empty css */
4
4
  /* empty css */
5
+ import "./Chatbot.css.ts.vanilla.css.js";
5
6
  /* empty css */
6
7
  var borderHoverGradient = "_7u9pv31";
7
8
  var bubbleWrapper = "_7u9pv32";
@@ -1,4 +1,3 @@
1
- import "./Chatbot.css.ts.vanilla.css.js";
2
1
  var chatbotAXB = "_1hpv6vm0";
3
2
  var chatbotUFB = "_1hpv6vm1";
4
3
  export {
@@ -81,10 +81,10 @@ import "../Auth/SignInPassword.js";
81
81
  /* empty css */
82
82
  import "../Carousel/index.js";
83
83
  /* empty css */
84
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
84
85
  /* empty css */
85
86
  import "../Chatbot/store/chat.js";
86
87
  import "../Chatbot/Chatbot.js";
87
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
88
88
  /* empty css */
89
89
  import "../Chatbot/store/messages.js";
90
90
  /* empty css */
@@ -81,10 +81,10 @@ import "../Auth/SignInPassword.js";
81
81
  /* empty css */
82
82
  import "../Carousel/index.js";
83
83
  /* empty css */
84
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
84
85
  /* empty css */
85
86
  import "../Chatbot/store/chat.js";
86
87
  import "../Chatbot/Chatbot.js";
87
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
88
88
  /* empty css */
89
89
  import "../Chatbot/store/messages.js";
90
90
  /* empty css */
@@ -82,10 +82,10 @@ import "../Auth/SignInPassword.js";
82
82
  /* empty css */
83
83
  import "../Carousel/index.js";
84
84
  /* empty css */
85
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
85
86
  /* empty css */
86
87
  import "../Chatbot/store/chat.js";
87
88
  import "../Chatbot/Chatbot.js";
88
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
89
89
  /* empty css */
90
90
  import "../Chatbot/store/messages.js";
91
91
  /* empty css */
@@ -82,10 +82,10 @@ import "../Auth/SignInPassword.js";
82
82
  /* empty css */
83
83
  import "../Carousel/index.js";
84
84
  /* empty css */
85
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
85
86
  /* empty css */
86
87
  import "../Chatbot/store/chat.js";
87
88
  import "../Chatbot/Chatbot.js";
88
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
89
89
  /* empty css */
90
90
  import "../Chatbot/store/messages.js";
91
91
  /* empty css */
@@ -78,10 +78,10 @@ import "../../Auth/SignInPassword.js";
78
78
  /* empty css */
79
79
  import "../../Carousel/index.js";
80
80
  /* empty css */
81
+ import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
81
82
  /* empty css */
82
83
  import "../../Chatbot/store/chat.js";
83
84
  import "../../Chatbot/Chatbot.js";
84
- import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
85
85
  /* empty css */
86
86
  import "../../Chatbot/store/messages.js";
87
87
  /* empty css */
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -84,10 +84,10 @@ import "../Auth/SignInPassword.js";
84
84
  /* empty css */
85
85
  import "../Carousel/index.js";
86
86
  /* empty css */
87
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
87
88
  /* empty css */
88
89
  import "../Chatbot/store/chat.js";
89
90
  import "../Chatbot/Chatbot.js";
90
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
91
91
  /* empty css */
92
92
  import "../Chatbot/store/messages.js";
93
93
  /* empty css */
@@ -84,10 +84,10 @@ import "../../Auth/SignInPassword.js";
84
84
  /* empty css */
85
85
  import "../../Carousel/index.js";
86
86
  /* empty css */
87
+ import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
87
88
  /* empty css */
88
89
  import "../../Chatbot/store/chat.js";
89
90
  import "../../Chatbot/Chatbot.js";
90
- import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
91
91
  /* empty css */
92
92
  import "../../Chatbot/store/messages.js";
93
93
  /* empty css */
@@ -1,6 +1,6 @@
1
1
  export type RateWatchInputs = {
2
2
  updateType: string;
3
- updateCadence: string;
3
+ updateCadence?: string;
4
4
  loanTerms?: string;
5
5
  hasSmsConsent: boolean;
6
6
  tR1DesiredRate?: string;
@@ -80,10 +80,10 @@ import "../../Auth/SignInPassword.js";
80
80
  /* empty css */
81
81
  import "../../Carousel/index.js";
82
82
  /* empty css */
83
+ import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
83
84
  /* empty css */
84
85
  import "../../Chatbot/store/chat.js";
85
86
  import "../../Chatbot/Chatbot.js";
86
- import "../../Chatbot/Chatbot.css.ts.vanilla.css.js";
87
87
  /* empty css */
88
88
  import "../../Chatbot/store/messages.js";
89
89
  /* empty css */
@@ -140,12 +140,34 @@ const RateWatchForm = ({
140
140
  toggleModal,
141
141
  setRateWatchSubmitted
142
142
  }) => {
143
+ const desiredRateFields = [
144
+ "tR1DesiredRate",
145
+ "tR2DesiredRate",
146
+ "tR3DesiredRate"
147
+ ];
148
+ const sanitizeDesiredRate = (value) => {
149
+ if (!value) return "";
150
+ const normalizedValue = value.replace(/[^\d.]/g, "");
151
+ if (!normalizedValue || normalizedValue === ".") return "";
152
+ const [wholePart, decimalPart = ""] = normalizedValue.split(".");
153
+ const trimmedDecimal = decimalPart.slice(0, 4);
154
+ const formattedValue = trimmedDecimal ? `${wholePart || "0"}.${trimmedDecimal}` : wholePart || "0";
155
+ const numericValue = Number(formattedValue);
156
+ if (!Number.isFinite(numericValue)) return "";
157
+ return Number.isInteger(numericValue) ? String(numericValue) : numericValue.toFixed(4).replace(/\.0+$|(?<=\.\d*)(0+)$/, "").replace(/\.$/, "");
158
+ };
159
+ const isDesiredRateOutOfRange = (value) => {
160
+ if (!value) return false;
161
+ const numericValue = Number(value);
162
+ if (!Number.isFinite(numericValue)) return false;
163
+ return numericValue < 2 || numericValue > 10;
164
+ };
143
165
  const [updateType, setUpdateType] = useState(
144
166
  "Target Rate"
145
167
  );
146
168
  const schema = z.object({
147
169
  updateType: z.string().min(1, { message: "Update type is required." }),
148
- updateCadence: z.string().refine((val) => !(updateType === "Frequency" && !val), {
170
+ updateCadence: z.string().optional().refine((val) => !(updateType === "Frequency" && !val), {
149
171
  message: "Frequency is required."
150
172
  }),
151
173
  loanTerms: z.string().optional().refine((val) => !(updateType === "Frequency" && !val), {
@@ -154,11 +176,13 @@ const RateWatchForm = ({
154
176
  hasSmsConsent: z.boolean().refine((val) => val === true, {
155
177
  message: "You must agree to receive SMS messages."
156
178
  }),
157
- tR1DesiredRate: z.string().optional().refine(
179
+ tR1DesiredRate: z.string().optional().refine((val) => updateType === "Target Rate" ? !!val : true, {
180
+ message: "Desired Rate is required."
181
+ }).refine(
158
182
  (val) => {
159
183
  if (val && updateType === "Target Rate") {
160
184
  const numericValue = +val;
161
- return !val || numericValue >= 2 && numericValue <= 10;
185
+ return numericValue >= 2 && numericValue <= 10;
162
186
  }
163
187
  return true;
164
188
  },
@@ -197,15 +221,21 @@ const RateWatchForm = ({
197
221
  email: z.string()
198
222
  });
199
223
  const methods = useForm({
200
- resolver: zodResolver(schema)
224
+ resolver: zodResolver(schema),
225
+ mode: "onChange"
201
226
  });
202
227
  const {
203
228
  handleSubmit,
204
229
  register,
205
230
  formState: { errors, isSubmitting, isValid },
206
231
  setValue,
207
- clearErrors
232
+ clearErrors,
233
+ watch
208
234
  } = methods;
235
+ const watchedDesiredRates = watch(desiredRateFields);
236
+ const hasDesiredRateWarning = desiredRateFields.some(
237
+ (_, index) => isDesiredRateOutOfRange(watchedDesiredRates[index])
238
+ );
209
239
  const submitForm = async (data) => {
210
240
  const processedData = {
211
241
  ...data,
@@ -244,12 +274,22 @@ const RateWatchForm = ({
244
274
  const handleTypeChange = (event) => {
245
275
  const value = event.target.value;
246
276
  setUpdateType(value);
277
+ methods.setValue("updateType", value, { shouldValidate: true });
278
+ };
279
+ const handleDesiredRateChange = (fieldName) => (event) => {
280
+ const sanitizedValue = sanitizeDesiredRate(event.target.value);
281
+ event.target.value = sanitizedValue;
282
+ setValue(fieldName, sanitizedValue, {
283
+ shouldValidate: true,
284
+ shouldDirty: true,
285
+ shouldTouch: true
286
+ });
247
287
  };
248
288
  const handleSubmitClick = () => {
249
289
  handleSubmit(submitForm)();
250
290
  };
251
291
  useEffect(() => {
252
- methods.reset();
292
+ methods.reset({ updateType });
253
293
  }, [updateType]);
254
294
  return /* @__PURE__ */ jsx("section", { className: "rate-watch-form", children: /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx(
255
295
  SuccesFormWrapper,
@@ -327,7 +367,7 @@ const RateWatchForm = ({
327
367
  /* @__PURE__ */ jsx("p", { className: mt1Rem, children: "You can establish up to three different targets with one rate watch." }),
328
368
  /* @__PURE__ */ jsxs("div", { className: threeColRow, children: [
329
369
  /* @__PURE__ */ jsxs("div", { children: [
330
- /* @__PURE__ */ jsx("label", { className: resposiveLabel, children: "Select a Loan Type*" }),
370
+ /* @__PURE__ */ jsx("label", { className: resposiveLabel, children: "Select a Loan Type" }),
331
371
  /* @__PURE__ */ jsxs(
332
372
  Dropdown,
333
373
  {
@@ -346,18 +386,24 @@ const RateWatchForm = ({
346
386
  )
347
387
  ] }),
348
388
  /* @__PURE__ */ jsxs("div", { children: [
349
- /* @__PURE__ */ jsx("label", { className: resposiveLabel, children: "Desired Rate" }),
389
+ /* @__PURE__ */ jsxs("label", { className: resposiveLabel, children: [
390
+ "Desired Rate",
391
+ /* @__PURE__ */ jsx("sup", { children: "*" })
392
+ ] }),
350
393
  /* @__PURE__ */ jsx(
351
394
  Input,
352
395
  {
353
396
  className: dynPH,
354
397
  ...register("tR1DesiredRate", {
355
- setValueAs: (value) => value ? `${value}` : ""
398
+ setValueAs: (value) => sanitizeDesiredRate(String(value ?? ""))
356
399
  }),
400
+ onChange: handleDesiredRateChange("tR1DesiredRate"),
357
401
  type: "number",
402
+ min: "2",
403
+ max: "10",
358
404
  placeholder: "Desired Rate",
359
405
  error: !!errors.tR1DesiredRate,
360
- helperText: errors.tR1DesiredRate?.message
406
+ helperText: isDesiredRateOutOfRange(watch("tR1DesiredRate")) ? "Desired Rate must be between 2 and 10." : errors.tR1DesiredRate?.message
361
407
  }
362
408
  )
363
409
  ] }),
@@ -408,9 +454,16 @@ const RateWatchForm = ({
408
454
  Input,
409
455
  {
410
456
  className: dynPH,
411
- ...register("tR2DesiredRate"),
412
- type: "string",
413
- placeholder: "Desired Rate"
457
+ ...register("tR2DesiredRate", {
458
+ setValueAs: (value) => sanitizeDesiredRate(String(value ?? ""))
459
+ }),
460
+ onChange: handleDesiredRateChange("tR2DesiredRate"),
461
+ type: "number",
462
+ min: "2",
463
+ max: "10",
464
+ placeholder: "Desired Rate",
465
+ error: isDesiredRateOutOfRange(watch("tR2DesiredRate")),
466
+ helperText: isDesiredRateOutOfRange(watch("tR2DesiredRate")) ? "Desired Rate must be between 2 and 10." : errors.tR2DesiredRate?.message
414
467
  }
415
468
  ) }),
416
469
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
@@ -456,10 +509,17 @@ const RateWatchForm = ({
456
509
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
457
510
  Input,
458
511
  {
459
- ...register("tR3DesiredRate"),
460
- type: "string",
512
+ ...register("tR3DesiredRate", {
513
+ setValueAs: (value) => sanitizeDesiredRate(String(value ?? ""))
514
+ }),
515
+ onChange: handleDesiredRateChange("tR3DesiredRate"),
516
+ type: "number",
517
+ min: "2",
518
+ max: "10",
461
519
  placeholder: "Desired Rate",
462
- className: dynPH
520
+ className: dynPH,
521
+ error: isDesiredRateOutOfRange(watch("tR3DesiredRate")),
522
+ helperText: isDesiredRateOutOfRange(watch("tR3DesiredRate")) ? "Desired Rate must be between 2 and 10." : errors.tR3DesiredRate?.message
463
523
  }
464
524
  ) }),
465
525
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
@@ -484,7 +544,20 @@ const RateWatchForm = ({
484
544
  }
485
545
  ) })
486
546
  ] }),
487
- /* @__PURE__ */ jsx("p", { className: mt1Rem, children: "*The number in Desired Rate must be at least 2% and no more than 10%" })
547
+ /* @__PURE__ */ jsxs(
548
+ "p",
549
+ {
550
+ className: mt1Rem,
551
+ style: {
552
+ color: hasDesiredRateWarning ? "#d92d20" : void 0,
553
+ fontWeight: hasDesiredRateWarning ? 600 : void 0
554
+ },
555
+ children: [
556
+ /* @__PURE__ */ jsx("sup", { children: "*" }),
557
+ " Please enter a desired rate between 2% and 10%"
558
+ ]
559
+ }
560
+ )
488
561
  ] }),
489
562
  /* @__PURE__ */ jsxs("div", { className: modalCheckboxContainer, children: [
490
563
  /* @__PURE__ */ jsx(
@@ -83,10 +83,10 @@ import "../Auth/SignInPassword.js";
83
83
  /* empty css */
84
84
  import "../Carousel/index.js";
85
85
  /* empty css */
86
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
86
87
  /* empty css */
87
88
  import "../Chatbot/store/chat.js";
88
89
  import "../Chatbot/Chatbot.js";
89
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
90
90
  /* empty css */
91
91
  import "../Chatbot/store/messages.js";
92
92
  /* empty css */
@@ -66,10 +66,10 @@ import "../Auth/SignInPassword.js";
66
66
  /* empty css */
67
67
  import "../Carousel/index.js";
68
68
  /* empty css */
69
+ import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
69
70
  /* empty css */
70
71
  import "../Chatbot/store/chat.js";
71
72
  import "../Chatbot/Chatbot.js";
72
- import "../Chatbot/Chatbot.css.ts.vanilla.css.js";
73
73
  import "../LoadingIndicator/LoadingIndicator.css.js";
74
74
  import "react-use";
75
75
  /* empty css */