add name account ui
This commit is contained in:
parent
34a4e5ee19
commit
7f53a44345
|
@ -0,0 +1,116 @@
|
|||
import { FunctionComponent, useState } from 'react'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import {
|
||||
ExclamationCircleIcon,
|
||||
InformationCircleIcon,
|
||||
} from '@heroicons/react/outline'
|
||||
import Input from './Input'
|
||||
import Button from './Button'
|
||||
import Modal from './Modal'
|
||||
import { ElementTitle } from './styles'
|
||||
import Tooltip from './Tooltip'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
// import { addMarginAccountInfo } from '../utils/mango'
|
||||
import { notify } from '../utils/notifications'
|
||||
|
||||
interface AccountNameModalProps {
|
||||
accountName?: string
|
||||
isOpen: boolean
|
||||
onClose?: (x?) => void
|
||||
}
|
||||
|
||||
const AccountNameModal: FunctionComponent<AccountNameModalProps> = ({
|
||||
accountName,
|
||||
isOpen,
|
||||
onClose,
|
||||
}) => {
|
||||
const [name, setName] = useState(accountName || '')
|
||||
const [invalidNameMessage, setInvalidNameMessage] = useState('')
|
||||
const wallet = useMangoStore.getState().wallet.current
|
||||
const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const { connection, programId } = useConnection()
|
||||
|
||||
const submitName = async () => {
|
||||
// addMarginAccountInfo(
|
||||
// connection,
|
||||
// new PublicKey(programId),
|
||||
// selectedMangoGroup,
|
||||
// mangoAccount,
|
||||
// wallet,
|
||||
// name
|
||||
// )
|
||||
// .then(() => {
|
||||
// actions.fetchMarginAccounts()
|
||||
// onClose()
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.warn('Error setting account name:', err)
|
||||
// notify({
|
||||
// message: 'Could not set account name',
|
||||
// description: `${err}`,
|
||||
// txid: err.txid,
|
||||
// type: 'error',
|
||||
// })
|
||||
// })
|
||||
}
|
||||
|
||||
const validateNameInput = () => {
|
||||
if (name.length >= 33) {
|
||||
setInvalidNameMessage('Account name must be 32 characters or less')
|
||||
}
|
||||
if (name.length === 0) {
|
||||
setInvalidNameMessage('Enter an account name')
|
||||
}
|
||||
}
|
||||
|
||||
const onChangeNameInput = (name) => {
|
||||
setName(name)
|
||||
if (invalidNameMessage) {
|
||||
setInvalidNameMessage('')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal onClose={onClose} isOpen={isOpen}>
|
||||
<Modal.Header>
|
||||
<div className="flex items-center">
|
||||
<ElementTitle noMarignBottom>Name your Account</ElementTitle>
|
||||
</div>
|
||||
</Modal.Header>
|
||||
<div className="flex items-center justify-center text-th-fgd-3 pb-4">
|
||||
Edit the public nickname for your account
|
||||
<Tooltip content="Account names are stored on-chain">
|
||||
<InformationCircleIcon className="h-5 w-5 ml-2 text-th-primary" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="pb-2 text-th-fgd-1">Account Name</div>
|
||||
<Input
|
||||
type="text"
|
||||
className={`border border-th-fgd-4 flex-grow`}
|
||||
error={!!invalidNameMessage}
|
||||
placeholder="e.g. Calypso"
|
||||
value={name}
|
||||
onBlur={validateNameInput}
|
||||
onChange={(e) => onChangeNameInput(e.target.value)}
|
||||
/>
|
||||
{invalidNameMessage ? (
|
||||
<div className="flex items-center pt-1.5 text-th-red">
|
||||
<ExclamationCircleIcon className="h-4 w-4 mr-1.5" />
|
||||
{invalidNameMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<Button
|
||||
onClick={() => submitName()}
|
||||
disabled={name.length >= 33}
|
||||
className="mt-4 w-full"
|
||||
>
|
||||
Save Name
|
||||
</Button>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccountNameModal
|
|
@ -44,8 +44,8 @@ const ConnectWalletButton = () => {
|
|||
{connected && wallet?.publicKey ? (
|
||||
<Menu>
|
||||
<div className="relative h-full">
|
||||
<Menu.Button className="bg-th-fgd-4 flex items-center justify-center rounded-full w-9 h-9 text-th-fgd-2 focus:outline-none hover:bg-th-bkg-3 hover:text-th-fgd-3">
|
||||
<ProfileIcon className="fill-current h-5 w-5" />
|
||||
<Menu.Button className="bg-th-fgd-4 flex items-center justify-center rounded-full w-10 h-10 text-th-fgd-2 focus:outline-none hover:bg-th-bkg-3 hover:text-th-fgd-3">
|
||||
<ProfileIcon className="fill-current h-6 w-6" />
|
||||
</Menu.Button>
|
||||
<Menu.Items className="bg-th-bkg-1 mt-2 p-1 absolute right-0 shadow-lg outline-none rounded-md w-48 z-20">
|
||||
<Menu.Item>
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import { StyledMarketInfoLabel } from './MarketHeader'
|
||||
|
||||
const DayHighLow = () => {
|
||||
return (
|
||||
<div className="pr-6">
|
||||
<StyledMarketInfoLabel className="text-center text-th-fgd-3">
|
||||
24h Range
|
||||
</StyledMarketInfoLabel>
|
||||
<div className="text-center text-th-fgd-3 tiny-text">24h Range</div>
|
||||
<div className="flex items-center">
|
||||
<div className="pr-2 text-th-fgd-1 text-xs">$XX.XX</div>
|
||||
<div className="h-1.5 flex rounded bg-th-bkg-3 w-24">
|
||||
|
|
|
@ -47,11 +47,9 @@ export default function MarginInfo() {
|
|||
<div className={`text-th-fgd-1`}>{leverage.toFixed(2)}x</div>
|
||||
</div>
|
||||
<div className={`flex justify-between pt-2 pb-2`}>
|
||||
<Tooltip content="Leverage">
|
||||
<div className="font-normal text-th-fgd-3 leading-4">
|
||||
Total Assets Value
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="font-normal text-th-fgd-3 leading-4">
|
||||
Total Assets Value
|
||||
</div>
|
||||
<div className={`text-th-fgd-1`}>
|
||||
$
|
||||
{mangoAccount
|
||||
|
@ -60,11 +58,9 @@ export default function MarginInfo() {
|
|||
</div>
|
||||
</div>
|
||||
<div className={`flex justify-between pt-2 pb-2`}>
|
||||
<Tooltip content="Leverage">
|
||||
<div className="font-normal text-th-fgd-3 leading-4">
|
||||
Total Liabilities Value
|
||||
</div>
|
||||
</Tooltip>
|
||||
<div className="font-normal text-th-fgd-3 leading-4">
|
||||
Total Liabilities Value
|
||||
</div>
|
||||
<div className={`text-th-fgd-1`}>
|
||||
$
|
||||
{mangoAccount
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useCallback, useMemo, useState } from 'react'
|
||||
import styled from '@emotion/styled'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import usePrevious from '../hooks/usePrevious'
|
||||
import useInterval from '../hooks/useInterval'
|
||||
|
@ -9,10 +8,6 @@ import ManualRefresh from './ManualRefresh'
|
|||
import useOraclePrice from '../hooks/useOraclePrice'
|
||||
import DayHighLow from './DayHighLow'
|
||||
|
||||
export const StyledMarketInfoLabel = styled.div`
|
||||
font-size: 0.7rem;
|
||||
`
|
||||
|
||||
const MarketHeader = () => {
|
||||
const oraclePrice = useOraclePrice()
|
||||
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
||||
|
@ -75,7 +70,7 @@ const MarketHeader = () => {
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-end sm:items-center justify-between pt-4 px-6 md:px-6`}
|
||||
className={`flex items-end sm:items-center justify-between pt-4 px-6 md:pb-1 md:pt-8 md:px-6`}
|
||||
>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center">
|
||||
<div className="pb-3 sm:pb-0 pr-8">
|
||||
|
@ -99,17 +94,13 @@ const MarketHeader = () => {
|
|||
</div>
|
||||
<div className="flex items-center">
|
||||
<div className="pr-6">
|
||||
<StyledMarketInfoLabel className="text-th-fgd-3">
|
||||
Oracle price
|
||||
</StyledMarketInfoLabel>
|
||||
<div className="text-th-fgd-3 tiny-text">Oracle price</div>
|
||||
<div className="font-semibold text-th-fgd-1 text-xs">
|
||||
{oraclePrice ? oraclePrice.toFixed(2) : '--'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="pr-4">
|
||||
<StyledMarketInfoLabel className="text-th-fgd-3">
|
||||
24h Change
|
||||
</StyledMarketInfoLabel>
|
||||
<div className="text-th-fgd-3 tiny-text">24h Change</div>
|
||||
{ohlcv && !loading ? (
|
||||
<div
|
||||
className={`font-semibold text-xs ${
|
||||
|
@ -128,15 +119,15 @@ const MarketHeader = () => {
|
|||
)}
|
||||
</div>
|
||||
<div className="pr-6">
|
||||
<StyledMarketInfoLabel className="text-th-fgd-3">
|
||||
24h Vol
|
||||
</StyledMarketInfoLabel>
|
||||
<div className="text-th-fgd-3 tiny-text">24h Vol</div>
|
||||
<div className="font-semibold text-th-fgd-1 text-xs">
|
||||
{ohlcv && !loading && volume ? (
|
||||
volume !== '--' ? (
|
||||
<>
|
||||
{volume.toFixed(2)}
|
||||
<span className="ml-1 text-th-fgd-3">{baseSymbol}</span>
|
||||
<span className="ml-1 text-th-fgd-3 tiny-text">
|
||||
{baseSymbol}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
volume
|
||||
|
@ -150,17 +141,13 @@ const MarketHeader = () => {
|
|||
{selectedMarketName.includes('PERP') ? (
|
||||
<>
|
||||
<div className="pr-6">
|
||||
<StyledMarketInfoLabel className="text-th-fgd-3">
|
||||
Funding (8h Ave)
|
||||
</StyledMarketInfoLabel>
|
||||
<div className="text-th-fgd-3 tiny-text">Funding (8h Ave)</div>
|
||||
<div className="font-semibold text-th-fgd-1 text-xs">
|
||||
0.001%
|
||||
</div>
|
||||
</div>
|
||||
<div className="pr-6">
|
||||
<StyledMarketInfoLabel className="text-th-fgd-3">
|
||||
Open Interest
|
||||
</StyledMarketInfoLabel>
|
||||
<div className="text-th-fgd-3 tiny-text">Open Interest</div>
|
||||
<div className="font-semibold text-th-fgd-1 text-xs">$XXXm</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
@ -125,8 +125,10 @@ export default function MarketPosition() {
|
|||
<span className="text-th-fgd-2">{symbol}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pb-2">
|
||||
<div className="text-th-fgd-3 tiny-text">Deposits</div>
|
||||
<div className="pb-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
Deposits
|
||||
</div>
|
||||
<div className={`text-th-fgd-1`}>
|
||||
{selectedMangoAccount
|
||||
? selectedMangoAccount
|
||||
|
@ -141,8 +143,10 @@ export default function MarketPosition() {
|
|||
: (0).toFixed(tokenPrecision[symbol])}
|
||||
</div>
|
||||
</div>
|
||||
<div className="pb-2">
|
||||
<div className="text-th-fgd-3 tiny-text">Borrows</div>
|
||||
<div className="pb-3">
|
||||
<div className="pb-0.5 text-th-fgd-3 text-xs">
|
||||
Borrows
|
||||
</div>
|
||||
<div className={`text-th-fgd-1`}>
|
||||
{selectedMangoAccount
|
||||
? selectedMangoAccount
|
||||
|
@ -160,7 +164,7 @@ export default function MarketPosition() {
|
|||
{/* <div className="w-1/4">
|
||||
<Tooltip content="Maximum available with leverage">
|
||||
<div
|
||||
className={`cursor-help font-normal pb-0.5 text-th-fgd-3 tiny-text default-transition hover:border-th-bkg-2 hover:text-th-fgd-3`}
|
||||
className={`cursor-help font-normal pb-0.5 text-th-fgd-3 text-xs default-transition hover:border-th-bkg-2 hover:text-th-fgd-3`}
|
||||
>
|
||||
Available
|
||||
</div>
|
||||
|
@ -170,7 +174,7 @@ export default function MarketPosition() {
|
|||
<div>
|
||||
<Tooltip content="Deposit APY and Borrow APR">
|
||||
<div
|
||||
className={`cursor-help font-normal pb-0.5 text-th-fgd-3 tiny-text default-transition hover:border-th-bkg-2 hover:text-th-fgd-3`}
|
||||
className={`cursor-help font-normal pb-0.5 text-th-fgd-3 text-xs default-transition hover:border-th-bkg-2 hover:text-th-fgd-3`}
|
||||
>
|
||||
Interest Rates
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,15 @@ import { LinkButton } from './Button'
|
|||
import MarketsModal from './MarketsModal'
|
||||
import useLocalStorageState from '../hooks/useLocalStorageState'
|
||||
|
||||
const StyledMarketSelectWrapper = styled.div`
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
const StyledMarketTypeToggleWrapper = styled.div`
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
`
|
||||
|
@ -44,7 +53,7 @@ const MarketSelect = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-th-bkg-3 flex h-10">
|
||||
<StyledMarketSelectWrapper className="bg-th-bkg-3 flex h-10 overflow-x-auto">
|
||||
<StyledMarketTypeToggleWrapper className="flex items-center pl-6 md:pl-9 pr-1">
|
||||
<LinkButton
|
||||
className="font-normal text-th-fgd-2 text-xs"
|
||||
|
@ -67,7 +76,7 @@ const MarketSelect = () => {
|
|||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</StyledMarketSelectWrapper>
|
||||
{showMarketsModal ? (
|
||||
<MarketsModal
|
||||
isOpen={showMarketsModal}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import React, { FunctionComponent, useEffect, useState } from 'react'
|
||||
import { ExclamationCircleIcon } from '@heroicons/react/outline'
|
||||
import React, { FunctionComponent, useEffect, useMemo, useState } from 'react'
|
||||
import {
|
||||
ExclamationCircleIcon,
|
||||
InformationCircleIcon,
|
||||
} from '@heroicons/react/outline'
|
||||
// import {
|
||||
// nativeToUi,
|
||||
// sleep,
|
||||
|
@ -18,6 +21,7 @@ import {
|
|||
import Loading from './Loading'
|
||||
import Button from './Button'
|
||||
import Slider from './Slider'
|
||||
import Tooltip from './Tooltip'
|
||||
import { notify } from '../utils/notifications'
|
||||
import useMangoGroupConfig from '../hooks/useMangoGroupConfig'
|
||||
import { deposit } from '../utils/mango'
|
||||
|
@ -36,6 +40,9 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
const [invalidAmountMessage, setInvalidAmountMessage] = useState('')
|
||||
const [sliderPercentage, setSliderPercentage] = useState(0)
|
||||
const [maxButtonTransition, setMaxButtonTransition] = useState(false)
|
||||
const [showNewAccountName, setShowNewAccountName] = useState(true)
|
||||
const [invalidNameMessage, setInvalidNameMessage] = useState('')
|
||||
const [name, setName] = useState('')
|
||||
const walletTokens = useMangoStore((s) => s.wallet.tokens)
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
|
||||
|
@ -116,6 +123,22 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
validateAmountInput(amount)
|
||||
}
|
||||
|
||||
const validateNameInput = () => {
|
||||
if (name.length >= 33) {
|
||||
setInvalidNameMessage('Account name must be 32 characters or less')
|
||||
}
|
||||
if (name.length === 0) {
|
||||
setInvalidNameMessage('Enter an account name')
|
||||
}
|
||||
}
|
||||
|
||||
const onChangeNameInput = (name) => {
|
||||
setName(name)
|
||||
if (invalidNameMessage) {
|
||||
setInvalidNameMessage('')
|
||||
}
|
||||
}
|
||||
|
||||
// turn off slider transition for dragging slider handle interaction
|
||||
useEffect(() => {
|
||||
if (maxButtonTransition) {
|
||||
|
@ -125,64 +148,103 @@ const NewAccount: FunctionComponent<NewAccountProps> = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<ElementTitle noMarignBottom>Create Margin Account</ElementTitle>
|
||||
<div className="text-th-fgd-3 text-center pb-4 pt-2">
|
||||
Make a deposit to initialize a new margin account
|
||||
</div>
|
||||
|
||||
<AccountSelect
|
||||
accounts={walletTokens}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={handleAccountSelect}
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>Amount</div>
|
||||
<div
|
||||
className="text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline"
|
||||
onClick={setMaxForSelectedAccount}
|
||||
>
|
||||
Max
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
className={`border border-th-fgd-4 flex-grow pr-11`}
|
||||
placeholder="0.00"
|
||||
error={!!invalidAmountMessage}
|
||||
onBlur={(e) => validateAmountInput(e.target.value)}
|
||||
value={inputAmount}
|
||||
onChange={(e) => onChangeAmountInput(e.target.value)}
|
||||
suffix={symbol}
|
||||
/>
|
||||
</div>
|
||||
{invalidAmountMessage ? (
|
||||
<div className="flex items-center pt-1.5 text-th-red">
|
||||
<ExclamationCircleIcon className="h-4 w-4 mr-1.5" />
|
||||
{invalidAmountMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="pt-3 pb-4">
|
||||
<Slider
|
||||
value={sliderPercentage}
|
||||
onChange={(v) => onChangeSlider(v)}
|
||||
step={1}
|
||||
maxButtonTransition={maxButtonTransition}
|
||||
/>
|
||||
</div>
|
||||
<div className={`pt-8 flex justify-center`}>
|
||||
<Button
|
||||
disabled={inputAmount <= 0 || inputAmount > selectedAccount.uiBalance}
|
||||
onClick={handleNewAccountDeposit}
|
||||
className="w-full"
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
{submitting && <Loading className="-ml-1 mr-3" />}
|
||||
Create Account
|
||||
<ElementTitle noMarignBottom>New Account</ElementTitle>
|
||||
{/* {showNewAccountName ? (
|
||||
<>
|
||||
<div className="flex items-center justify-center text-th-fgd-3 pb-4 pt-2">
|
||||
Create a public nickname for your account
|
||||
<Tooltip content="Account names are stored on-chain">
|
||||
<InformationCircleIcon className="h-5 w-5 ml-2 text-th-primary" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="pb-2 text-th-fgd-1">
|
||||
Account Name <span className="text-th-fgd-3">(Optional)</span>
|
||||
</div>
|
||||
<Input
|
||||
type="text"
|
||||
className={`border border-th-fgd-4 flex-grow`}
|
||||
error={!!invalidNameMessage}
|
||||
placeholder="e.g. Calypso"
|
||||
value={name}
|
||||
onBlur={validateNameInput}
|
||||
onChange={(e) => onChangeNameInput(e.target.value)}
|
||||
/>
|
||||
{invalidNameMessage ? (
|
||||
<div className="flex items-center pt-1.5 text-th-red">
|
||||
<ExclamationCircleIcon className="h-4 w-4 mr-1.5" />
|
||||
{invalidNameMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<Button
|
||||
onClick={() => setShowNewAccountName(false)}
|
||||
disabled={name.length >= 33}
|
||||
className="mt-4 w-full"
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</>
|
||||
) : ( */}
|
||||
<>
|
||||
<div className="text-th-fgd-3 text-center pb-4 pt-2">
|
||||
Make a deposit to initialize your new account
|
||||
</div>
|
||||
<AccountSelect
|
||||
accounts={walletTokens}
|
||||
selectedAccount={selectedAccount}
|
||||
onSelectAccount={handleAccountSelect}
|
||||
/>
|
||||
<div className="flex justify-between pb-2 pt-4">
|
||||
<div className={`text-th-fgd-1`}>Amount</div>
|
||||
<div
|
||||
className="text-th-fgd-1 underline cursor-pointer default-transition hover:text-th-primary hover:no-underline"
|
||||
onClick={setMaxForSelectedAccount}
|
||||
>
|
||||
Max
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
className={`border border-th-fgd-4 flex-grow pr-11`}
|
||||
placeholder="0.00"
|
||||
error={!!invalidAmountMessage}
|
||||
onBlur={(e) => validateAmountInput(e.target.value)}
|
||||
value={inputAmount}
|
||||
onChange={(e) => onChangeAmountInput(e.target.value)}
|
||||
suffix={symbol}
|
||||
/>
|
||||
</div>
|
||||
{invalidAmountMessage ? (
|
||||
<div className="flex items-center pt-1.5 text-th-red">
|
||||
<ExclamationCircleIcon className="h-4 w-4 mr-1.5" />
|
||||
{invalidAmountMessage}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="pt-3 pb-4">
|
||||
<Slider
|
||||
value={sliderPercentage}
|
||||
onChange={(v) => onChangeSlider(v)}
|
||||
step={1}
|
||||
maxButtonTransition={maxButtonTransition}
|
||||
/>
|
||||
</div>
|
||||
<div className={`pt-8 flex justify-center`}>
|
||||
<Button
|
||||
disabled={
|
||||
inputAmount <= 0 || inputAmount > selectedAccount.uiBalance
|
||||
}
|
||||
onClick={handleNewAccountDeposit}
|
||||
className="w-full"
|
||||
>
|
||||
<div className={`flex items-center justify-center`}>
|
||||
{submitting && <Loading className="-ml-1 mr-3" />}
|
||||
Create New Account
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
{/* )} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
import { useState } from 'react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { MenuIcon, XIcon } from '@heroicons/react/outline'
|
||||
import { abbreviateAddress } from '../utils/index'
|
||||
import MenuItem from './MenuItem'
|
||||
import ThemeSwitch from './ThemeSwitch'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import ConnectWalletButton from './ConnectWalletButton'
|
||||
import AlertsList from './AlertsList'
|
||||
import NavDropMenu from './NavDropMenu'
|
||||
import AccountsModal from './AccountsModal'
|
||||
import Button from './Button'
|
||||
|
||||
const TopBar = () => {
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const wallet = useMangoStore((s) => s.wallet.current)
|
||||
const [showMenu, setShowMenu] = useState(false)
|
||||
const [showAccountsModal, setShowAccountsModal] = useState(false)
|
||||
|
||||
const handleCloseAccounts = useCallback(() => {
|
||||
setShowAccountsModal(false)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -32,7 +41,7 @@ const TopBar = () => {
|
|||
<MenuItem href="/account">Account</MenuItem>
|
||||
<MenuItem href="/borrow">Borrow</MenuItem>
|
||||
{/* <MenuItem href="/alerts">Alerts</MenuItem> */}
|
||||
<MenuItem href="/stats">Stats</MenuItem>
|
||||
<MenuItem href="/stats">Stats</MenuItem>
|
||||
<MenuItem href="https://docs.mango.markets/">Learn</MenuItem>
|
||||
{/* TODO: change v2 link before mainnet */}
|
||||
<NavDropMenu
|
||||
|
@ -54,8 +63,21 @@ const TopBar = () => {
|
|||
<AlertsList />
|
||||
</div>
|
||||
) : null}
|
||||
{mangoAccount ? (
|
||||
<div className="pl-3">
|
||||
<Button
|
||||
className="pb-1 pt-1 pl-2 pr-2 text-xs"
|
||||
onClick={() => setShowAccountsModal(true)}
|
||||
>
|
||||
<div className="font-normal text-th-primary tiny-text">
|
||||
Account
|
||||
</div>
|
||||
{abbreviateAddress(mangoAccount.publicKey)}
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex">
|
||||
<div className="hidden md:block pl-4">
|
||||
<div className="hidden md:block pl-3">
|
||||
<ConnectWalletButton />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -114,6 +136,12 @@ const TopBar = () => {
|
|||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{showAccountsModal ? (
|
||||
<AccountsModal
|
||||
onClose={handleCloseAccounts}
|
||||
isOpen={showAccountsModal}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import { useCallback, useState } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import {
|
||||
CurrencyDollarIcon,
|
||||
ChartBarIcon,
|
||||
DuplicateIcon,
|
||||
ExternalLinkIcon,
|
||||
ChartPieIcon,
|
||||
LinkIcon,
|
||||
PencilIcon,
|
||||
} from '@heroicons/react/outline'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { abbreviateAddress } from '../utils'
|
||||
import { abbreviateAddress, copyToClipboard } from '../utils'
|
||||
import PageBodyContainer from '../components/PageBodyContainer'
|
||||
import TopBar from '../components/TopBar'
|
||||
import AccountAssets from '../components/account-page/AccountAssets'
|
||||
|
@ -15,7 +17,10 @@ import AccountBorrows from '../components/account-page/AccountBorrows'
|
|||
import AccountOrders from '../components/account-page/AccountOrders'
|
||||
import AccountHistory from '../components/account-page/AccountHistory'
|
||||
import AccountsModal from '../components/AccountsModal'
|
||||
import AccountNameModal from '../components/AccountNameModal'
|
||||
import Button from '../components/Button'
|
||||
import EmptyState from '../components/EmptyState'
|
||||
import { MangoAccount } from '@blockworks-foundation/mango-client'
|
||||
|
||||
const TABS = [
|
||||
'Assets',
|
||||
|
@ -26,15 +31,29 @@ const TABS = [
|
|||
'History',
|
||||
]
|
||||
|
||||
export function getMarginInfoString(marginAccount: MangoAccount) {
|
||||
return marginAccount?.info
|
||||
? String.fromCharCode(...marginAccount?.info).replaceAll(
|
||||
String.fromCharCode(0),
|
||||
''
|
||||
)
|
||||
: ''
|
||||
}
|
||||
|
||||
export default function Account() {
|
||||
const [activeTab, setActiveTab] = useState(TABS[0])
|
||||
const [showAccountsModal, setShowAccountsModal] = useState(false)
|
||||
const [showNameModal, setShowNameModal] = useState(false)
|
||||
const [isCopied, setIsCopied] = useState(false)
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
||||
const wallet = useMangoStore((s) => s.wallet.current)
|
||||
|
||||
const marginInfoString = getMarginInfoString(mangoAccount)
|
||||
const [accountName, setAccountName] = useState(marginInfoString)
|
||||
|
||||
const handleTabChange = (tabName) => {
|
||||
setActiveTab(tabName)
|
||||
}
|
||||
|
@ -42,41 +61,77 @@ export default function Account() {
|
|||
setShowAccountsModal(false)
|
||||
}, [])
|
||||
|
||||
const handleCopyPublicKey = (code) => {
|
||||
setIsCopied(true)
|
||||
copyToClipboard(code)
|
||||
}
|
||||
const handleCloseNameModal = useCallback(() => {
|
||||
setShowNameModal(false)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (isCopied) {
|
||||
const timer = setTimeout(() => {
|
||||
setIsCopied(false)
|
||||
}, 1500)
|
||||
return () => clearTimeout(timer)
|
||||
}
|
||||
}, [isCopied])
|
||||
|
||||
return (
|
||||
<div className={`bg-th-bkg-1 text-th-fgd-1 transition-all`}>
|
||||
<TopBar />
|
||||
<PageBodyContainer>
|
||||
<div className="flex flex-col sm:flex-row items-center justify-between pt-8 pb-3 sm:pb-6 md:pt-10">
|
||||
<h1 className={`text-th-fgd-1 text-2xl font-semibold`}>Account</h1>
|
||||
{mangoAccount ? (
|
||||
<div className="divide-x divide-th-fgd-4 flex justify-center w-full pt-4 sm:pt-0 sm:justify-end">
|
||||
<div className="pr-4 text-xs text-th-fgd-1">
|
||||
<div className="pb-0.5 text-2xs text-th-fgd-3">Owner</div>
|
||||
<a
|
||||
className="default-transition flex items-center text-th-fgd-2"
|
||||
href={`https://explorer.solana.com/address/${mangoAccount?.owner}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span>{abbreviateAddress(mangoAccount?.owner)}</span>
|
||||
<ExternalLinkIcon className={`h-3 w-3 ml-1`} />
|
||||
</a>
|
||||
</div>
|
||||
<div className="pl-4 text-xs text-th-fgd-1">
|
||||
<div className="pb-0.5 text-2xs text-th-fgd-3">
|
||||
Margin Account
|
||||
<>
|
||||
<div className="flex flex-col sm:flex-row sm:items-end pb-4 md:pb-0">
|
||||
<h1 className={`font-semibold mr-3 text-th-fgd-1 text-2xl`}>
|
||||
{accountName ? accountName : 'Account'}
|
||||
</h1>
|
||||
<div className="flex items-center pb-0.5 text-th-fgd-3 ">
|
||||
{abbreviateAddress(mangoAccount.publicKey)}
|
||||
<DuplicateIcon
|
||||
className="cursor-pointer default-transition h-4 w-4 ml-1.5 hover:text-th-fgd-1"
|
||||
onClick={() => handleCopyPublicKey(mangoAccount.publicKey)}
|
||||
/>
|
||||
{isCopied ? (
|
||||
<div className="ml-2 text-th-fgd-2 text-xs">Copied!</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{/* Re-instate when added to program code */}
|
||||
|
||||
{/* <Button
|
||||
className="text-xs flex flex-grow items-center justify-center mr-2 pt-0 pb-0 h-8 pl-3 pr-3"
|
||||
onClick={() => setShowNameModal(true)}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<PencilIcon className="h-4 w-4 mr-1.5" />
|
||||
{accountName ? 'Edit Name' : 'Add Name'}
|
||||
</div>
|
||||
</Button> */}
|
||||
<a
|
||||
className="default-transition flex items-center text-th-fgd-2"
|
||||
className="border border-th-fgd-4 bg-th-bkg-2 default-transition flex flex-grow font-bold h-8 items-center justify-center pl-3 pr-3 rounded-md text-th-fgd-1 text-xs hover:bg-th-bkg-3 hover:text-th-fgd-1 focus:outline-none"
|
||||
href={`https://explorer.solana.com/address/${mangoAccount?.publicKey}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span>{abbreviateAddress(mangoAccount?.publicKey)}</span>
|
||||
<ExternalLinkIcon className={`h-3 w-3 ml-1`} />
|
||||
<span>Explorer</span>
|
||||
<ExternalLinkIcon className={`h-4 w-4 ml-1.5`} />
|
||||
</a>
|
||||
<Button
|
||||
className="text-xs flex flex-grow items-center justify-center ml-2 pt-0 pb-0 h-8 pl-3 pr-3"
|
||||
onClick={() => setShowAccountsModal(true)}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<CurrencyDollarIcon className="h-4 w-4 mr-1.5" />
|
||||
Accounts
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="bg-th-bkg-2 overflow-none p-6 rounded-lg">
|
||||
|
@ -167,6 +222,13 @@ export default function Account() {
|
|||
isOpen={showAccountsModal}
|
||||
/>
|
||||
) : null}
|
||||
{showNameModal ? (
|
||||
<AccountNameModal
|
||||
accountName={accountName}
|
||||
isOpen={showNameModal}
|
||||
onClose={handleCloseNameModal}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ button {
|
|||
}
|
||||
|
||||
.tiny-text {
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.65rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Chart */
|
||||
|
|
Loading…
Reference in New Issue