orders and balances pages
This commit is contained in:
parent
7e26c63ec3
commit
d980ce7e05
|
@ -1,10 +1,11 @@
|
|||
import { UserOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { Button, Select, Popover } from 'antd';
|
||||
import React from 'react';
|
||||
import { InfoCircleOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { Button, Menu, Popover, Select } from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import logo from '../assets/logo.svg';
|
||||
import styled from 'styled-components';
|
||||
import { useWallet, WALLET_PROVIDERS } from '../utils/wallet';
|
||||
import { useConnectionConfig, ENDPOINTS } from '../utils/connection';
|
||||
import { ENDPOINTS, useConnectionConfig } from '../utils/connection';
|
||||
import LinkAddress from './LinkAddress';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
|
@ -27,11 +28,26 @@ const LogoWrapper = styled.div`
|
|||
`;
|
||||
|
||||
export default function TopBar() {
|
||||
const [current, setCurrent] = useState('/');
|
||||
const [connected, wallet, providerUrl, setProvider] = useWallet();
|
||||
const { endpoint, setEndpoint } = useConnectionConfig();
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
|
||||
const publicKey = wallet?.publicKey?.toBase58();
|
||||
|
||||
const handleClick = useCallback((e) => {
|
||||
history.push(e.key);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (location.pathname.includes('/orders')) {
|
||||
setCurrent('/orders');
|
||||
} else if (location.pathname.includes('/balances')) {
|
||||
setCurrent('/balances');
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<div>
|
||||
|
@ -40,6 +56,22 @@ export default function TopBar() {
|
|||
{'SERUM'}
|
||||
</LogoWrapper>
|
||||
</div>
|
||||
<Menu
|
||||
mode="horizontal"
|
||||
onClick={handleClick}
|
||||
selectedKeys={[current]}
|
||||
style={{
|
||||
borderBottom: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<Menu.Item key="/">TRADE</Menu.Item>
|
||||
<Menu.Item key="/orders">ORDERS</Menu.Item>
|
||||
<Menu.Item key="/balances">BALANCES</Menu.Item>
|
||||
</Menu>
|
||||
<div style={{ display: 'block' }}>
|
||||
<Select
|
||||
onSelect={setEndpoint}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
import {
|
||||
useBaseCurrencyBalances,
|
||||
useQuoteCurrencyBalances,
|
||||
useSelectedOpenOrdersAccount,
|
||||
useMarket,
|
||||
useSelectedBaseCurrencyAccount,
|
||||
|
@ -13,59 +11,13 @@ import { useConnection } from '../../utils/connection';
|
|||
import { useWallet } from '../../utils/wallet';
|
||||
import { settleFunds } from '../../utils/send';
|
||||
|
||||
export default function BalancesTable() {
|
||||
const [baseCurrencyBalances] = useBaseCurrencyBalances();
|
||||
const [quoteCurrencyBalances] = useQuoteCurrencyBalances();
|
||||
export default function BalancesTable({ balances }) {
|
||||
const baseCurrencyAccount = useSelectedBaseCurrencyAccount();
|
||||
const quoteCurrencyAccount = useSelectedQuoteCurrencyAccount();
|
||||
const connection = useConnection();
|
||||
const [, wallet] = useWallet();
|
||||
const openOrdersAccount = useSelectedOpenOrdersAccount(true);
|
||||
const { baseCurrency, quoteCurrency, market } = useMarket();
|
||||
const baseExists =
|
||||
openOrdersAccount &&
|
||||
openOrdersAccount.baseTokenTotal &&
|
||||
openOrdersAccount.baseTokenFree;
|
||||
const quoteExists =
|
||||
openOrdersAccount &&
|
||||
openOrdersAccount.quoteTokenTotal &&
|
||||
openOrdersAccount.quoteTokenFree;
|
||||
const dataSource = [
|
||||
{
|
||||
key: baseCurrency,
|
||||
coin: baseCurrency,
|
||||
wallet: baseCurrencyBalances,
|
||||
orders:
|
||||
baseExists && market
|
||||
? market.baseSplSizeToNumber(
|
||||
openOrdersAccount.baseTokenTotal.sub(
|
||||
openOrdersAccount.baseTokenFree,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
unsettled:
|
||||
baseExists && market
|
||||
? market.baseSplSizeToNumber(openOrdersAccount.baseTokenFree)
|
||||
: null,
|
||||
},
|
||||
{
|
||||
key: quoteCurrency,
|
||||
coin: quoteCurrency,
|
||||
wallet: quoteCurrencyBalances,
|
||||
orders:
|
||||
quoteExists && market
|
||||
? market.quoteSplSizeToNumber(
|
||||
openOrdersAccount.quoteTokenTotal.sub(
|
||||
openOrdersAccount.quoteTokenFree,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
unsettled:
|
||||
quoteExists && market
|
||||
? market.quoteSplSizeToNumber(openOrdersAccount.quoteTokenFree)
|
||||
: null,
|
||||
},
|
||||
];
|
||||
const { market } = useMarket();
|
||||
|
||||
async function onSettleFunds() {
|
||||
return await settleFunds({
|
||||
|
@ -113,7 +65,7 @@ export default function BalancesTable() {
|
|||
return (
|
||||
<DataTable
|
||||
emptyLabel="No balances"
|
||||
dataSource={dataSource}
|
||||
dataSource={balances}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useMarket, useOpenOrders } from '../../utils/markets';
|
||||
import { useMarket } from '../../utils/markets';
|
||||
import DataTable from '../layout/DataTable';
|
||||
|
||||
import styled from 'styled-components';
|
||||
|
@ -15,15 +15,13 @@ const CancelButton = styled(Button)`
|
|||
border: 1px solid #f23b69;
|
||||
`;
|
||||
|
||||
export default function OpenOrderTable() {
|
||||
export default function OpenOrderTable({ openOrders }) {
|
||||
let { market } = useMarket();
|
||||
let [, wallet] = useWallet();
|
||||
let connection = useConnection();
|
||||
|
||||
const [cancelId, setCancelId] = useState(null);
|
||||
|
||||
const openOrders = useOpenOrders();
|
||||
|
||||
async function cancel(order) {
|
||||
try {
|
||||
await cancelOrder({
|
||||
|
|
|
@ -4,6 +4,7 @@ import React from 'react';
|
|||
import { Tabs } from 'antd';
|
||||
import FillsTable from './FillsTable';
|
||||
import FloatingElement from '../layout/FloatingElement';
|
||||
import { useOpenOrders, useBalances } from '../../utils/markets';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
|
@ -12,15 +13,27 @@ export default function Index() {
|
|||
<FloatingElement style={{ flex: 1, paddingTop: 10 }}>
|
||||
<Tabs defaultActiveKey="orders">
|
||||
<TabPane tab="Open Orders" key="orders">
|
||||
<OpenOrderTable />
|
||||
<OpenOrdersTab />
|
||||
</TabPane>
|
||||
<TabPane tab="Trade History" key="fills">
|
||||
<FillsTable />
|
||||
</TabPane>
|
||||
<TabPane tab="Balances" key="balances">
|
||||
<BalancesTable />
|
||||
<BalancesTab />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</FloatingElement>
|
||||
);
|
||||
}
|
||||
|
||||
const OpenOrdersTab = () => {
|
||||
const openOrders = useOpenOrders();
|
||||
|
||||
return <OpenOrderTable openOrders={openOrders} />;
|
||||
};
|
||||
|
||||
const BalancesTab = () => {
|
||||
const balances = useBalances();
|
||||
|
||||
return <BalancesTable balances={balances} />;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
import { useBalances } from '../utils/markets';
|
||||
import FloatingElement from '../components/layout/FloatingElement';
|
||||
import BalancesTable from '../components/UserInfoTable/BalancesTable';
|
||||
|
||||
export default function BalancesPage() {
|
||||
const balances = useBalances();
|
||||
return (
|
||||
<FloatingElement style={{ flex: 1, paddingTop: 10 }}>
|
||||
<BalancesTable balances={balances} />
|
||||
</FloatingElement>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
import { useOpenOrdersForAllMarkets } from '../utils/markets';
|
||||
import FloatingElement from '../components/layout/FloatingElement';
|
||||
import OpenOrderTable from '../components/UserInfoTable/OpenOrderTable';
|
||||
|
||||
export default function OpenOrdersPage() {
|
||||
const [openOrders] = useOpenOrdersForAllMarkets();
|
||||
return (
|
||||
<FloatingElement style={{ flex: 1, paddingTop: 10 }}>
|
||||
<OpenOrderTable openOrders={openOrders} />
|
||||
</FloatingElement>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
import { HashRouter, Route } from 'react-router-dom';
|
||||
import TradePage from './pages/TradePage';
|
||||
import OpenOrdersPage from './pages/OpenOrdersPage';
|
||||
import React from 'react';
|
||||
import { Layout } from 'antd';
|
||||
import TopBar from './components/TopBar';
|
||||
import CustomFooter from './components/Footer';
|
||||
import BalancesPage from './pages/BalancesPage';
|
||||
|
||||
const { Header, Content } = Layout;
|
||||
|
||||
export function Routes() {
|
||||
return (
|
||||
<HashRouter basename={'/'}>
|
||||
<Route exact path="/" component={TradePageContents} />
|
||||
<Route exact path="/orders" component={OpenOrdersPageContents} />
|
||||
<Route exact path="/balances" component={BalancesPageContents} />
|
||||
</HashRouter>
|
||||
);
|
||||
}
|
||||
|
||||
function TradePageContents() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Layout
|
||||
style={{ display: 'flex', minHeight: '100vh', flexDirection: 'column' }}
|
||||
>
|
||||
<Header style={{ padding: 0 }}>
|
||||
<TopBar />
|
||||
</Header>
|
||||
<Content style={{ flex: 1 }}>
|
||||
<TradePage />
|
||||
</Content>
|
||||
<CustomFooter />
|
||||
</Layout>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
function OpenOrdersPageContents() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Layout
|
||||
style={{ display: 'flex', minHeight: '100vh', flexDirection: 'column' }}
|
||||
>
|
||||
<Header style={{ padding: 0 }}>
|
||||
<TopBar />
|
||||
</Header>
|
||||
<Content style={{ flex: 1 }}>
|
||||
<OpenOrdersPage />
|
||||
</Content>
|
||||
<CustomFooter />
|
||||
</Layout>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
function BalancesPageContents() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Layout
|
||||
style={{ display: 'flex', minHeight: '100vh', flexDirection: 'column' }}
|
||||
>
|
||||
<Header style={{ padding: 0 }}>
|
||||
<TopBar />
|
||||
</Header>
|
||||
<Content style={{ flex: 1 }}>
|
||||
<BalancesPage />
|
||||
</Content>
|
||||
<CustomFooter />
|
||||
</Layout>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
|
@ -524,3 +524,54 @@ export function useOpenOrdersForAllMarkets() {
|
|||
{ refreshInterval: _SLOW_REFRESH_INTERVAL },
|
||||
);
|
||||
}
|
||||
|
||||
export function useBalances() {
|
||||
const [baseCurrencyBalances] = useBaseCurrencyBalances();
|
||||
const [quoteCurrencyBalances] = useQuoteCurrencyBalances();
|
||||
const openOrdersAccount = useSelectedOpenOrdersAccount(true);
|
||||
const { baseCurrency, quoteCurrency, market } = useMarket();
|
||||
const baseExists =
|
||||
openOrdersAccount &&
|
||||
openOrdersAccount.baseTokenTotal &&
|
||||
openOrdersAccount.baseTokenFree;
|
||||
const quoteExists =
|
||||
openOrdersAccount &&
|
||||
openOrdersAccount.quoteTokenTotal &&
|
||||
openOrdersAccount.quoteTokenFree;
|
||||
return [
|
||||
{
|
||||
key: baseCurrency,
|
||||
coin: baseCurrency,
|
||||
wallet: baseCurrencyBalances,
|
||||
orders:
|
||||
baseExists && market
|
||||
? market.baseSplSizeToNumber(
|
||||
openOrdersAccount.baseTokenTotal.sub(
|
||||
openOrdersAccount.baseTokenFree,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
unsettled:
|
||||
baseExists && market
|
||||
? market.baseSplSizeToNumber(openOrdersAccount.baseTokenFree)
|
||||
: null,
|
||||
},
|
||||
{
|
||||
key: quoteCurrency,
|
||||
coin: quoteCurrency,
|
||||
wallet: quoteCurrencyBalances,
|
||||
orders:
|
||||
quoteExists && market
|
||||
? market.quoteSplSizeToNumber(
|
||||
openOrdersAccount.quoteTokenTotal.sub(
|
||||
openOrdersAccount.quoteTokenFree,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
unsettled:
|
||||
quoteExists && market
|
||||
? market.quoteSplSizeToNumber(openOrdersAccount.quoteTokenFree)
|
||||
: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue