Mp 2591 add terms of service (#300)
This commit is contained in:
parent
d949cc84b7
commit
48d07173fb
@ -19,7 +19,7 @@ NEXT_PUBLIC_CANDLES_ENDPOINT="https://api.thegraph.com/subgraphs/name/{NAME}/{GR
|
||||
CHARTING_LIBRARY_USERNAME="username_with_access_to_charting_library"
|
||||
CHARTING_LIBRARY_ACCESS_TOKEN="access_token_with_access_to_charting_library"
|
||||
CHARTING_LIBRARY_REPOSITORY="github.com/username/charting_library/"
|
||||
NEXT_PUBLIC_PYTH_ENDPOINT=https://xc-mainnet.pyth.network/api/
|
||||
NEXT_PUBLIC_PYTH_ENDPOINT=https://xc-mainnet.pyth.network/api
|
||||
NEXT_PUBLIC_MAINNET_REST=https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/
|
||||
|
||||
# MAINNET #
|
||||
|
@ -3,7 +3,7 @@ import { BN } from 'utils/helpers'
|
||||
|
||||
export default async function fetchPythPrices(...priceFeedIds: string[]) {
|
||||
try {
|
||||
const pricesUrl = new URL(`${ENV.PYTH_API}/latest_price_feeds`)
|
||||
const pricesUrl = new URL(`${ENV.PYTH_ENDPOINT}/latest_price_feeds`)
|
||||
priceFeedIds.forEach((id) => pricesUrl.searchParams.append('ids[]', id))
|
||||
|
||||
const pythResponse: PythPriceData[] = await fetch(pricesUrl).then((res) => res.json())
|
||||
|
@ -1,6 +1,7 @@
|
||||
import classNames from 'classnames'
|
||||
|
||||
import AccountMenu from 'components/Account/AccountMenu'
|
||||
import EscButton from 'components/Button/EscButton'
|
||||
import DesktopNavigation from 'components/Navigation/DesktopNavigation'
|
||||
import Settings from 'components/Settings'
|
||||
import Wallet from 'components/Wallet'
|
||||
@ -16,6 +17,12 @@ export const menuTree: { page: Page; label: string }[] = [
|
||||
|
||||
export default function DesktopHeader() {
|
||||
const address = useStore((s) => s.address)
|
||||
const isFocusMode = useStore((s) => s.isFocusMode)
|
||||
|
||||
function handleCloseFocusMode() {
|
||||
useStore.setState({ isFocusMode: false, showTermsOfService: false })
|
||||
}
|
||||
|
||||
return (
|
||||
<header
|
||||
className={classNames(
|
||||
@ -24,13 +31,22 @@ export default function DesktopHeader() {
|
||||
'lg:block',
|
||||
)}
|
||||
>
|
||||
<div className='flex items-center justify-between border-b border-white/20 py-3 pl-6 pr-4'>
|
||||
<div
|
||||
className={classNames(
|
||||
'flex items-center justify-between py-3 pl-6 pr-4',
|
||||
!isFocusMode && ' border-b border-white/20',
|
||||
)}
|
||||
>
|
||||
<DesktopNavigation />
|
||||
<div className='flex gap-4'>
|
||||
{address && <AccountMenu />}
|
||||
<Wallet />
|
||||
<Settings />
|
||||
</div>
|
||||
{isFocusMode ? (
|
||||
<EscButton onClick={handleCloseFocusMode} />
|
||||
) : (
|
||||
<div className='flex gap-4'>
|
||||
{address && <AccountMenu />}
|
||||
<Wallet />
|
||||
<Settings />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
|
@ -218,7 +218,7 @@ export default function SettingsModal() {
|
||||
<SettingsSwitch
|
||||
onChange={handleReduceMotion}
|
||||
name='reduceMotion'
|
||||
value={!reduceMotion}
|
||||
value={reduceMotion}
|
||||
label='Reduce Motion'
|
||||
decsription='Turns off all animations inside the dApp. Turning animations off can increase the
|
||||
overall performance on lower-end hardware.'
|
||||
|
@ -3,10 +3,12 @@ import { useParams } from 'react-router-dom'
|
||||
import { menuTree } from 'components/Header/DesktopHeader'
|
||||
import { Logo } from 'components/Icons'
|
||||
import { NavLink } from 'components/Navigation/NavLink'
|
||||
import useStore from 'store'
|
||||
import { getRoute } from 'utils/route'
|
||||
|
||||
export default function DesktopNavigation() {
|
||||
const { address, accountId } = useParams()
|
||||
const isFocusMode = useStore((s) => s.isFocusMode)
|
||||
|
||||
function getIsActive(href: string) {
|
||||
return location.pathname.includes(href)
|
||||
@ -14,22 +16,24 @@ export default function DesktopNavigation() {
|
||||
|
||||
return (
|
||||
<div className='flex flex-1 items-center'>
|
||||
<NavLink href={getRoute('trade', address, accountId)} isActive={false}>
|
||||
<NavLink href={getRoute('trade', address, accountId)}>
|
||||
<span className='block h-10 w-10'>
|
||||
<Logo />
|
||||
<Logo className='text-white' />
|
||||
</span>
|
||||
</NavLink>
|
||||
<div className='flex gap-8 px-6'>
|
||||
{menuTree.map((item, index) => (
|
||||
<NavLink
|
||||
key={index}
|
||||
href={getRoute(item.page, address, accountId)}
|
||||
isActive={getIsActive(item.page)}
|
||||
>
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
{!isFocusMode && (
|
||||
<div className='flex gap-8 px-6'>
|
||||
{menuTree.map((item, index) => (
|
||||
<NavLink
|
||||
key={index}
|
||||
href={getRoute(item.page, address, accountId)}
|
||||
isActive={getIsActive(item.page)}
|
||||
>
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
86
src/components/TermsOfService.tsx
Normal file
86
src/components/TermsOfService.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import { useWalletManager } from '@marsprotocol/wallet-connector'
|
||||
import classNames from 'classnames'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import Text from 'components/Text'
|
||||
import { TERMS_OF_SERVICE_KEY } from 'constants/localStore'
|
||||
import useLocalStorage from 'hooks/useLocalStorage'
|
||||
import useStore from 'store'
|
||||
import Button from 'components/Button'
|
||||
import { Check, ExternalLink } from 'components/Icons'
|
||||
|
||||
interface BenefitsProps {
|
||||
benefits: string[]
|
||||
}
|
||||
|
||||
function Benefits({ benefits }: BenefitsProps) {
|
||||
return (
|
||||
<ul className='w-full list-none px-0 py-3'>
|
||||
{benefits.map((benefit, index) => (
|
||||
<li className='relative my-6 flex h-6 w-full items-center px-0 pl-8' key={index}>
|
||||
<div
|
||||
className={classNames(
|
||||
'absolute left-0 top-0 isolate h-6 w-6 rounded-full bg-white/10',
|
||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:rounded-full before:p-[1px] before:border-glas',
|
||||
)}
|
||||
>
|
||||
<Check className='p-1.5' />
|
||||
</div>
|
||||
<Text size='sm' className=' text-white/60'>
|
||||
{benefit}
|
||||
</Text>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
export default function TermsOfService() {
|
||||
const { connect } = useWalletManager()
|
||||
const [hasAgreedToTerms, setHasAgreedToTerms] = useLocalStorage(TERMS_OF_SERVICE_KEY, false)
|
||||
|
||||
const handleAgreeTermsOfService = useCallback(() => {
|
||||
useStore.setState({ showTermsOfService: false, isFocusMode: false })
|
||||
setHasAgreedToTerms(true)
|
||||
connect()
|
||||
}, [connect, hasAgreedToTerms, setHasAgreedToTerms])
|
||||
|
||||
return (
|
||||
<div className='relative flex h-full w-full items-center justify-center'>
|
||||
<div className='w-100'>
|
||||
<Text size='4xl' className='w-full pb-2'>
|
||||
Master the Red Planet
|
||||
</Text>
|
||||
<Text size='sm' className='w-full text-white/60'>
|
||||
Mars offers the easiest way to margin trade, lend & borrow and yield farm with leverage
|
||||
any whitelisted token
|
||||
</Text>
|
||||
<Benefits
|
||||
benefits={[
|
||||
'Swap tokens with margin acress any whitelisted pair',
|
||||
'Amplify your LP rewards with leveraged yield farming',
|
||||
'Earn interest on deposited tokens',
|
||||
]}
|
||||
/>
|
||||
<Button
|
||||
className='w-full'
|
||||
text='Agree & continue'
|
||||
color='tertiary'
|
||||
onClick={handleAgreeTermsOfService}
|
||||
size='lg'
|
||||
/>
|
||||
<Text size='sm' className='w-full pt-5 text-center text-white/60'>
|
||||
By continuing you accept our{' '}
|
||||
<a
|
||||
href='https://docs.marsprotocol.io/docs/overview/legal/terms-of-service'
|
||||
target='_blank'
|
||||
className='leading-4 text-white hover:underline'
|
||||
>
|
||||
terms of service
|
||||
<ExternalLink className='-mt-1 ml-1 inline w-3.5' />
|
||||
</a>
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -5,7 +5,7 @@ interface Props {
|
||||
children: ReactNode | string
|
||||
className?: string
|
||||
monospace?: boolean
|
||||
size?: '3xs' | '2xs' | 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '6xl'
|
||||
size?: '3xs' | '2xs' | 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl'
|
||||
tag?: 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4'
|
||||
uppercase?: boolean
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { useWalletManager, WalletConnectionStatus } from '@marsprotocol/wallet-connector'
|
||||
import { ReactNode } from 'react'
|
||||
import { ReactNode, useCallback } from 'react'
|
||||
|
||||
import Button from 'components/Button'
|
||||
import { CircularProgress } from 'components/CircularProgress'
|
||||
import { Wallet } from 'components/Icons'
|
||||
import { TERMS_OF_SERVICE_KEY } from 'constants/localStore'
|
||||
import useLocalStorage from 'hooks/useLocalStorage'
|
||||
import useStore from 'store'
|
||||
|
||||
interface Props {
|
||||
textOverride?: string | ReactNode
|
||||
@ -13,6 +16,15 @@ interface Props {
|
||||
|
||||
export default function ConnectButton(props: Props) {
|
||||
const { connect } = useWalletManager()
|
||||
const [hasAgreedToTerms] = useLocalStorage(TERMS_OF_SERVICE_KEY, false)
|
||||
|
||||
const handleConnect = useCallback(() => {
|
||||
if (!hasAgreedToTerms) {
|
||||
useStore.setState({ showTermsOfService: true, isFocusMode: true })
|
||||
return
|
||||
}
|
||||
connect()
|
||||
}, [connect, hasAgreedToTerms])
|
||||
|
||||
return (
|
||||
<div className='relative'>
|
||||
@ -20,7 +32,7 @@ export default function ConnectButton(props: Props) {
|
||||
variant='solid'
|
||||
color='tertiary'
|
||||
disabled={props.disabled}
|
||||
onClick={connect}
|
||||
onClick={handleConnect}
|
||||
leftIcon={<Wallet />}
|
||||
>
|
||||
{props.status === WalletConnectionStatus.Connecting ? (
|
||||
|
@ -16,7 +16,7 @@ interface EnvironmentVariables {
|
||||
URL_API: string
|
||||
URL_APOLLO_APR: string
|
||||
WALLETS: string[]
|
||||
PYTH_API: string
|
||||
PYTH_ENDPOINT: string
|
||||
MAINNET_REST_API: string
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ export const ENV: EnvironmentVariables = {
|
||||
: process.env.NEXT_PUBLIC_API || '',
|
||||
URL_APOLLO_APR: process.env.NEXT_PUBLIC_APOLLO_APR || '',
|
||||
WALLETS: process.env.NEXT_PUBLIC_WALLETS?.split(',') || [],
|
||||
PYTH_API: process.env.NEXT_PUBLIC_PYTH_API || '',
|
||||
PYTH_ENDPOINT: process.env.NEXT_PUBLIC_PYTH_ENDPOINT || '',
|
||||
MAINNET_REST_API: process.env.NEXT_PUBLIC_MAINNET_REST || '',
|
||||
}
|
||||
|
||||
|
@ -5,3 +5,4 @@ export const FAVORITE_ASSETS_KEY = 'favoriteAssets'
|
||||
export const LEND_ASSETS_KEY = 'lendAssets'
|
||||
export const AUTO_LEND_ENABLED_ACCOUNT_IDS_KEY = 'autoLendEnabledAccountIds'
|
||||
export const SLIPPAGE_KEY = 'slippage'
|
||||
export const TERMS_OF_SERVICE_KEY = 'termsOfService'
|
||||
|
@ -7,10 +7,13 @@ import Footer from 'components/Footer'
|
||||
import DesktopHeader from 'components/Header/DesktopHeader'
|
||||
import ModalsContainer from 'components/Modals/ModalsContainer'
|
||||
import PageMetadata from 'components/PageMetadata'
|
||||
import TermsOfService from 'components/TermsOfService'
|
||||
import Toaster from 'components/Toaster'
|
||||
import useStore from 'store'
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
const location = useLocation()
|
||||
const showTermsOfService = useStore((s) => s.showTermsOfService)
|
||||
const isFullWidth = location.pathname.includes('trade') || location.pathname === '/'
|
||||
|
||||
return (
|
||||
@ -25,7 +28,9 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
'align-items-center grid h-full min-h-[900px] grid-cols-[auto_min-content] place-items-start gap-6 p-6',
|
||||
)}
|
||||
>
|
||||
{isFullWidth ? children : <div className='mx-auto w-full max-w-content'>{children}</div>}
|
||||
<div className={classNames('mx-auto h-full w-full', !isFullWidth && 'max-w-content')}>
|
||||
{showTermsOfService ? <TermsOfService /> : children}
|
||||
</div>
|
||||
<AccountDetails />
|
||||
</main>
|
||||
<Footer />
|
||||
|
@ -9,5 +9,7 @@ export default function createCommonSlice(set: SetState<CommonSlice>, get: GetSt
|
||||
isOpen: true,
|
||||
selectedAccount: null,
|
||||
status: WalletConnectionStatus.Unconnected,
|
||||
isFocusMode: false,
|
||||
showTermsOfService: false,
|
||||
}
|
||||
}
|
||||
|
2
src/types/interfaces/store/common.d.ts
vendored
2
src/types/interfaces/store/common.d.ts
vendored
@ -6,4 +6,6 @@ interface CommonSlice {
|
||||
isOpen: boolean
|
||||
selectedAccount: string | null
|
||||
status: import('@marsprotocol/wallet-connector').WalletConnectionStatus
|
||||
isFocusMode: boolean
|
||||
showTermsOfService: boolean
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user