Skip to content

Commit

Permalink
Display welcome modal in correct order
Browse files Browse the repository at this point in the history
Use react router loaders to display modals in correct order. We want to
display welcome modal after access code modal in standalone app and
before wallet connection in embedded apps.
  • Loading branch information
r-czajkowski committed Nov 8, 2024
1 parent a2469bd commit 82e8809
Show file tree
Hide file tree
Showing 14 changed files with 178 additions and 29 deletions.
14 changes: 10 additions & 4 deletions dapp/src/DApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@ import queryClient from "./queryClient"
import { delay, logPromiseFailure } from "./utils"
import { AcreLogo } from "./assets/icons"

function SplashPage() {
return (
<Center h="100vh" w="100vw">
<Icon as={AcreLogo} w={200} h={300} />
</Center>
)
}

function DApp() {
useInitApp()

return (
<>
<GlobalStyles />
<RouterProvider router={router} />
<RouterProvider router={router} fallbackElement={<SplashPage />} />
<ReactQueryDevtools initialIsOpen={false} />
</>
)
Expand All @@ -48,9 +56,7 @@ function DAppProviders() {
if (!config)
return (
<Fade in={!config}>
<Center h="100vh" w="100vw">
<Icon as={AcreLogo} alt="Acre logo" w={200} h={300} />
</Center>
<SplashPage />
</Fade>
)

Expand Down
11 changes: 2 additions & 9 deletions dapp/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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 <MobileModeBanner forceOpen />

Expand Down
9 changes: 7 additions & 2 deletions dapp/src/hooks/useAccessCode.ts
Original file line number Diff line number Diff line change
@@ -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<string | undefined>(
"acre.accessCode",
LOCAL_STORAGE_KEY,
undefined,
)

Expand Down
2 changes: 0 additions & 2 deletions dapp/src/hooks/useInitApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ 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
// useDetectThemeMode()
useSentry()
useDetectEmbed()
useDetectReferral()
useGatingDApp()
useInitializeAcreSdk()
useInitDataFromSdk()
useFetchBTCPriceUSD()
Expand Down
15 changes: 15 additions & 0 deletions dapp/src/pages/AccessPage/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<GateModal
closeModal={() => {
navigate("/dashboard")
}}
/>
)
}
40 changes: 40 additions & 0 deletions dapp/src/pages/AccessPage/loader.ts
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions dapp/src/pages/DashboardPage/loader.ts
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions dapp/src/pages/WelcomePage/index.tsx
Original file line number Diff line number Diff line change
@@ -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<boolean>(
LOCAL_STORAGE_KEY,
true,
)

return (
<WelcomeModal
closeModal={() => {
setShouldDisplayWelcomeModal(false)
navigate("/dashboard")
}}
/>
)
}

export default WelcomePage
10 changes: 10 additions & 0 deletions dapp/src/pages/WelcomePage/loader.ts
Original file line number Diff line number Diff line change
@@ -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
47 changes: 36 additions & 11 deletions dapp/src/router/index.tsx
Original file line number Diff line number Diff line change
@@ -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: <Layout />,
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: <DashboardPage />,
loader: dashboardPageLoader,
},
{
path: "/access",
element: <AccessPage />,
loader: accessPageLoader,
},
{
path: "/welcome",
element: <WelcomePage />,
loader: welcomePageLoader,
},
],
},
Expand Down
2 changes: 1 addition & 1 deletion dapp/src/router/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]
9 changes: 9 additions & 0 deletions dapp/src/router/utils.ts
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions dapp/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
7 changes: 7 additions & 0 deletions dapp/src/utils/shouldDisplayWelcomeModal.ts
Original file line number Diff line number Diff line change
@@ -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"
}

0 comments on commit 82e8809

Please sign in to comment.