Merge remote-tracking branch 'origin/table-styling' into main
This commit is contained in:
commit
7b8035e960
|
@ -4,6 +4,7 @@ import { settleAll } from '../utils/mango'
|
|||
import useConnection from '../hooks/useConnection'
|
||||
import Button from '../components/Button'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
|
||||
|
||||
const BalancesTable = () => {
|
||||
const balances = useBalances()
|
||||
|
@ -49,8 +50,14 @@ const BalancesTable = () => {
|
|||
<div className={`flex flex-col py-6`}>
|
||||
<div className={`-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8`}>
|
||||
<div className={`align-middle inline-block min-w-full sm:px-6 lg:px-8`}>
|
||||
{balances.length ? (
|
||||
<div className={`text-right`}>
|
||||
{balances.length &&
|
||||
balances.find((balance) => balance.unsettled > 0) ? (
|
||||
<div
|
||||
className={`flex items-center justify-center p-4 mb-2 rounded-md bg-th-bkg-1`}
|
||||
>
|
||||
<div className="text-fgd-1 font-semibold pr-4">
|
||||
You have an unsettled balance
|
||||
</div>
|
||||
<Button onClick={handleSettleAll}>Settle All</Button>
|
||||
</div>
|
||||
) : null}
|
||||
|
@ -58,89 +65,89 @@ const BalancesTable = () => {
|
|||
<div
|
||||
className={`overflow-hidden border-b border-th-bkg-2 sm:rounded-md`}
|
||||
>
|
||||
<table className={`min-w-full divide-y divide-th-bkg-2`}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
<Table className={`min-w-full divide-y divide-th-bkg-2`}>
|
||||
<Thead>
|
||||
<Tr className="text-th-fgd-3">
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Coin
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Deposits
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Borrows
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
In Orders
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Unsettled
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Net
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{balances.map((balance, index) => (
|
||||
<tr
|
||||
<Tr
|
||||
key={`${index}`}
|
||||
className={`
|
||||
${index % 2 === 0 ? `bg-th-bkg-1` : `bg-th-bkg-3`}
|
||||
className={`border-b border-th-bkg-3
|
||||
${index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
|
||||
`}
|
||||
>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{balance.coin}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{balance.marginDeposits}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{balance.borrows}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{balance.orders}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{balance.unsettled}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{balance.net}
|
||||
</td>
|
||||
</tr>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
|
|
|
@ -156,7 +156,7 @@ export default function MarginInfo() {
|
|||
<div className={`flex justify-between pt-2 pb-2`} key={i}>
|
||||
<Tooltip content={entry.desc}>
|
||||
<div
|
||||
className={`cursor-help text-th-fgd-4 border-b border-th-fgd-4 border-dashed border-opacity-20 leading-4 default-transition hover:border-th-bkg-2 hover:text-th-fgd-3`}
|
||||
className={`cursor-help font-normal text-th-fgd-4 border-b border-th-fgd-4 border-dashed border-opacity-20 leading-4 default-transition hover:border-th-bkg-2 hover:text-th-fgd-3`}
|
||||
>
|
||||
{entry.label}
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from 'react'
|
||||
import { TrashIcon } from '@heroicons/react/solid'
|
||||
import { TrashIcon } from '@heroicons/react/outline'
|
||||
import { useOpenOrders } from '../hooks/useOpenOrders'
|
||||
import { cancelOrderAndSettle } from '../utils/mango'
|
||||
import Button from './Button'
|
||||
|
@ -8,6 +8,8 @@ import { PublicKey } from '@solana/web3.js'
|
|||
import useConnection from '../hooks/useConnection'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
|
||||
import SideBadge from './SideBadge'
|
||||
|
||||
const OpenOrdersTable = () => {
|
||||
const openOrders = useOpenOrders()
|
||||
|
@ -54,89 +56,83 @@ const OpenOrdersTable = () => {
|
|||
<div
|
||||
className={`shadow overflow-hidden border-b border-th-bkg-2 sm:rounded-md`}
|
||||
>
|
||||
<table className={`min-w-full divide-y divide-th-bkg-2`}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
<Table className={`min-w-full divide-y divide-th-bkg-2`}>
|
||||
<Thead>
|
||||
<Tr className="text-th-fgd-3">
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Market
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Side
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Size
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Price
|
||||
</th>
|
||||
<th scope="col" className={`relative px-6 py-3`}>
|
||||
</Th>
|
||||
<Th scope="col" className={`relative px-6 py-3`}>
|
||||
<span className={`sr-only`}>Edit</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{openOrders.map((order, index) => (
|
||||
<tr
|
||||
<Tr
|
||||
key={`${order.orderId}${order.side}`}
|
||||
className={`
|
||||
${index % 2 === 0 ? `bg-th-bkg-1` : `bg-th-bkg-3`}
|
||||
className={`border-b border-th-bkg-3
|
||||
${index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
|
||||
`}
|
||||
>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{order.marketName}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
<div
|
||||
className={`rounded inline-block bg-mango-green px-2 py-1 text-mango-dark font-bold`}
|
||||
>
|
||||
{order.side.toUpperCase()}
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
|
||||
<SideBadge side={order.side} />
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{order.size}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2 font-light`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{order.price}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 opacity-75 whitespace-nowrap text-right text-sm font-medium`}
|
||||
>
|
||||
</Td>
|
||||
<Td className={`px-6 py-4 whitespace-nowrap text-left`}>
|
||||
<Button
|
||||
onClick={() => handleCancelOrder(order)}
|
||||
className={`flex items-center ml-auto rounded text-th-red border border-th-red hover:text-th-red hover:border-th-red py-1`}
|
||||
className={`flex items-center md:ml-auto px-2 py-1 text-xs`}
|
||||
>
|
||||
{cancelId + '' === order?.orderId + '' ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<TrashIcon className={`h-5 w-5 mr-1`} />
|
||||
<TrashIcon className={`h-4 w-4 mr-1`} />
|
||||
)}
|
||||
<span>Cancel Order</span>
|
||||
<span>Cancel</span>
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import React, { FunctionComponent } from 'react'
|
||||
|
||||
type SideBadgeProps = {
|
||||
side: string
|
||||
}
|
||||
|
||||
const SideBadge: FunctionComponent<SideBadgeProps> = ({ side }) => {
|
||||
return (
|
||||
<div
|
||||
className={`rounded-md inline-block ${
|
||||
side === 'buy'
|
||||
? 'border border-th-green text-th-green'
|
||||
: 'border border-th-red text-th-red'
|
||||
}
|
||||
px-2 py-1 text-xs`}
|
||||
>
|
||||
{side.toUpperCase()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SideBadge
|
|
@ -310,7 +310,7 @@ export default function TradeForm() {
|
|||
<Button
|
||||
disabled={disabledTradeButton}
|
||||
onClick={onSubmit}
|
||||
className={`rounded ${
|
||||
className={`${
|
||||
!disabledTradeButton &&
|
||||
'border-th-green hover:border-th-green-dark'
|
||||
} text-th-green hover:text-th-fgd-1 hover:bg-th-green-dark flex-grow`}
|
||||
|
@ -321,7 +321,7 @@ export default function TradeForm() {
|
|||
<Button
|
||||
disabled={disabledTradeButton}
|
||||
onClick={onSubmit}
|
||||
className={`rounded ${
|
||||
className={`${
|
||||
!disabledTradeButton &&
|
||||
'border-th-red hover:border-th-red-dark'
|
||||
} text-th-red hover:text-th-fgd-1 hover:bg-th-red-dark flex-grow`}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import useTradeHistory from '../hooks/useTradeHistory'
|
||||
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
|
||||
import SideBadge from './SideBadge'
|
||||
// import useMangoStore from '../stores/useMangoStore'
|
||||
// import Loading from './Loading'
|
||||
|
||||
|
@ -14,111 +16,102 @@ const TradeHistoryTable = () => {
|
|||
<div
|
||||
className={`shadow overflow-hidden border-b border-th-bkg-2 sm:rounded-md`}
|
||||
>
|
||||
<table className={`min-w-full divide-y divide-th-bkg-2`}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
<Table className={`min-w-full divide-y divide-th-bkg-2`}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Market
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Side
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Size
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Price
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Liquidity
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Fees
|
||||
</th>
|
||||
<th
|
||||
</Th>
|
||||
<Th
|
||||
scope="col"
|
||||
className={`px-6 py-3 text-left text-base font-medium text-th-fgd-2 tracking-wider`}
|
||||
className={`px-6 py-3 text-left font-normal`}
|
||||
>
|
||||
Date
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{tradeHistory.map((trade, index) => (
|
||||
<tr
|
||||
<Tr
|
||||
key={`${trade.orderId}${trade.side}${trade.uuid}`}
|
||||
className={`
|
||||
className={`border-b border-th-bkg-3
|
||||
${index % 2 === 0 ? `bg-th-bkg-3` : `bg-th-bkg-2`}
|
||||
`}
|
||||
>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{trade.marketName}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
<div
|
||||
className={`rounded inline-block ${
|
||||
trade.side === 'buy'
|
||||
? 'bg-th-green text-th-bkg-1'
|
||||
: 'bg-th-red text-white'
|
||||
}
|
||||
px-2 py-1 font-bold`}
|
||||
>
|
||||
{trade.side.toUpperCase()}
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
<SideBadge side={trade.side} />
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{trade.size}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{trade.price}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{trade.liquidity}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{trade.feeCost}
|
||||
</td>
|
||||
<td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-2`}
|
||||
</Td>
|
||||
<Td
|
||||
className={`px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1`}
|
||||
>
|
||||
{trade.loadTimestamp
|
||||
? new Date(trade.loadTimestamp).toLocaleDateString()
|
||||
: 'Recent'}
|
||||
</td>
|
||||
</tr>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
"react-dom": "^17.0.1",
|
||||
"react-grid-layout": "^1.2.4",
|
||||
"react-portal": "^4.2.1",
|
||||
"react-super-responsive-table": "^5.2.0",
|
||||
"recharts": "^2.0.9",
|
||||
"zustand": "^3.3.3"
|
||||
},
|
||||
|
|
238
pages/stats.tsx
238
pages/stats.tsx
|
@ -1,15 +1,13 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import styled from '@emotion/styled'
|
||||
import { LineChart, Line, ReferenceLine, XAxis, YAxis, Tooltip } from 'recharts'
|
||||
import useDimensions from 'react-cool-dimensions'
|
||||
import { IDS, MangoClient } from '@blockworks-foundation/mango-client'
|
||||
import { PublicKey, Connection } from '@solana/web3.js'
|
||||
import { DEFAULT_MANGO_GROUP } from '../utils/mango'
|
||||
import FloatingElement from '../components/FloatingElement'
|
||||
import useConnection from '../hooks/useConnection'
|
||||
import TopBar from '../components/TopBar'
|
||||
import Select from '../components/Select'
|
||||
import { formatBalanceDisplay } from '../utils/index'
|
||||
import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table'
|
||||
|
||||
const DECIMALS = {
|
||||
BTC: 4,
|
||||
|
@ -27,20 +25,6 @@ const icons = {
|
|||
WUSDT: '/assets/icons/usdt.svg',
|
||||
}
|
||||
|
||||
const ChartLayover = styled.div`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: #525a6a;
|
||||
`
|
||||
|
||||
const ChartWrapper = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
const useMangoStats = () => {
|
||||
const [stats, setStats] = useState([
|
||||
{
|
||||
|
@ -119,25 +103,22 @@ const StatsChart = ({ title, xAxis, yAxis, data, labelFormat }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<ChartWrapper ref={observe}>
|
||||
<ChartLayover>
|
||||
<div>
|
||||
<strong>
|
||||
{title}
|
||||
{mouseData ? `: ${labelFormat(mouseData[yAxis])}` : null}
|
||||
</strong>
|
||||
<div className="h-full w-full" ref={observe}>
|
||||
<div className="absolute -top-4 left-0 h-full w-full pb-4">
|
||||
<div className="text-center text-th-fgd-1 text-base font-semibold">
|
||||
{title}
|
||||
</div>
|
||||
{mouseData ? (
|
||||
<div>
|
||||
<strong>
|
||||
Date
|
||||
{mouseData
|
||||
? `: ${new Date(mouseData[xAxis]).toDateString()}`
|
||||
: null}
|
||||
</strong>
|
||||
<div className="text-center pt-1">
|
||||
<div className="text-sm font-normal text-th-fgd-3">
|
||||
{labelFormat(mouseData[yAxis])}
|
||||
</div>
|
||||
<div className="text-xs font-normal text-th-fgd-4">
|
||||
{new Date(mouseData[xAxis]).toDateString()}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</ChartLayover>
|
||||
</div>
|
||||
{width > 0 ? (
|
||||
<LineChart
|
||||
width={width}
|
||||
|
@ -176,7 +157,7 @@ const StatsChart = ({ title, xAxis, yAxis, data, labelFormat }) => {
|
|||
<YAxis dataKey={yAxis} hide />
|
||||
</LineChart>
|
||||
) : null}
|
||||
</ChartWrapper>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -191,99 +172,116 @@ export default function StatsPage() {
|
|||
return (
|
||||
<div className={`bg-th-bkg-1 text-th-fgd-1 transition-all `}>
|
||||
<TopBar />
|
||||
<div className="min-h-screen w-full lg:w-2/3 mx-auto p-1 sm:px-2 sm:py-1 md:px-6 md:py-1">
|
||||
<FloatingElement className="h-auto">
|
||||
<div className="text-center">
|
||||
<h1 className={`text-th-fgd-1 text-3xl`}>Mango Stats</h1>
|
||||
</div>
|
||||
<div className="hidden md:flex md:flex-col min-w-full">
|
||||
<table className="min-w-full">
|
||||
<thead className="">
|
||||
<tr>
|
||||
<th scope="col" className="text-left py-4">
|
||||
Asset
|
||||
</th>
|
||||
<th scope="col" className="text-left py-4">
|
||||
Total Deposits
|
||||
</th>
|
||||
<th scope="col" className="text-left py-4">
|
||||
Total Borrows
|
||||
</th>
|
||||
<th scope="col" className="text-left py-4">
|
||||
Deposit Interest
|
||||
</th>
|
||||
<th scope="col" className="text-left py-4">
|
||||
Borrow Interest
|
||||
</th>
|
||||
<th scope="col" className="text-left py-4">
|
||||
Utilization
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-600">
|
||||
{latestStats.map((stat) => (
|
||||
<tr key={stat.symbol}>
|
||||
<td className="flex items-center text-left py-4">
|
||||
<img src={icons[stat.symbol]} alt={icons[stat.symbol]} />
|
||||
<div className="min-h-screen w-full xl:w-3/4 mx-auto px-4 sm:px-6 sm:py-1 md:px-8 md:py-1 lg:px-12">
|
||||
<div className="text-center pt-8 pb-6 md:pt-10">
|
||||
<h1 className={`text-th-fgd-1 text-2xl font-semibold`}>
|
||||
Mango Stats
|
||||
</h1>
|
||||
</div>
|
||||
<div className="md:flex md:flex-col min-w-full">
|
||||
<Table className="min-w-full divide-y divide-th-bkg-2">
|
||||
<Thead>
|
||||
<Tr className="text-th-fgd-3">
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
Asset
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
Total Deposits
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
Total Borrows
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
Deposit Interest
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
Borrow Interest
|
||||
</Th>
|
||||
<Th scope="col" className="px-6 py-3 text-left font-normal">
|
||||
Utilization
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{latestStats.map((stat, index) => (
|
||||
<Tr
|
||||
key={stat.symbol}
|
||||
className={`border-b border-th-bkg-2
|
||||
${index % 2 === 0 ? `bg-th-bkg-2` : `bg-th-bkg-1`}
|
||||
`}
|
||||
>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={icons[stat.symbol]}
|
||||
alt={icons[stat.symbol]}
|
||||
className="w-5 h-5 md:w-6 md:h-6"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setSelectedAsset(stat.symbol)}
|
||||
className="text-th-primary cursor-pointer ml-2"
|
||||
className="underline cursor-pointer ml-3 hover:text-th-primary hover:no-underline"
|
||||
>
|
||||
<div style={{ width: '100%' }}>{stat.symbol}</div>
|
||||
{stat.symbol}
|
||||
</button>
|
||||
</td>
|
||||
<td className="text-left py-4">
|
||||
{formatBalanceDisplay(
|
||||
stat.totalDeposits,
|
||||
DECIMALS[stat.symbol]
|
||||
).toLocaleString(undefined, {
|
||||
maximumFractionDigits: DECIMALS[stat.symbol],
|
||||
})}
|
||||
</td>
|
||||
<td className="text-left py-4">
|
||||
{formatBalanceDisplay(
|
||||
stat.totalBorrows,
|
||||
DECIMALS[stat.symbol]
|
||||
).toLocaleString(undefined, {
|
||||
maximumFractionDigits: DECIMALS[stat.symbol],
|
||||
})}
|
||||
</td>
|
||||
<td className="text-left py-4">
|
||||
{stat.depositInterest.toFixed(2)}%
|
||||
</td>
|
||||
<td className="text-left py-4">
|
||||
{stat.borrowInterest.toFixed(2)}%
|
||||
</td>
|
||||
<td className="text-left py-4">
|
||||
{(parseFloat(stat.utilization) * 100).toFixed(2)}%
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</FloatingElement>
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{formatBalanceDisplay(
|
||||
stat.totalDeposits,
|
||||
DECIMALS[stat.symbol]
|
||||
).toLocaleString(undefined, {
|
||||
maximumFractionDigits: DECIMALS[stat.symbol],
|
||||
})}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{formatBalanceDisplay(
|
||||
stat.totalBorrows,
|
||||
DECIMALS[stat.symbol]
|
||||
).toLocaleString(undefined, {
|
||||
maximumFractionDigits: DECIMALS[stat.symbol],
|
||||
})}
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{stat.depositInterest.toFixed(2)}%
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{stat.borrowInterest.toFixed(2)}%
|
||||
</Td>
|
||||
<Td className="px-6 py-4 whitespace-nowrap text-sm text-th-fgd-1">
|
||||
{(parseFloat(stat.utilization) * 100).toFixed(2)}%
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
{selectedAsset ? (
|
||||
<FloatingElement className="h-auto">
|
||||
<div className="flex justify-center text-2xl">
|
||||
<span className={`text-th-fgd-1`}>Historical</span>
|
||||
<Select
|
||||
className="mx-4 text-lg"
|
||||
value={selectedAsset}
|
||||
onChange={(val) => setSelectedAsset(val)}
|
||||
>
|
||||
{latestStats.map(({ symbol }) => (
|
||||
<Select.Option key={symbol} value={symbol}>
|
||||
{symbol}
|
||||
</Select.Option>
|
||||
<div className="py-10 md:py-14">
|
||||
<div className="flex flex-col items-center pb-12">
|
||||
<h2 className="text-th-fgd-1 text-center text-2xl font-semibold mb-4">
|
||||
Historical Stats
|
||||
</h2>
|
||||
<div className="flex self-center">
|
||||
{latestStats.map((stat) => (
|
||||
<div
|
||||
className={`px-2 py-1 mr-2 rounded-md cursor-pointer default-transition bg-th-bkg-3
|
||||
${
|
||||
selectedAsset === stat.symbol
|
||||
? `text-th-primary`
|
||||
: `text-th-fgd-1 opacity-50 hover:opacity-100`
|
||||
}
|
||||
`}
|
||||
onClick={() => setSelectedAsset(stat.symbol)}
|
||||
key={stat.symbol as string}
|
||||
>
|
||||
{stat.symbol}
|
||||
</div>
|
||||
))}
|
||||
</Select>
|
||||
<span className={`text-th-fgd-1`}>Stats</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col md:flex-row mt-2">
|
||||
<div className="flex flex-col md:flex-row pb-14">
|
||||
<div
|
||||
className="relative my-2 md:w-1/2"
|
||||
className="relative my-2 pb-14 md:pb-0 md:w-1/2"
|
||||
style={{ height: '300px' }}
|
||||
>
|
||||
<StatsChart
|
||||
|
@ -309,7 +307,7 @@ export default function StatsPage() {
|
|||
</div>
|
||||
<div className="flex flex-col md:flex-row">
|
||||
<div
|
||||
className="relative my-2 md:w-1/2"
|
||||
className="relative my-2 pb-14 md:pb-0 md:w-1/2"
|
||||
style={{ height: '300px' }}
|
||||
>
|
||||
<StatsChart
|
||||
|
@ -333,7 +331,7 @@ export default function StatsPage() {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</FloatingElement>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* Theme */
|
||||
|
||||
:root {
|
||||
--primary: theme('colors.light-theme.orange');
|
||||
--red: theme('colors.light-theme.red.DEFAULT');
|
||||
|
@ -47,19 +49,23 @@
|
|||
--fgd-4: theme('colors.mango-theme["fgd-4"]');
|
||||
}
|
||||
|
||||
/* Base */
|
||||
|
||||
body {
|
||||
@apply text-sm font-body tracking-wide;
|
||||
}
|
||||
|
||||
button {
|
||||
transition: all 0.3s ease;
|
||||
@apply font-semibold;
|
||||
@apply font-semibold rounded-md;
|
||||
}
|
||||
|
||||
.default-transition {
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
/* Chart */
|
||||
|
||||
.TVChartContainer {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
@ -69,6 +75,8 @@ button {
|
|||
display: contents;
|
||||
}
|
||||
|
||||
/* Grid */
|
||||
|
||||
.react-grid-item.react-grid-placeholder {
|
||||
background: var(--bkg-3);
|
||||
opacity: 90%;
|
||||
|
@ -114,6 +122,8 @@ input[type='number'] {
|
|||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
/* Scrollbars */
|
||||
|
||||
.thin-scroll {
|
||||
overflow: auto !important;
|
||||
overflow-x: hidden !important;
|
||||
|
@ -137,3 +147,70 @@ input[type='number'] {
|
|||
.thin-scroll::-webkit-scrollbar-corner {
|
||||
background-color: var(--bkg-3);
|
||||
}
|
||||
|
||||
/* Responsive table */
|
||||
|
||||
/* inspired by: https://css-tricks.com/responsive-data-tables/ */
|
||||
.responsiveTable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.responsiveTable td .tdBefore {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.responsiveTable table,
|
||||
.responsiveTable thead,
|
||||
.responsiveTable tbody,
|
||||
.responsiveTable th,
|
||||
.responsiveTable td,
|
||||
.responsiveTable tr {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.responsiveTable thead tr {
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
border-bottom: 2px solid #333;
|
||||
}
|
||||
|
||||
.responsiveTable tbody tr {
|
||||
@apply px-4;
|
||||
}
|
||||
|
||||
.responsiveTable td.pivoted {
|
||||
/* Behave like a "row" */
|
||||
@apply pb-1;
|
||||
position: relative;
|
||||
padding-left: calc(50% + 10px) !important;
|
||||
text-align: left !important;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.responsiveTable td.pivoted:last-child {
|
||||
/* Behave like a "row" */
|
||||
@apply pb-4;
|
||||
}
|
||||
|
||||
.responsiveTable td.pivoted:last-child {
|
||||
/* Behave like a "row" */
|
||||
@apply border-b-0;
|
||||
}
|
||||
|
||||
.responsiveTable td .tdBefore {
|
||||
/* Now like a table header */
|
||||
@apply text-th-fgd-3 font-normal;
|
||||
position: absolute;
|
||||
display: block;
|
||||
|
||||
/* Top/left values mimic padding */
|
||||
left: 1rem;
|
||||
width: calc(50% - 20px);
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue