diff --git a/dapp/src/DApp.tsx b/dapp/src/DApp.tsx
index aa67ce180..31255b53d 100644
--- a/dapp/src/DApp.tsx
+++ b/dapp/src/DApp.tsx
@@ -20,13 +20,21 @@ import queryClient from "./queryClient"
import { delay, logPromiseFailure } from "./utils"
import { AcreLogo } from "./assets/icons"
+function SplashPage() {
+ return (
+
+
+
+ )
+}
+
function DApp() {
useInitApp()
return (
<>
-
+ } />
>
)
@@ -48,9 +56,7 @@ function DAppProviders() {
if (!config)
return (
-
-
-
+
)
diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx
index 88e533cbe..64d4a99be 100644
--- a/dapp/src/components/Layout.tsx
+++ b/dapp/src/components/Layout.tsx
@@ -1,8 +1,7 @@
-import React, { useEffect } from "react"
+import React from "react"
import { Outlet } from "react-router-dom"
import { Flex, VStack } from "@chakra-ui/react"
-import { useIsEmbed, useMobileMode, useModal } from "#/hooks"
-import { MODAL_TYPES } from "#/types"
+import { useIsEmbed, useMobileMode } from "#/hooks"
import DocsDrawer from "./DocsDrawer"
import Header from "./Header"
import ModalRoot from "./ModalRoot"
@@ -19,12 +18,6 @@ const PAGE_MAX_WIDTH = {
function Layout() {
const isMobileMode = useMobileMode()
const { embeddedApp } = useIsEmbed()
- const { openModal } = useModal()
-
- // TODO: Temporary solution to test Welcome modal.
- useEffect(() => {
- openModal(MODAL_TYPES.WELCOME, { navigateToOnClose: "/" })
- }, [openModal])
if (isMobileMode) return
diff --git a/dapp/src/hooks/useAccessCode.ts b/dapp/src/hooks/useAccessCode.ts
index 691f16cb7..428ae9fa6 100644
--- a/dapp/src/hooks/useAccessCode.ts
+++ b/dapp/src/hooks/useAccessCode.ts
@@ -1,9 +1,14 @@
import { useCallback } from "react"
-import useLocalStorage from "./useLocalStorage"
+import useLocalStorage, { getLocalStorageItem } from "./useLocalStorage"
+const LOCAL_STORAGE_KEY = "acre.accessCode"
+
+export function getAccessCodeFromLocalStorage() {
+ return getLocalStorageItem(LOCAL_STORAGE_KEY)
+}
export default function useAccessCode() {
const [encodedCode, setAccessCode] = useLocalStorage(
- "acre.accessCode",
+ LOCAL_STORAGE_KEY,
undefined,
)
diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts
index 3f462d8db..e87e8955a 100644
--- a/dapp/src/hooks/useInitApp.ts
+++ b/dapp/src/hooks/useInitApp.ts
@@ -7,7 +7,6 @@ import useDetectEmbed from "./useDetectEmbed"
import useDetectReferral from "./useDetectReferral"
import { useDisconnectWallet } from "./useDisconnectWallet"
import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD"
-import useGatingDApp from "./useGatingDApp"
export function useInitApp() {
// TODO: Let's uncomment when dark mode is ready
@@ -15,7 +14,6 @@ export function useInitApp() {
useSentry()
useDetectEmbed()
useDetectReferral()
- useGatingDApp()
useInitializeAcreSdk()
useInitDataFromSdk()
useFetchBTCPriceUSD()
diff --git a/dapp/src/pages/AccessPage/index.tsx b/dapp/src/pages/AccessPage/index.tsx
new file mode 100644
index 000000000..41acf7020
--- /dev/null
+++ b/dapp/src/pages/AccessPage/index.tsx
@@ -0,0 +1,15 @@
+import React from "react"
+import { useAppNavigate } from "#/hooks"
+import GateModal from "#/components/GateModal"
+
+export default function AccessPage() {
+ const navigate = useAppNavigate()
+
+ return (
+ {
+ navigate("/dashboard")
+ }}
+ />
+ )
+}
diff --git a/dapp/src/pages/AccessPage/loader.ts b/dapp/src/pages/AccessPage/loader.ts
new file mode 100644
index 000000000..956c07065
--- /dev/null
+++ b/dapp/src/pages/AccessPage/loader.ts
@@ -0,0 +1,40 @@
+import { getAccessCodeFromLocalStorage } from "#/hooks/useAccessCode"
+import redirectWithSearchParams from "#/router/utils"
+import { acreApi, shouldDisplayWelcomeModal } from "#/utils"
+import { LoaderFunction } from "react-router-dom"
+
+export const redirectToAccessPageLoader = async (
+ url: string,
+ redirectToOnSuccess: null | string = null,
+ redirectToOnFail: null | string = null,
+) => {
+ try {
+ const isValid = await acreApi.verifyAccessCode(
+ getAccessCodeFromLocalStorage() ?? "",
+ )
+
+ if (isValid) {
+ const shouldRedirectToWelcomeModal = shouldDisplayWelcomeModal()
+
+ return shouldRedirectToWelcomeModal
+ ? redirectWithSearchParams(url, "/welcome")
+ : !redirectToOnSuccess ||
+ redirectWithSearchParams(url, redirectToOnSuccess)
+ }
+
+ return redirectToOnFail
+ ? redirectWithSearchParams(url, redirectToOnFail)
+ : null
+ } catch (error) {
+ console.error("Failed to verify access code")
+
+ return redirectToOnFail
+ ? redirectWithSearchParams(url, redirectToOnFail)
+ : null
+ }
+}
+
+const accessPageLoader: LoaderFunction = async ({ request }) =>
+ redirectToAccessPageLoader(request.url, "/dashboard")
+
+export default accessPageLoader
diff --git a/dapp/src/pages/DashboardPage/loader.ts b/dapp/src/pages/DashboardPage/loader.ts
new file mode 100644
index 000000000..f04804b98
--- /dev/null
+++ b/dapp/src/pages/DashboardPage/loader.ts
@@ -0,0 +1,17 @@
+import { referralProgram, shouldDisplayWelcomeModal } from "#/utils"
+import { LoaderFunction } from "react-router-dom"
+import redirectWithSearchParams from "#/router/utils"
+import { redirectToAccessPageLoader } from "../AccessPage/loader"
+
+const dashboardPageLoader: LoaderFunction = async (args) => {
+ const { request } = args
+
+ if (referralProgram.isEmbedApp(referralProgram.getEmbeddedApp(request.url)))
+ return shouldDisplayWelcomeModal()
+ ? redirectWithSearchParams(request.url, "/welcome")
+ : null
+
+ return redirectToAccessPageLoader(request.url, null, "/access")
+}
+
+export default dashboardPageLoader
diff --git a/dapp/src/pages/WelcomePage/index.tsx b/dapp/src/pages/WelcomePage/index.tsx
new file mode 100644
index 000000000..f1ef5dd23
--- /dev/null
+++ b/dapp/src/pages/WelcomePage/index.tsx
@@ -0,0 +1,23 @@
+import React from "react"
+import WelcomeModal from "#/components/WelcomeModal"
+import { useAppNavigate, useLocalStorage } from "#/hooks"
+import { LOCAL_STORAGE_KEY } from "#/utils/shouldDisplayWelcomeModal"
+
+function WelcomePage() {
+ const navigate = useAppNavigate()
+ const [_, setShouldDisplayWelcomeModal] = useLocalStorage(
+ LOCAL_STORAGE_KEY,
+ true,
+ )
+
+ return (
+ {
+ setShouldDisplayWelcomeModal(false)
+ navigate("/dashboard")
+ }}
+ />
+ )
+}
+
+export default WelcomePage
diff --git a/dapp/src/pages/WelcomePage/loader.ts b/dapp/src/pages/WelcomePage/loader.ts
new file mode 100644
index 000000000..180104869
--- /dev/null
+++ b/dapp/src/pages/WelcomePage/loader.ts
@@ -0,0 +1,10 @@
+import redirectWithSearchParams from "#/router/utils"
+import { shouldDisplayWelcomeModal } from "#/utils"
+import { LoaderFunction } from "react-router-dom"
+
+const welcomePageLoader: LoaderFunction = ({ request }) =>
+ shouldDisplayWelcomeModal()
+ ? null
+ : redirectWithSearchParams(request.url, "/dashboard")
+
+export default welcomePageLoader
diff --git a/dapp/src/router/index.tsx b/dapp/src/router/index.tsx
index 5943ddd6f..869551f0c 100644
--- a/dapp/src/router/index.tsx
+++ b/dapp/src/router/index.tsx
@@ -1,28 +1,53 @@
import React from "react"
import Layout from "#/components/Layout"
import DashboardPage from "#/pages/DashboardPage"
-import { createBrowserRouter, redirectDocument } from "react-router-dom"
-import { referralProgram } from "#/utils"
+import { createBrowserRouter, LoaderFunction } from "react-router-dom"
+import { shouldDisplayWelcomeModal, referralProgram } from "#/utils"
+import dashboardPageLoader from "#/pages/DashboardPage/loader"
+import AccessPage from "#/pages/AccessPage"
+import WelcomePage from "#/pages/WelcomePage"
+import welcomePageLoader from "#/pages/WelcomePage/loader"
+import accessPageLoader from "#/pages/AccessPage/loader"
+import redirectWithSearchParams from "./utils"
import { routerPath } from "./path"
+const mainLayoutLoader: LoaderFunction = ({ request }) => {
+ const embedApp = referralProgram.getEmbeddedApp(request.url)
+
+ if (referralProgram.isEmbedApp(embedApp)) {
+ const shouldRedirectToWelcomeModal = !shouldDisplayWelcomeModal()
+
+ return shouldRedirectToWelcomeModal
+ ? redirectWithSearchParams(request.url, "/welcome")
+ : redirectWithSearchParams(request.url, "/dashboard")
+ }
+
+ return redirectWithSearchParams(request.url, "/access")
+}
+
export const router = createBrowserRouter([
{
path: "/",
element: ,
- loader: ({ request }) => {
- const embedApp = referralProgram.getEmbeddedApp(request.url)
-
- if (!!embedApp && !referralProgram.isEmbedApp(embedApp)) {
- return redirectDocument("/")
- }
-
- return null
- },
children: [
{
index: true,
+ loader: mainLayoutLoader,
+ },
+ {
path: routerPath.home,
element: ,
+ loader: dashboardPageLoader,
+ },
+ {
+ path: "/access",
+ element: ,
+ loader: accessPageLoader,
+ },
+ {
+ path: "/welcome",
+ element: ,
+ loader: welcomePageLoader,
},
],
},
diff --git a/dapp/src/router/path.ts b/dapp/src/router/path.ts
index ce48928bf..ea138162a 100644
--- a/dapp/src/router/path.ts
+++ b/dapp/src/router/path.ts
@@ -5,7 +5,7 @@ export const SEARCH_PARAMS_NAMES = {
}
export const routerPath = {
- home: "/",
+ home: "/dashboard",
} as const
export type Pathname = (typeof routerPath)[keyof typeof routerPath]
diff --git a/dapp/src/router/utils.ts b/dapp/src/router/utils.ts
new file mode 100644
index 000000000..76fad6c5f
--- /dev/null
+++ b/dapp/src/router/utils.ts
@@ -0,0 +1,9 @@
+import { redirect } from "react-router-dom"
+
+const redirectWithSearchParams = (url: string, to: string) => {
+ const requestUrl = new URL(url)
+
+ return redirect(`${to}${requestUrl.search}`)
+}
+
+export default redirectWithSearchParams
diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts
index 2deea8e9e..c79d332b7 100644
--- a/dapp/src/utils/index.ts
+++ b/dapp/src/utils/index.ts
@@ -17,3 +17,4 @@ export { default as referralProgram } from "./referralProgram"
export { default as acreApi } from "./acreApi"
export { default as router } from "./router"
export { default as delay } from "./delay"
+export { default as shouldDisplayWelcomeModal } from "./shouldDisplayWelcomeModal"
diff --git a/dapp/src/utils/shouldDisplayWelcomeModal.ts b/dapp/src/utils/shouldDisplayWelcomeModal.ts
new file mode 100644
index 000000000..19cc1da8d
--- /dev/null
+++ b/dapp/src/utils/shouldDisplayWelcomeModal.ts
@@ -0,0 +1,7 @@
+import { getLocalStorageItem } from "#/hooks/useLocalStorage"
+
+export const LOCAL_STORAGE_KEY = "acre.shouldDisplayWelcomeModal"
+
+export default function shouldDisplayWelcomeModal() {
+ return getLocalStorageItem(LOCAL_STORAGE_KEY) !== "false"
+}