diff --git a/components/Layout.tsx b/components/Layout.tsx index 21653440..90c08404 100644 --- a/components/Layout.tsx +++ b/components/Layout.tsx @@ -8,12 +8,7 @@ import BottomBar from './mobile/BottomBar' import BounceLoader from './shared/BounceLoader' import TopBar from './TopBar' import useLocalStorageState from '../hooks/useLocalStorageState' -import { - IS_ONBOARDED_KEY, - ONBOARDING_TOUR_KEY, - SIDEBAR_COLLAPSE_KEY, -} from '../utils/constants' -import OnboardingTour from './OnboardingTour' +import { SIDEBAR_COLLAPSE_KEY } from '../utils/constants' const sideBarAnimationDuration = 500 @@ -24,8 +19,6 @@ const Layout = ({ children }: { children: ReactNode }) => { SIDEBAR_COLLAPSE_KEY, false ) - const [showOnboardingTour] = useLocalStorageState(ONBOARDING_TOUR_KEY, false) - const [isOnboarded] = useLocalStorageState(IS_ONBOARDED_KEY) const { width } = useViewport() useEffect(() => { @@ -94,9 +87,6 @@ const Layout = ({ children }: { children: ReactNode }) => { - {showOnboardingTour && isOnboarded && connected ? ( - - ) : null} ) } diff --git a/components/MangoAccountsList.tsx b/components/MangoAccountsList.tsx index 869ce76d..4bd7c2bb 100644 --- a/components/MangoAccountsList.tsx +++ b/components/MangoAccountsList.tsx @@ -50,7 +50,7 @@ const MangoAccountsList = ({ } return ( -
+
{({ open }) => ( <> diff --git a/components/OnboardingTour.tsx b/components/OnboardingTour.tsx deleted file mode 100644 index 33afafb4..00000000 --- a/components/OnboardingTour.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { XMarkIcon } from '@heroicons/react/20/solid' -import { useRouter } from 'next/router' -import { - CardinalOrientation, - MaskOptions, - Walktour, - WalktourLogic, -} from 'walktour' -import useLocalStorageState from '../hooks/useLocalStorageState' -import { ONBOARDING_TOUR_KEY } from '../utils/constants' - -const OnboardingTour = () => { - const [, setShowOnboardingTour] = useLocalStorageState(ONBOARDING_TOUR_KEY) - const router = useRouter() - - const renderTooltip = (tourLogic: WalktourLogic | undefined) => { - const { title, description } = tourLogic!.stepContent - const { next, prev, close, allSteps, stepIndex } = tourLogic! - - const handleClose = () => { - setShowOnboardingTour(false) - close() - } - - return ( -
- -

{title}

-

{description}

-
- {stepIndex !== 0 ? ( - - ) : ( -
- )} -
- {allSteps.map((s, i) => ( -
- ))} -
- {stepIndex !== allSteps.length - 1 ? ( - - ) : ( - - )} -
-
- ) - } - - const steps = [ - { - selector: '#step-one', - title: 'Your Accounts', - description: - 'Switch between accounts and create new ones. Use multiple accounts to trade isolated margin and protect your capital from liquidation.', - orientationPreferences: [CardinalOrientation.SOUTHEAST], - movingTarget: true, - }, - { - selector: '#step-two', - title: 'Account Value', - description: - 'The value of your assets (deposits) minus the value of your liabilities (borrows).', - orientationPreferences: [CardinalOrientation.EASTNORTH], - movingTarget: true, - customNextFunc: (tourLogic: WalktourLogic) => { - router.push('/') - setTimeout(() => tourLogic.next(), 1000) - }, - }, - { - selector: '#step-three', - title: 'Health', - description: - 'If your account health reaches 0% your account will be liquidated. You can increase the health of your account by making a deposit.', - orientationPreferences: [CardinalOrientation.SOUTHWEST], - movingTarget: true, - }, - { - selector: '#step-four', - title: 'Free Collateral', - description: - "The amount of capital you have to trade or borrow against. When your free collateral reaches $0 you won't be able to make withdrawals.", - orientationPreferences: [CardinalOrientation.SOUTHWEST], - movingTarget: true, - }, - { - selector: '#step-five', - title: 'Total Interest Value', - description: - 'The value of interest earned (deposits) minus interest paid (borrows).', - orientationPreferences: [CardinalOrientation.SOUTHWEST], - movingTarget: true, - }, - { - selector: '#step-six', - title: 'Health Check', - description: - 'Check the health of your account from any screen in the app. A green heart represents good health, orange okay and red poor.', - orientationPreferences: [CardinalOrientation.EASTSOUTH], - movingTarget: true, - customNextFunc: (tourLogic: WalktourLogic) => { - router.push('/swap') - setTimeout(() => tourLogic.next(), 1000) - }, - }, - { - selector: '#step-seven', - title: 'Swap', - description: - "You choose the quote token of your trades. This means you can easily trade tokens on their relative strength vs. another token. Let's say your thesis is BTC will see diminishing returns relative to SOL. You can sell BTC and buy SOL. Now you are long SOL/BTC", - orientationPreferences: [CardinalOrientation.CENTER], - customPrevFunc: (tourLogic: WalktourLogic) => { - router.push('/swap') - tourLogic.prev() - }, - }, - { - selector: '#step-eight', - title: 'Trade Settings', - description: - 'Edit your slippage settings and toggle margin on and off. When margin is off your trades will be limited by your balance for each token.', - orientationPreferences: [CardinalOrientation.WESTNORTH], - movingTarget: true, - }, - { - selector: '#step-nine', - title: 'Token to Sell', - description: - 'Select the token you want to sell. If your sell size is above your token balance a loan will be opened to cover the shortfall.', - orientationPreferences: [CardinalOrientation.WESTNORTH], - movingTarget: true, - }, - { - selector: '#step-ten', - title: 'Health Impact', - description: - 'Projects the health of your account before you make a trade.', - orientationPreferences: [CardinalOrientation.WESTNORTH], - movingTarget: true, - }, - ] - - return ( - - ) -} - -export default OnboardingTour diff --git a/components/SideNav.tsx b/components/SideNav.tsx index b6ebc118..adc4e5cb 100644 --- a/components/SideNav.tsx +++ b/components/SideNav.tsx @@ -20,26 +20,16 @@ import MangoAccountSummary from './account/MangoAccountSummary' import Tooltip from './shared/Tooltip' import { HealthType } from '@blockworks-foundation/mango-v4' import { useWallet } from '@solana/wallet-adapter-react' -import useLocalStorageState from '../hooks/useLocalStorageState' -import { ONBOARDING_TOUR_KEY } from '../utils/constants' import mangoStore from '@store/mangoStore' import HealthHeart from './account/HealthHeart' const SideNav = ({ collapsed }: { collapsed: boolean }) => { - const [, setShowOnboardingTour] = useLocalStorageState(ONBOARDING_TOUR_KEY) const { t } = useTranslation('common') const { connected } = useWallet() const mangoAccount = mangoStore((s) => s.mangoAccount.current) const router = useRouter() const { pathname } = router - const handleTakeTour = () => { - if (pathname !== '/') { - router.push('/') - } - setShowOnboardingTour(true) - } - return (
{ isExternal showTooltip={false} /> - {connected ? ( - - ) : null}
diff --git a/components/TokenList.tsx b/components/TokenList.tsx index 2c6d3177..22addf73 100644 --- a/components/TokenList.tsx +++ b/components/TokenList.tsx @@ -105,21 +105,17 @@ const TokenList = () => {
- -
- - - {t('interest-earned-paid')} - - -
+ + + + {t('interest-earned-paid')} + + - -
- - {t('rates')} - -
+ + + {t('rates')} + {t('price')} @@ -127,7 +123,7 @@ const TokenList = () => { - {banks.map(({ key, value }) => { + {banks.map(({ key, value }, i) => { const bank = value[0] const oraclePrice = bank.uiPrice @@ -256,7 +252,10 @@ const TokenList = () => {
-
+
diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index 3c6d17a2..7a7388ed 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -1,8 +1,6 @@ import { HealthType, - I80F48, toUiDecimalsForQuote, - ZERO_I80F48, } from '@blockworks-foundation/mango-v4' import { useTranslation } from 'next-i18next' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' @@ -13,7 +11,6 @@ import WithdrawModal from '../modals/WithdrawModal' import mangoStore, { PerformanceDataItem } from '@store/mangoStore' import { formatDecimal, formatFixedDecimals } from '../../utils/numbers' import FlipNumbers from 'react-flip-numbers' -import { DownTriangle, UpTriangle } from '../shared/DirectionTriangles' import SimpleAreaChart from '../shared/SimpleAreaChart' import { COLORS } from '../../styles/colors' import { useTheme } from 'next-themes' @@ -31,6 +28,10 @@ import { breakpoints } from '../../utils/theme' import useMangoAccount from '../shared/useMangoAccount' import PercentageChange from '../shared/PercentageChange' import Tooltip from '@components/shared/Tooltip' +import { IS_ONBOARDED_KEY } from 'utils/constants' +import { useWallet } from '@solana/wallet-adapter-react' +import useLocalStorageState from 'hooks/useLocalStorageState' +import AccountOnboardingTour from '@components/tours/AccountOnboardingTour' export async function getStaticProps({ locale }: { locale: string }) { return { @@ -46,7 +47,8 @@ export async function getStaticProps({ locale }: { locale: string }) { const AccountPage = () => { const { t } = useTranslation('common') - const { mangoAccount, lastUpdatedAt } = useMangoAccount() + const { connected } = useWallet() + const { mangoAccount } = useMangoAccount() const actions = mangoStore((s) => s.actions) const loadPerformanceData = mangoStore( (s) => s.mangoAccount.stats.performance.loading @@ -69,6 +71,8 @@ const AccountPage = () => { const { theme } = useTheme() const { width } = useViewport() const isMobile = width ? width < breakpoints.md : false + const tourSettings = mangoStore((s) => s.settings.tours) + const [isOnboarded] = useLocalStorageState(IS_ONBOARDED_KEY) useEffect(() => { if (mangoAccount) { @@ -151,7 +155,7 @@ const AccountPage = () => { <>
-
+
{
-
+
{
-
+
{ onClick={() => handleChartToShow('pnl')} >
-
+
{ onClick={() => handleChartToShow('cumulative-interest-value')} >
-
+
{ onClose={() => setShowWithdrawModal(false)} /> ) : null} + {!tourSettings?.account_tour_seen && isOnboarded && connected ? ( + + ) : null} ) : (
diff --git a/components/account/HealthHeart.tsx b/components/account/HealthHeart.tsx index 10af6f70..334c0db8 100644 --- a/components/account/HealthHeart.tsx +++ b/components/account/HealthHeart.tsx @@ -12,7 +12,7 @@ const HealthHeart = ({ return ( { }) await actions.reloadMangoAccount() - setShowSetupStep(4) + onClose() setSubmitDeposit(false) } catch (e: any) { notify({ @@ -379,7 +379,7 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => { setShowSetupStep(4)} + onClick={onClose} > Skip for now @@ -506,7 +506,7 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => { Deposit
- setShowSetupStep(4)}> + Skip for now diff --git a/components/swap/SwapForm.tsx b/components/swap/SwapForm.tsx index b5ac8975..fb925820 100644 --- a/components/swap/SwapForm.tsx +++ b/components/swap/SwapForm.tsx @@ -237,7 +237,7 @@ const SwapForm = () => {

{t('swap')}

-
+
{
-
+

{t('swap:from')}

{

{t('swap:to')}

-
+
{ />
{ const inputTokenInfo = mangoStore((s) => s.swap.inputTokenInfo) const outputTokenInfo = mangoStore((s) => s.swap.outputTokenInfo) + const { connected } = useWallet() + const tourSettings = mangoStore((s) => s.settings.tours) return ( -
-
- + <> +
+
+ +
+
+ +
+
+ +
-
- -
-
- -
-
+ {!tourSettings?.swap_tour_seen && connected ? ( + + ) : null} + ) } diff --git a/components/tours/AccountOnboardingTour.tsx b/components/tours/AccountOnboardingTour.tsx new file mode 100644 index 00000000..d221cd01 --- /dev/null +++ b/components/tours/AccountOnboardingTour.tsx @@ -0,0 +1,119 @@ +import { CardinalOrientation, Walktour, WalktourLogic } from 'walktour' +import CustomTooltip from './CustomTooltip' + +const AccountOnboardingTour = () => { + const renderTooltip = (tourLogic: WalktourLogic | undefined) => { + return ( + + ) + } + + const steps = [ + { + selector: '#account-step-zero', + title: 'Your Account Dashboard', + description: + "Here you'll find the important information related to your account. Let us show you around. Click close to skip the tour at any time.", + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#account-step-one', + title: 'Profile Menu', + description: + "If you haven't chosen a profile name yet, you'll see your assigned one here. You can edit it and change your profile picture from this menu.", + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#account-step-two', + title: 'Your Accounts', + description: + 'Switch between accounts and create new ones. Use multiple accounts to trade isolated margin and protect your capital from liquidation.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#account-step-three', + title: 'Account Value', + description: + 'The value of your assets (deposits) minus the value of your liabilities (borrows).', + orientationPreferences: [CardinalOrientation.EASTNORTH], + movingTarget: true, + }, + { + selector: '#account-step-four', + title: 'Health', + description: + 'If your account health reaches 0% your account will be liquidated. You can increase the health of your account by making a deposit.', + orientationPreferences: [CardinalOrientation.SOUTHWEST], + movingTarget: true, + }, + { + selector: '#account-step-five', + title: 'Free Collateral', + description: + "The amount of capital you have to trade or borrow against. When your free collateral reaches $0 you won't be able to make withdrawals.", + orientationPreferences: [CardinalOrientation.SOUTHWEST], + movingTarget: true, + }, + { + selector: '#account-step-six', + title: 'PnL (Profit and Loss)', + description: 'The amount your account has made or lost.', + orientationPreferences: [CardinalOrientation.SOUTHWEST], + movingTarget: true, + }, + { + selector: '#account-step-seven', + title: 'Total Interest Value', + description: + 'The value of interest earned (deposits) minus interest paid (borrows).', + orientationPreferences: [CardinalOrientation.SOUTHWEST], + movingTarget: true, + }, + { + selector: '#account-step-eight', + title: 'Interest Earned', + description: + 'The sum of interest earned and interest paid for each token.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#account-step-nine', + title: 'Rates', + description: + 'The interest rates (per year) for depositing (green/left) and borrowing (red/right).', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#account-step-ten', + title: 'Token Actions', + description: + 'Deposit, withdraw, borrow, buy and sell buttons for each token.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#account-step-eleven', + title: 'Health Check', + description: + 'Check the health of your account from any screen in the app. A green heart represents good health, orange okay and red poor.', + orientationPreferences: [CardinalOrientation.EASTSOUTH], + movingTarget: true, + }, + ] + + return ( + + ) +} + +export default AccountOnboardingTour diff --git a/components/tours/CustomTooltip.tsx b/components/tours/CustomTooltip.tsx new file mode 100644 index 00000000..72ff1394 --- /dev/null +++ b/components/tours/CustomTooltip.tsx @@ -0,0 +1,115 @@ +import Loading from '@components/shared/Loading' +import { XMarkIcon } from '@heroicons/react/20/solid' +import { useWallet } from '@solana/wallet-adapter-react' +import mangoStore from '@store/mangoStore' +import { useState } from 'react' +import { WalktourLogic } from 'walktour' + +const CustomTooltip = ({ + customOnClose, + hasSeenKey, + tourLogic, +}: { + customOnClose?: () => void + hasSeenKey: 'account_tour_seen' | 'swap_tour_seen' | 'trade_tour_seen' + tourLogic: WalktourLogic | undefined +}) => { + const { title, description } = tourLogic!.stepContent + const { next, prev, close, allSteps, stepIndex } = tourLogic! + const { publicKey } = useWallet() + const actions = mangoStore((s) => s.actions) + const tourSettings = mangoStore((s) => s.settings.tours) + const [loading, setLoading] = useState(false) + + const onClose = async () => { + if (!publicKey || !tourSettings) return + setLoading(true) + try { + const settings = { + ...tourSettings, + } + settings[hasSeenKey] = true + const message = JSON.stringify(settings) + const requestOptions = { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: message, + } + const response = await fetch( + 'https://mango-transaction-log.herokuapp.com/v4/user-data/settings-unsigned', + requestOptions + ) + if (response.status === 200) { + await actions.fetchTourSettings(publicKey.toString()) + } + } catch (e) { + console.log(e) + } finally { + if (customOnClose) { + customOnClose() + } + setLoading(false) + close() + } + } + + return ( +
+ {!loading ? ( + <> + +

{title}

+

{description}

+
+ {stepIndex !== 0 ? ( + + ) : ( +
+ )} +
+ {allSteps.map((s, i) => ( +
+ ))} +
+ {stepIndex !== allSteps.length - 1 ? ( + + ) : ( + + )} +
+ + ) : ( +
+ +
+ )} +
+ ) +} + +export default CustomTooltip diff --git a/components/tours/SwapOnboardingTour.tsx b/components/tours/SwapOnboardingTour.tsx new file mode 100644 index 00000000..397447f6 --- /dev/null +++ b/components/tours/SwapOnboardingTour.tsx @@ -0,0 +1,61 @@ +import { CardinalOrientation, Walktour, WalktourLogic } from 'walktour' +import CustomTooltip from './CustomTooltip' + +const SwapOnboardingTour = () => { + const renderTooltip = (tourLogic: WalktourLogic | undefined) => { + return + } + + const steps = [ + { + selector: '#swap-step-zero', + title: "We've Juiced Swap", + description: + "The swap you know and love + leverage. Swap lets you trade tokens on their relative strength. Let's say your thesis is BTC will see diminishing returns relative to SOL. You can sell BTC and buy SOL. Now you are long SOL/BTC", + orientationPreferences: [CardinalOrientation.CENTER], + }, + { + selector: '#swap-step-one', + title: 'Swap Settings', + description: + 'Edit your slippage settings and toggle margin on and off. When margin is off your swaps will be limited by your balance for each token.', + orientationPreferences: [CardinalOrientation.WESTNORTH], + movingTarget: true, + }, + { + selector: '#swap-step-two', + title: 'From Token', + description: + 'Select the token you want to swap from (sell). If you have margin on and your size is above your token balance a loan will be opened to cover the shortfall. Check the borrow rate before making a margin swap.', + orientationPreferences: [CardinalOrientation.WESTNORTH], + movingTarget: true, + }, + { + selector: '#swap-step-three', + title: 'To Token', + description: + "The token you'll receive in your Mango Account after making a swap. You can think of this token as the one you're buying/longing.", + orientationPreferences: [CardinalOrientation.WESTNORTH], + movingTarget: true, + }, + { + selector: '#swap-step-four', + title: 'Health Impact', + description: + 'Projects the health of your account before you make a swap. The first value is your current account health and the second, your projected account health.', + orientationPreferences: [CardinalOrientation.WESTNORTH], + movingTarget: true, + }, + ] + + return ( + + ) +} + +export default SwapOnboardingTour diff --git a/components/tours/TradeOnboardingTour.tsx b/components/tours/TradeOnboardingTour.tsx new file mode 100644 index 00000000..d1f3b53e --- /dev/null +++ b/components/tours/TradeOnboardingTour.tsx @@ -0,0 +1,108 @@ +import { CardinalOrientation, Walktour, WalktourLogic } from 'walktour' +import CustomTooltip from './CustomTooltip' + +const TradeOnboardingTour = () => { + const renderTooltip = (tourLogic: WalktourLogic | undefined) => { + return + } + + const steps = [ + { + selector: '#trade-step-zero', + title: 'Trade 100s of Tokens...', + description: + 'A refined interface without listing limits. The tokens you want to trade are now on Mango and no longer only quoted in USDC.', + orientationPreferences: [CardinalOrientation.CENTER], + }, + { + selector: '#trade-step-one', + title: 'Market Selector', + description: 'Chose the market you want to trade.', + orientationPreferences: [CardinalOrientation.SOUTHWEST], + movingTarget: true, + }, + { + selector: '#trade-step-two', + title: 'Oracle Price', + description: + "The oracle price uses an average of price data from many sources. It's used to avoid price manipulation which could lead to liquidations.", + orientationPreferences: [CardinalOrientation.SOUTHWEST], + movingTarget: true, + }, + { + selector: '#trade-step-three', + title: 'Toggle Orderbook', + description: + 'Use these buttons if you only want to see one side of the orderbook. Looking to bid/buy? Toggle off the buy orders to only see the sells and vice versa.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-four', + title: 'Orderbook Grouping', + description: + 'Adjust the price intervals to change how orders are grouped. Small intervals will show more small orders in the book', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-five', + title: 'Recent Trades', + description: + 'Shows the most recent orders for a market across all accounts.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-six', + title: 'Post Only', + description: + "An order condition that will only allow your order to enter the orderbook as a maker order. If the condition can't be met the order will be cancelled.", + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-seven', + title: 'Immediate or Cancel (IoC)', + description: + 'An order condition that attempts to execute all or part of an order immediately and then cancels any unfilled portion.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-eight', + title: 'Margin', + description: + "When margin is on you can trade with more size than your token balance. Using margin increases your risk of loss. If you're not an experienced trader, use it with caution.", + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-nine', + title: 'Spread', + description: + 'The difference between the prices quoted for an immediate sell (ask) and an immediate buy (bid). Or, in other words, the difference between the lowest sell price and the highest buy price.', + orientationPreferences: [CardinalOrientation.SOUTHEAST], + movingTarget: true, + }, + { + selector: '#trade-step-ten', + title: 'Unsettled Balance', + description: + 'When a limit order is filled, the funds are placed in your unsettled balances. When you have an unsettled balance you\'ll see a "Settle All" button above this table. Use it to move the funds to your account balance.', + orientationPreferences: [CardinalOrientation.NORTHEAST], + movingTarget: true, + }, + ] + + return ( + + ) +} + +export default TradeOnboardingTour diff --git a/components/trade/AdvancedMarketHeader.tsx b/components/trade/AdvancedMarketHeader.tsx index 916b8359..e1d1ae18 100644 --- a/components/trade/AdvancedMarketHeader.tsx +++ b/components/trade/AdvancedMarketHeader.tsx @@ -49,7 +49,10 @@ const MarketSelectDropdown = () => { return ( {({ close, open }) => ( -
+
@@ -160,7 +163,7 @@ const AdvancedMarketHeader = () => {
-
+
{t('trade:oracle-price')}
diff --git a/components/trade/AdvancedTradeForm.tsx b/components/trade/AdvancedTradeForm.tsx index ff4100d6..7ade40a8 100644 --- a/components/trade/AdvancedTradeForm.tsx +++ b/components/trade/AdvancedTradeForm.tsx @@ -370,7 +370,7 @@ const AdvancedTradeForm = () => {
{tradeForm.tradeType === 'Limit' ? (
-
+
{
-
+
{
) : null} -
+
{ return (
-
+
{
{serum3MarketExternal ? ( - - - +
+ + + +
) : null}
@@ -458,7 +460,10 @@ const Orderbook = () => { }) : null} {showBuys && showSells ? ( -
+
{t('trade:spread')}
diff --git a/components/trade/TradeAdvancedPage.tsx b/components/trade/TradeAdvancedPage.tsx index 0861b505..03022ee2 100644 --- a/components/trade/TradeAdvancedPage.tsx +++ b/components/trade/TradeAdvancedPage.tsx @@ -12,6 +12,8 @@ import AdvancedTradeForm from './AdvancedTradeForm' import TradeInfoTabs from './TradeInfoTabs' import MobileTradeAdvancedPage from './MobileTradeAdvancedPage' import OrderbookAndTrades from './OrderbookAndTrades' +import { useWallet } from '@solana/wallet-adapter-react' +import TradeOnboardingTour from '@components/tours/TradeOnboardingTour' const TradingViewChart = dynamic(() => import('./TradingViewChart'), { ssr: false, @@ -49,6 +51,8 @@ const TradeAdvancedPage = () => { const [currentBreakpoint, setCurrentBreakpoint] = useState() const { uiLocked } = mangoStore((s) => s.settings) const showMobileView = width <= breakpoints.md + const tourSettings = mangoStore((s) => s.settings.tours) + const { connected } = useWallet() const defaultLayouts: ReactGridLayout.Layouts = useMemo(() => { const topnavbarHeight = 67 @@ -162,52 +166,62 @@ const TradeAdvancedPage = () => { return showMobileView ? ( ) : ( - onBreakpointChange(newBreakpoint)} - onLayoutChange={(layout, layouts) => onLayoutChange(layouts)} - measureBeforeMount - containerPadding={[0, 0]} - margin={[0, 0]} - useCSSTransforms - > -
- -
-
-
- + <> + + onBreakpointChange(newBreakpoint) + } + onLayoutChange={(layout, layouts) => onLayoutChange(layouts)} + measureBeforeMount + containerPadding={[0, 0]} + margin={[0, 0]} + useCSSTransforms + > +
+
-
-
- -
-
- -
-
- -
- +
+
+ +
+
+
+ +
+
+ +
+
+ +
+ + {!tourSettings?.trade_tour_seen && connected ? ( + + ) : null} + ) } diff --git a/components/wallet/ConnectWalletButton.tsx b/components/wallet/ConnectWalletButton.tsx index 3263ba09..db766644 100644 --- a/components/wallet/ConnectWalletButton.tsx +++ b/components/wallet/ConnectWalletButton.tsx @@ -46,7 +46,7 @@ const onConnectFetchAccountData = async (wallet: Wallet) => { if (!wallet) return const actions = mangoStore.getState().actions await actions.fetchMangoAccounts(wallet.adapter as unknown as AnchorWallet) - actions.fetchProfilePicture(wallet.adapter as unknown as AnchorWallet) + actions.fetchTourSettings(wallet.adapter.publicKey?.toString() as string) actions.fetchWalletTokens(wallet.adapter as unknown as AnchorWallet) } diff --git a/components/wallet/ConnectedMenu.tsx b/components/wallet/ConnectedMenu.tsx index 7b6fc3e4..bcd889a7 100644 --- a/components/wallet/ConnectedMenu.tsx +++ b/components/wallet/ConnectedMenu.tsx @@ -54,27 +54,29 @@ const ConnectedMenu = () => { {({ open }) => (
- - {!loadProfileDetails && !isMobile ? ( -
-

- {wallet_pk - ? abbreviateAddress(new PublicKey(wallet_pk)) - : ''} -

-

- {profile_name} -

-
- ) : null} +
+ + {!loadProfileDetails && !isMobile ? ( +
+

+ {wallet_pk + ? abbreviateAddress(new PublicKey(wallet_pk)) + : ''} +

+

+ {profile_name} +

+
+ ) : null} +
void) => void - settings: { - uiLocked: boolean - } tradeForm: { side: 'buy' | 'sell' price: string @@ -162,8 +184,6 @@ export type MangoStore = { ioc: boolean } wallet: { - loadProfilePic: boolean - profilePic: ProfilePicture | undefined tokens: TokenAccount[] nfts: { data: NFT[] | [] @@ -183,8 +203,8 @@ export type MangoStore = { fetchMangoAccounts: (wallet: Wallet) => Promise fetchNfts: (connection: Connection, walletPk: PublicKey) => void fetchSerumOpenOrders: (ma?: MangoAccount) => Promise - fetchProfilePicture: (wallet: Wallet) => void fetchProfileDetails: (walletPk: string) => void + fetchTourSettings: (walletPk: string) => void fetchTradeHistory: (mangoAccountPk: string) => Promise fetchWalletTokens: (wallet: Wallet) => Promise connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise @@ -238,6 +258,13 @@ const mangoStore = create()( serumOrders: undefined, set: (fn) => _set(produce(fn)), settings: { + loading: false, + tours: { + account_tour_seen: true, + swap_tour_seen: true, + trade_tour_seen: true, + wallet_pk: '', + }, uiLocked: true, }, tradeForm: { @@ -258,8 +285,6 @@ const mangoStore = create()( slippage: 0.5, }, wallet: { - loadProfilePic: true, - profilePic: undefined, tokens: [], nfts: { data: [], @@ -674,27 +699,6 @@ const mangoStore = create()( console.error('Error fetching group', e) } }, - async fetchProfilePicture(wallet: Wallet) { - const set = get().set - const walletPk = wallet?.publicKey - const connection = get().connection - - if (!walletPk) return - - try { - const result = await getProfilePicture(connection, walletPk) - - set((state) => { - state.wallet.profilePic = result - state.wallet.loadProfilePic = false - }) - } catch (e) { - console.error('Could not get profile picture', e) - set((state) => { - state.wallet.loadProfilePic = false - }) - } - }, async fetchProfileDetails(walletPk: string) { const set = get().set set((state) => { @@ -711,12 +715,34 @@ const mangoStore = create()( }) } catch (e) { notify({ type: 'error', title: 'Failed to load profile details' }) - console.error(e) + console.log(e) set((state) => { state.profile.loadDetails = false }) } }, + async fetchTourSettings(walletPk: string) { + const set = get().set + set((state) => { + state.settings.loading = true + }) + try { + const response = await fetch( + `https://mango-transaction-log.herokuapp.com/v4/user-data/settings-unsigned?wallet-pk=${walletPk}` + ) + const data = await response.json() + set((state) => { + state.settings.tours = data + state.settings.loading = false + }) + } catch (e) { + notify({ type: 'error', title: 'Failed to load profile details' }) + console.error(e) + set((state) => { + state.settings.loading = false + }) + } + }, }, } })