From d494bce26aa6c9d36a3b4e3b93468baa351a7b72 Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Tue, 8 Aug 2023 21:50:07 +0200 Subject: [PATCH] MP-2802: created get started overlay (#351) --- src/components/Account/AccountCreateFirst.tsx | 13 ++- src/components/Account/AccountFund.tsx | 2 +- src/components/Account/AccountList.tsx | 11 ++- src/components/Account/AccountMenuContent.tsx | 17 +++- src/components/Button/ActionButton.tsx | 2 +- src/components/DocsLink.tsx | 38 +++----- src/components/Header/DesktopHeader.tsx | 3 +- src/components/Icons/Compass.svg | 8 ++ src/components/Icons/Flag.svg | 8 ++ src/components/Icons/HandCoins.svg | 8 ++ src/components/Icons/Luggage.svg | 8 ++ src/components/Icons/index.ts | 6 +- .../Modals/FundWithdraw/FundAccount.tsx | 2 +- src/components/Modals/GetStartedModal.tsx | 93 +++++++++++++++++++ src/components/Modals/ModalsContainer.tsx | 2 + .../Modals/Settings/SettingsOptions.tsx | 4 +- .../Modals/Settings/SettingsSwitch.tsx | 20 ++-- src/components/Modals/Settings/index.tsx | 51 ++++++++-- src/components/Modals/index.tsx | 1 + src/components/TermsOfService.tsx | 6 +- src/components/TextLink.tsx | 6 +- src/components/Wallet/WalletBridges.tsx | 12 +-- src/components/Wallet/WalletConnectButton.tsx | 4 +- src/components/Wallet/WalletConnecting.tsx | 20 ++-- src/components/Wallet/WalletSelect.tsx | 10 +- src/components/Wallet/index.tsx | 2 +- src/constants/defaultSettings.ts | 1 + src/constants/localStore.ts | 1 + src/pages/_layout.tsx | 2 +- src/store/slices/modal.ts | 1 + src/types/enums/docURL.ts | 8 ++ src/types/interfaces/store/common.d.ts | 5 + src/types/interfaces/store/modals.d.ts | 1 + src/types/interfaces/store/settings.d.ts | 1 + 34 files changed, 289 insertions(+), 88 deletions(-) create mode 100644 src/components/Icons/Compass.svg create mode 100644 src/components/Icons/Flag.svg create mode 100644 src/components/Icons/HandCoins.svg create mode 100644 src/components/Icons/Luggage.svg create mode 100644 src/components/Modals/GetStartedModal.tsx diff --git a/src/components/Account/AccountCreateFirst.tsx b/src/components/Account/AccountCreateFirst.tsx index 3343f2fc..aef52760 100644 --- a/src/components/Account/AccountCreateFirst.tsx +++ b/src/components/Account/AccountCreateFirst.tsx @@ -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: }) + if (!address) useStore.setState({ focusComponent: { component: } }) }, [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: }) + useStore.setState({ + focusComponent: { + component: , + onClose: () => { + useStore.setState({ getStartedModal: true }) + }, + }, + }) } }, [createAccount, navigate, pathname, address, setIsCreating]) diff --git a/src/components/Account/AccountFund.tsx b/src/components/Account/AccountFund.tsx index ff9eccf7..e2ada6cb 100644 --- a/src/components/Account/AccountFund.tsx +++ b/src/components/Account/AccountFund.tsx @@ -96,7 +96,7 @@ export default function AccountFund() { useEffect(() => { if (BN(baseBalance).isLessThan(hardcodedFee.amount[0].amount)) { - useStore.setState({ focusComponent: }) + useStore.setState({ focusComponent: { component: } }) } }, [baseBalance]) diff --git a/src/components/Account/AccountList.tsx b/src/components/Account/AccountList.tsx index 30a10b33..9312af58 100644 --- a/src/components/Account/AccountList.tsx +++ b/src/components/Account/AccountList.tsx @@ -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={} onClick={() => { if (positionBalance.isLessThanOrEqualTo(0)) { - useStore.setState({ focusComponent: }) + useStore.setState({ + focusComponent: { + component: , + onClose: () => { + useStore.setState({ getStartedModal: true }) + }, + }, + }) return } useStore.setState({ fundAndWithdrawModal: 'fund' }) diff --git a/src/components/Account/AccountMenuContent.tsx b/src/components/Account/AccountMenuContent.tsx index 7484a060..3fcda45d 100644 --- a/src/components/Account/AccountMenuContent.tsx +++ b/src/components/Account/AccountMenuContent.tsx @@ -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: }) + useStore.setState({ + focusComponent: { + component: , + onClose: () => { + useStore.setState({ getStartedModal: true }) + }, + }, + }) } }, [createAccount, navigate, pathname, address, setShowMenu, setIsCreating]) const handleCreateAccountClick = useCallback(() => { setShowMenu(!showMenu) if (!checkHasFunds() && !hasCreditAccounts) { - useStore.setState({ focusComponent: }) + useStore.setState({ focusComponent: { component: } }) return } if (!hasCreditAccounts) { - useStore.setState({ focusComponent: }) + useStore.setState({ focusComponent: { component: } }) return } }, [checkHasFunds, hasCreditAccounts, setShowMenu, showMenu]) @@ -127,7 +134,7 @@ export default function AccountMenuContent(props: Props) { )} > {isAccountSelected && isLoadingAccount && ( -
+
)} diff --git a/src/components/Button/ActionButton.tsx b/src/components/Button/ActionButton.tsx index f7860fe3..34a63e3d 100644 --- a/src/components/Button/ActionButton.tsx +++ b/src/components/Button/ActionButton.tsx @@ -16,7 +16,7 @@ export default function ActionButton(props: ButtonProps) { const { accountId } = useParams() const handleCreateAccountClick = useCallback(() => { - useStore.setState({ focusComponent: }) + useStore.setState({ focusComponent: { component: } }) }, []) if (!address) return diff --git a/src/components/DocsLink.tsx b/src/components/DocsLink.tsx index 417be4d5..46e20b62 100644 --- a/src/components/DocsLink.tsx +++ b/src/components/DocsLink.tsx @@ -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 ( {`${intro} `} - + {linkText} - + ) } diff --git a/src/components/Header/DesktopHeader.tsx b/src/components/Header/DesktopHeader.tsx index b337ae98..9fc57711 100644 --- a/src/components/Header/DesktopHeader.tsx +++ b/src/components/Header/DesktopHeader.tsx @@ -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() { > {focusComponent ? ( -
+
{address && } diff --git a/src/components/Icons/Compass.svg b/src/components/Icons/Compass.svg new file mode 100644 index 00000000..ba5cb13b --- /dev/null +++ b/src/components/Icons/Compass.svg @@ -0,0 +1,8 @@ + + + diff --git a/src/components/Icons/Flag.svg b/src/components/Icons/Flag.svg new file mode 100644 index 00000000..589282a9 --- /dev/null +++ b/src/components/Icons/Flag.svg @@ -0,0 +1,8 @@ + + + diff --git a/src/components/Icons/HandCoins.svg b/src/components/Icons/HandCoins.svg new file mode 100644 index 00000000..0ca60bb6 --- /dev/null +++ b/src/components/Icons/HandCoins.svg @@ -0,0 +1,8 @@ + + + diff --git a/src/components/Icons/Luggage.svg b/src/components/Icons/Luggage.svg new file mode 100644 index 00000000..05a24f89 --- /dev/null +++ b/src/components/Icons/Luggage.svg @@ -0,0 +1,8 @@ + + + diff --git a/src/components/Icons/index.ts b/src/components/Icons/index.ts index 735a9164..9989a95e 100644 --- a/src/components/Icons/index.ts +++ b/src/components/Icons/index.ts @@ -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 diff --git a/src/components/Modals/FundWithdraw/FundAccount.tsx b/src/components/Modals/FundWithdraw/FundAccount.tsx index 7d482bea..e2bfcfdf 100644 --- a/src/components/Modals/FundWithdraw/FundAccount.tsx +++ b/src/components/Modals/FundWithdraw/FundAccount.tsx @@ -95,7 +95,7 @@ export default function FundAccount(props: Props) { useEffect(() => { if (BN(baseBalance).isLessThan(hardcodedFee.amount[0].amount)) { - useStore.setState({ focusComponent: }) + useStore.setState({ focusComponent: { component: } }) } }, [baseBalance]) diff --git a/src/components/Modals/GetStartedModal.tsx b/src/components/Modals/GetStartedModal.tsx new file mode 100644 index 00000000..0d5311de --- /dev/null +++ b/src/components/Modals/GetStartedModal.tsx @@ -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 ( + +
+ {props.icon} +
+
+ + {props.title} + + + {props.description} + +
+
+ +
+
+ ) +} + +export default function GetStartedModal() { + const modal = useStore((s) => s.getStartedModal) + const onClose = useCallback(() => { + useStore.setState({ getStartedModal: false }) + }, []) + + if (!modal) return null + + return ( + Get Started} + className='relative' + headerClassName='gradient-header p-4 border-b-white/5 border-b' + contentClassName='flex flex-col p-3 pb-8' + > + + Tutorials + + } + /> + } + /> + } + /> + } + /> + + You can access this modal via the settings if you decide to close it. + + + ) +} diff --git a/src/components/Modals/ModalsContainer.tsx b/src/components/Modals/ModalsContainer.tsx index 0c95024c..8cea4036 100644 --- a/src/components/Modals/ModalsContainer.tsx +++ b/src/components/Modals/ModalsContainer.tsx @@ -4,6 +4,7 @@ import { AlertDialogController, BorrowModal, FundAndWithdrawModal, + GetStartedModal, LendAndReclaimModalController, SettingsModal, UnlockModal, @@ -19,6 +20,7 @@ export default function ModalsContainer() { + diff --git a/src/components/Modals/Settings/SettingsOptions.tsx b/src/components/Modals/Settings/SettingsOptions.tsx index 0b71064d..1a22bbfb 100644 --- a/src/components/Modals/Settings/SettingsOptions.tsx +++ b/src/components/Modals/Settings/SettingsOptions.tsx @@ -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} - {props.decsription} + {props.description}
{props.children}
diff --git a/src/components/Modals/Settings/SettingsSwitch.tsx b/src/components/Modals/Settings/SettingsSwitch.tsx index 5bf00ecf..394bab9f 100644 --- a/src/components/Modals/Settings/SettingsSwitch.tsx +++ b/src/components/Modals/Settings/SettingsSwitch.tsx @@ -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, )} > -
- +
+ {props.label} - - {props.decsription} - + {typeof props.description === 'string' ? ( + + {props.description} + + ) : ( + <>{props.description} + )}
-
+
{props.withStatus && ( - + {props.value ? 'ON' : 'OFF'} )} diff --git a/src/components/Modals/Settings/index.tsx b/src/components/Modals/Settings/index.tsx index a0934621..c42658ae 100644 --- a/src/components/Modals/Settings/index.tsx +++ b/src/components/Modals/Settings/index.tsx @@ -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(TUTORIAL_KEY, DEFAULT_SETTINGS.tutorial) const [lendAssets, setLendAssets] = useLocalStorage( LEND_ASSETS_KEY, DEFAULT_SETTINGS.lendAssets, @@ -59,7 +62,7 @@ export default function SettingsModal() { label: (
{asset.denom === 'usd' ? ( - + {asset.symbol} ) : ( @@ -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: ( -
+
), @@ -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 /> + + Show tutorial elements in the UI. Like the{' '} + { + useStore.setState({ settingsModal: false, getStartedModal: true }) + }} + > + Get Started Modal. + + + } + withStatus + /> @@ -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' />