saafe-redirection-flow 2.0.0
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/.github/workflows/build-and-deploy.yml +41 -0
- package/.gitlab-ci.yml +108 -0
- package/.releaserc.json +18 -0
- package/.storybook/main.ts +28 -0
- package/.storybook/preview.ts +16 -0
- package/.storybook/vitest.setup.ts +9 -0
- package/.vite/deps/@radix-ui_react-avatar.js +230 -0
- package/.vite/deps/@radix-ui_react-avatar.js.map +7 -0
- package/.vite/deps/@radix-ui_react-slot.js +12 -0
- package/.vite/deps/@radix-ui_react-slot.js.map +7 -0
- package/.vite/deps/_metadata.json +79 -0
- package/.vite/deps/chunk-5VGQBUCU.js +597 -0
- package/.vite/deps/chunk-5VGQBUCU.js.map +7 -0
- package/.vite/deps/chunk-DC5AMYBS.js +38 -0
- package/.vite/deps/chunk-DC5AMYBS.js.map +7 -0
- package/.vite/deps/chunk-HUIEPYH7.js +11265 -0
- package/.vite/deps/chunk-HUIEPYH7.js.map +7 -0
- package/.vite/deps/chunk-TKHB4QMX.js +281 -0
- package/.vite/deps/chunk-TKHB4QMX.js.map +7 -0
- package/.vite/deps/chunk-YLDSBLSF.js +1139 -0
- package/.vite/deps/chunk-YLDSBLSF.js.map +7 -0
- package/.vite/deps/class-variance-authority.js +63 -0
- package/.vite/deps/class-variance-authority.js.map +7 -0
- package/.vite/deps/lucide-react.js +36984 -0
- package/.vite/deps/lucide-react.js.map +7 -0
- package/.vite/deps/package.json +3 -0
- package/.vite/deps/react-dom_client.js +17917 -0
- package/.vite/deps/react-dom_client.js.map +7 -0
- package/.vite/deps/react-router-dom.js +452 -0
- package/.vite/deps/react-router-dom.js.map +7 -0
- package/.vite/deps/react-router.js +234 -0
- package/.vite/deps/react-router.js.map +7 -0
- package/.vite/deps/react.js +5 -0
- package/.vite/deps/react.js.map +7 -0
- package/.vite/deps/react_jsx-dev-runtime.js +470 -0
- package/.vite/deps/react_jsx-dev-runtime.js.map +7 -0
- package/CHANGELOG.md +420 -0
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/RELEASE_CHEATSHEET.md +93 -0
- package/RELEASE_NOTES.md +120 -0
- package/components.json +21 -0
- package/docs/DEPLOYMENT_WORKFLOW.md +262 -0
- package/docs/RELEASE_GUIDE.md +591 -0
- package/docs/architecture.md +432 -0
- package/docs/components.md +199 -0
- package/docs/index.md +69 -0
- package/docs/local-release-workflow.md +234 -0
- package/docs/routes.md +118 -0
- package/docs/sdk-integration.md +325 -0
- package/docs/semantic-release.md +124 -0
- package/docs/user-flow.md +206 -0
- package/eslint.config.js +28 -0
- package/index.html +19 -0
- package/install.sh +198 -0
- package/package.json +115 -0
- package/public/images/bank-logo.png +0 -0
- package/public/saafe-icon.svg +9 -0
- package/src/App.tsx +171 -0
- package/src/__tests__/url-parameters.test.ts +82 -0
- package/src/assets/brand/applestore.svg +13 -0
- package/src/assets/brand/playstore.svg +23 -0
- package/src/assets/brand/saafe-color-white-logo.svg +14 -0
- package/src/assets/brand/saafe-icon.svg +9 -0
- package/src/assets/brand/saafe-logo.svg +18 -0
- package/src/assets/icons/check-icon-dark.svg +27 -0
- package/src/assets/icons/check-icon.svg +23 -0
- package/src/components/ErrorBoundary.tsx +132 -0
- package/src/components/alert/alert.tsx +27 -0
- package/src/components/auth/AuthGuard.tsx +76 -0
- package/src/components/cards/BankCard.stories.tsx +69 -0
- package/src/components/cards/BankCard.tsx +227 -0
- package/src/components/cards/OuterCard.tsx +109 -0
- package/src/components/cards/WrapperCard.tsx +64 -0
- package/src/components/documents/PrivacyContent.tsx +1 -0
- package/src/components/dummyFooter.tsx +29 -0
- package/src/components/icons/github.tsx +12 -0
- package/src/components/language/LanguageSwitcher.tsx +44 -0
- package/src/components/layouts/FrostedLayout.stories.tsx +42 -0
- package/src/components/layouts/FrostedLayout.tsx +333 -0
- package/src/components/layouts/MobileLayout.tsx +403 -0
- package/src/components/mobile-background.tsx +136 -0
- package/src/components/mobileAppDownload.tsx +30 -0
- package/src/components/modal/ModalComp.tsx +27 -0
- package/src/components/mode-toggle.tsx +36 -0
- package/src/components/page-header.tsx +50 -0
- package/src/components/session/SessionTimeoutScreen.tsx +134 -0
- package/src/components/session/SessionTimer.tsx +173 -0
- package/src/components/step-navigation.tsx +87 -0
- package/src/components/title/AppBar.stories.tsx +50 -0
- package/src/components/title/AppBar.tsx +150 -0
- package/src/components/title/SectionTitle.tsx +31 -0
- package/src/components/ui/AnimatedButton.module.css +13 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/animatedButton.tsx +111 -0
- package/src/components/ui/avatar.tsx +51 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/bottom-sheet.tsx +122 -0
- package/src/components/ui/button.tsx +59 -0
- package/src/components/ui/calendar.tsx +86 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.stories.tsx +49 -0
- package/src/components/ui/checkbox.tsx +67 -0
- package/src/components/ui/collapsible.tsx +45 -0
- package/src/components/ui/dialog.tsx +134 -0
- package/src/components/ui/document-link.tsx +26 -0
- package/src/components/ui/dot-stepper.tsx +57 -0
- package/src/components/ui/dropdown-menu.tsx +255 -0
- package/src/components/ui/form.tsx +165 -0
- package/src/components/ui/frosted-panel.stories.tsx +86 -0
- package/src/components/ui/frosted-panel.tsx +276 -0
- package/src/components/ui/input.tsx +39 -0
- package/src/components/ui/label.stories.tsx +67 -0
- package/src/components/ui/label.tsx +23 -0
- package/src/components/ui/mobile-footer.tsx +54 -0
- package/src/components/ui/modal.tsx +90 -0
- package/src/components/ui/otp-input.stories.tsx +62 -0
- package/src/components/ui/otp-input.tsx +221 -0
- package/src/components/ui/platform-specific-behavior.tsx +28 -0
- package/src/components/ui/popover.tsx +46 -0
- package/src/components/ui/progress.tsx +103 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/scroll-area.tsx +56 -0
- package/src/components/ui/sdk-params-docs.tsx +53 -0
- package/src/components/ui/select.tsx +159 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +137 -0
- package/src/components/ui/sidebar.tsx +724 -0
- package/src/components/ui/skeleton.stories.tsx +50 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/sonner.tsx +23 -0
- package/src/components/ui/step.stories.tsx +132 -0
- package/src/components/ui/step.tsx +234 -0
- package/src/components/ui/stepper-progress.tsx +136 -0
- package/src/components/ui/stepper.tsx +259 -0
- package/src/components/ui/tabs.tsx +55 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/components/ui/url-decode-loader.tsx +36 -0
- package/src/components/ui/version-display.tsx +104 -0
- package/src/components/ui/web-footer.tsx +36 -0
- package/src/config/environments.ts +99 -0
- package/src/config/urls.ts +53 -0
- package/src/const/fiTypeCategoryMap.ts +19 -0
- package/src/contexts/LanguageContext.tsx +41 -0
- package/src/contexts/RTLContext.tsx +42 -0
- package/src/contexts/ThemeContext.tsx +93 -0
- package/src/hooks/use-account-discovery.ts +205 -0
- package/src/hooks/use-auth-query.ts +141 -0
- package/src/hooks/use-fip-query.ts +72 -0
- package/src/hooks/use-media-query.ts +32 -0
- package/src/hooks/use-mobile.ts +24 -0
- package/src/hooks/use-page-title.tsx +48 -0
- package/src/hooks/use-platform.ts +52 -0
- package/src/hooks/use-trusted-count.ts +21 -0
- package/src/hooks/use-url-decode.ts +90 -0
- package/src/hooks/useStep.ts +170 -0
- package/src/index.css +154 -0
- package/src/interfaces/app.interfaces.ts +39 -0
- package/src/interfaces/services.interfaces.ts +65 -0
- package/src/lib/i18n.ts +68 -0
- package/src/lib/utils.ts +6 -0
- package/src/locales/en/common.json +167 -0
- package/src/locales/hi/common.json +137 -0
- package/src/locales/kn/common.json +137 -0
- package/src/locales/ml/common.json +137 -0
- package/src/locales/ta/common.json +137 -0
- package/src/locales/te/common.json +137 -0
- package/src/locales/ur/common.json +138 -0
- package/src/main.tsx +46 -0
- package/src/pages/Login.tsx +363 -0
- package/src/pages/accounts/AccountsToProceed.tsx +396 -0
- package/src/pages/accounts/Discover.tsx +76 -0
- package/src/pages/accounts/DiscoverAccount.tsx +751 -0
- package/src/pages/accounts/LinkSelectedAccounts.tsx +638 -0
- package/src/pages/accounts/OldUser.tsx +329 -0
- package/src/pages/accounts/link-accounts.tsx +913 -0
- package/src/pages/consent/ReviewConsent.tsx +836 -0
- package/src/pages/consent/rejected.tsx +253 -0
- package/src/pages/consent/success.tsx +220 -0
- package/src/providers/query-provider.tsx +24 -0
- package/src/providers/toast-provider.tsx +26 -0
- package/src/services/api/account.service.ts +296 -0
- package/src/services/api/auth.service.ts +206 -0
- package/src/services/api/axios.ts +138 -0
- package/src/services/api/consent.service.ts +142 -0
- package/src/services/api/decode.service.ts +53 -0
- package/src/services/api/feedback.service.ts +34 -0
- package/src/services/api/fip.service.ts +187 -0
- package/src/services/api/index.ts +9 -0
- package/src/services/api/public.service.ts +18 -0
- package/src/services/api.ts +2 -0
- package/src/services/postMessage.service.ts +179 -0
- package/src/store/NavigationBlockContext.tsx +34 -0
- package/src/store/auth.store.ts +79 -0
- package/src/store/fip.store.ts +396 -0
- package/src/store/mandatoryConsent.store.ts +24 -0
- package/src/store/redirect.store.ts +73 -0
- package/src/store/step.store.ts +124 -0
- package/src/stories/Button.stories.ts +53 -0
- package/src/stories/Button.tsx +37 -0
- package/src/stories/Configure.mdx +364 -0
- package/src/stories/Header.stories.ts +33 -0
- package/src/stories/Header.tsx +56 -0
- package/src/stories/Page.stories.ts +32 -0
- package/src/stories/Page.tsx +73 -0
- package/src/stories/button.css +30 -0
- package/src/stories/header.css +32 -0
- package/src/stories/page.css +68 -0
- package/src/styles/rtl-utils.css +90 -0
- package/src/styles/rtl.css +105 -0
- package/src/utils/api-error.ts +26 -0
- package/src/utils/cn.ts +10 -0
- package/src/utils/error-callback.ts +116 -0
- package/src/utils/formatAccountNumber.ts +9 -0
- package/src/utils/handleIdentifiers.ts +90 -0
- package/src/utils/posthog.ts +67 -0
- package/src/utils/toast-helpers.ts +61 -0
- package/src/vite-env.d.ts +1 -0
- package/stage-aa-2506251021.zip +0 -0
- package/tsconfig.app.json +33 -0
- package/tsconfig.json +13 -0
- package/tsconfig.node.json +24 -0
- package/vite.config.ts +45 -0
- package/vitest.shims.d.ts +1 -0
- package/vitest.workspace.ts +46 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
<svg width="38" height="53" viewBox="0 0 38 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path d="M10.6206 20.8957H5.30688V13.5776C5.30688 6.10368 11.4696 0 19.0157 0C26.5618 0 32.7245 6.10368 32.7245 13.5776H27.4108C27.4108 8.99981 23.6377 5.26286 19.0157 5.26286C14.3937 5.26286 10.6206 8.99981 10.6206 13.5776V20.8957Z" fill="#FCB034"/>
|
3
|
+
<path d="M5.33841 19.4633C3.57765 20.0238 1.84832 20.6778 0.181885 21.4563C0.40198 23.2936 0.716402 25.0998 1.15659 26.8437C2.76015 26.0341 4.42659 25.3489 6.12447 24.7573C5.74716 23.0134 5.46418 21.2383 5.33841 19.4633Z" fill="#00B2C1"/>
|
4
|
+
<path d="M36.8436 26.8126C37.2837 25.0375 37.5982 23.2625 37.8183 21.4252C36.1518 20.6778 34.4225 19.9927 32.6617 19.4321C32.5045 21.2383 32.253 23.0134 31.8442 24.7261C33.605 25.3178 35.2714 26.0341 36.8436 26.8126Z" fill="#00B2C1"/>
|
5
|
+
<path d="M5.33838 19.4632C5.49559 21.2694 5.74713 23.0445 6.15588 24.7572C10.1805 23.387 14.5195 22.6396 19.0158 22.6396C23.512 22.6396 27.851 23.387 31.8756 24.7572C32.2529 23.0445 32.5359 21.2694 32.6931 19.4632C28.3855 18.093 23.795 17.3768 19.0158 17.3768C14.2365 17.3456 9.64597 18.093 5.33838 19.4632Z" fill="#00B2C1"/>
|
6
|
+
<path d="M14.6454 49.2343C16.0288 50.4799 17.4752 51.6322 19.0159 52.691C20.5565 51.6322 22.0029 50.4799 23.3863 49.2343C21.8457 48.2378 20.3993 47.179 19.0159 45.9956C17.6324 47.179 16.1861 48.2378 14.6454 49.2343Z" fill="#00B2C1"/>
|
7
|
+
<path d="M7.75943 30.0511L2.823 32.0442C5.33838 38.6773 9.42587 44.5629 14.6453 49.2341C16.186 48.2376 17.6323 47.1788 19.0158 45.9954C14.0164 41.7291 10.1176 36.2794 7.75943 30.0511Z" fill="#00B2C1"/>
|
8
|
+
<path d="M19.0157 45.9955C20.3992 47.1789 21.8455 48.2377 23.3862 49.2342C29.9262 43.3485 34.7054 35.5944 36.8749 26.8125C35.2714 26.0029 33.6049 25.3178 31.9071 24.7261C29.9891 33.1653 25.3671 40.5458 19.0157 45.9955Z" fill="#00B2C1"/>
|
9
|
+
</svg>
|
package/src/App.tsx
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
import {
|
2
|
+
BrowserRouter as Router,
|
3
|
+
Routes,
|
4
|
+
Route,
|
5
|
+
Navigate,
|
6
|
+
} from "react-router-dom";
|
7
|
+
import Login from "./pages/Login";
|
8
|
+
import Discover from "./pages/accounts/Discover";
|
9
|
+
import { PageTitleProvider } from "./hooks/use-page-title";
|
10
|
+
import AuthGuard from "./components/auth/AuthGuard";
|
11
|
+
import { QueryProvider } from "./providers/query-provider";
|
12
|
+
import { ToastProvider } from "./providers/toast-provider";
|
13
|
+
import { useUrlDecode } from "./hooks/use-url-decode";
|
14
|
+
import { useRedirectStore } from "./store/redirect.store";
|
15
|
+
import { useEffect } from "react";
|
16
|
+
import { UrlDecodeLoader } from "./components/ui/url-decode-loader";
|
17
|
+
import { trackEvent, EVENTS } from "@/utils/posthog";
|
18
|
+
import { ThemeProvider } from "./contexts/ThemeContext";
|
19
|
+
import ReviewConsent from "./pages/consent/ReviewConsent";
|
20
|
+
import Success from "./pages/consent/success";
|
21
|
+
import Rejected from "./pages/consent/rejected";
|
22
|
+
import OldUser from "./pages/accounts/OldUser";
|
23
|
+
import { useNavigationBlock } from "./store/NavigationBlockContext";
|
24
|
+
import { UrlDecodeHandlerProps } from "./interfaces/app.interfaces";
|
25
|
+
import { APP_URLS } from "./config/urls";
|
26
|
+
import { usePlatform } from "./hooks/use-platform";
|
27
|
+
import { useFipStore } from "./store/fip.store";
|
28
|
+
|
29
|
+
// Component to handle URL decoding and theming
|
30
|
+
function UrlDecodeHandler({ children }: UrlDecodeHandlerProps) {
|
31
|
+
// Initialize URL decoding
|
32
|
+
const { isLoading, isError, error } = useUrlDecode();
|
33
|
+
const { decodedInfo, getCustomStyle } = useRedirectStore();
|
34
|
+
const { isNativeSDK } = usePlatform();
|
35
|
+
|
36
|
+
// Apply custom styles if provided
|
37
|
+
useEffect(() => {
|
38
|
+
const customStyles = getCustomStyle();
|
39
|
+
if (customStyles) {
|
40
|
+
// Apply custom colors to CSS variables
|
41
|
+
const root = document.documentElement;
|
42
|
+
|
43
|
+
if (customStyles.primaryButtonColor) {
|
44
|
+
root.style.setProperty('--primary', customStyles.primaryButtonColor);
|
45
|
+
}
|
46
|
+
|
47
|
+
if (customStyles.primaryButtonColor) {
|
48
|
+
root.style.setProperty('--ring', `${customStyles.primaryButtonColor}10`);
|
49
|
+
}
|
50
|
+
|
51
|
+
// Add other custom styling as needed
|
52
|
+
}
|
53
|
+
}, [decodedInfo, getCustomStyle]);
|
54
|
+
|
55
|
+
const { shouldAllowNavigation } = useNavigationBlock(); // Track if in-app back button was used
|
56
|
+
|
57
|
+
useEffect(() => {
|
58
|
+
// Skip navigation warnings for native SDKs
|
59
|
+
if (isNativeSDK) return;
|
60
|
+
|
61
|
+
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
|
62
|
+
e.preventDefault();
|
63
|
+
e.returnValue = '';
|
64
|
+
};
|
65
|
+
|
66
|
+
const handlePopState = () => {
|
67
|
+
if (shouldAllowNavigation()) return; // skip confirmation
|
68
|
+
|
69
|
+
const confirmed = window.confirm('Are you sure you want to leave this page?');
|
70
|
+
if (!confirmed) {
|
71
|
+
window.history.pushState(null, '', window.location.href);
|
72
|
+
}
|
73
|
+
};
|
74
|
+
|
75
|
+
window.addEventListener('beforeunload', handleBeforeUnload);
|
76
|
+
window.addEventListener('popstate', handlePopState);
|
77
|
+
window.history.pushState(null, '', window.location.href);
|
78
|
+
|
79
|
+
return () => {
|
80
|
+
window.removeEventListener('beforeunload', handleBeforeUnload);
|
81
|
+
window.removeEventListener('popstate', handlePopState);
|
82
|
+
};
|
83
|
+
}, [shouldAllowNavigation, isNativeSDK]);
|
84
|
+
|
85
|
+
if (isLoading) {
|
86
|
+
return <UrlDecodeLoader message="Setting up your experience..." />;
|
87
|
+
}
|
88
|
+
|
89
|
+
if (isError) {
|
90
|
+
return <UrlDecodeLoader
|
91
|
+
isError
|
92
|
+
message={error?.message || "Invalid URL parameters. Please check the URL and try again."}
|
93
|
+
/>;
|
94
|
+
}
|
95
|
+
if (!decodedInfo && !isLoading) {
|
96
|
+
return <UrlDecodeLoader
|
97
|
+
isWarning
|
98
|
+
message={"Please provide the correct URL parameters."}
|
99
|
+
/>;
|
100
|
+
}
|
101
|
+
|
102
|
+
return <>{children}</>;
|
103
|
+
}
|
104
|
+
|
105
|
+
function App() {
|
106
|
+
const { categories } = useFipStore();
|
107
|
+
useEffect(() => {
|
108
|
+
const handleBeforeUnload = () => {
|
109
|
+
const currentPath = window.location.pathname;
|
110
|
+
trackEvent(EVENTS.USER_EXIT, {
|
111
|
+
path: currentPath,
|
112
|
+
timestamp: new Date().toISOString()
|
113
|
+
});
|
114
|
+
};
|
115
|
+
|
116
|
+
window.addEventListener('beforeunload', handleBeforeUnload);
|
117
|
+
return () => {
|
118
|
+
window.removeEventListener('beforeunload', handleBeforeUnload);
|
119
|
+
};
|
120
|
+
}, []);
|
121
|
+
|
122
|
+
return (
|
123
|
+
<QueryProvider>
|
124
|
+
<ThemeProvider>
|
125
|
+
<ToastProvider>
|
126
|
+
<PageTitleProvider>
|
127
|
+
<UrlDecodeHandler>
|
128
|
+
<Router>
|
129
|
+
<Routes>
|
130
|
+
<Route path="" element={<Navigate to={APP_URLS.LOGIN} replace />} />
|
131
|
+
|
132
|
+
{/* Public routes */}
|
133
|
+
<Route
|
134
|
+
path="login"
|
135
|
+
element={
|
136
|
+
<AuthGuard requireAuth={false}>
|
137
|
+
<Login />
|
138
|
+
</AuthGuard>
|
139
|
+
}
|
140
|
+
/>
|
141
|
+
|
142
|
+
{/* Protected routes */}
|
143
|
+
<Route path="link-accounts">
|
144
|
+
{categories.length > 0 && <Route index element={<AuthGuard><Navigate to={`/link-accounts/${categories[0].toLowerCase()}`} replace /></AuthGuard>} />}
|
145
|
+
{categories.length === 0 && <Route index element={<AuthGuard><Navigate to={'/link-accounts/banks'} replace /></AuthGuard>} />}
|
146
|
+
|
147
|
+
{/* Flow screens for account discovery and linking */}
|
148
|
+
<Route path="discovery" element={<AuthGuard><Discover /></AuthGuard>} />
|
149
|
+
<Route path="proceed" element={<AuthGuard><Discover /></AuthGuard>} />
|
150
|
+
<Route path="link" element={<AuthGuard><Discover /></AuthGuard>} />
|
151
|
+
<Route path="discover-account" element={<AuthGuard><Discover /></AuthGuard>} />
|
152
|
+
<Route path="old-user" element={<AuthGuard><OldUser /></AuthGuard>} />
|
153
|
+
|
154
|
+
{/* Category-specific paths - for FIP listing */}
|
155
|
+
<Route path=":category" element={<AuthGuard><Discover /></AuthGuard>} />
|
156
|
+
</Route>
|
157
|
+
|
158
|
+
<Route path="review" element={<AuthGuard><ReviewConsent /></AuthGuard>} />
|
159
|
+
<Route path="success" element={<AuthGuard><Success /></AuthGuard>} />
|
160
|
+
<Route path="rejected" element={<AuthGuard><Rejected /></AuthGuard>} />
|
161
|
+
</Routes>
|
162
|
+
</Router>
|
163
|
+
</UrlDecodeHandler>
|
164
|
+
</PageTitleProvider>
|
165
|
+
</ToastProvider>
|
166
|
+
</ThemeProvider>
|
167
|
+
</QueryProvider>
|
168
|
+
);
|
169
|
+
}
|
170
|
+
|
171
|
+
export default App;
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import { extractUrlParams } from '../hooks/use-url-decode';
|
2
|
+
|
3
|
+
// Mock window location
|
4
|
+
const mockWindowLocation = (search: string) => {
|
5
|
+
const originalLocation = window.location;
|
6
|
+
delete window.location;
|
7
|
+
window.location = { ...originalLocation, search } as Location;
|
8
|
+
return () => {
|
9
|
+
window.location = originalLocation;
|
10
|
+
};
|
11
|
+
};
|
12
|
+
|
13
|
+
describe('URL parameters', () => {
|
14
|
+
beforeEach(() => {
|
15
|
+
// Reset window location before each test
|
16
|
+
jest.resetModules();
|
17
|
+
});
|
18
|
+
|
19
|
+
test('extractUrlParams should extract required parameters', () => {
|
20
|
+
const cleanup = mockWindowLocation('?fi=test-fi&ecreq=test-ecreq&reqdate=test-reqdate');
|
21
|
+
|
22
|
+
const params = extractUrlParams();
|
23
|
+
expect(params).not.toBeNull();
|
24
|
+
expect(params?.fi).toBe('test-fi');
|
25
|
+
expect(params?.ecreq).toBe('test-ecreq');
|
26
|
+
expect(params?.reqdate).toBe('test-reqdate');
|
27
|
+
expect(params?.platform).toBeUndefined();
|
28
|
+
expect(params?.theme).toBeUndefined();
|
29
|
+
|
30
|
+
cleanup();
|
31
|
+
});
|
32
|
+
|
33
|
+
test('extractUrlParams should extract platform and theme', () => {
|
34
|
+
const cleanup = mockWindowLocation('?fi=test-fi&ecreq=test-ecreq&reqdate=test-reqdate&platform=ios&theme=dark');
|
35
|
+
|
36
|
+
const params = extractUrlParams();
|
37
|
+
expect(params).not.toBeNull();
|
38
|
+
expect(params?.platform).toBe('ios');
|
39
|
+
expect(params?.theme).toBe('dark');
|
40
|
+
|
41
|
+
cleanup();
|
42
|
+
});
|
43
|
+
|
44
|
+
test('extractUrlParams should return null if required params are missing', () => {
|
45
|
+
const cleanup = mockWindowLocation('?fi=test-fi&platform=ios&theme=dark');
|
46
|
+
|
47
|
+
const params = extractUrlParams();
|
48
|
+
expect(params).toBeNull();
|
49
|
+
|
50
|
+
cleanup();
|
51
|
+
});
|
52
|
+
});
|
53
|
+
|
54
|
+
describe('Platform normalization', () => {
|
55
|
+
test('should normalize React Native platform values', () => {
|
56
|
+
const { usePlatform } = require('../hooks/use-platform');
|
57
|
+
const { useRedirectStore } = require('../store/redirect.store');
|
58
|
+
|
59
|
+
// Mock Zustand store
|
60
|
+
jest.mock('../store/redirect.store', () => ({
|
61
|
+
useRedirectStore: jest.fn()
|
62
|
+
}));
|
63
|
+
|
64
|
+
// Test React Native (with hyphen)
|
65
|
+
useRedirectStore.mockReturnValue({
|
66
|
+
decodedInfo: { platform: 'react-native' }
|
67
|
+
});
|
68
|
+
|
69
|
+
let result = usePlatform();
|
70
|
+
expect(result.platform).toBe('react-native');
|
71
|
+
expect(result.isReactNative).toBe(true);
|
72
|
+
|
73
|
+
// Test ReactNative (without hyphen)
|
74
|
+
useRedirectStore.mockReturnValue({
|
75
|
+
decodedInfo: { platform: 'reactnative' }
|
76
|
+
});
|
77
|
+
|
78
|
+
result = usePlatform();
|
79
|
+
expect(result.platform).toBe('react-native');
|
80
|
+
expect(result.isReactNative).toBe(true);
|
81
|
+
});
|
82
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
3
|
+
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_8317)"/>
|
4
|
+
<path d="M18.4468 8.65403C18.7494 8.12586 18.5685 7.45126 18.0428 7.14727C17.5171 6.84328 16.8456 7.02502 16.543 7.55318L16.0153 8.47442L15.4875 7.55318C15.1849 7.02502 14.5134 6.84328 13.9877 7.14727C13.462 7.45126 13.2811 8.12586 13.5837 8.65403L14.748 10.6864L11.0652 17.1149H8.09831C7.49173 17.1149 7 17.6089 7 18.2183C7 18.8277 7.49173 19.3217 8.09831 19.3217H18.4324C18.523 19.0825 18.6184 18.6721 18.5169 18.2949C18.3644 17.7279 17.8 17.1149 16.8542 17.1149H13.5997L18.4468 8.65403Z" fill="white"/>
|
5
|
+
<path d="M11.6364 20.5419C11.449 20.3328 11.0292 19.9987 10.661 19.8888C10.0997 19.7211 9.67413 19.8263 9.45942 19.9179L8.64132 21.346C8.33874 21.8741 8.51963 22.5487 9.04535 22.8527C9.57107 23.1567 10.2425 22.975 10.5451 22.4468L11.6364 20.5419Z" fill="white"/>
|
6
|
+
<path d="M22.2295 19.3217H23.9017C24.5083 19.3217 25 18.8277 25 18.2183C25 17.6089 24.5083 17.1149 23.9017 17.1149H20.9653L17.6575 11.3411C17.4118 11.5757 16.9407 12.175 16.8695 12.8545C16.778 13.728 16.9152 14.4636 17.3271 15.1839C18.7118 17.6056 20.0987 20.0262 21.4854 22.4468C21.788 22.975 22.4594 23.1567 22.9852 22.8527C23.5109 22.5487 23.6918 21.8741 23.3892 21.346L22.2295 19.3217Z" fill="white"/>
|
7
|
+
<defs>
|
8
|
+
<linearGradient id="paint0_linear_87_8317" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
9
|
+
<stop stop-color="#2AC9FA"/>
|
10
|
+
<stop offset="1" stop-color="#1F65EB"/>
|
11
|
+
</linearGradient>
|
12
|
+
</defs>
|
13
|
+
</svg>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
3
|
+
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
4
|
+
viewBox="0 0 511.999 511.999" xml:space="preserve">
|
5
|
+
<g>
|
6
|
+
<path style="fill:#32BBFF;" d="M382.369,175.623C322.891,142.356,227.427,88.937,79.355,6.028
|
7
|
+
C69.372-0.565,57.886-1.429,47.962,1.93l254.05,254.05L382.369,175.623z"/>
|
8
|
+
<path style="fill:#32BBFF;" d="M47.962,1.93c-1.86,0.63-3.67,1.39-5.401,2.308C31.602,10.166,23.549,21.573,23.549,36v439.96
|
9
|
+
c0,14.427,8.052,25.834,19.012,31.761c1.728,0.917,3.537,1.68,5.395,2.314L302.012,255.98L47.962,1.93z"/>
|
10
|
+
<path style="fill:#32BBFF;" d="M302.012,255.98L47.956,510.035c9.927,3.384,21.413,2.586,31.399-4.103
|
11
|
+
c143.598-80.41,237.986-133.196,298.152-166.746c1.675-0.941,3.316-1.861,4.938-2.772L302.012,255.98z"/>
|
12
|
+
</g>
|
13
|
+
<path style="fill:#2C9FD9;" d="M23.549,255.98v219.98c0,14.427,8.052,25.834,19.012,31.761c1.728,0.917,3.537,1.68,5.395,2.314
|
14
|
+
L302.012,255.98H23.549z"/>
|
15
|
+
<path style="fill:#29CC5E;" d="M79.355,6.028C67.5-1.8,53.52-1.577,42.561,4.239l255.595,255.596l84.212-84.212
|
16
|
+
C322.891,142.356,227.427,88.937,79.355,6.028z"/>
|
17
|
+
<path style="fill:#D93F21;" d="M298.158,252.126L42.561,507.721c10.96,5.815,24.939,6.151,36.794-1.789
|
18
|
+
c143.598-80.41,237.986-133.196,298.152-166.746c1.675-0.941,3.316-1.861,4.938-2.772L298.158,252.126z"/>
|
19
|
+
<path style="fill:#FFD500;" d="M488.45,255.98c0-12.19-6.151-24.492-18.342-31.314c0,0-22.799-12.721-92.682-51.809l-83.123,83.123
|
20
|
+
l83.204,83.205c69.116-38.807,92.6-51.892,92.6-51.892C482.299,280.472,488.45,268.17,488.45,255.98z"/>
|
21
|
+
<path style="fill:#FFAA00;" d="M470.108,287.294c12.191-6.822,18.342-19.124,18.342-31.314H294.303l83.204,83.205
|
22
|
+
C446.624,300.379,470.108,287.294,470.108,287.294z"/>
|
23
|
+
</svg>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<svg width="76" height="25" viewBox="0 0 76 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path d="M24.058 13.8033C24.058 14.1421 24.2507 14.3961 24.6508 14.5937C25.0361 14.7913 25.5104 14.9607 26.0587 15.1301C26.6071 15.2853 27.1703 15.4547 27.7483 15.6241C28.3262 15.7935 28.8005 16.104 29.1858 16.5557C29.5712 17.0073 29.7638 17.586 29.7638 18.2777C29.7638 19.2516 29.3785 19.9997 28.593 20.5501C27.8075 21.1006 26.8294 21.3829 25.6438 21.3829C24.6063 21.3829 23.7023 21.1712 22.9613 20.7619C22.2203 20.3525 21.6719 19.7738 21.3311 19.0257L23.3022 17.9389C23.6727 18.9128 24.4581 19.3927 25.6438 19.3927C26.8442 19.3927 27.437 19.0116 27.437 18.2636C27.437 17.9389 27.2444 17.6848 26.859 17.4731C26.4737 17.2755 25.9995 17.092 25.4511 16.9368C24.9027 16.7815 24.3396 16.6121 23.7616 16.4428C23.1836 16.2734 22.7093 15.977 22.324 15.5394C21.9387 15.1019 21.746 14.5514 21.746 13.8739C21.746 12.9423 22.1165 12.1942 22.8575 11.6438C23.5986 11.0792 24.5174 10.7969 25.6141 10.7969C26.4885 10.7969 27.274 10.9804 27.9557 11.3473C28.6375 11.7143 29.171 12.2366 29.5267 12.8858L27.6 13.9162C27.2295 13.154 26.5774 12.7729 25.6141 12.7729C25.1695 12.7729 24.8138 12.8576 24.5174 13.0411C24.2062 13.1964 24.058 13.4504 24.058 13.8033Z" fill="white"/>
|
3
|
+
<path d="M39.7379 11.037H42.0202V21.1149H39.7379V19.6611C38.8783 20.8043 37.6482 21.3689 36.0328 21.3689C34.5804 21.3689 33.3355 20.8608 32.3129 19.8304C31.2903 18.8001 30.7716 17.5439 30.7716 16.0759C30.7716 14.5798 31.2903 13.3236 32.3129 12.3073C33.3355 11.291 34.5804 10.7688 36.0328 10.7688C37.6482 10.7688 38.8783 11.3334 39.7379 12.4626V11.037ZM34.0024 18.3766C34.6397 18.9836 35.44 19.2941 36.3885 19.2941C37.3518 19.2941 38.1521 18.9836 38.7746 18.3766C39.4119 17.7697 39.7231 16.9934 39.7231 16.0759C39.7231 15.1444 39.4119 14.3822 38.7746 13.7752C38.1373 13.1683 37.337 12.8578 36.3885 12.8578C35.4252 12.8578 34.6249 13.1683 34.0024 13.7752C33.3652 14.3822 33.0539 15.1585 33.0539 16.0759C33.0391 16.9934 33.3652 17.7697 34.0024 18.3766Z" fill="white"/>
|
4
|
+
<path d="M52.765 11.037H55.0473V21.1149H52.765V19.6611C51.9054 20.8043 50.6753 21.3689 49.0599 21.3689C47.6075 21.3689 46.3626 20.8608 45.34 19.8304C44.3174 18.8001 43.7987 17.5439 43.7987 16.0759C43.7987 14.5798 44.3174 13.3236 45.34 12.3073C46.3626 11.291 47.6075 10.7688 49.0599 10.7688C50.6753 10.7688 51.9054 11.3334 52.765 12.4626V11.037ZM47.0295 18.3766C47.6668 18.9836 48.4671 19.2941 49.4156 19.2941C50.3789 19.2941 51.1792 18.9836 51.8017 18.3766C52.439 17.7697 52.7502 16.9934 52.7502 16.0759C52.7502 15.1444 52.439 14.3822 51.8017 13.7752C51.1644 13.1683 50.3641 12.8578 49.4156 12.8578C48.4523 12.8578 47.652 13.1683 47.0295 13.7752C46.3923 14.3822 46.081 15.1585 46.081 16.0759C46.0662 16.9934 46.3923 17.7697 47.0295 18.3766Z" fill="white"/>
|
5
|
+
<path d="M62.8724 8.83514C61.2126 8.69399 60.3826 9.35738 60.3826 10.8253V11.0229H62.8724V13.1119H60.3826V21.0867H58.1003V13.1119H56.4849V11.0229H58.1003V10.8253C58.1003 9.44207 58.5004 8.38346 59.3156 7.67773C60.1307 6.95788 61.3163 6.64736 62.8873 6.74616V8.83514H62.8724Z" fill="white"/>
|
6
|
+
<path d="M65.7031 16.9934C65.8662 17.7556 66.2663 18.3484 66.874 18.7578C67.4816 19.1671 68.2226 19.3788 69.097 19.3788C70.3123 19.3788 71.2163 18.9695 71.8239 18.1226L73.7061 19.1812C72.6687 20.6491 71.1126 21.3831 69.0674 21.3831C67.3482 21.3831 65.9551 20.8891 64.9028 19.8869C63.8506 18.8848 63.3171 17.6145 63.3171 16.0901C63.3171 14.5798 63.8358 13.3236 64.888 12.3073C65.9255 11.2911 67.2741 10.783 68.9043 10.783C70.4605 10.783 71.735 11.3052 72.728 12.3356C73.7209 13.3659 74.2248 14.6222 74.2248 16.1042C74.2248 16.33 74.1952 16.6406 74.1359 17.0075H65.7031V16.9934ZM65.6883 15.2291H71.9129C71.7647 14.4104 71.3942 13.7894 70.8458 13.3801C70.2826 12.9707 69.6305 12.759 68.8895 12.759C68.0448 12.759 67.3334 12.9849 66.7702 13.4224C66.1922 13.86 65.8365 14.4528 65.6883 15.2291Z" fill="white"/>
|
7
|
+
<path d="M4.93031 10.1241H2.42059V6.8127C2.42059 3.43082 5.33127 0.668945 8.89536 0.668945C12.4594 0.668945 15.3701 3.43082 15.3701 6.8127H12.8604C12.8604 4.7413 11.0784 3.05035 8.89536 3.05035C6.71235 3.05035 4.93031 4.7413 4.93031 6.8127V10.1241Z" fill="#FCB034"/>
|
8
|
+
<path d="M2.43546 9.47583C1.60384 9.72947 0.78707 10.0254 0 10.3777C0.103953 11.209 0.252456 12.0263 0.460361 12.8154C1.21773 12.4491 2.0048 12.1391 2.80672 11.8713C2.62852 11.0822 2.49486 10.279 2.43546 9.47583Z" fill="#00B2C1"/>
|
9
|
+
<path d="M17.3156 12.8015C17.5235 11.9983 17.672 11.1951 17.7759 10.3638C16.9888 10.0256 16.1721 9.71556 15.3405 9.46191C15.2662 10.2792 15.1474 11.0824 14.9543 11.8574C15.786 12.1251 16.573 12.4492 17.3156 12.8015Z" fill="#00B2C1"/>
|
10
|
+
<path d="M2.43549 9.47602C2.50974 10.2933 2.62854 11.0965 2.8216 11.8715C4.72245 11.2515 6.7718 10.9133 8.8954 10.9133C11.019 10.9133 13.0684 11.2515 14.9692 11.8715C15.1474 11.0965 15.2811 10.2933 15.3553 9.47602C13.3208 8.85601 11.1527 8.53192 8.8954 8.53192C6.63814 8.51783 4.46999 8.85601 2.43549 9.47602Z" fill="#00B2C1"/>
|
11
|
+
<path d="M6.83118 22.9472C7.48459 23.5108 8.16771 24.0322 8.89538 24.5113C9.62305 24.0322 10.3062 23.5108 10.9596 22.9472C10.2319 22.4963 9.5488 22.0172 8.89538 21.4817C8.24196 22.0172 7.55885 22.4963 6.83118 22.9472Z" fill="#00B2C1"/>
|
12
|
+
<path d="M3.57895 14.2668L1.24744 15.1687C2.43547 18.1701 4.36602 20.8333 6.83118 22.947C7.55885 22.4961 8.24196 22.017 8.89538 21.4815C6.53417 19.551 4.69272 17.0851 3.57895 14.2668Z" fill="#00B2C1"/>
|
13
|
+
<path d="M8.89539 21.4817C9.5488 22.0172 10.2319 22.4963 10.9596 22.9472C14.0485 20.284 16.3057 16.7752 17.3304 12.8015C16.573 12.4352 15.786 12.1252 14.984 11.8574C14.0782 15.6761 11.8952 19.0157 8.89539 21.4817Z" fill="#00B2C1"/>
|
14
|
+
</svg>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<svg width="38" height="53" viewBox="0 0 38 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path d="M10.6206 20.8957H5.30688V13.5776C5.30688 6.10368 11.4696 0 19.0157 0C26.5618 0 32.7245 6.10368 32.7245 13.5776H27.4108C27.4108 8.99981 23.6377 5.26286 19.0157 5.26286C14.3937 5.26286 10.6206 8.99981 10.6206 13.5776V20.8957Z" fill="#FCB034"/>
|
3
|
+
<path d="M5.33841 19.4633C3.57765 20.0238 1.84832 20.6778 0.181885 21.4563C0.40198 23.2936 0.716402 25.0998 1.15659 26.8437C2.76015 26.0341 4.42659 25.3489 6.12447 24.7573C5.74716 23.0134 5.46418 21.2383 5.33841 19.4633Z" fill="#00B2C1"/>
|
4
|
+
<path d="M36.8436 26.8126C37.2837 25.0375 37.5982 23.2625 37.8183 21.4252C36.1518 20.6778 34.4225 19.9927 32.6617 19.4321C32.5045 21.2383 32.253 23.0134 31.8442 24.7261C33.605 25.3178 35.2714 26.0341 36.8436 26.8126Z" fill="#00B2C1"/>
|
5
|
+
<path d="M5.33838 19.4632C5.49559 21.2694 5.74713 23.0445 6.15588 24.7572C10.1805 23.387 14.5195 22.6396 19.0158 22.6396C23.512 22.6396 27.851 23.387 31.8756 24.7572C32.2529 23.0445 32.5359 21.2694 32.6931 19.4632C28.3855 18.093 23.795 17.3768 19.0158 17.3768C14.2365 17.3456 9.64597 18.093 5.33838 19.4632Z" fill="#00B2C1"/>
|
6
|
+
<path d="M14.6454 49.2343C16.0288 50.4799 17.4752 51.6322 19.0159 52.691C20.5565 51.6322 22.0029 50.4799 23.3863 49.2343C21.8457 48.2378 20.3993 47.179 19.0159 45.9956C17.6324 47.179 16.1861 48.2378 14.6454 49.2343Z" fill="#00B2C1"/>
|
7
|
+
<path d="M7.75943 30.0511L2.823 32.0442C5.33838 38.6773 9.42587 44.5629 14.6453 49.2341C16.186 48.2376 17.6323 47.1788 19.0158 45.9954C14.0164 41.7291 10.1176 36.2794 7.75943 30.0511Z" fill="#00B2C1"/>
|
8
|
+
<path d="M19.0157 45.9955C20.3992 47.1789 21.8455 48.2377 23.3862 49.2342C29.9262 43.3485 34.7054 35.5944 36.8749 26.8125C35.2714 26.0029 33.6049 25.3178 31.9071 24.7261C29.9891 33.1653 25.3671 40.5458 19.0157 45.9955Z" fill="#00B2C1"/>
|
9
|
+
</svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg width="52" height="17" viewBox="0 0 52 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<g clip-path="url(#clip0_8233_3220)">
|
3
|
+
<path d="M17.2531 9.48741C17.2531 9.71583 17.3817 9.89643 17.6372 10.0284C17.8936 10.1611 18.2019 10.2824 18.5606 10.3937C18.9192 10.5042 19.2868 10.618 19.6636 10.7343C20.0412 10.8497 20.3553 11.0641 20.6075 11.3783C20.8598 11.6925 20.9859 12.0883 20.9859 12.565C20.9859 13.2321 20.7295 13.7549 20.2159 14.1343C19.7023 14.5136 19.0577 14.7033 18.2794 14.7033C17.5952 14.7033 17.0074 14.5598 16.5169 14.2728C16.0264 13.9858 15.6702 13.5884 15.4485 13.0787L16.7395 12.3283C16.9794 12.9954 17.493 13.3286 18.2794 13.3286C19.0659 13.3286 19.4591 13.0688 19.4591 12.5501C19.4591 12.3283 19.3322 12.1477 19.0774 12.0092C18.8227 11.8706 18.5152 11.7461 18.1574 11.6356C17.798 11.5243 17.4303 11.4113 17.0536 11.295C16.676 11.1787 16.3603 10.9701 16.1063 10.6691C15.8516 10.3681 15.7238 9.98632 15.7238 9.52369C15.7238 8.88542 15.967 8.37084 16.4534 7.98244C16.939 7.59403 17.5433 7.39941 18.2646 7.39941C18.8384 7.39941 19.3487 7.52641 19.798 7.78122C20.2473 8.03604 20.5919 8.38981 20.8317 8.84336L19.5688 9.55173C19.3289 9.02396 18.8928 8.76007 18.2638 8.76007C17.9769 8.76007 17.7362 8.82192 17.5424 8.94562C17.3479 9.06931 17.2506 9.24909 17.2506 9.48658" fill="#105476"/>
|
4
|
+
<path d="M27.5333 7.58084H29.0328V14.5235H27.5333V13.5232C26.9694 14.3099 26.1598 14.7033 25.1046 14.7033C24.1516 14.7033 23.3371 14.3495 22.6619 13.6403C21.986 12.9328 21.6479 12.0702 21.6479 11.0509C21.6479 10.0317 21.986 9.15838 22.6619 8.45413C23.3371 7.75154 24.1516 7.39941 25.1046 7.39941C26.1598 7.39941 26.9694 7.78782 27.5333 8.56546V7.58001V7.58084ZM23.7724 12.6417C24.1887 13.0622 24.7114 13.2733 25.3412 13.2733C25.971 13.2733 26.4929 13.0622 26.9092 12.6417C27.3255 12.2211 27.5341 11.6909 27.5341 11.0518C27.5341 10.4127 27.3255 9.88324 26.9092 9.46184C26.4929 9.04128 25.9702 8.83017 25.3412 8.83017C24.7122 8.83017 24.1887 9.04128 23.7724 9.46184C23.3561 9.88324 23.1475 10.4127 23.1475 11.0518C23.1475 11.6909 23.3561 12.2211 23.7724 12.6417Z" fill="#105476"/>
|
5
|
+
<path d="M36.0796 7.58084H37.5784V14.5235H36.0796V13.5232C35.5149 14.3099 34.7054 14.7033 33.6502 14.7033C32.6972 14.7033 31.8827 14.3495 31.2075 13.6403C30.5315 12.9328 30.1943 12.0702 30.1943 11.0509C30.1943 10.0317 30.5315 9.15838 31.2075 8.45413C31.8827 7.75154 32.6972 7.39941 33.6502 7.39941C34.7054 7.39941 35.5149 7.78782 36.0796 8.56546V7.58001V7.58084ZM32.318 12.6417C32.7343 13.0622 33.2569 13.2733 33.8868 13.2733C34.5166 13.2733 35.0393 13.0622 35.4556 12.6417C35.8719 12.2211 36.0805 11.6909 36.0805 11.0518C36.0805 10.4127 35.8719 9.88324 35.4556 9.46184C35.0393 9.04128 34.5166 8.83017 33.8868 8.83017C33.2569 8.83017 32.7343 9.04128 32.318 9.46184C31.9016 9.88324 31.6931 10.4127 31.6931 11.0518C31.6931 11.6909 31.9016 12.2211 32.318 12.6417Z" fill="#105476"/>
|
6
|
+
<path d="M42.7152 6.06751C41.6229 5.96525 41.0771 6.42375 41.0771 7.44218V7.58155H42.7152V9.0255H41.0771V14.5234H39.5776V9.0255H38.5232V7.58155H39.5776V7.44218C39.5776 6.48972 39.8439 5.76486 40.3764 5.27008C40.9081 4.77529 41.688 4.56006 42.7152 4.62438V6.06833V6.06751Z" fill="#105476"/>
|
7
|
+
<path d="M44.5715 11.691C44.682 12.2188 44.9367 12.6237 45.3341 12.9057C45.7322 13.1886 46.2178 13.3296 46.7916 13.3296C47.5871 13.3296 48.184 13.0426 48.583 12.4686L49.8179 13.1902C49.1328 14.1996 48.1205 14.7034 46.7784 14.7034C45.649 14.7034 44.738 14.3587 44.0439 13.6693C43.3498 12.9799 43.0027 12.1075 43.0027 11.0519C43.0027 9.99637 43.3448 9.14781 44.0291 8.44851C44.7141 7.74921 45.5937 7.40039 46.6663 7.40039C47.7388 7.40039 48.5195 7.75664 49.1716 8.46913C49.8237 9.18162 50.1501 10.0467 50.1501 11.0651C50.1501 11.2226 50.132 11.4312 50.0949 11.6902H44.5707L44.5715 11.691ZM44.5567 10.4689H48.6374C48.536 9.904 48.3019 9.47849 47.9367 9.19151C47.5714 8.90454 47.1428 8.76105 46.6523 8.76105C46.0974 8.76105 45.635 8.91361 45.2648 9.21955C44.8947 9.52467 44.6589 9.94111 44.5567 10.4689Z" fill="#105476"/>
|
8
|
+
<path d="M3.691 6.49488H1.94824V4.28732C1.94907 1.92389 3.87154 0 6.23507 0C8.59859 0 10.5211 1.92389 10.5211 4.28732H8.77913C8.77913 2.8846 7.63735 1.74247 6.23507 1.74247C4.83278 1.74247 3.691 2.8846 3.691 4.28732V6.49488Z" fill="#FCB034"/>
|
9
|
+
<path d="M6.37772 16.9998L5.84681 16.5916C4.42886 15.5006 3.32995 14.3659 2.48908 13.1215C2.27473 12.8032 2.07523 12.475 1.89634 12.1443C1.7867 11.9415 1.68117 11.7312 1.5839 11.5225L1.21787 10.7317L2.79822 10.0002L3.16507 10.7903C3.24669 10.9667 3.3349 11.1432 3.42805 11.3156C3.57974 11.5959 3.74874 11.8755 3.93176 12.146C4.55994 13.0762 5.3629 13.9437 6.37689 14.7865C8.75361 12.8073 10.0454 10.6171 10.3917 7.9741C9.16498 7.57003 7.88141 7.36634 6.56733 7.36634C4.99769 7.36634 3.09747 7.77619 1.48414 8.46394L0.60617 8.84163L0.000244141 7.20224L0.801551 6.86083C2.64653 6.07413 4.74873 5.62305 6.56733 5.62305C8.38593 5.62305 10.0298 5.94218 11.6431 6.57221L12.2416 6.80558L12.1954 7.44633C11.9358 11.0616 10.207 14.0534 6.9078 16.5916L6.37689 17.0006L6.37772 16.9998Z" fill="#00B2C1"/>
|
10
|
+
<path d="M51.1731 9.02988C50.7247 9.02988 50.3586 8.66457 50.3586 8.21514C50.3586 7.76571 50.7238 7.40039 51.1731 7.40039C51.6224 7.40039 51.9876 7.76571 51.9876 8.21514C51.9876 8.66457 51.6224 9.02988 51.1731 9.02988ZM51.1731 7.49852C50.7783 7.49852 50.4567 7.82013 50.4567 8.21514C50.4567 8.61014 50.7783 8.93175 51.1731 8.93175C51.568 8.93175 51.8895 8.61014 51.8895 8.21514C51.8895 7.82013 51.568 7.49852 51.1731 7.49852Z" fill="#105476" stroke="#105476" stroke-width="0.0251713" stroke-miterlimit="10"/>
|
11
|
+
<path d="M51.3909 8.6314L51.2071 8.31721H51.0134V8.6314H50.9045V7.81006H51.2327C51.3027 7.81006 51.3629 7.8348 51.4132 7.88428C51.4635 7.93376 51.4882 7.99395 51.4882 8.06405C51.4882 8.11683 51.4725 8.16548 51.4404 8.20919C51.4091 8.25289 51.3678 8.28423 51.3176 8.30155L51.5113 8.62975H51.3901L51.3909 8.6314ZM51.0134 7.91231V8.21826H51.2327C51.273 8.21826 51.3077 8.20341 51.3365 8.1729C51.3654 8.14321 51.3794 8.10693 51.3794 8.06405C51.3794 8.02117 51.3654 7.98571 51.3365 7.95602C51.3077 7.92633 51.273 7.91149 51.2327 7.91149H51.0134V7.91231Z" fill="#105476" stroke="#105476" stroke-width="0.0251713"/>
|
12
|
+
</g>
|
13
|
+
<defs>
|
14
|
+
<clipPath id="clip0_8233_3220">
|
15
|
+
<rect width="52" height="17" fill="white"/>
|
16
|
+
</clipPath>
|
17
|
+
</defs>
|
18
|
+
</svg>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<svg width="268" height="264" viewBox="0 0 268 264" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<g filter="url(#filter0_d_4663_1939)">
|
3
|
+
<path d="M174.223 217.272C171.839 223.55 164.434 226.245 158.572 222.968L147.678 216.878C143.739 214.676 138.855 215.104 135.358 217.956L125.687 225.845C120.483 230.09 112.723 228.722 109.285 222.953L102.895 212.232C100.585 208.356 96.1415 206.284 91.6868 207.006L79.3672 209.002C72.738 210.076 66.7018 205.011 66.6086 198.296L66.4354 185.817C66.3728 181.305 63.5605 177.288 59.3418 175.686L47.6744 171.255C41.3962 168.871 38.7012 161.467 41.978 155.605L48.0676 144.711C50.2696 140.772 49.8422 135.887 46.9898 132.391L39.101 122.72C34.856 117.516 36.2243 109.756 41.9931 106.318L52.7138 99.928C56.5902 97.6176 58.6624 93.174 57.9405 88.7193L55.944 76.3997C54.8697 69.7705 59.9347 63.7343 66.6497 63.6411L79.1289 63.4679C83.6412 63.4053 87.6575 60.593 89.2597 56.3743L93.6905 44.7069C96.0748 38.4287 103.479 35.7337 109.341 39.0105L120.235 45.1001C124.174 47.3021 129.059 46.8747 132.555 44.0223L142.226 36.1335C147.43 31.8885 155.19 33.2568 158.628 39.0256L165.018 49.7463C167.328 53.6227 171.772 55.6949 176.227 54.973L188.546 52.9765C195.176 51.9023 201.212 56.9672 201.305 63.6822L201.478 76.1614C201.541 80.6737 204.353 84.6901 208.572 86.2922L220.239 90.7231C226.517 93.1073 229.212 100.512 225.936 106.374L219.846 117.268C217.644 121.207 218.071 126.091 220.924 129.588L228.813 139.259C233.058 144.463 231.689 152.223 225.92 155.661L215.2 162.051C211.323 164.361 209.251 168.805 209.973 173.259L211.97 185.579C213.044 192.208 207.979 198.244 201.264 198.337L188.785 198.511C184.272 198.573 180.256 201.385 178.654 205.604L174.223 217.272Z" fill="url(#paint0_radial_4663_1939)"/>
|
4
|
+
</g>
|
5
|
+
<g clip-path="url(#clip0_4663_1939)">
|
6
|
+
<path d="M169.79 103.99L121.207 152.573L99.1233 130.49" stroke="white" stroke-width="8.83333" stroke-linecap="round" stroke-linejoin="round"/>
|
7
|
+
</g>
|
8
|
+
<defs>
|
9
|
+
<filter id="filter0_d_4663_1939" x="32.6233" y="33.6559" width="202.667" height="202.667" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
10
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
11
|
+
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
12
|
+
<feOffset dy="4"/>
|
13
|
+
<feGaussianBlur stdDeviation="2"/>
|
14
|
+
<feComposite in2="hardAlpha" operator="out"/>
|
15
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
16
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_4663_1939"/>
|
17
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_4663_1939" result="shape"/>
|
18
|
+
</filter>
|
19
|
+
<radialGradient id="paint0_radial_4663_1939" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(133.957 130.989) rotate(-110) scale(104.5)">
|
20
|
+
<stop offset="0.12" stop-color="#006B74"/>
|
21
|
+
<stop offset="0.855" stop-color="#008E9A"/>
|
22
|
+
</radialGradient>
|
23
|
+
<clipPath id="clip0_4663_1939">
|
24
|
+
<rect width="112" height="96" fill="white" transform="translate(78.4565 82.4895)"/>
|
25
|
+
</clipPath>
|
26
|
+
</defs>
|
27
|
+
</svg>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<svg width="268" height="264" viewBox="0 0 268 264" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<g filter="url(#filter0_d_3983_1492)">
|
3
|
+
<path d="M174.223 217.272C171.839 223.55 164.434 226.245 158.572 222.968L147.678 216.878C143.739 214.676 138.855 215.104 135.358 217.956L125.687 225.845C120.483 230.09 112.723 228.722 109.285 222.953L102.895 212.232C100.585 208.356 96.1415 206.284 91.6868 207.006L79.3672 209.002C72.738 210.076 66.7018 205.011 66.6086 198.296L66.4354 185.817C66.3728 181.305 63.5605 177.288 59.3418 175.686L47.6744 171.255C41.3962 168.871 38.7012 161.467 41.978 155.605L48.0676 144.711C50.2696 140.772 49.8422 135.887 46.9898 132.391L39.101 122.72C34.856 117.516 36.2243 109.756 41.9931 106.318L52.7138 99.928C56.5902 97.6176 58.6624 93.174 57.9405 88.7193L55.944 76.3997C54.8697 69.7705 59.9347 63.7343 66.6497 63.6411L79.1289 63.4679C83.6412 63.4053 87.6575 60.593 89.2597 56.3743L93.6905 44.7069C96.0748 38.4287 103.479 35.7337 109.341 39.0105L120.235 45.1001C124.174 47.3021 129.059 46.8747 132.555 44.0223L142.226 36.1335C147.43 31.8885 155.19 33.2568 158.628 39.0256L165.018 49.7463C167.328 53.6227 171.772 55.6949 176.227 54.973L188.546 52.9765C195.176 51.9023 201.212 56.9672 201.305 63.6822L201.478 76.1614C201.541 80.6737 204.353 84.6901 208.572 86.2922L220.239 90.7231C226.517 93.1073 229.212 100.512 225.936 106.374L219.846 117.268C217.644 121.207 218.071 126.091 220.924 129.588L228.813 139.259C233.058 144.463 231.689 152.223 225.92 155.661L215.2 162.051C211.323 164.361 209.251 168.805 209.973 173.259L211.97 185.579C213.044 192.208 207.979 198.244 201.264 198.337L188.785 198.511C184.272 198.573 180.256 201.385 178.654 205.604L174.223 217.272Z" fill="#F9FAFB"/>
|
4
|
+
</g>
|
5
|
+
<g clip-path="url(#clip0_3983_1492)">
|
6
|
+
<path d="M169.79 103.99L121.207 152.573L99.1232 130.49" stroke="#008E9A" stroke-width="8.83333" stroke-linecap="round" stroke-linejoin="round"/>
|
7
|
+
</g>
|
8
|
+
<defs>
|
9
|
+
<filter id="filter0_d_3983_1492" x="32.6234" y="33.6559" width="202.667" height="202.667" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
10
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
11
|
+
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
12
|
+
<feOffset dy="4"/>
|
13
|
+
<feGaussianBlur stdDeviation="2"/>
|
14
|
+
<feComposite in2="hardAlpha" operator="out"/>
|
15
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
16
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3983_1492"/>
|
17
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3983_1492" result="shape"/>
|
18
|
+
</filter>
|
19
|
+
<clipPath id="clip0_3983_1492">
|
20
|
+
<rect width="112" height="96" fill="white" transform="translate(78.4565 82.4895)"/>
|
21
|
+
</clipPath>
|
22
|
+
</defs>
|
23
|
+
</svg>
|
@@ -0,0 +1,132 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { sendErrorCallback } from '@/utils/error-callback';
|
3
|
+
import { useRedirectStore } from '@/store/redirect.store';
|
4
|
+
|
5
|
+
interface ErrorBoundaryState {
|
6
|
+
hasError: boolean;
|
7
|
+
error?: Error;
|
8
|
+
}
|
9
|
+
|
10
|
+
interface ErrorBoundaryProps {
|
11
|
+
children: React.ReactNode;
|
12
|
+
fallback?: React.ComponentType<{ error?: Error; resetError?: () => void }>;
|
13
|
+
}
|
14
|
+
|
15
|
+
export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
16
|
+
constructor(props: ErrorBoundaryProps) {
|
17
|
+
super(props);
|
18
|
+
this.state = { hasError: false };
|
19
|
+
}
|
20
|
+
|
21
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
22
|
+
return { hasError: true, error };
|
23
|
+
}
|
24
|
+
|
25
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
26
|
+
console.error('ErrorBoundary caught an error:', error, errorInfo);
|
27
|
+
|
28
|
+
// Send error callback to parent
|
29
|
+
sendErrorCallback(error.message || 'An unexpected error occurred', {
|
30
|
+
errorType: 'unknown',
|
31
|
+
stack: error.stack,
|
32
|
+
flowCompleted: true
|
33
|
+
});
|
34
|
+
}
|
35
|
+
|
36
|
+
resetError = () => {
|
37
|
+
this.setState({ hasError: false, error: undefined });
|
38
|
+
};
|
39
|
+
|
40
|
+
render() {
|
41
|
+
if (this.state.hasError) {
|
42
|
+
const FallbackComponent = this.props.fallback;
|
43
|
+
|
44
|
+
if (FallbackComponent) {
|
45
|
+
return <FallbackComponent error={this.state.error} resetError={this.resetError} />;
|
46
|
+
}
|
47
|
+
|
48
|
+
return (
|
49
|
+
<div className="flex flex-col items-center justify-center min-h-screen p-6 bg-background">
|
50
|
+
<div className="text-center space-y-4">
|
51
|
+
<h2 className="text-2xl font-semibold text-red-600">Something went wrong</h2>
|
52
|
+
<p className="text-muted-foreground">
|
53
|
+
An unexpected error occurred. Please try refreshing the page.
|
54
|
+
</p>
|
55
|
+
<div className="space-x-4">
|
56
|
+
<button
|
57
|
+
onClick={this.resetError}
|
58
|
+
className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
|
59
|
+
>
|
60
|
+
Try Again
|
61
|
+
</button>
|
62
|
+
<button
|
63
|
+
onClick={() => window.location.reload()}
|
64
|
+
className="px-4 py-2 bg-secondary text-secondary-foreground rounded-md hover:bg-secondary/90"
|
65
|
+
>
|
66
|
+
Refresh Page
|
67
|
+
</button>
|
68
|
+
</div>
|
69
|
+
{process.env.NODE_ENV === 'development' && this.state.error && (
|
70
|
+
<details className="mt-4 text-left">
|
71
|
+
<summary className="cursor-pointer text-sm text-muted-foreground">
|
72
|
+
Error Details (Development Only)
|
73
|
+
</summary>
|
74
|
+
<pre className="mt-2 p-4 bg-red-50 text-red-800 text-xs overflow-auto rounded">
|
75
|
+
{this.state.error.stack}
|
76
|
+
</pre>
|
77
|
+
</details>
|
78
|
+
)}
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
);
|
82
|
+
}
|
83
|
+
|
84
|
+
return this.props.children;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
// Hook to use ErrorBoundary with redirect store data
|
89
|
+
export const ErrorBoundaryWithContext: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
90
|
+
const { decodedInfo } = useRedirectStore();
|
91
|
+
|
92
|
+
const handleError = (error: Error) => {
|
93
|
+
sendErrorCallback(error.message || 'An unexpected error occurred', {
|
94
|
+
errorType: 'unknown',
|
95
|
+
stack: error.stack,
|
96
|
+
consentHandle: decodedInfo?.srcref,
|
97
|
+
redirectUrl: decodedInfo?.redirect,
|
98
|
+
flowCompleted: true
|
99
|
+
});
|
100
|
+
};
|
101
|
+
|
102
|
+
return (
|
103
|
+
<ErrorBoundary
|
104
|
+
fallback={({ error, resetError }) => (
|
105
|
+
<div className="flex flex-col items-center justify-center min-h-screen p-6 bg-background">
|
106
|
+
<div className="text-center space-y-4">
|
107
|
+
<h2 className="text-2xl font-semibold text-red-600">Something went wrong</h2>
|
108
|
+
<p className="text-muted-foreground">
|
109
|
+
An unexpected error occurred. The parent application has been notified.
|
110
|
+
</p>
|
111
|
+
<div className="space-x-4">
|
112
|
+
<button
|
113
|
+
onClick={resetError}
|
114
|
+
className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
|
115
|
+
>
|
116
|
+
Try Again
|
117
|
+
</button>
|
118
|
+
<button
|
119
|
+
onClick={() => window.location.reload()}
|
120
|
+
className="px-4 py-2 bg-secondary text-secondary-foreground rounded-md hover:bg-secondary/90"
|
121
|
+
>
|
122
|
+
Refresh Page
|
123
|
+
</button>
|
124
|
+
</div>
|
125
|
+
</div>
|
126
|
+
</div>
|
127
|
+
)}
|
128
|
+
>
|
129
|
+
{children}
|
130
|
+
</ErrorBoundary>
|
131
|
+
);
|
132
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
interface AlertInterface {
|
2
|
+
icon?: React.ReactNode
|
3
|
+
title?: string
|
4
|
+
description?: string
|
5
|
+
rightSection?: React.ReactNode
|
6
|
+
}
|
7
|
+
|
8
|
+
const AlertComp = ({ icon, title, description, rightSection }: AlertInterface) => {
|
9
|
+
return (
|
10
|
+
<div className='bg-orange-100/50 dark:bg-ring border-orange-400/50 dark:border-orange-400/50 border-1 text-yellow-600 dark:text-yellow-600 p-4 rounded-lg'>
|
11
|
+
<div className='flex items-center justify-between'>
|
12
|
+
<div className='flex items-start w-full gap-4'>
|
13
|
+
{icon ? icon : null}
|
14
|
+
<div className='flex flex-col gap-1'>
|
15
|
+
{title ? <p className='text-md md:text-lg font-medium'>{title}</p> : null}
|
16
|
+
{description ? <p className="text-sm md:text-md">{description}</p> : null}
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
{rightSection ?
|
20
|
+
rightSection
|
21
|
+
: null}
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
)
|
25
|
+
}
|
26
|
+
|
27
|
+
export default AlertComp
|