MP-2802: created get started overlay (#351)

This commit is contained in:
Linkie Link 2023-08-08 21:50:07 +02:00 committed by GitHub
parent f4fc2dcfcc
commit d494bce26a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 289 additions and 88 deletions

View File

@ -1,7 +1,7 @@
import { useCallback, useEffect } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import AccountFundFirst from 'components/Account/AccountFund'
import AccountFund from 'components/Account/AccountFund'
import FullOverlayContent from 'components/FullOverlayContent'
import WalletSelect from 'components/Wallet/WalletSelect'
import useToggle from 'hooks/useToggle'
@ -17,7 +17,7 @@ export default function AccountCreateFirst() {
const [isCreating, setIsCreating] = useToggle(false)
useEffect(() => {
if (!address) useStore.setState({ focusComponent: <WalletSelect /> })
if (!address) useStore.setState({ focusComponent: { component: <WalletSelect /> } })
}, [address])
const handleClick = useCallback(async () => {
@ -26,7 +26,14 @@ export default function AccountCreateFirst() {
setIsCreating(false)
if (accountId) {
navigate(getRoute(getPage(pathname), address, accountId))
useStore.setState({ focusComponent: <AccountFundFirst /> })
useStore.setState({
focusComponent: {
component: <AccountFund />,
onClose: () => {
useStore.setState({ getStartedModal: true })
},
},
})
}
}, [createAccount, navigate, pathname, address, setIsCreating])

View File

@ -96,7 +96,7 @@ export default function AccountFund() {
useEffect(() => {
if (BN(baseBalance).isLessThan(hardcodedFee.amount[0].amount)) {
useStore.setState({ focusComponent: <WalletBridges /> })
useStore.setState({ focusComponent: { component: <WalletBridges /> } })
}
}, [baseBalance])

View File

@ -2,7 +2,7 @@ import classNames from 'classnames'
import { useCallback, useEffect } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import AccountFundFirst from 'components/Account/AccountFund'
import AccountFund from 'components/Account/AccountFund'
import AccountStats from 'components/Account/AccountStats'
import Button from 'components/Button'
import Card from 'components/Card'
@ -89,7 +89,14 @@ export default function AccountList(props: Props) {
leftIcon={<ArrowUpLine />}
onClick={() => {
if (positionBalance.isLessThanOrEqualTo(0)) {
useStore.setState({ focusComponent: <AccountFundFirst /> })
useStore.setState({
focusComponent: {
component: <AccountFund />,
onClose: () => {
useStore.setState({ getStartedModal: true })
},
},
})
return
}
useStore.setState({ fundAndWithdrawModal: 'fund' })

View File

@ -3,7 +3,7 @@ import { useCallback, useEffect } from 'react'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import AccountCreateFirst from 'components/Account/AccountCreateFirst'
import AccountFundFirst from 'components/Account/AccountFund'
import AccountFund from 'components/Account/AccountFund'
import AccountList from 'components/Account/AccountList'
import Button from 'components/Button'
import { CircularProgress } from 'components/CircularProgress'
@ -57,18 +57,25 @@ export default function AccountMenuContent(props: Props) {
if (accountId) {
navigate(getRoute(getPage(pathname), address, accountId))
useStore.setState({ focusComponent: <AccountFundFirst /> })
useStore.setState({
focusComponent: {
component: <AccountFund />,
onClose: () => {
useStore.setState({ getStartedModal: true })
},
},
})
}
}, [createAccount, navigate, pathname, address, setShowMenu, setIsCreating])
const handleCreateAccountClick = useCallback(() => {
setShowMenu(!showMenu)
if (!checkHasFunds() && !hasCreditAccounts) {
useStore.setState({ focusComponent: <WalletBridges /> })
useStore.setState({ focusComponent: { component: <WalletBridges /> } })
return
}
if (!hasCreditAccounts) {
useStore.setState({ focusComponent: <AccountCreateFirst /> })
useStore.setState({ focusComponent: { component: <AccountCreateFirst /> } })
return
}
}, [checkHasFunds, hasCreditAccounts, setShowMenu, showMenu])
@ -127,7 +134,7 @@ export default function AccountMenuContent(props: Props) {
)}
>
{isAccountSelected && isLoadingAccount && (
<div className='flex h-full w-full items-center justify-center p-4'>
<div className='flex items-center justify-center w-full h-full p-4'>
<CircularProgress size={40} />
</div>
)}

View File

@ -16,7 +16,7 @@ export default function ActionButton(props: ButtonProps) {
const { accountId } = useParams()
const handleCreateAccountClick = useCallback(() => {
useStore.setState({ focusComponent: <AccountCreateFirst /> })
useStore.setState({ focusComponent: { component: <AccountCreateFirst /> } })
}, [])
if (!address) return <WalletConnectButton {...defaultProps} />

View File

@ -1,34 +1,17 @@
import { ExternalLink } from 'components/Icons'
import Text from 'components/Text'
import { TextLink } from 'components/TextLink'
import { DocURL } from 'types/enums/docURL'
interface Props {
type: DocLinkType
}
function getData(type: string) {
if (type === 'account')
return [
'Why mint your account?',
'Learn more',
'https://docs.marsprotocol.io/docs/learn/workstation/rover/rover-intro',
]
if (type === 'fund')
return [
'Why fund your account?',
'Learn more',
'https://docs.marsprotocol.io/docs/learn/workstation/rover/managing-credit-accounts',
]
if (type === 'wallet')
return [
'New with wallets?',
'Learn more',
'https://docs.marsprotocol.io/docs/learn/workstation/basics/basics-intro',
]
return [
'By continuing you accept our',
'terms of service',
'https://docs.marsprotocol.io/docs/overview/legal/terms-of-service',
]
if (type === 'account') return ['Why mint your account?', 'Learn more', DocURL.ROVER_INTRO_URL]
if (type === 'fund') return ['Why fund your account?', 'Learn more', DocURL.MANAGE_ACCOUNT_URL]
if (type === 'wallet') return ['New with wallets?', 'Learn more', DocURL.WALLET_INTRO_URL]
return ['By continuing you accept our', 'terms of service', DocURL.TERMS_OF_SERVICE_URL]
}
export default function DocsLink(props: Props) {
@ -37,10 +20,15 @@ export default function DocsLink(props: Props) {
return (
<Text size='sm' className='w-full pt-3 text-center text-white/60'>
{`${intro} `}
<a href={url} target='_blank' className='leading-4 text-white hover:underline'>
<TextLink
href={url}
target='_blank'
className='leading-4 text-white hover:underline'
title={linkText}
>
{linkText}
<ExternalLink className='-mt-1 ml-1 inline w-3.5' />
</a>
</TextLink>
</Text>
)
}

View File

@ -20,6 +20,7 @@ export default function DesktopHeader() {
const focusComponent = useStore((s) => s.focusComponent)
function handleCloseFocusMode() {
if (focusComponent.onClose) focusComponent.onClose()
useStore.setState({ focusComponent: null })
}
@ -39,7 +40,7 @@ export default function DesktopHeader() {
>
<DesktopNavigation />
{focusComponent ? (
<div className='flex w-full justify-between'>
<div className='flex justify-between w-full'>
<div className='flex h-5 w-13' />
{address && <Wallet />}
<EscButton onClick={handleCloseFocusMode} />

View File

@ -0,0 +1,8 @@
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M22 12C22 17.5228 17.5228 22 12 22M22 12C22 6.47715 17.5228 2 12 2M22 12H20M12 22C6.47715 22 2 17.5228 2 12M12 22V20M2 12C2 6.47715 6.47715 2 12 2M2 12H4M12 2V4M19.0711 19.0711L17.6569 17.6569M6.34315 6.34315L4.92893 4.92893M17.6569 6.34315L19.0711 4.92893M4.92893 19.0711L6.34315 17.6569M8 12L10.5 10.5L12 8L13.5 10.5L16 12L13.5 13.5L12 16L10.5 13.5L8 12Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

After

Width:  |  Height:  |  Size: 539 B

View File

@ -0,0 +1,8 @@
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M3.33398 12.4974C3.33398 12.4974 4.16732 11.6641 6.66732 11.6641C9.16732 11.6641 10.834 13.3307 13.334 13.3307C15.834 13.3307 16.6673 12.4974 16.6673 12.4974V3.33073C16.6673 3.33073 15.834 4.16406 13.334 4.16406C10.834 4.16406 9.16732 2.4974 6.66732 2.4974C4.16732 2.4974 3.33398 3.33073 3.33398 3.33073M3.33399 18.3307L3.33398 1.66406"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

After

Width:  |  Height:  |  Size: 518 B

View File

@ -0,0 +1,8 @@
<svg viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M10.2739 5.95728C9.79691 6.29735 9.21316 6.4974 8.58268 6.4974C6.97185 6.4974 5.66602 5.19156 5.66602 3.58073C5.66602 1.9699 6.97185 0.664062 8.58268 0.664062C9.62684 0.664062 10.5428 1.21274 11.0581 2.03751M3.99935 15.7367H6.17459C6.45821 15.7367 6.74009 15.7704 7.01503 15.8379L9.31343 16.3965C9.81214 16.518 10.3317 16.5298 10.8356 16.4319L13.3768 15.9375C14.0481 15.8067 14.6657 15.4853 15.1496 15.0145L16.9476 13.2655C17.461 12.7669 17.461 11.9578 16.9476 11.4583C16.4853 11.0086 15.7533 10.958 15.2303 11.3393L13.1348 12.8681C12.8348 13.0875 12.4696 13.2056 12.0941 13.2056H10.0706L11.3586 13.2055C12.0845 13.2055 12.6726 12.6335 12.6726 11.9273V11.6717C12.6726 11.0853 12.2623 10.574 11.6777 10.4323L9.68984 9.94885C9.36633 9.87038 9.03502 9.83073 8.70197 9.83073C7.89796 9.83073 6.44259 10.4964 6.44259 10.4964L3.99935 11.5181M15.666 4.41406C15.666 6.02489 14.3602 7.33073 12.7493 7.33073C11.1385 7.33073 9.83268 6.02489 9.83268 4.41406C9.83268 2.80323 11.1385 1.4974 12.7493 1.4974C14.3602 1.4974 15.666 2.80323 15.666 4.41406ZM0.666016 11.1641L0.666016 15.9974C0.666016 16.4641 0.666016 16.6975 0.756843 16.8757C0.836738 17.0325 0.964222 17.16 1.12102 17.2399C1.29928 17.3307 1.53264 17.3307 1.99935 17.3307H2.66602C3.13273 17.3307 3.36608 17.3307 3.54434 17.2399C3.70114 17.16 3.82863 17.0325 3.90852 16.8757C3.99935 16.6975 3.99935 16.4641 3.99935 15.9974V11.1641C3.99935 10.6974 3.99935 10.464 3.90852 10.2857C3.82863 10.1289 3.70114 10.0015 3.54434 9.92156C3.36608 9.83073 3.13273 9.83073 2.66602 9.83073L1.99935 9.83073C1.53264 9.83073 1.29928 9.83073 1.12102 9.92156C0.964222 10.0015 0.836738 10.1289 0.756844 10.2857C0.666016 10.464 0.666016 10.6974 0.666016 11.1641Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,8 @@
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.66732 18.3307V16.6641M7.91732 12.4974V5.83073M13.334 18.3307V16.6641M12.084 12.4974V5.83073M7.33398 16.6641H12.6673C14.0674 16.6641 14.7675 16.6641 15.3023 16.3916C15.7727 16.1519 16.1552 15.7694 16.3948 15.299C16.6673 14.7643 16.6673 14.0642 16.6673 12.6641V5.66406C16.6673 4.26393 16.6673 3.56387 16.3948 3.02909C16.1552 2.55868 15.7727 2.17623 15.3023 1.93655C14.7675 1.66406 14.0674 1.66406 12.6673 1.66406H7.33398C5.93385 1.66406 5.23379 1.66406 4.69901 1.93655C4.2286 2.17623 3.84615 2.55868 3.60647 3.02909C3.33398 3.56387 3.33398 4.26393 3.33398 5.66406V12.6641C3.33398 14.0642 3.33398 14.7643 3.60647 15.299C3.84615 15.7694 4.2286 16.1519 4.69901 16.3916C5.23379 16.6641 5.93385 16.6641 7.33398 16.6641Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

After

Width:  |  Height:  |  Size: 898 B

View File

@ -13,6 +13,7 @@ export { default as ChevronDown } from 'components/Icons/ChevronDown.svg'
export { default as ChevronLeft } from 'components/Icons/ChevronLeft.svg'
export { default as ChevronRight } from 'components/Icons/ChevronRight.svg'
export { default as ChevronUp } from 'components/Icons/ChevronUp.svg'
export { default as Compass } from 'components/Icons/Compass.svg'
export { default as Copy } from 'components/Icons/Copy.svg'
export { default as Cross } from 'components/Icons/Cross.svg'
export { default as CrossCircled } from 'components/Icons/CrossCircled.svg'
@ -20,11 +21,15 @@ export { default as Enter } from 'components/Icons/Enter.svg'
export { default as ExclamationMarkCircled } from 'components/Icons/ExclamationMarkCircled.svg'
export { default as ExclamationMarkTriangle } from 'components/Icons/ExclamationMarkTriangle.svg'
export { default as ExternalLink } from 'components/Icons/ExternalLink.svg'
export { default as Flag } from 'components/Icons/Flag.svg'
export { default as Gear } from 'components/Icons/Gear.svg'
export { default as HandCoins } from 'components/Icons/HandCoins.svg'
export { default as Heart } from 'components/Icons/Heart.svg'
export { default as InfoCircle } from 'components/Icons/InfoCircle.svg'
export { default as LockLocked } from 'components/Icons/LockLocked.svg'
export { default as LockUnlocked } from 'components/Icons/LockUnlocked.svg'
export { default as Logo } from 'components/Icons/Logo.svg'
export { default as Luggage } from 'components/Icons/Luggage.svg'
export { default as MarsProtocol } from 'components/Icons/MarsProtocol.svg'
export { default as Osmo } from 'components/Icons/Osmo.svg'
export { default as OverlayMark } from 'components/Icons/OverlayMark.svg'
@ -44,5 +49,4 @@ export { default as SwapIcon } from 'components/Icons/SwapIcon.svg'
export { default as TrashBin } from 'components/Icons/TrashBin.svg'
export { default as VerticalThreeLine } from 'components/Icons/VerticalThreeLine.svg'
export { default as Wallet } from 'components/Icons/Wallet.svg'
export { default as InfoCircle } from 'components/Icons/InfoCircle.svg'
// @endindex

View File

@ -95,7 +95,7 @@ export default function FundAccount(props: Props) {
useEffect(() => {
if (BN(baseBalance).isLessThan(hardcodedFee.amount[0].amount)) {
useStore.setState({ focusComponent: <WalletBridges /> })
useStore.setState({ focusComponent: { component: <WalletBridges /> } })
}
}, [baseBalance])

View File

@ -0,0 +1,93 @@
import { useCallback } from 'react'
import { ChevronRight, Compass, Flag, HandCoins, Luggage } from 'components/Icons'
import Modal from 'components/Modal'
import Text from 'components/Text'
import useStore from 'store'
import { DocURL } from 'types/enums/docURL'
interface TutorialItemProps {
title: string
description: string
link: string
icon: React.ReactNode
}
function TutorialItem(props: TutorialItemProps) {
return (
<a
href={props.link}
title={props.title}
target='_blank'
className='flex items-center px-2 py-3 rounded-base hover:bg-white/5 group/item'
>
<div className='flex items-center justify-center w-8 h-8 rounded-base bg-white/5'>
{props.icon}
</div>
<div className='flex flex-col ml-3'>
<Text size='sm' className='pb-1'>
{props.title}
</Text>
<Text size='sm' className='text-white/50'>
{props.description}
</Text>
</div>
<div className='flex items-center justify-end flex-grow h-full pr-4'>
<ChevronRight className='w-3 h-3 opacity-0 group-hover/item:opacity-100' />
</div>
</a>
)
}
export default function GetStartedModal() {
const modal = useStore((s) => s.getStartedModal)
const onClose = useCallback(() => {
useStore.setState({ getStartedModal: false })
}, [])
if (!modal) return null
return (
<Modal
onClose={onClose}
header={<Text>Get Started</Text>}
className='relative'
headerClassName='gradient-header p-4 border-b-white/5 border-b'
contentClassName='flex flex-col p-3 pb-8'
>
<Text size='sm' className='p-2 pt-0 text-white/50'>
Tutorials
</Text>
<TutorialItem
title='Beginner Trading'
description='Learn how to conduct basic swapping, setting slippage percentages and more.'
link={DocURL.TRADING_INTRO_URL}
icon={<Compass className='w-5 opacity-50 group-hover/item:opacity-100' />}
/>
<TutorialItem
title='Advanced Trading'
description='Learn how to margin trade, stop-loss trade and operate our advanced trading module.'
link={DocURL.ADVANCED_TRADING_URL}
icon={<Luggage className='w-5 opacity-50 group-hover/item:opacity-100' />}
/>
<TutorialItem
title='Concentrated Liquidity'
description='Understand how to maximise your profits using concentrated liquidity'
link={DocURL.CONCENTRATED_LIQUIDITY_URL}
icon={<Flag className='w-5 opacity-50 group-hover/item:opacity-100' />}
/>
<TutorialItem
title='Borrowing & Lending'
description='Borrow and lend money against your assets on the blockchain'
link={DocURL.BORROW_LENDING_URL}
icon={<HandCoins className='w-5 opacity-50 group-hover/item:opacity-100' />}
/>
<Text
size='sm'
className='absolute bottom-0 left-0 w-full px-4 py-1 rounded-b-base bg-black/80 text-white/30'
>
You can access this modal via the settings if you decide to close it.
</Text>
</Modal>
)
}

View File

@ -4,6 +4,7 @@ import {
AlertDialogController,
BorrowModal,
FundAndWithdrawModal,
GetStartedModal,
LendAndReclaimModalController,
SettingsModal,
UnlockModal,
@ -19,6 +20,7 @@ export default function ModalsContainer() {
<AddVaultBorrowAssetsModal />
<BorrowModal />
<FundAndWithdrawModal />
<GetStartedModal />
<LendAndReclaimModalController />
<SettingsModal />
<UnlockModal />

View File

@ -5,7 +5,7 @@ import Text from 'components/Text'
interface Props {
label: string
decsription: string
description: string
className?: string
children: ReactNode | ReactNode[]
}
@ -23,7 +23,7 @@ export default function SettingsOptions(props: Props) {
{props.label}
</Text>
<Text size='xs' className='text-white/50'>
{props.decsription}
{props.description}
</Text>
</div>
<div className='flex w-60 flex-wrap justify-end'>{props.children}</div>

View File

@ -8,7 +8,7 @@ interface Props {
name: string
value: boolean
label: string
decsription: string
description: string | React.ReactNode
className?: string
withStatus?: boolean
}
@ -21,18 +21,22 @@ export default function SettingsSwitch(props: Props) {
props.className,
)}
>
<div className='flex w-100 flex-wrap'>
<Text size='lg' className='mb-2 w-full'>
<div className='flex flex-wrap w-100'>
<Text size='lg' className='w-full mb-2'>
{props.label}
</Text>
<Text size='xs' className='text-white/50'>
{props.decsription}
</Text>
{typeof props.description === 'string' ? (
<Text size='xs' className='text-white/50'>
{props.description}
</Text>
) : (
<>{props.description}</>
)}
</div>
<div className='flex w-60 flex-wrap justify-end'>
<div className='flex flex-wrap justify-end w-60'>
<Switch name={props.name} checked={props.value} onChange={props.onChange} />
{props.withStatus && (
<Text size='sm' className='mt-2 w-full text-end'>
<Text size='sm' className='w-full mt-2 text-end'>
{props.value ? 'ON' : 'OFF'}
</Text>
)}

View File

@ -10,6 +10,7 @@ import SettingsSwitch from 'components/Modals/Settings/SettingsSwitch'
import NumberInput from 'components/NumberInput'
import Select from 'components/Select'
import Text from 'components/Text'
import { TextLink } from 'components/TextLink'
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
import {
DISPLAY_CURRENCY_KEY,
@ -17,6 +18,7 @@ import {
PREFERRED_ASSET_KEY,
REDUCE_MOTION_KEY,
SLIPPAGE_KEY,
TUTORIAL_KEY,
} from 'constants/localStore'
import { BN_ZERO } from 'constants/math'
import useAlertDialog from 'hooks/useAlertDialog'
@ -47,6 +49,7 @@ export default function SettingsModal() {
REDUCE_MOTION_KEY,
DEFAULT_SETTINGS.reduceMotion,
)
const [tutorial, setTutorial] = useLocalStorage<boolean>(TUTORIAL_KEY, DEFAULT_SETTINGS.tutorial)
const [lendAssets, setLendAssets] = useLocalStorage<boolean>(
LEND_ASSETS_KEY,
DEFAULT_SETTINGS.lendAssets,
@ -59,7 +62,7 @@ export default function SettingsModal() {
label: (
<div className='flex w-full gap-2' key={index}>
{asset.denom === 'usd' ? (
<Text size='sm' className='h-4 w-4 text-center leading-4'>
<Text size='sm' className='w-4 h-4 leading-4 text-center'>
{asset.symbol}
</Text>
) : (
@ -105,6 +108,13 @@ export default function SettingsModal() {
[setLendAssets],
)
const handleTutorial = useCallback(
(value: boolean) => {
setTutorial(value)
},
[setTutorial],
)
const handlePreferredAsset = useCallback(
(value: string) => {
setPreferredAsset(value)
@ -177,7 +187,7 @@ export default function SettingsModal() {
const showResetModal = useCallback(() => {
showResetDialog({
icon: (
<div className='flex h-full w-full p-3'>
<div className='flex w-full h-full p-3'>
<ArrowCircle />
</div>
),
@ -219,7 +229,7 @@ export default function SettingsModal() {
name='lendAssets'
value={lendAssets}
label='Lend assets in credit account'
decsription='By turning this on you will automatically lend out all the assets you deposit into your credit account to earn yield.'
description='By turning this on you will automatically lend out all the assets you deposit into your credit account to earn yield.'
withStatus
/>
<SettingsSwitch
@ -227,13 +237,36 @@ export default function SettingsModal() {
name='reduceMotion'
value={reduceMotion}
label='Reduce Motion'
decsription='Turns off all animations inside the dApp. Turning animations off can increase the
description='Turns off all animations inside the dApp. Turning animations off can increase the
overall performance on lower-end hardware.'
withStatus
/>
<SettingsSwitch
onChange={handleTutorial}
name='tutoruial'
value={tutorial}
label='Tutorial'
description={
<Text size='xs' className='text-white/50'>
Show tutorial elements in the UI. Like the{' '}
<TextLink
title='Get Started Modal'
color='secondary'
textSize='extraSmall'
className='leading-4 text-white hover:underline'
onClick={() => {
useStore.setState({ settingsModal: false, getStartedModal: true })
}}
>
Get Started Modal.
</TextLink>
</Text>
}
withStatus
/>
<SettingsOptions
label='Preferred asset'
decsription='By selecting a different asset you always have the trading pair or asset selector
description='By selecting a different asset you always have the trading pair or asset selector
pre-filled with this asset.'
className='pb-6'
>
@ -242,7 +275,7 @@ export default function SettingsModal() {
options={preferredAssetsOptions}
defaultValue={preferredAsset}
onChange={handlePreferredAsset}
className='relative w-60 rounded-base border border-white/10'
className='relative border w-60 rounded-base border-white/10'
containerClassName='justify-end mb-4'
/>
<Select
@ -250,13 +283,13 @@ export default function SettingsModal() {
options={displayCurrenciesOptions}
defaultValue={displayCurrency}
onChange={handleDisplayCurrency}
className='relative w-60 rounded-base border border-white/10'
className='relative border w-60 rounded-base border-white/10'
containerClassName='justify-end'
/>
</SettingsOptions>
<SettingsOptions
label='Slippage tolerance'
decsription='Some vaults require token swaps. The transaction will fail if the price of the swap asset changes unfavourably by more than this percentage'
description='Some vaults require token swaps. The transaction will fail if the price of the swap asset changes unfavourably by more than this percentage'
className='pb-21'
>
{slippages.map((value) => (
@ -298,7 +331,7 @@ export default function SettingsModal() {
%
</Button>
</SettingsOptions>
<div className='flex w-full justify-between'>
<div className='flex justify-between w-full'>
<Button
color='quaternary'
variant='transparent'

View File

@ -3,6 +3,7 @@ export { default as AddVaultBorrowAssetsModal } from 'components/Modals/AddVault
export { default as AlertDialogController } from 'components/Modals/AlertDialog'
export { default as BorrowModal } from 'components/Modals/BorrowModal'
export { default as FundAndWithdrawModal } from 'components/Modals/FundWithdraw'
export { default as GetStartedModal } from 'components/Modals/GetStartedModal'
export { default as LendAndReclaimModalController } from 'components/Modals/LendAndReclaim'
export { default as SettingsModal } from 'components/Modals/Settings'
export { default as UnlockModal } from 'components/Modals/Unlock'

View File

@ -15,9 +15,9 @@ interface BenefitsProps {
function Benefits({ benefits }: BenefitsProps) {
return (
<ul className='w-full list-none px-0'>
<ul className='w-full px-0 list-none'>
{benefits.map((benefit, index) => (
<li className='relative mb-6 flex h-6 w-full items-center px-0 pl-8' key={index}>
<li className='relative flex items-center w-full h-6 px-0 pl-8 mb-6' key={index}>
<div
className={classNames(
'absolute left-0 top-0 isolate h-6 w-6 rounded-full bg-white/10',
@ -40,7 +40,7 @@ export default function TermsOfService() {
const handleAgreeTermsOfService = useCallback(() => {
setHasAgreedToTerms(true)
useStore.setState({ focusComponent: <WalletSelect /> })
useStore.setState({ focusComponent: { component: <WalletSelect /> } })
}, [setHasAgreedToTerms])
return (

View File

@ -6,9 +6,10 @@ interface Props extends React.HTMLProps<HTMLAnchorElement> {
className?: string
color?: 'primary' | 'secondary' | 'tertiary' | 'quaternary'
externalLink?: boolean
textSize?: 'small' | 'medium' | 'large'
textSize?: 'extraSmall' | 'small' | 'medium' | 'large'
text?: string | ReactNode
uppercase?: boolean
onClick?: () => void
}
const colorClasses = {
@ -19,6 +20,7 @@ const colorClasses = {
quaternary: 'hover:text-white active:text-white',
}
const textSizeClasses = {
extraSmall: 'text-xs',
small: 'text-sm',
medium: 'text-base',
large: 'text-lg',
@ -56,7 +58,7 @@ export const TextLink = React.forwardRef(function TextLink(
? (e) => {
e.preventDefault()
if (disabled) return
onClick
onClick()
}
: undefined
}

View File

@ -33,8 +33,8 @@ function Bridge({ name, url, image }: Bridge) {
}}
>
<Image className='rounded-full' width={20} height={20} src={image} alt={name} />
<Text className='ml-2 flex-1 text-left'>{name}</Text>
<ChevronRight className='h-4 w-4' />
<Text className='flex-1 ml-2 text-left'>{name}</Text>
<ChevronRight className='w-4 h-4' />
</Button>
)
}
@ -55,12 +55,12 @@ export default function WalletBridges() {
const handleClick = useCallback(() => {
if (!currentWallet) return
disconnectWallet(currentWallet)
useStore.setState({ focusComponent: <WalletSelect /> })
useStore.setState({ focusComponent: { component: <WalletSelect /> } })
}, [currentWallet, disconnectWallet])
useEffect(() => {
if (hasFunds) {
useStore.setState({ focusComponent: <WalletFetchBalancesAndAccounts /> })
useStore.setState({ focusComponent: { component: <WalletFetchBalancesAndAccounts /> } })
return
}
@ -82,13 +82,13 @@ export default function WalletBridges() {
}}
docs='wallet'
>
<div className='flex w-full flex-wrap gap-3'>
<div className='flex flex-wrap w-full gap-3'>
{BRIDGES.map((bridge) => (
<Bridge key={bridge.name} {...bridge} />
))}
</div>
{IS_TESTNET && (
<div className='flex w-full flex-wrap gap-3'>
<div className='flex flex-wrap w-full gap-3'>
<Text size='lg' className='mt-4 text-white'>
Need Testnet Funds?
</Text>

View File

@ -21,8 +21,8 @@ export default function WalletConnectButton(props: Props) {
const [hasAgreedToTerms] = useLocalStorage(TERMS_OF_SERVICE_KEY, false)
const handleClick = useCallback(() => {
const focusedComponent = hasAgreedToTerms ? <WalletSelect /> : <TermsOfService />
useStore.setState({ focusComponent: focusedComponent })
const component = hasAgreedToTerms ? <WalletSelect /> : <TermsOfService />
useStore.setState({ focusComponent: { component } })
}, [hasAgreedToTerms])
return (

View File

@ -58,7 +58,7 @@ export default function WalletConnecting(props: Props) {
useStore.setState({
client: walletClient,
address: response.account.address,
focusComponent: <WalletFetchBalancesAndAccounts />,
focusComponent: { component: <WalletFetchBalancesAndAccounts /> },
})
} catch (error) {
if (error instanceof Error) {
@ -67,14 +67,16 @@ export default function WalletConnecting(props: Props) {
client: undefined,
address: undefined,
accounts: null,
focusComponent: (
<WalletSelect
error={{
title: 'Failed to connect to wallet',
message: mapErrorMessages(extensionProviderId, error.message),
}}
/>
),
focusComponent: {
component: (
<WalletSelect
error={{
title: 'Failed to connect to wallet',
message: mapErrorMessages(extensionProviderId, error.message),
}}
/>
),
},
})
}
}

View File

@ -47,8 +47,8 @@ function WalletOption(props: WalletOptionProps) {
src={props.imageSrc}
alt={props.name}
/>
<Text className='ml-2 flex-1 text-left'>{props.name}</Text>
<ChevronRight className='h-4 w-4' />
<Text className='flex-1 ml-2 text-left'>{props.name}</Text>
<ChevronRight className='w-4 h-4' />
</Button>
)
}
@ -61,7 +61,7 @@ export default function WalletSelect(props: Props) {
const handleConnectClick = (extensionProviderId: string) => {
useStore.setState({
focusComponent: <WalletConnecting providerId={extensionProviderId} />,
focusComponent: { component: <WalletConnecting providerId={extensionProviderId} /> },
})
}
@ -117,7 +117,7 @@ export default function WalletSelect(props: Props) {
text: 'Back',
}}
>
<div className='mb-4 rounded-sm bg-white p-2'>
<div className='p-2 mb-4 bg-white rounded-sm'>
<QRCode value={qrCodeUrl} />
</div>
</FullOverlayContent>
@ -129,7 +129,7 @@ export default function WalletSelect(props: Props) {
copy={`Deposit assets from your ${currentChain.name} address to your Mars credit account.`}
docs='wallet'
>
<div className='flex w-full flex-wrap gap-3'>
<div className='flex flex-wrap w-full gap-3'>
{!isMobile() && (
<>
{sortedExtensionProviders.map((provider) => {

View File

@ -27,7 +27,7 @@ export default function Wallet() {
useStore.setState({ address: currentWallet.account.address })
return
}
useStore.setState({ focusComponent: <WalletConnecting autoConnect /> })
useStore.setState({ focusComponent: { component: <WalletConnecting autoConnect /> } })
}, [currentWallet, client, address])
// Redirect when switching wallets or on first connection

View File

@ -7,4 +7,5 @@ export const DEFAULT_SETTINGS: Settings = {
preferredAsset: ASSETS[0].denom,
displayCurrency: ORACLE_DENOM,
slippage: 0.02,
tutorial: true,
}

View File

@ -6,3 +6,4 @@ 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'
export const TUTORIAL_KEY = 'tutorial'

View File

@ -33,7 +33,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
<div className={classNames('mx-auto h-full w-full', !isFullWidth && 'max-w-content')}>
{focusComponent ? (
<div className='relative flex h-full w-full items-center justify-center'>
{focusComponent}
{focusComponent.component}
</div>
) : (
children

View File

@ -9,6 +9,7 @@ export default function createModalSlice(set: SetState<ModalSlice>, get: GetStat
createAccountModal: false,
fundAccountModal: false,
fundAndWithdrawModal: null,
getStartedModal: false,
lendAndReclaimModal: null,
resetStettingsModal: false,
settingsModal: false,

View File

@ -1,4 +1,12 @@
export enum DocURL {
ADVANCED_TRADING_URL = 'https://docs.marsprotocol.io',
BORROW_LENDING_URL = 'https://docs.marsprotocol.io',
COOKIE_POLICY_URL = 'https://docs.marsprotocol.io/mars-protocol/terms-of-service/mars-cookie-policy',
CONCENTRATED_LIQUIDITY_URL = 'https://docs.marsprotocol.io',
MANAGE_ACCOUNT_URL = 'https://docs.marsprotocol.io/docs/learn/workstation/rover/managing-credit-accounts',
ROVER_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/workstation/rover/rover-intro',
PRIVACY_POLICY_URL = 'https://docs.marsprotocol.io/mars-protocol/terms-of-service/mars-privacy-policy',
TERMS_OF_SERVICE_URL = 'https://docs.marsprotocol.io/docs/overview/legal/terms-of-service',
TRADING_INTRO_URL = 'https://docs.marsprotocol.io',
WALLET_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/workstation/basics/basics-intro',
}

View File

@ -7,3 +7,8 @@ interface CommonSlice {
selectedAccount: string | null
focusComponent: ReactNode
}
interface FocusComponent {
component: ReactNode
onClose?: () => void
}

View File

@ -6,6 +6,7 @@ interface ModalSlice {
createAccountModal: boolean
fundAccountModal: boolean
fundAndWithdrawModal: 'fund' | 'withdraw' | null
getStartedModal: boolean
lendAndReclaimModal: LendAndReclaimModalConfig | null
settingsModal: boolean
unlockModal: UnlockModal | null

View File

@ -4,4 +4,5 @@ interface Settings {
preferredAsset: string
lendAssets: boolean
slippage: number
tutorial: boolean
}