@stokr/components-library 3.0.21 → 3.0.23
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/README.md +217 -11
- package/dist/analytics/index.js +5 -1
- package/dist/api/authenticationApi.js +13 -0
- package/dist/auth/index.js +4 -2
- package/dist/components/2FA/login-with-otp-flow.js +9 -4
- package/dist/components/Footer/FooterLayout.js +98 -95
- package/dist/components/Footer/FooterMenu.js +1 -1
- package/dist/components/Header/Header.js +102 -54
- package/dist/components/MainMenu/MainMenu.js +14 -4
- package/dist/components/Modal/NewVentureModal/NewVentureModal.js +6 -2
- package/dist/components/Modal/SuccessModal/SuccessModal.js +7 -1
- package/dist/components/Payment/PaymentDetailsCard.js +1 -1
- package/dist/components/StatusDot/StatusDot.js +68 -0
- package/dist/components/StatusDot/StatusDot.styles.js +45 -0
- package/dist/components/VerifyEmailModal/VerifyEmailModal.js +2 -1
- package/dist/components/headerHo/HeaderHo.js +8 -5
- package/dist/config.js +5 -21
- package/dist/constants/globalVariables.js +6 -4
- package/dist/context/Auth.js +5 -2
- package/dist/context/AuthContext.js +22 -8
- package/dist/firebase-config.js +4 -18
- package/dist/index.js +38 -5
- package/dist/model/axios.js +3 -1
- package/dist/model/axiosPublic.js +2 -2
- package/dist/routing/RouterWrapper.js +17 -0
- package/dist/routing/app-routes.js +22 -0
- package/dist/routing/navigate-app.js +36 -0
- package/dist/routing/resolve-app-href.js +149 -0
- package/dist/runtime-config.js +94 -0
- package/dist/static/animations/upload.lottie +0 -0
- package/dist/static/animations/upload.lottie.js +4 -0
- package/dist/static/images/upload.svg +5 -1
- package/dist/utils/app-urls-analytics-backoffice.js +30 -0
- package/dist/utils/app-urls.js +28 -0
- package/dist/utils/checklistGenerator.js +6 -5
- package/dist/utils/customHooks.js +1 -1
- package/dist/utils/formatCurrencyValue.js +2 -1
- package/dist/utils/get-cookie-domain.js +4 -1
- package/dist/utils/set-redirect-cookie.js +4 -1
- package/dist/utils/withRouter.js +5 -3
- package/package.json +1 -1
- package/dist/api/auth.js +0 -15
|
@@ -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
|
|
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
|
-
|
|
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 && !
|
|
409
|
-
|
|
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" && !
|
|
412
|
-
|
|
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
|
|
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,
|
package/dist/firebase-config.js
CHANGED
|
@@ -1,23 +1,9 @@
|
|
|
1
1
|
import { getApps, getApp, initializeApp } from "firebase/app";
|
|
2
2
|
import { initializeAuth, inMemoryPersistence, getAuth } from "firebase/auth";
|
|
3
|
-
|
|
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
|
|
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(
|
|
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";
|
|
@@ -119,6 +119,7 @@ import { CurrencyLogo, DetailItem, DetailsSection, PaymentDetailsCard } from "./
|
|
|
119
119
|
import { Timeline } from "./components/Timeline/Timeline.js";
|
|
120
120
|
import { TimelineStep } from "./components/Timeline/TimelineStep.js";
|
|
121
121
|
import { StatusTag } from "./components/StatusTag/StatusTag.js";
|
|
122
|
+
import { StatusDot } from "./components/StatusDot/StatusDot.js";
|
|
122
123
|
import { StepIndicator } from "./components/StepsProgress/StepIndicator.js";
|
|
123
124
|
import { Snackbar } from "./components/Snackbar/Snackbar.js";
|
|
124
125
|
import { SnackbarContext, SnackbarProvider } from "./components/Snackbar/SnackbarProvider.js";
|
|
@@ -192,7 +193,13 @@ import { openFile, saveAs } from "./utils/saveAs.js";
|
|
|
192
193
|
import { ScrollToTop, scrollToElement, useScrollActions } from "./utils/scrollUtils.js";
|
|
193
194
|
import { useTimer } from "./hooks/useTimer.js";
|
|
194
195
|
import { useTransactionPolling } from "./hooks/useTransactionPolling.js";
|
|
195
|
-
import { configure
|
|
196
|
+
import { configure } from "./config.js";
|
|
197
|
+
import { AppRoute, AppSurface } from "./routing/app-routes.js";
|
|
198
|
+
import { SURFACE_ROUTING_PATH_KEYS, getAppPublicOrigin, isAlreadyOnOnboardingFlow, isPathBasedRouting, isPathForSurface, resolveAppHref } from "./routing/resolve-app-href.js";
|
|
199
|
+
import { navigateApp, navigateToHref, pathnameIfSameOrigin } from "./routing/navigate-app.js";
|
|
200
|
+
import { RouterWrapper } from "./routing/RouterWrapper.js";
|
|
201
|
+
import { buildDashboardUrl, buildOnboardingUrl, getAdminAppUrl, getDashboardBaseUrl, getInvestorAppOrigin, getOnboardingAppBaseUrl, getRegisterEntryUrl } from "./utils/app-urls.js";
|
|
202
|
+
import { authenticationApi } from "./api/authenticationApi.js";
|
|
196
203
|
import { default as default40 } from "./components/2FA/Connect2FA.js";
|
|
197
204
|
import { default as default41 } from "./components/2FA/enable-2fa-flow.js";
|
|
198
205
|
import { default as default42 } from "./components/2FA/EnterCode.js";
|
|
@@ -214,7 +221,7 @@ import { default as default52 } from "./styles/semanticUi.js";
|
|
|
214
221
|
import { default as default53 } from "./styles/spacing.js";
|
|
215
222
|
import { default as default54 } from "./styles/theme.js";
|
|
216
223
|
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,
|
|
224
|
+
import { LoanActivityTypes, ProfessionalInvestorStatuses, ProjectStates, ProjectStatus, ProjectTypes, TransactionTypes, USInvestorAcreditationStatuses, UserTypes, emailRegex, getPlatformURL, transactionTypeDisplayNames, walletTypes } from "./constants/globalVariables.js";
|
|
218
225
|
import { BackButtonIcon, StyledBackButton, StyledBackButtonExternal, StyledWindowBackButton } from "./components/BackButton/BackButton.styles.js";
|
|
219
226
|
import { ContainerWithLine } from "./components/RegisterConfirmModal/RegisterConfirmModal.styles.js";
|
|
220
227
|
import { CopyToClipboard } from "react-copy-to-clipboard";
|
|
@@ -230,6 +237,8 @@ import { StyledReactTable, Styles, TableWrap } from "./components/AdminDashboard
|
|
|
230
237
|
import { Tab } from "./components/Tabs/Tabs.styles.js";
|
|
231
238
|
import { default as default55 } from "./components/TabsNav/TabNav.js";
|
|
232
239
|
import { format } from "date-fns";
|
|
240
|
+
import { getAnalyticsIngestUrl, getBackofficeAppUrl } from "./utils/app-urls-analytics-backoffice.js";
|
|
241
|
+
import { getConfig, resetRuntimeConfig } from "./runtime-config.js";
|
|
233
242
|
import { learnMoreCategoryPropTypes, learnMorePostPropTypes } from "./components/LearnMorePage/LearnMore.propTypes.js";
|
|
234
243
|
export {
|
|
235
244
|
AccountBalance,
|
|
@@ -237,6 +246,8 @@ export {
|
|
|
237
246
|
AgreementItem,
|
|
238
247
|
AnimatedSpan,
|
|
239
248
|
AnnouncementTitleMain,
|
|
249
|
+
AppRoute,
|
|
250
|
+
AppSurface,
|
|
240
251
|
Arrow,
|
|
241
252
|
ArrowSimple,
|
|
242
253
|
Auth,
|
|
@@ -462,11 +473,13 @@ export {
|
|
|
462
473
|
default47 as ResetCode,
|
|
463
474
|
ResetConfirmModal,
|
|
464
475
|
ResetPasswordModal,
|
|
476
|
+
RouterWrapper,
|
|
465
477
|
Row,
|
|
466
478
|
SEO,
|
|
467
479
|
SLIDER_HEIGHT,
|
|
468
480
|
SLIDER_MOBILE_HEIGHT,
|
|
469
481
|
SLIDER_TABLET_HEIGHT,
|
|
482
|
+
SURFACE_ROUTING_PATH_KEYS,
|
|
470
483
|
Scroll,
|
|
471
484
|
ScrollToTop,
|
|
472
485
|
SearchInput,
|
|
@@ -497,6 +510,7 @@ export {
|
|
|
497
510
|
default35 as SocialYoutube,
|
|
498
511
|
SpanButton,
|
|
499
512
|
StatusBadge,
|
|
513
|
+
StatusDot,
|
|
500
514
|
StatusTag,
|
|
501
515
|
StepController,
|
|
502
516
|
StepControllerConsumer,
|
|
@@ -569,6 +583,9 @@ export {
|
|
|
569
583
|
X,
|
|
570
584
|
Youtube,
|
|
571
585
|
alias,
|
|
586
|
+
authenticationApi,
|
|
587
|
+
buildDashboardUrl,
|
|
588
|
+
buildOnboardingUrl,
|
|
572
589
|
checkSaleTimeLeft,
|
|
573
590
|
checkTodoStatus,
|
|
574
591
|
colors,
|
|
@@ -582,13 +599,23 @@ export {
|
|
|
582
599
|
format,
|
|
583
600
|
formatCurrencyValue,
|
|
584
601
|
generateCoreChecklistTasks,
|
|
602
|
+
getAdminAppUrl,
|
|
585
603
|
getAmountBucket,
|
|
604
|
+
getAnalyticsIngestUrl,
|
|
605
|
+
getAppPublicOrigin,
|
|
606
|
+
getBackofficeAppUrl,
|
|
586
607
|
getConfig,
|
|
587
608
|
getCurrencyIcon,
|
|
588
609
|
getCurrencySymbol,
|
|
610
|
+
getDashboardBaseUrl,
|
|
611
|
+
getFooterGroups,
|
|
612
|
+
getInvestorAppOrigin,
|
|
589
613
|
getLiquidAssetIcon,
|
|
590
614
|
getMedia,
|
|
615
|
+
getOnboardingAppBaseUrl,
|
|
616
|
+
getPlatformURL,
|
|
591
617
|
getProjectCurrencySign,
|
|
618
|
+
getRegisterEntryUrl,
|
|
592
619
|
getTokenBucket,
|
|
593
620
|
getVerifyIdentityChecklist,
|
|
594
621
|
default49 as grid,
|
|
@@ -596,19 +623,25 @@ export {
|
|
|
596
623
|
iconsMap,
|
|
597
624
|
identify,
|
|
598
625
|
initAnalytics,
|
|
626
|
+
isAlreadyOnOnboardingFlow,
|
|
627
|
+
isPathBasedRouting,
|
|
628
|
+
isPathForSurface,
|
|
599
629
|
isUSInvestor,
|
|
600
630
|
km_ify,
|
|
601
631
|
learnMoreCategoryPropTypes,
|
|
602
632
|
learnMorePostPropTypes,
|
|
603
633
|
loaderGif,
|
|
604
634
|
momentUtils,
|
|
635
|
+
navigateApp,
|
|
636
|
+
navigateToHref,
|
|
605
637
|
openFile,
|
|
606
638
|
optIn,
|
|
607
639
|
optOut,
|
|
608
|
-
|
|
609
|
-
platformURL,
|
|
640
|
+
pathnameIfSameOrigin,
|
|
610
641
|
default50 as reactTippyStyle,
|
|
611
642
|
reset,
|
|
643
|
+
resetRuntimeConfig,
|
|
644
|
+
resolveAppHref,
|
|
612
645
|
default51 as rwd,
|
|
613
646
|
rwdMax,
|
|
614
647
|
saveAs,
|
package/dist/model/axios.js
CHANGED
|
@@ -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
|
-
|
|
2
|
+
import { getConfig } from "../runtime-config.js";
|
|
3
3
|
const axiosInstance = axios?.create({
|
|
4
4
|
headers: { "Content-Type": "application/json" },
|
|
5
|
-
baseURL:
|
|
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
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const __vite_import_meta_env__ = { "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false };
|
|
2
|
+
const _overrides = {};
|
|
3
|
+
const ENV_KEY_BY_CONFIG = {
|
|
4
|
+
apiUrl: "VITE_API_URL",
|
|
5
|
+
baseUrlPublic: "VITE_BASE_URL_PUBLIC",
|
|
6
|
+
cookieDomain: "VITE_COOKIE_DOMAIN",
|
|
7
|
+
websiteDomain: "VITE_WEBSITE_DOMAIN",
|
|
8
|
+
photoApiUrl: "VITE_PHOTO_API_URL",
|
|
9
|
+
/** `'path'` = single-origin URLs (`https://DOMAIN/dashboard`, …). Anything else = legacy subdomains (`dashboard.`, `signup.`, …). */
|
|
10
|
+
routingMode: "VITE_ROUTING_MODE"
|
|
11
|
+
};
|
|
12
|
+
const FIREBASE_ENV_VARS = [
|
|
13
|
+
"VITE_FIREBASE_API_KEY",
|
|
14
|
+
"VITE_FIREBASE_AUTH_DOMAIN",
|
|
15
|
+
"VITE_FIREBASE_PROJECT_ID",
|
|
16
|
+
"VITE_FIREBASE_STORAGE_BUCKET",
|
|
17
|
+
"VITE_FIREBASE_MESSAGING_SENDER_ID",
|
|
18
|
+
"VITE_FIREBASE_APP_ID"
|
|
19
|
+
];
|
|
20
|
+
let hasWarnedMissingEnv = false;
|
|
21
|
+
function env(name) {
|
|
22
|
+
try {
|
|
23
|
+
return __vite_import_meta_env__?.[name];
|
|
24
|
+
} catch {
|
|
25
|
+
return void 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function isProvided(value) {
|
|
29
|
+
if (value == null) return false;
|
|
30
|
+
if (typeof value === "string") return value.trim() !== "";
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
function getMissingRuntimeEnvVarNames() {
|
|
34
|
+
const missing = [];
|
|
35
|
+
for (const [configKey, envName] of Object.entries(ENV_KEY_BY_CONFIG)) {
|
|
36
|
+
const resolved = _overrides[configKey] ?? env(envName);
|
|
37
|
+
if (!isProvided(resolved)) missing.push(envName);
|
|
38
|
+
}
|
|
39
|
+
if (!_overrides.firebase) {
|
|
40
|
+
for (const envName of FIREBASE_ENV_VARS) {
|
|
41
|
+
if (!isProvided(env(envName))) missing.push(envName);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return missing;
|
|
45
|
+
}
|
|
46
|
+
function warnMissingRuntimeEnvOnce() {
|
|
47
|
+
if (hasWarnedMissingEnv || typeof console === "undefined" || !console.warn) return;
|
|
48
|
+
const missing = getMissingRuntimeEnvVarNames();
|
|
49
|
+
if (missing.length === 0) return;
|
|
50
|
+
hasWarnedMissingEnv = true;
|
|
51
|
+
console.warn(
|
|
52
|
+
"[@stokr/components-library] Missing runtime configuration: no value from configure() / AuthProvider and no Vite env fallback for:\n - " + missing.join("\n - ")
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function assignRuntimeConfig(config = {}) {
|
|
56
|
+
Object.assign(_overrides, config);
|
|
57
|
+
warnMissingRuntimeEnvOnce();
|
|
58
|
+
}
|
|
59
|
+
function resetRuntimeConfig() {
|
|
60
|
+
for (const k of Object.keys(_overrides)) {
|
|
61
|
+
delete _overrides[k];
|
|
62
|
+
}
|
|
63
|
+
hasWarnedMissingEnv = false;
|
|
64
|
+
}
|
|
65
|
+
function buildFirebaseConfigFromEnv() {
|
|
66
|
+
return {
|
|
67
|
+
apiKey: env("VITE_FIREBASE_API_KEY"),
|
|
68
|
+
authDomain: env("VITE_FIREBASE_AUTH_DOMAIN"),
|
|
69
|
+
projectId: env("VITE_FIREBASE_PROJECT_ID"),
|
|
70
|
+
storageBucket: env("VITE_FIREBASE_STORAGE_BUCKET"),
|
|
71
|
+
messagingSenderId: env("VITE_FIREBASE_MESSAGING_SENDER_ID"),
|
|
72
|
+
appId: env("VITE_FIREBASE_APP_ID"),
|
|
73
|
+
measurementId: env("VITE_FIREBASE_MEASUREMENT_ID")
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function getConfig(key) {
|
|
77
|
+
if (key === "firebase") {
|
|
78
|
+
return _overrides.firebase ?? buildFirebaseConfigFromEnv();
|
|
79
|
+
}
|
|
80
|
+
if (key === "appUrlPaths") {
|
|
81
|
+
return _overrides.appUrlPaths;
|
|
82
|
+
}
|
|
83
|
+
const envName = ENV_KEY_BY_CONFIG[key];
|
|
84
|
+
if (envName) {
|
|
85
|
+
return _overrides[key] ?? env(envName);
|
|
86
|
+
}
|
|
87
|
+
return _overrides[key];
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
assignRuntimeConfig,
|
|
91
|
+
getConfig,
|
|
92
|
+
getMissingRuntimeEnvVarNames,
|
|
93
|
+
resetRuntimeConfig
|
|
94
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const uploadAnimation = "data:application/octet-stream;base64,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";
|
|
2
|
+
export {
|
|
3
|
+
uploadAnimation as default
|
|
4
|
+
};
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg width="27" height="25" viewBox="0 0 27 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M1 11.1348V20.4681C1 21.1753 1.29266 21.8536 1.81359 22.3537C2.33453 22.8538 3.04107 23.1348 3.77778 23.1348H23.2222C23.9589 23.1348 24.6655 22.8538 25.1864 22.3537C25.7073 21.8536 26 21.1753 26 20.4681V11.1348" stroke="#56606F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M7.73096 9L13.4601 1L19.1893 9" stroke="#56606F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M13.4253 19.1341V3.80078" stroke="#56606F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getConfig } from "../runtime-config.js";
|
|
2
|
+
function trimmedWebsiteDomain() {
|
|
3
|
+
const d = getConfig("websiteDomain");
|
|
4
|
+
return d != null && String(d).trim() !== "" ? String(d).trim() : "";
|
|
5
|
+
}
|
|
6
|
+
function normalizeLeading(path) {
|
|
7
|
+
if (path == null || path === "") return "";
|
|
8
|
+
const p = String(path);
|
|
9
|
+
return p.startsWith("/") ? p : `/${p}`;
|
|
10
|
+
}
|
|
11
|
+
function stripTrailingSlash(s) {
|
|
12
|
+
return String(s).replace(/\/+$/, "");
|
|
13
|
+
}
|
|
14
|
+
function getAnalyticsIngestUrl() {
|
|
15
|
+
const domain = trimmedWebsiteDomain();
|
|
16
|
+
if (!domain) return "";
|
|
17
|
+
return `https://analytics.${domain}`;
|
|
18
|
+
}
|
|
19
|
+
function getBackofficeAppUrl(relativePath = "") {
|
|
20
|
+
const domain = trimmedWebsiteDomain();
|
|
21
|
+
if (!domain) return "";
|
|
22
|
+
const root = `https://backoffice.${domain}`;
|
|
23
|
+
const p = normalizeLeading(relativePath);
|
|
24
|
+
if (!p) return root;
|
|
25
|
+
return `${stripTrailingSlash(root)}${p}`;
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
getAnalyticsIngestUrl,
|
|
29
|
+
getBackofficeAppUrl
|
|
30
|
+
};
|