import { Dialog, Transition } from '@headlessui/react' import { useTranslation } from 'next-i18next' import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react' import { ModalProps } from '../../types/modal' import Input from '../forms/Input' import Label from '../forms/Label' import Button, { IconButton, LinkButton } from '../shared/Button' import InlineNotification from '../shared/InlineNotification' import useLocalStorageState from '../../hooks/useLocalStorageState' import { ArrowDownTrayIcon, CheckCircleIcon, FireIcon, PencilIcon, PlusCircleIcon, XMarkIcon, } from '@heroicons/react/20/solid' import { useWallet } from '@solana/wallet-adapter-react' import mangoStore from '@store/mangoStore' import { EnterBottomExitBottom, EnterRightExitLeft, FadeInFadeOut, } from '../shared/Transitions' import Image from 'next/image' import BounceLoader from '../shared/BounceLoader' import { notify } from '../../utils/notifications' import { Wallet } from '@project-serum/anchor' import ActionTokenList from '../account/ActionTokenList' import { walletBalanceForToken } from './DepositModal' import { floorToDecimal } from '../../utils/numbers' import { handleWalletConnect } from '../wallet/ConnectWalletButton' import { IS_ONBOARDED_KEY } from '../../utils/constants' import ParticlesBackground from '../ParticlesBackground' import ButtonGroup from '../forms/ButtonGroup' import Decimal from 'decimal.js' import WalletIcon from '../icons/WalletIcon' import EditProfileForm from '@components/profile/EditProfileForm' import EditNftProfilePic from '@components/profile/EditNftProfilePic' const UserSetupModal = ({ isOpen, onClose }: ModalProps) => { const { t } = useTranslation() const group = mangoStore((s) => s.group) const { connected, select, wallet, wallets } = useWallet() const mangoAccount = mangoStore((s) => s.mangoAccount.current) const mangoAccountLoading = mangoStore((s) => s.mangoAccount.initialLoad) const [accountName, setAccountName] = useState('') const [loadingAccount, setLoadingAccount] = useState(false) const [showSetupStep, setShowSetupStep] = useState(0) const [depositToken, setDepositToken] = useState('') const [depositAmount, setDepositAmount] = useState('') const [submitDeposit, setSubmitDeposit] = useState(false) const [sizePercentage, setSizePercentage] = useState('') const [showEditProfilePic, setShowEditProfilePic] = useState(false) const [, setIsOnboarded] = useLocalStorageState(IS_ONBOARDED_KEY) const walletTokens = mangoStore((s) => s.wallet.tokens) const handleNextStep = () => { setShowSetupStep(showSetupStep + 1) } const connectWallet = async () => { if (wallet) { try { await handleWalletConnect(wallet) setShowSetupStep(2) setIsOnboarded(true) } catch (e) { notify({ title: 'Setup failed. Refresh and try again.', type: 'error', }) } } } const handleCreateAccount = useCallback(async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const actions = mangoStore.getState().actions if (!group || !wallet) return setLoadingAccount(true) try { const tx = await client.createMangoAccount( group, 0, accountName || 'Account 1' ) actions.fetchMangoAccounts(wallet!.adapter as unknown as Wallet) if (tx) { setLoadingAccount(false) setShowSetupStep(3) notify({ title: t('new-account-success'), type: 'success', txid: tx, }) } } catch (e: any) { setLoadingAccount(false) notify({ title: t('new-account-failed'), txid: e?.signature, type: 'error', }) console.error(e) } }, [accountName, wallet, t]) const handleDeposit = useCallback(async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const actions = mangoStore.getState().actions const mangoAccount = mangoStore.getState().mangoAccount.current if (!mangoAccount || !group) return const bank = group.banksMapByName.get(depositToken)![0] try { setSubmitDeposit(true) const tx = await client.tokenDeposit( group, mangoAccount, bank.mint, parseFloat(depositAmount) ) notify({ title: 'Transaction confirmed', type: 'success', txid: tx, }) await actions.reloadMangoAccount() setShowSetupStep(4) setSubmitDeposit(false) } catch (e: any) { notify({ title: 'Transaction failed', description: e.message, txid: e?.txid, type: 'error', }) setSubmitDeposit(false) console.error(e) } }, [depositAmount, depositToken, onClose]) useEffect(() => { if (mangoAccount && showSetupStep === 2) { onClose() } }, [mangoAccount, showSetupStep, onClose]) // TODO extract into a shared hook for DepositModal.tsx const banks = useMemo(() => { const banks = group?.banksMapByName ? Array.from(group?.banksMapByName, ([key, value]) => { const walletBalance = walletBalanceForToken(walletTokens, key) return { key, value, tokenDecimals: walletBalance.maxDecimals, walletBalance: floorToDecimal( walletBalance.maxAmount, walletBalance.maxDecimals ).toNumber(), walletBalanceValue: walletBalance.maxAmount * value[0]?.uiPrice!, } }) : [] return banks }, [group?.banksMapByName, walletTokens]) const tokenMax = useMemo(() => { const bank = banks.find((bank) => bank.key === depositToken) if (bank) { return { amount: bank.walletBalance, decimals: bank.tokenDecimals } } return { amount: 0, decimals: 0 } }, [banks, depositToken]) const handleSizePercentage = useCallback( (percentage: string) => { setSizePercentage(percentage) let amount = new Decimal(tokenMax.amount).mul(percentage).div(100) if (percentage !== '100') { amount = floorToDecimal(amount, tokenMax.decimals) } setDepositAmount(amount.toString()) }, [tokenMax] ) return (
{/*
next
*/}
onClose()}>

Welcome

{ "You're seconds away from trading the most liquid dex markets on Solana." }

Trusted by 1,000s of DeFi users

Deeply liquid markets

Up to 20x leverage across 100s of tokens

Earn interest on your deposits

Borrow 100s of tokens with many collateral options

{connected && mangoAccountLoading ? (
) : (

Connect Wallet

Choose Wallet

{wallets?.map((w) => ( ))}
)}
{loadingAccount ? (
) : (

Create Account

You need a Mango Account to get started.

setShowSetupStep(4)} > Skip for now
)}
{submitDeposit ? (
) : (

Fund Your Account

) => setDepositAmount(e.target.value) } />
handleSizePercentage(p)} values={['10', '25', '50', '75', '100']} unit="%" />
{!depositToken ? (

{t('token')}

{t('deposit-rate')}

{t('wallet-balance')}

) : null}
setShowSetupStep(4)}> Skip for now
)}

Your Profile

Add an NFT profile pic and edit your assigned name. Your profile will be used for social features in the app.

setShowEditProfilePic(true)} /> Skip and Finish setShowEditProfilePic(false)} />
) } export default UserSetupModal