Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Commit

Permalink
Merge branch 'safe-app-landing-page' of github.com:gnosis/safe-react …
Browse files Browse the repository at this point in the history
…into feat/create-safe-apps-redirect
  • Loading branch information
mmv08 committed Apr 18, 2022
2 parents 93f5ff2 + fa7ced8 commit 49fbce8
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 191 deletions.
207 changes: 16 additions & 191 deletions src/routes/SafeAppLandingPage/SafeAppLandingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,36 @@
import { ReactElement, useCallback, useEffect } from 'react'
import { ReactElement, useCallback, useEffect, useMemo } from 'react'
import { useSelector } from 'react-redux'
import { Redirect } from 'react-router-dom'
import styled from 'styled-components'
import { Card, Title, Button, Text, Loader } from '@gnosis.pm/safe-react-components'
import Divider from '@material-ui/core/Divider'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import List from '@material-ui/core/List'
import Popper from '@material-ui/core/Popper'
import { Card, Title, Loader } from '@gnosis.pm/safe-react-components'

import SuccessSvg from 'src/assets/icons/safe-created.svg'
import DemoSvg from 'src/assets/icons/demo.svg'
import { getChainById, isValidChainId } from 'src/config'
import { demoSafeRoute, history, OPEN_SAFE_ROUTE, WELCOME_ROUTE, SAFE_ROUTES } from 'src/routes/routes'
import { isValidChainId } from 'src/config'
import { history, WELCOME_ROUTE } from 'src/routes/routes'
import { useAppList } from 'src/routes/safe/components/Apps/hooks/appList/useAppList'
import { SafeApp } from 'src/routes/safe/components/Apps/types'
import { getAppInfoFromUrl } from 'src/routes/safe/components/Apps/utils'
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
import { useStateHandler } from 'src/logic/hooks/useStateHandler'
import { setChainId } from 'src/logic/config/utils'
import ProviderDisconnected from 'src/components/AppLayout/Header/components/ProviderInfo/ProviderDisconnected'
import Provider from 'src/components/AppLayout/Header/components/Provider'
import ConnectDetails from 'src/components/AppLayout/Header/components/ProviderDetails/ConnectDetails'
import NetworkLabel from 'src/components/NetworkLabel/NetworkLabel'
import Img from 'src/components/layout/Img'
import Link from 'src/components/layout/Link'
import { black300, grey400, secondary } from 'src/theme/variables'
import useAsync from 'src/logic/hooks/useAsync'
import { useQuery } from 'src/logic/hooks/useQuery'
import useAsync from 'src/logic/hooks/useAsync'
import SafeAppDetails from 'src/routes/SafeAppLandingPage/components/SafeAppsDetails'
import CreateNewSafe from 'src/routes/SafeAppLandingPage/components/CreateNewSafe'
import ConnectWallet from 'src/routes/SafeAppLandingPage/components/ConnectWallet'
import TryDemoSafe from 'src/routes/SafeAppLandingPage/components/TryDemoSafe'

function SafeAppLandingPage(): ReactElement {
const SafeAppLandingPage = (): ReactElement => {
const query = useQuery()
const safeAppChainId = query.get('chainId')
const safeAppUrl = query.get('appUrl')
const isValidChain = useMemo(() => isValidChainId(safeAppChainId), [safeAppChainId])

// if no valid chainId or Safe App url is present in query params we redirect to the Welcome page
// if no valid chainId is present in query params we redirect to the Welcome page
useEffect(() => {
const isValidChain = isValidChainId(safeAppChainId)
const redirectToWelcome = !safeAppUrl || !isValidChain
if (redirectToWelcome) {
history.push(WELCOME_ROUTE)
}

// we set the valid Safe App chainId in the state
if (isValidChain) {
setChainId(safeAppChainId)
setChainId(safeAppChainId as string)
}
}, [safeAppChainId, safeAppUrl])
}, [safeAppChainId, isValidChain])

const userAddress = useSelector(userAccountSelector)
const isWalletConnected = !!userAddress
Expand Down Expand Up @@ -81,11 +66,11 @@ function SafeAppLandingPage(): ReactElement {
}
}, [isLoading, safeAppDetails, isManifestError])

const availableChains = safeAppDetails?.chainIds
const availableChains = safeAppDetails?.chainIds || []

const showLoader = isLoading || !safeAppDetails

if (!safeAppUrl) {
if (!safeAppUrl || !isValidChain) {
return <Redirect to={WELCOME_ROUTE} />
}

Expand Down Expand Up @@ -126,106 +111,6 @@ function SafeAppLandingPage(): ReactElement {

export default SafeAppLandingPage

const SafeAppDetails = ({ iconUrl, name, description, availableChains }) => {
const showAvailableChains = availableChains?.length > 0

return (
<>
<DetailsContainer>
<SafeIcon src={iconUrl} />
<DescriptionContainer>
<SafeAppTitle size="sm">{name}</SafeAppTitle>
<div>{description}</div>
</DescriptionContainer>
</DetailsContainer>
<Separator />

{/* Available chains */}
{showAvailableChains && (
<>
<ChainLabel size="lg">Available networks</ChainLabel>
<ChainsContainer>
{availableChains.map((chainId) => (
<div key={chainId}>
<NetworkLabel networkInfo={getChainById(chainId)} />
</div>
))}
</ChainsContainer>
<Separator />
</>
)}
</>
)
}

const CreateNewSafe = ({ safeAppUrl }: { safeAppUrl: string }) => {
const openSafeLink = `${OPEN_SAFE_ROUTE}?redirect=${encodeURIComponent(`${SAFE_ROUTES.APPS}?appUrl=${safeAppUrl}`)}`

return (
<>
<BodyImage>
<Img alt="Vault" height={92} src={SuccessSvg} />
</BodyImage>

<Button size="lg" color="primary" variant="contained" component={Link} to={openSafeLink}>
<Text size="xl" color="white">
Create new Safe
</Text>
</Button>
</>
)
}

const ConnectWallet = () => {
const { clickAway, open, toggle } = useStateHandler()

return (
<StyledProvider>
<Provider
info={<ProviderDisconnected />}
open={open}
toggle={toggle}
render={(providerRef) => (
<StyledPopper
anchorEl={providerRef.current}
open={open}
placement="bottom"
popperOptions={{ positionFixed: true }}
>
<ClickAwayListener onClickAway={clickAway} touchEvent={false}>
<List component="div">
<ConnectDetails />
</List>
</ClickAwayListener>
</StyledPopper>
)}
/>
</StyledProvider>
)
}

const TryDemoSafe = ({ safeAppUrl }) => {
return (
<SafeDemoContainer>
<Title size="xs">Want to try the app before using it?</Title>

<BodyImage>
<Img alt="Demo" height={92} src={DemoSvg} />
</BodyImage>
{safeAppUrl && (
<StyledDemoButton
color="primary"
component={Link}
to={`${demoSafeRoute}?appUrl=${encodeURI(safeAppUrl)}`}
size="lg"
variant="outlined"
>
Try Demo
</StyledDemoButton>
)}
</SafeDemoContainer>
)
}
const Container = styled.main`
display: flex;
justify-content: center;
Expand All @@ -246,46 +131,6 @@ const LoaderContainer = styled.div`
min-height: 400px;
`

const DetailsContainer = styled.div`
display: flex;
`

const SafeIcon = styled.img`
width: 90px;
height: 90px;
`

const SafeAppTitle = styled(Title)`
margin-top: 0px;
margin-bottom: 12px;
`

const DescriptionContainer = styled.div`
padding-left: 66px;
flex-grow: 1;
`

const Separator = styled(Divider)`
margin: 32px 0;
`

const ChainLabel = styled(Text)`
color: ${black300};
`

const ChainsContainer = styled.div`
display: flex;
flex-wrap: wrap;
&& > div {
margin-top: 12px;
margin-right: 8px;
}
`

const StyledPopper = styled(Popper)`
z-index: 1301;
`
const ActionsContainer = styled.div`
display: flex;
`
Expand All @@ -294,23 +139,3 @@ const UserSafeContainer = styled.div`
flex: 1 0 50%;
text-align: center;
`

const SafeDemoContainer = styled.div`
flex: 1 0 50%;
text-align: center;
`
const StyledProvider = styled.div`
width: 300px;
height: 56px;
margin: 0 auto;
border-radius: 8px;
border: 2px solid ${grey400};
`

const BodyImage = styled.div`
margin: 30px 0;
`

const StyledDemoButton = styled(Button)`
border: 2px solid ${secondary};
`
52 changes: 52 additions & 0 deletions src/routes/SafeAppLandingPage/components/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ReactElement } from 'react'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import styled from 'styled-components'
import List from '@material-ui/core/List'
import Popper from '@material-ui/core/Popper'

import { useStateHandler } from 'src/logic/hooks/useStateHandler'
import { grey400 } from 'src/theme/variables'
import ProviderDisconnected from 'src/components/AppLayout/Header/components/ProviderInfo/ProviderDisconnected'
import Provider from 'src/components/AppLayout/Header/components/Provider'
import ConnectDetails from 'src/components/AppLayout/Header/components/ProviderDetails/ConnectDetails'

const ConnectWallet = (): ReactElement => {
const { clickAway, open, toggle } = useStateHandler()

return (
<StyledProvider>
<Provider
info={<ProviderDisconnected />}
open={open}
toggle={toggle}
render={(providerRef) => (
<StyledPopper
anchorEl={providerRef.current}
open={open}
placement="bottom"
popperOptions={{ positionFixed: true }}
>
<ClickAwayListener onClickAway={clickAway} touchEvent={false}>
<List component="div">
<ConnectDetails />
</List>
</ClickAwayListener>
</StyledPopper>
)}
/>
</StyledProvider>
)
}

export default ConnectWallet

const StyledProvider = styled.div`
width: 300px;
height: 56px;
margin: 0 auto;
border-radius: 8px;
border: 2px solid ${grey400};
`
const StyledPopper = styled(Popper)`
z-index: 1301;
`
31 changes: 31 additions & 0 deletions src/routes/SafeAppLandingPage/components/CreateNewSafe.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Button, Text } from '@gnosis.pm/safe-react-components'
import styled from 'styled-components'

import { OPEN_SAFE_ROUTE, SAFE_ROUTES } from 'src/routes/routes'
import Img from 'src/components/layout/Img'
import Link from 'src/components/layout/Link'
import SuccessSvg from 'src/assets/icons/safe-created.svg'

const CreateNewSafe = ({ safeAppUrl }: { safeAppUrl: string }): React.ReactElement => {
const openSafeLink = `${OPEN_SAFE_ROUTE}?redirect=${encodeURIComponent(`${SAFE_ROUTES.APPS}?appUrl=${safeAppUrl}`)}`

return (
<>
<BodyImage>
<Img alt="Vault" height={92} src={SuccessSvg} />
</BodyImage>

<Button size="lg" color="primary" variant="contained" component={Link} to={openSafeLink}>
<Text size="xl" color="white">
Create new Safe
</Text>
</Button>
</>
)
}

export default CreateNewSafe

const BodyImage = styled.div`
margin: 30px 0;
`
Loading

0 comments on commit 49fbce8

Please sign in to comment.