@stokr/components-library 3.0.21 → 3.0.22

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 (58) hide show
  1. package/README.md +467 -261
  2. package/dist/analytics/index.js +5 -1
  3. package/dist/api/authenticationApi.js +13 -0
  4. package/dist/auth/index.js +4 -2
  5. package/dist/components/2FA/login-with-otp-flow.js +9 -4
  6. package/dist/components/Footer/FooterLayout.js +98 -95
  7. package/dist/components/Footer/FooterMenu.js +1 -1
  8. package/dist/components/Header/Header.js +102 -54
  9. package/dist/components/MainMenu/MainMenu.js +14 -4
  10. package/dist/components/Modal/NewVentureModal/NewVentureModal.js +6 -2
  11. package/dist/components/Payment/PaymentDetailsCard.js +1 -1
  12. package/dist/components/VerifyEmailModal/VerifyEmailModal.js +2 -1
  13. package/dist/components/headerHo/HeaderHo.js +8 -5
  14. package/dist/components/icons/LinkIcon.js +2 -2
  15. package/dist/config.js +5 -21
  16. package/dist/constants/globalVariables.js +6 -4
  17. package/dist/context/Auth.js +5 -2
  18. package/dist/context/AuthContext.js +22 -8
  19. package/dist/firebase-config.js +4 -18
  20. package/dist/index.js +36 -5
  21. package/dist/model/axios.js +3 -1
  22. package/dist/model/axiosPublic.js +2 -2
  23. package/dist/routing/RouterWrapper.js +17 -0
  24. package/dist/routing/app-routes.js +22 -0
  25. package/dist/routing/navigate-app.js +36 -0
  26. package/dist/routing/resolve-app-href.js +149 -0
  27. package/dist/runtime-config.js +94 -0
  28. package/dist/static/country-list.json +251 -251
  29. package/dist/static/fonts/Ionicons/ionicons.min.css +2810 -2810
  30. package/dist/static/fonts/Ionicons/ionicons.min.css.js +1 -1
  31. package/dist/static/fonts/icomoon/selection.json +910 -910
  32. package/dist/static/fonts/icomoon/style.css +139 -139
  33. package/dist/static/images/copy_icon.svg +4 -4
  34. package/dist/static/images/download_icon.svg +3 -3
  35. package/dist/static/images/numbers/number_eight.svg +3 -3
  36. package/dist/static/images/numbers/number_five.svg +4 -4
  37. package/dist/static/images/numbers/number_four.svg +3 -3
  38. package/dist/static/images/numbers/number_nine.svg +4 -4
  39. package/dist/static/images/numbers/number_one.svg +4 -4
  40. package/dist/static/images/numbers/number_seven.svg +4 -4
  41. package/dist/static/images/numbers/number_six.svg +4 -4
  42. package/dist/static/images/numbers/number_three.svg +3 -3
  43. package/dist/static/images/numbers/number_two.svg +4 -4
  44. package/dist/static/images/numbers/number_zero.svg +3 -3
  45. package/dist/static/images/plus-icon.svg +4 -4
  46. package/dist/static/images/search-icon.svg +3 -3
  47. package/dist/static/images/transfer-icon.svg +10 -10
  48. package/dist/static/images/warning-filled.svg +3 -3
  49. package/dist/utils/app-urls-analytics-backoffice.js +30 -0
  50. package/dist/utils/app-urls.js +28 -0
  51. package/dist/utils/checklistGenerator.js +6 -5
  52. package/dist/utils/customHooks.js +1 -1
  53. package/dist/utils/formatCurrencyValue.js +2 -1
  54. package/dist/utils/get-cookie-domain.js +4 -1
  55. package/dist/utils/set-redirect-cookie.js +4 -1
  56. package/dist/utils/withRouter.js +5 -3
  57. package/package.json +1 -1
  58. package/dist/api/auth.js +0 -15
@@ -30,12 +30,16 @@ import "js-cookie";
30
30
  import "../../model/axios.js";
31
31
  import "../Layout/Layout.js";
32
32
  import stdin_default$3 from "../2FA/ResetCode.js";
33
- import { authAPI } from "../../api/auth.js";
33
+ import { authenticationApi } from "../../api/authenticationApi.js";
34
+ import { buildOnboardingUrl } from "../../utils/app-urls.js";
35
+ import "react-router-dom";
34
36
  import "../2FA/main-flow.js";
35
37
  import fetchDataPublic from "../../api/fetchDataPublic.js";
36
38
  import { withRouter } from "../../utils/withRouter.js";
37
39
  import { checkActionCode } from "firebase/auth";
38
40
  import { auth } from "../../firebase-config.js";
41
+ import { navigateApp } from "../../routing/navigate-app.js";
42
+ import { AppSurface } from "../../routing/app-routes.js";
39
43
  const Outer = styled.div.withConfig({
40
44
  shouldForwardProp: (props) => !["fixed"].includes(props)
41
45
  })`
@@ -233,7 +237,6 @@ const _HeaderHoClass = class _HeaderHoClass extends Component {
233
237
  }
234
238
  if (verifyEmailError?.code === "auth/invalid-action-code" && !window.location.href.includes("login")) {
235
239
  this.props.navigate("/login");
236
- this.props.navigate(0);
237
240
  }
238
241
  if (!isFetchingUser) {
239
242
  this.checkForModals();
@@ -553,7 +556,7 @@ const _HeaderHoClass = class _HeaderHoClass extends Component {
553
556
  payload.ventureInvite = true;
554
557
  }
555
558
  try {
556
- await authAPI("forgotPass", payload);
559
+ await authenticationApi.post("forgotPass", payload);
557
560
  this.setPopupSuccess(
558
561
  "forgot",
559
562
  `We sent a message to ${email} (you might need to check your junk or spam folder) — tap the link inside to create a new password.`
@@ -651,7 +654,7 @@ const _HeaderHoClass = class _HeaderHoClass extends Component {
651
654
  const query = new URLSearchParams(location?.search);
652
655
  let userType = query.get("user_type");
653
656
  if (userType && userType === "sa") {
654
- window.open(`https://backoffice.${void 0}`);
657
+ navigateApp(this.props.navigate, AppSurface.BACKOFFICE, "");
655
658
  } else {
656
659
  this.switchOpenModal("confirmReset", "login");
657
660
  }
@@ -666,7 +669,7 @@ const _HeaderHoClass = class _HeaderHoClass extends Component {
666
669
  popupError: this.state.popupError,
667
670
  popupSuccess: this.state.popupSuccess,
668
671
  isModalOpen: isModalOpen.verifyEmail,
669
- continueUrl: `https://signup.${void 0}/welcome`,
672
+ continueUrl: buildOnboardingUrl("/welcome"),
670
673
  error: verifyEmailError,
671
674
  isSuccess: !verifyEmailError,
672
675
  onModalSwitch: () => {
@@ -17,13 +17,13 @@ const LinkIcon = () => /* @__PURE__ */ jsxs(
17
17
  /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
18
18
  "path",
19
19
  {
20
- d: "M312.453,199.601c-6.066-6.102-12.792-11.511-20.053-16.128c-19.232-12.315-41.59-18.859-64.427-18.859\r\n c-31.697-0.059-62.106,12.535-84.48,34.987L34.949,308.23c-22.336,22.379-34.89,52.7-34.91,84.318\r\n c-0.042,65.98,53.41,119.501,119.39,119.543c31.648,0.11,62.029-12.424,84.395-34.816l89.6-89.6\r\n c1.628-1.614,2.537-3.816,2.524-6.108c-0.027-4.713-3.87-8.511-8.583-8.484h-3.413c-18.72,0.066-37.273-3.529-54.613-10.581\r\n c-3.195-1.315-6.867-0.573-9.301,1.877l-64.427,64.512c-20.006,20.006-52.442,20.006-72.448,0\r\n c-20.006-20.006-20.006-52.442,0-72.448l108.971-108.885c19.99-19.965,52.373-19.965,72.363,0\r\n c13.472,12.679,34.486,12.679,47.957,0c5.796-5.801,9.31-13.495,9.899-21.675C322.976,216.108,319.371,206.535,312.453,199.601z"
20
+ d: "M312.453,199.601c-6.066-6.102-12.792-11.511-20.053-16.128c-19.232-12.315-41.59-18.859-64.427-18.859\n c-31.697-0.059-62.106,12.535-84.48,34.987L34.949,308.23c-22.336,22.379-34.89,52.7-34.91,84.318\n c-0.042,65.98,53.41,119.501,119.39,119.543c31.648,0.11,62.029-12.424,84.395-34.816l89.6-89.6\n c1.628-1.614,2.537-3.816,2.524-6.108c-0.027-4.713-3.87-8.511-8.583-8.484h-3.413c-18.72,0.066-37.273-3.529-54.613-10.581\n c-3.195-1.315-6.867-0.573-9.301,1.877l-64.427,64.512c-20.006,20.006-52.442,20.006-72.448,0\n c-20.006-20.006-20.006-52.442,0-72.448l108.971-108.885c19.99-19.965,52.373-19.965,72.363,0\n c13.472,12.679,34.486,12.679,47.957,0c5.796-5.801,9.31-13.495,9.899-21.675C322.976,216.108,319.371,206.535,312.453,199.601z"
21
21
  }
22
22
  ) }) }),
23
23
  /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
24
24
  "path",
25
25
  {
26
- d: "M477.061,34.993c-46.657-46.657-122.303-46.657-168.96,0l-89.515,89.429c-2.458,2.47-3.167,6.185-1.792,9.387\r\n c1.359,3.211,4.535,5.272,8.021,5.205h3.157c18.698-0.034,37.221,3.589,54.528,10.667c3.195,1.315,6.867,0.573,9.301-1.877\r\n l64.256-64.171c20.006-20.006,52.442-20.006,72.448,0c20.006,20.006,20.006,52.442,0,72.448l-80.043,79.957l-0.683,0.768\r\n l-27.989,27.819c-19.99,19.965-52.373,19.965-72.363,0c-13.472-12.679-34.486-12.679-47.957,0\r\n c-5.833,5.845-9.35,13.606-9.899,21.845c-0.624,9.775,2.981,19.348,9.899,26.283c9.877,9.919,21.433,18.008,34.133,23.893\r\n c1.792,0.853,3.584,1.536,5.376,2.304c1.792,0.768,3.669,1.365,5.461,2.048c1.792,0.683,3.669,1.28,5.461,1.792l5.035,1.365\r\n c3.413,0.853,6.827,1.536,10.325,2.133c4.214,0.626,8.458,1.025,12.715,1.195h5.973h0.512l5.12-0.597\r\n c1.877-0.085,3.84-0.512,6.059-0.512h2.901l5.888-0.853l2.731-0.512l4.949-1.024h0.939c20.961-5.265,40.101-16.118,55.381-31.403\r\n l108.629-108.629C523.718,157.296,523.718,81.65,477.061,34.993z"
26
+ d: "M477.061,34.993c-46.657-46.657-122.303-46.657-168.96,0l-89.515,89.429c-2.458,2.47-3.167,6.185-1.792,9.387\n c1.359,3.211,4.535,5.272,8.021,5.205h3.157c18.698-0.034,37.221,3.589,54.528,10.667c3.195,1.315,6.867,0.573,9.301-1.877\n l64.256-64.171c20.006-20.006,52.442-20.006,72.448,0c20.006,20.006,20.006,52.442,0,72.448l-80.043,79.957l-0.683,0.768\n l-27.989,27.819c-19.99,19.965-52.373,19.965-72.363,0c-13.472-12.679-34.486-12.679-47.957,0\n c-5.833,5.845-9.35,13.606-9.899,21.845c-0.624,9.775,2.981,19.348,9.899,26.283c9.877,9.919,21.433,18.008,34.133,23.893\n c1.792,0.853,3.584,1.536,5.376,2.304c1.792,0.768,3.669,1.365,5.461,2.048c1.792,0.683,3.669,1.28,5.461,1.792l5.035,1.365\n c3.413,0.853,6.827,1.536,10.325,2.133c4.214,0.626,8.458,1.025,12.715,1.195h5.973h0.512l5.12-0.597\n c1.877-0.085,3.84-0.512,6.059-0.512h2.901l5.888-0.853l2.731-0.512l4.949-1.024h0.939c20.961-5.265,40.101-16.118,55.381-31.403\n l108.629-108.629C523.718,157.296,523.718,81.65,477.061,34.993z"
27
27
  }
28
28
  ) }) }),
29
29
  /* @__PURE__ */ jsx("g", {}),
package/dist/config.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { initFirebase } from "./firebase-config.js";
2
2
  import axiosInstance from "./model/axios.js";
3
3
  import axiosInstance$1 from "./model/axiosPublic.js";
4
- const __vite_import_meta_env__ = { "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false };
5
- const _overrides = {};
4
+ import { assignRuntimeConfig } from "./runtime-config.js";
5
+ import { getConfig, resetRuntimeConfig } from "./runtime-config.js";
6
6
  let _lastFirebaseConfig = null;
7
7
  function configure(config = {}) {
8
- Object.assign(_overrides, config);
8
+ assignRuntimeConfig(config);
9
9
  if (config.apiUrl != null) {
10
10
  axiosInstance.defaults.baseURL = config.apiUrl;
11
11
  }
@@ -20,25 +20,9 @@ function configure(config = {}) {
20
20
  function getLastFirebaseConfig() {
21
21
  return _lastFirebaseConfig;
22
22
  }
23
- function env(name) {
24
- try {
25
- return __vite_import_meta_env__?.[name];
26
- } catch {
27
- return void 0;
28
- }
29
- }
30
- function getConfig(key) {
31
- const envMap = {
32
- apiUrl: "VITE_API_URL",
33
- baseUrlPublic: "VITE_BASE_URL_PUBLIC",
34
- cookieDomain: "VITE_COOKIE_DOMAIN",
35
- websiteDomain: "VITE_WEBSITE_DOMAIN",
36
- photoApiUrl: "VITE_PHOTO_API_URL"
37
- };
38
- return _overrides[key] ?? env(envMap[key]);
39
- }
40
23
  export {
41
24
  configure,
42
25
  getConfig,
43
- getLastFirebaseConfig
26
+ getLastFirebaseConfig,
27
+ resetRuntimeConfig
44
28
  };
@@ -1,5 +1,8 @@
1
- const platformDomain = void 0;
2
- const platformURL = "https://" + platformDomain;
1
+ import { getConfig } from "../runtime-config.js";
2
+ function getPlatformURL() {
3
+ const domain = getConfig("websiteDomain");
4
+ return domain ? `https://${domain}` : "";
5
+ }
3
6
  const walletTypes = {
4
7
  LIQUID: "liquid"
5
8
  };
@@ -80,8 +83,7 @@ export {
80
83
  USInvestorAcreditationStatuses,
81
84
  UserTypes,
82
85
  emailRegex,
83
- platformDomain,
84
- platformURL,
86
+ getPlatformURL,
85
87
  transactionTypeDisplayNames,
86
88
  walletTypes
87
89
  };
@@ -2,9 +2,10 @@ import Cookies from "js-cookie";
2
2
  import axios from "axios";
3
3
  import axiosInstance from "../model/axios.js";
4
4
  import getCookieDomain from "../utils/get-cookie-domain.js";
5
- import { getConfig, getLastFirebaseConfig } from "../config.js";
5
+ import { getLastFirebaseConfig } from "../config.js";
6
6
  import { getFirebaseAuth, initFirebase } from "../firebase-config.js";
7
7
  import { signInWithEmailAndPassword, createUserWithEmailAndPassword, applyActionCode, verifyPasswordResetCode, confirmPasswordReset, onAuthStateChanged, signInWithCustomToken, updatePassword, updateProfile } from "firebase/auth";
8
+ import { getConfig } from "../runtime-config.js";
8
9
  function normalizeCustomToken(token) {
9
10
  if (token == null) return "";
10
11
  if (typeof token === "object" && token !== null) {
@@ -61,7 +62,9 @@ class Auth {
61
62
  static async login(email, password) {
62
63
  const auth = getFirebaseAuth();
63
64
  if (!auth) {
64
- throw new Error("Firebase is not configured. Set VITE_FIREBASE_API_KEY (and other env vars) for auth.");
65
+ throw new Error(
66
+ "Firebase is not configured. Pass config.firebase via configure() / AuthProvider, or set VITE_FIREBASE_* for dev."
67
+ );
65
68
  }
66
69
  try {
67
70
  const userCredential = await signInWithEmailAndPassword(auth, email, password);
@@ -5,7 +5,11 @@ import React__default, { Component } from "react";
5
5
  import fetchData from "../api/fetchData.js";
6
6
  import { identify, reset } from "../analytics/index.js";
7
7
  import { withRouter } from "../utils/withRouter.js";
8
- import { configure, getConfig } from "../config.js";
8
+ import { configure } from "../config.js";
9
+ import { AppSurface, AppRoute } from "../routing/app-routes.js";
10
+ import { resolveAppHref, isAlreadyOnOnboardingFlow } from "../routing/resolve-app-href.js";
11
+ import { navigateToHref, navigateApp } from "../routing/navigate-app.js";
12
+ import { getConfig } from "../runtime-config.js";
9
13
  import { Text } from "../components/Text/Text.styles.js";
10
14
  import { getFirebaseAuth } from "../firebase-config.js";
11
15
  import { Auth } from "./Auth.js";
@@ -304,7 +308,8 @@ class AuthProviderClass extends Component {
304
308
  loggedOutDueToCookieExpiry: options.dueToCookieExpiry === true
305
309
  });
306
310
  if (redirect) {
307
- window.location.href = `https://${getConfig("websiteDomain")}`;
311
+ const home = resolveAppHref(AppSurface.INVESTOR_ROOT, "") || `https://${getConfig("websiteDomain")}`;
312
+ navigateToHref(this.props.navigate, home);
308
313
  }
309
314
  };
310
315
  clearLoggedOutDueToInactivity = () => {
@@ -405,11 +410,11 @@ class AuthProviderClass extends Component {
405
410
  checkUserIsValid = (user) => {
406
411
  if (!user) {
407
412
  throw new Error("User is not defined");
408
- } else if (!user?.emailVerified && !window.location.href.includes("signup.")) {
409
- window.location.href = `https://signup.${getConfig("websiteDomain")}/resend-activation-email`;
413
+ } else if (!user?.emailVerified && !isAlreadyOnOnboardingFlow()) {
414
+ navigateApp(this.props.navigate, AppSurface.ONBOARDING, AppRoute.RESEND_ACTIVATION);
410
415
  return false;
411
- } else if (!user?.country && user?.user_type === "investor" && !window.location.href.includes("signup.")) {
412
- window.location.href = `https://signup.${getConfig("websiteDomain")}/welcome`;
416
+ } else if (!user?.country && user?.user_type === "investor" && !isAlreadyOnOnboardingFlow()) {
417
+ navigateApp(this.props.navigate, AppSurface.ONBOARDING, AppRoute.WELCOME);
413
418
  return false;
414
419
  }
415
420
  return true;
@@ -447,7 +452,6 @@ class AuthProviderClass extends Component {
447
452
  };
448
453
  replaceLocationPathName = () => {
449
454
  const pathname = this.props.location?.pathname ?? "";
450
- console.log("🚀 ~ file: AuthContext.js:511 ~ replaceLocationPathName ~ pathname:", pathname);
451
455
  if (pathname === "/login" || pathname === "/signup") {
452
456
  this.props.navigate("/");
453
457
  }
@@ -740,7 +744,7 @@ class AuthProviderClass extends Component {
740
744
  AuthProviderClass.propTypes = {
741
745
  children: PropTypes.node.isRequired,
742
746
  /** Runtime config for the library. Sets API URLs, Firebase config, cookie domain, etc.
743
- * When omitted, the library falls back to import.meta.env.VITE_* (Storybook / dev).
747
+ * When omitted, the library falls back to Vite env via getConfig() (Storybook / dev).
744
748
  * When consumed as an npm package, pass this prop so values are available at runtime. */
745
749
  config: PropTypes.shape({
746
750
  apiUrl: PropTypes.string,
@@ -748,6 +752,16 @@ AuthProviderClass.propTypes = {
748
752
  cookieDomain: PropTypes.string,
749
753
  websiteDomain: PropTypes.string,
750
754
  photoApiUrl: PropTypes.string,
755
+ /** Set to `'path'` for single-origin URLs (`/dashboard`, `/admin`, …). Omit for legacy `*.websiteDomain` subdomains. */
756
+ routingMode: PropTypes.oneOf(["path"]),
757
+ /** Path mode only: override first path segments (e.g. `{ onboarding: '/signup', dashboard: '/app/dashboard' }`). */
758
+ appUrlPaths: PropTypes.object,
759
+ /**
760
+ * Optional per-surface URL style for incremental cutover. Keys: `onboarding`, `dashboard`, `admin`, `registerEntry`, `investorRoot`.
761
+ * Each value: `'path'` (same-origin prefix from `appUrlPaths`) or `'subdomain'` (legacy `https://{sub}.{websiteDomain}`).
762
+ * Omitted keys follow global `routingMode` (`path` vs default subdomain).
763
+ */
764
+ surfaceRoutingMode: PropTypes.object,
751
765
  firebase: PropTypes.shape({
752
766
  apiKey: PropTypes.string,
753
767
  authDomain: PropTypes.string,
@@ -1,23 +1,9 @@
1
1
  import { getApps, getApp, initializeApp } from "firebase/app";
2
2
  import { initializeAuth, inMemoryPersistence, getAuth } from "firebase/auth";
3
- const __vite_import_meta_env__ = { "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false };
3
+ import { getConfig } from "./runtime-config.js";
4
+ const __vite_import_meta_env__ = {};
4
5
  let app = null;
5
6
  let auth = null;
6
- function getEnvFirebaseConfig() {
7
- try {
8
- return {
9
- apiKey: __vite_import_meta_env__?.VITE_FIREBASE_API_KEY,
10
- authDomain: __vite_import_meta_env__?.VITE_FIREBASE_AUTH_DOMAIN,
11
- projectId: __vite_import_meta_env__?.VITE_FIREBASE_PROJECT_ID,
12
- storageBucket: __vite_import_meta_env__?.VITE_FIREBASE_STORAGE_BUCKET,
13
- messagingSenderId: __vite_import_meta_env__?.VITE_FIREBASE_MESSAGING_SENDER_ID,
14
- appId: __vite_import_meta_env__?.VITE_FIREBASE_APP_ID,
15
- measurementId: __vite_import_meta_env__?.VITE_FIREBASE_MEASUREMENT_ID
16
- };
17
- } catch {
18
- return {};
19
- }
20
- }
21
7
  function isValidConfig(config) {
22
8
  return config?.apiKey != null && String(config.apiKey).trim() !== "";
23
9
  }
@@ -25,7 +11,7 @@ function getFirebaseAuth() {
25
11
  return auth;
26
12
  }
27
13
  function initFirebase(configOverride) {
28
- const firebaseConfig = configOverride || getEnvFirebaseConfig();
14
+ const firebaseConfig = configOverride != null ? configOverride : getConfig("firebase");
29
15
  if (!isValidConfig(firebaseConfig)) {
30
16
  if (configOverride && typeof console !== "undefined" && console.warn) {
31
17
  console.warn(
@@ -63,7 +49,7 @@ function initFirebase(configOverride) {
63
49
  }
64
50
  }
65
51
  }
66
- if (typeof __vite_import_meta_env__ !== "undefined" && isValidConfig(getEnvFirebaseConfig())) {
52
+ if (typeof __vite_import_meta_env__ !== "undefined" && isValidConfig(getConfig("firebase"))) {
67
53
  initFirebase();
68
54
  }
69
55
  export {
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import { ErrorMessage } from "./components/ErrorMessage/ErrorMessage.styles.js";
22
22
  import { FAQ } from "./components/FAQ/FAQ.js";
23
23
  import { default as default2 } from "./components/Footer/Footer.js";
24
24
  import { default as default3 } from "./components/Footer/FooterMenu.js";
25
- import { default as default4 } from "./components/Footer/FooterLayout.js";
25
+ import { default as default4, getFooterGroups } from "./components/Footer/FooterLayout.js";
26
26
  import { Newsletter } from "./components/Newsletter/Newsletter.js";
27
27
  import { ForgotPasswordModal } from "./components/ForgotPasswordModal/ForgotPasswordModal.js";
28
28
  import { Form } from "./components/Form/Form.js";
@@ -192,7 +192,13 @@ import { openFile, saveAs } from "./utils/saveAs.js";
192
192
  import { ScrollToTop, scrollToElement, useScrollActions } from "./utils/scrollUtils.js";
193
193
  import { useTimer } from "./hooks/useTimer.js";
194
194
  import { useTransactionPolling } from "./hooks/useTransactionPolling.js";
195
- import { configure, getConfig } from "./config.js";
195
+ import { configure } from "./config.js";
196
+ import { AppRoute, AppSurface } from "./routing/app-routes.js";
197
+ import { SURFACE_ROUTING_PATH_KEYS, getAppPublicOrigin, isAlreadyOnOnboardingFlow, isPathBasedRouting, isPathForSurface, resolveAppHref } from "./routing/resolve-app-href.js";
198
+ import { navigateApp, navigateToHref, pathnameIfSameOrigin } from "./routing/navigate-app.js";
199
+ import { RouterWrapper } from "./routing/RouterWrapper.js";
200
+ import { buildDashboardUrl, buildOnboardingUrl, getAdminAppUrl, getDashboardBaseUrl, getInvestorAppOrigin, getOnboardingAppBaseUrl, getRegisterEntryUrl } from "./utils/app-urls.js";
201
+ import { authenticationApi } from "./api/authenticationApi.js";
196
202
  import { default as default40 } from "./components/2FA/Connect2FA.js";
197
203
  import { default as default41 } from "./components/2FA/enable-2fa-flow.js";
198
204
  import { default as default42 } from "./components/2FA/EnterCode.js";
@@ -214,7 +220,7 @@ import { default as default52 } from "./styles/semanticUi.js";
214
220
  import { default as default53 } from "./styles/spacing.js";
215
221
  import { default as default54 } from "./styles/theme.js";
216
222
  import { BASE_COLOR_HEX, BASE_FONT_SIZE, BASE_MARGIN, BASE_MARGIN_2X_PX, BASE_MARGIN_PX, BLUE_BASE_HEX, BLUE_BASE_RELEASED_HEX, CAPITAL_ANIMATION_LENGTH, COLUMN, DESKTOP_MEDIA, GRAY_BASE_HEX, GRAY_DEEP_HEX, GRAY_SECONDARY_HEX, GREEN, MAX_WIDTH, PHONE_MEDIA, RED_BASE_HEX, RED_BASE_RELEASE_HEX, SLIDER_HEIGHT, SLIDER_MOBILE_HEIGHT, SLIDER_TABLET_HEIGHT, TABLET_MEDIA, WHITE_HEX } from "./constants/style.js";
217
- import { LoanActivityTypes, ProfessionalInvestorStatuses, ProjectStates, ProjectStatus, ProjectTypes, TransactionTypes, USInvestorAcreditationStatuses, UserTypes, emailRegex, platformDomain, platformURL, transactionTypeDisplayNames, walletTypes } from "./constants/globalVariables.js";
223
+ import { LoanActivityTypes, ProfessionalInvestorStatuses, ProjectStates, ProjectStatus, ProjectTypes, TransactionTypes, USInvestorAcreditationStatuses, UserTypes, emailRegex, getPlatformURL, transactionTypeDisplayNames, walletTypes } from "./constants/globalVariables.js";
218
224
  import { BackButtonIcon, StyledBackButton, StyledBackButtonExternal, StyledWindowBackButton } from "./components/BackButton/BackButton.styles.js";
219
225
  import { ContainerWithLine } from "./components/RegisterConfirmModal/RegisterConfirmModal.styles.js";
220
226
  import { CopyToClipboard } from "react-copy-to-clipboard";
@@ -230,6 +236,8 @@ import { StyledReactTable, Styles, TableWrap } from "./components/AdminDashboard
230
236
  import { Tab } from "./components/Tabs/Tabs.styles.js";
231
237
  import { default as default55 } from "./components/TabsNav/TabNav.js";
232
238
  import { format } from "date-fns";
239
+ import { getAnalyticsIngestUrl, getBackofficeAppUrl } from "./utils/app-urls-analytics-backoffice.js";
240
+ import { getConfig, resetRuntimeConfig } from "./runtime-config.js";
233
241
  import { learnMoreCategoryPropTypes, learnMorePostPropTypes } from "./components/LearnMorePage/LearnMore.propTypes.js";
234
242
  export {
235
243
  AccountBalance,
@@ -237,6 +245,8 @@ export {
237
245
  AgreementItem,
238
246
  AnimatedSpan,
239
247
  AnnouncementTitleMain,
248
+ AppRoute,
249
+ AppSurface,
240
250
  Arrow,
241
251
  ArrowSimple,
242
252
  Auth,
@@ -462,11 +472,13 @@ export {
462
472
  default47 as ResetCode,
463
473
  ResetConfirmModal,
464
474
  ResetPasswordModal,
475
+ RouterWrapper,
465
476
  Row,
466
477
  SEO,
467
478
  SLIDER_HEIGHT,
468
479
  SLIDER_MOBILE_HEIGHT,
469
480
  SLIDER_TABLET_HEIGHT,
481
+ SURFACE_ROUTING_PATH_KEYS,
470
482
  Scroll,
471
483
  ScrollToTop,
472
484
  SearchInput,
@@ -569,6 +581,9 @@ export {
569
581
  X,
570
582
  Youtube,
571
583
  alias,
584
+ authenticationApi,
585
+ buildDashboardUrl,
586
+ buildOnboardingUrl,
572
587
  checkSaleTimeLeft,
573
588
  checkTodoStatus,
574
589
  colors,
@@ -582,13 +597,23 @@ export {
582
597
  format,
583
598
  formatCurrencyValue,
584
599
  generateCoreChecklistTasks,
600
+ getAdminAppUrl,
585
601
  getAmountBucket,
602
+ getAnalyticsIngestUrl,
603
+ getAppPublicOrigin,
604
+ getBackofficeAppUrl,
586
605
  getConfig,
587
606
  getCurrencyIcon,
588
607
  getCurrencySymbol,
608
+ getDashboardBaseUrl,
609
+ getFooterGroups,
610
+ getInvestorAppOrigin,
589
611
  getLiquidAssetIcon,
590
612
  getMedia,
613
+ getOnboardingAppBaseUrl,
614
+ getPlatformURL,
591
615
  getProjectCurrencySign,
616
+ getRegisterEntryUrl,
592
617
  getTokenBucket,
593
618
  getVerifyIdentityChecklist,
594
619
  default49 as grid,
@@ -596,19 +621,25 @@ export {
596
621
  iconsMap,
597
622
  identify,
598
623
  initAnalytics,
624
+ isAlreadyOnOnboardingFlow,
625
+ isPathBasedRouting,
626
+ isPathForSurface,
599
627
  isUSInvestor,
600
628
  km_ify,
601
629
  learnMoreCategoryPropTypes,
602
630
  learnMorePostPropTypes,
603
631
  loaderGif,
604
632
  momentUtils,
633
+ navigateApp,
634
+ navigateToHref,
605
635
  openFile,
606
636
  optIn,
607
637
  optOut,
608
- platformDomain,
609
- platformURL,
638
+ pathnameIfSameOrigin,
610
639
  default50 as reactTippyStyle,
611
640
  reset,
641
+ resetRuntimeConfig,
642
+ resolveAppHref,
612
643
  default51 as rwd,
613
644
  rwdMax,
614
645
  saveAs,
@@ -1,7 +1,9 @@
1
1
  import axios from "axios";
2
+ import { getConfig } from "../runtime-config.js";
3
+ if (!getConfig("apiUrl") && false) ;
2
4
  const axiosInstance = axios?.create({
3
5
  headers: { "Content-Type": "application/json" },
4
- baseURL: void 0
6
+ baseURL: getConfig("apiUrl") || void 0
5
7
  });
6
8
  export {
7
9
  axiosInstance as default
@@ -1,8 +1,8 @@
1
1
  import axios from "axios";
2
- const BASE_URL = void 0;
2
+ import { getConfig } from "../runtime-config.js";
3
3
  const axiosInstance = axios?.create({
4
4
  headers: { "Content-Type": "application/json" },
5
- baseURL: BASE_URL
5
+ baseURL: getConfig("baseUrlPublic")
6
6
  });
7
7
  export {
8
8
  axiosInstance as default
@@ -0,0 +1,17 @@
1
+ import { jsx, Fragment } from "react/jsx-runtime";
2
+ import "react";
3
+ import PropTypes from "prop-types";
4
+ import { useInRouterContext, BrowserRouter } from "react-router-dom";
5
+ function RouterWrapper({ children }) {
6
+ const inRouter = useInRouterContext();
7
+ if (inRouter) {
8
+ return /* @__PURE__ */ jsx(Fragment, { children });
9
+ }
10
+ return /* @__PURE__ */ jsx(BrowserRouter, { future: { v7_relativeSplatPath: false, v7_startTransition: false }, children });
11
+ }
12
+ RouterWrapper.propTypes = {
13
+ children: PropTypes.node
14
+ };
15
+ export {
16
+ RouterWrapper
17
+ };
@@ -0,0 +1,22 @@
1
+ const AppSurface = Object.freeze({
2
+ ONBOARDING: "onboarding",
3
+ DASHBOARD: "dashboard",
4
+ ADMIN: "admin",
5
+ BACKOFFICE: "backoffice",
6
+ /** Apex / public app origin (`https://{websiteDomain}`; path mode uses the same base as {@link getPlatformURL}). */
7
+ INVESTOR_ROOT: "investorRoot",
8
+ /** Register / sign-up entry from login flows. */
9
+ REGISTER: "register",
10
+ /** Default Mixpanel proxy host (subdomain or path). */
11
+ ANALYTICS: "analytics"
12
+ });
13
+ const AppRoute = Object.freeze({
14
+ WELCOME: "/welcome",
15
+ RESEND_ACTIVATION: "/resend-activation-email",
16
+ CHECKLIST: "/checklist",
17
+ OVERVIEW: "/overview"
18
+ });
19
+ export {
20
+ AppRoute,
21
+ AppSurface
22
+ };
@@ -0,0 +1,36 @@
1
+ import { resolveAppHref } from "./resolve-app-href.js";
2
+ function pathnameIfSameOrigin(absoluteHref) {
3
+ if (typeof window === "undefined" || !absoluteHref) return null;
4
+ try {
5
+ const u = new URL(absoluteHref, window.location.href);
6
+ if (u.origin === window.location.origin) {
7
+ return `${u.pathname}${u.search}${u.hash}`;
8
+ }
9
+ } catch {
10
+ }
11
+ return null;
12
+ }
13
+ function navigateApp(navigate, surface, relativePath = "") {
14
+ const href = resolveAppHref(surface, relativePath);
15
+ if (!href) return;
16
+ const internal = pathnameIfSameOrigin(href);
17
+ if (internal != null && typeof navigate === "function") {
18
+ navigate(internal);
19
+ return;
20
+ }
21
+ window.location.assign(href);
22
+ }
23
+ function navigateToHref(navigate, href) {
24
+ if (!href) return;
25
+ const internal = pathnameIfSameOrigin(href);
26
+ if (internal != null && typeof navigate === "function") {
27
+ navigate(internal);
28
+ return;
29
+ }
30
+ window.location.assign(href);
31
+ }
32
+ export {
33
+ navigateApp,
34
+ navigateToHref,
35
+ pathnameIfSameOrigin
36
+ };
@@ -0,0 +1,149 @@
1
+ import { getPlatformURL } from "../constants/globalVariables.js";
2
+ import { getConfig } from "../runtime-config.js";
3
+ import { AppSurface } from "./app-routes.js";
4
+ import { getAnalyticsIngestUrl, getBackofficeAppUrl } from "../utils/app-urls-analytics-backoffice.js";
5
+ const DEFAULT_APP_PATHS = {
6
+ onboarding: "/signin",
7
+ registerEntry: "/signup",
8
+ dashboard: "/dashboard",
9
+ admin: "/admin"
10
+ };
11
+ const SURFACE_ROUTING_PATH_KEYS = Object.freeze([
12
+ "onboarding",
13
+ "dashboard",
14
+ "admin",
15
+ "registerEntry",
16
+ "investorRoot"
17
+ ]);
18
+ function routingModeRaw() {
19
+ const v = getConfig("routingMode");
20
+ return typeof v === "string" ? v.trim().toLowerCase() : "";
21
+ }
22
+ function isPathBasedRouting() {
23
+ return routingModeRaw() === "path";
24
+ }
25
+ function isPathForSurface(pathKey) {
26
+ const per = getConfig("surfaceRoutingMode");
27
+ if (!per || typeof per !== "object" || Array.isArray(per)) return isPathBasedRouting();
28
+ if (!Object.prototype.hasOwnProperty.call(per, pathKey)) return isPathBasedRouting();
29
+ const v = per[pathKey];
30
+ if (v === "path") return true;
31
+ if (v === "subdomain") return false;
32
+ return isPathBasedRouting();
33
+ }
34
+ function mergedPaths() {
35
+ const o = getConfig("appUrlPaths");
36
+ if (o && typeof o === "object" && !Array.isArray(o)) {
37
+ return { ...DEFAULT_APP_PATHS, ...o };
38
+ }
39
+ return { ...DEFAULT_APP_PATHS };
40
+ }
41
+ function stripTrailingSlash(s) {
42
+ return String(s).replace(/\/+$/, "");
43
+ }
44
+ function normalizeLeading(path) {
45
+ if (path == null || path === "") return "";
46
+ const p = String(path);
47
+ return p.startsWith("/") ? p : `/${p}`;
48
+ }
49
+ function isNonEmptyString(v) {
50
+ return v != null && String(v).trim() !== "";
51
+ }
52
+ function trimmedWebsiteDomain() {
53
+ const d = getConfig("websiteDomain");
54
+ return isNonEmptyString(d) ? String(d).trim() : "";
55
+ }
56
+ function getAppPublicOrigin() {
57
+ const u = getPlatformURL();
58
+ if (!isNonEmptyString(u)) return "";
59
+ return stripTrailingSlash(String(u).trim());
60
+ }
61
+ function subdomainOrigin(sub) {
62
+ const domain = trimmedWebsiteDomain();
63
+ if (!domain) return "";
64
+ return `https://${sub}.${domain}`;
65
+ }
66
+ function surfaceBase(pathKey, legacySubdomain) {
67
+ if (isPathForSurface(pathKey)) {
68
+ const origin = getAppPublicOrigin();
69
+ if (!origin) return "";
70
+ const seg = stripTrailingSlash(normalizeLeading(mergedPaths()[pathKey]));
71
+ return `${origin}${seg}`;
72
+ }
73
+ return subdomainOrigin(legacySubdomain);
74
+ }
75
+ function onboardingBase() {
76
+ return surfaceBase("onboarding", "signup");
77
+ }
78
+ function dashboardBase() {
79
+ return surfaceBase("dashboard", "dashboard");
80
+ }
81
+ function adminBase() {
82
+ return surfaceBase("admin", "admin");
83
+ }
84
+ function investorRootBase() {
85
+ if (isPathForSurface("investorRoot")) return getAppPublicOrigin() || "";
86
+ const domain = trimmedWebsiteDomain();
87
+ if (!domain) return "";
88
+ return `https://${domain}`;
89
+ }
90
+ function registerEntryHref() {
91
+ if (isPathForSurface("registerEntry")) {
92
+ const origin = getAppPublicOrigin();
93
+ if (!origin) return "";
94
+ const seg = stripTrailingSlash(normalizeLeading(mergedPaths().registerEntry));
95
+ return `${origin}${seg}`;
96
+ }
97
+ const domain = trimmedWebsiteDomain();
98
+ if (!domain) return "";
99
+ return `https://${domain}/signup`;
100
+ }
101
+ function resolveAppHref(surface, relativePath = "") {
102
+ let base = "";
103
+ switch (surface) {
104
+ case AppSurface.ONBOARDING:
105
+ base = onboardingBase();
106
+ break;
107
+ case AppSurface.DASHBOARD:
108
+ base = dashboardBase();
109
+ break;
110
+ case AppSurface.ADMIN:
111
+ base = adminBase();
112
+ break;
113
+ case AppSurface.BACKOFFICE:
114
+ base = getBackofficeAppUrl("");
115
+ break;
116
+ case AppSurface.INVESTOR_ROOT:
117
+ base = investorRootBase();
118
+ break;
119
+ case AppSurface.REGISTER:
120
+ return registerEntryHref();
121
+ case AppSurface.ANALYTICS:
122
+ return getAnalyticsIngestUrl();
123
+ default:
124
+ return "";
125
+ }
126
+ const p = normalizeLeading(relativePath);
127
+ if (!base) return "";
128
+ const root = stripTrailingSlash(base);
129
+ return p ? `${root}${p}` : root;
130
+ }
131
+ function isAlreadyOnOnboardingFlow() {
132
+ if (typeof window === "undefined") return false;
133
+ const { href, hostname } = window.location;
134
+ if (isPathForSurface("onboarding")) {
135
+ const base = onboardingBase();
136
+ if (base && href.startsWith(base)) return true;
137
+ const seg = mergedPaths().onboarding.replace(/^\//, "");
138
+ return href.includes(`/${seg}/`) || href.includes(`/${seg}?`) || href.endsWith(`/${seg}`);
139
+ }
140
+ return Boolean(hostname?.startsWith("signup.") || href.includes("signup."));
141
+ }
142
+ export {
143
+ SURFACE_ROUTING_PATH_KEYS,
144
+ getAppPublicOrigin,
145
+ isAlreadyOnOnboardingFlow,
146
+ isPathBasedRouting,
147
+ isPathForSurface,
148
+ resolveAppHref
149
+ };