Skip to content

Commit

Permalink
requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
pldespaigne committed Sep 5, 2023
1 parent f7f69d2 commit 87a50ca
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 141 deletions.
58 changes: 46 additions & 12 deletions packages/app/src/pages/dashboard/history.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import Head from 'next/head'
import { ReactNode, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'

import UploadIcon from 'assets/svg/futures/upload-icon.svg'
import { FlexDivCol, FlexDivRowCentered } from 'components/layout/flex'
import { MobileHiddenView, MobileOnlyView } from 'components/Media'
import Pill from 'components/Pill'
import Spacer from 'components/Spacer'
import { Body, Heading } from 'components/Text'
import DashboardLayout from 'sections/dashboard/DashboardLayout'
import HistoryTabs, { HistoryTab } from 'sections/dashboard/HistoryTabs'
import TradesTab from 'sections/futures/MobileTrade/UserTabs/TradesTab'
import { usePollDashboardFuturesData } from 'state/futures/hooks'
import { selectCsvExport } from 'state/futures/selectors'
import { selectPositionsCsvData, selectTradesCsvData } from 'state/futures/selectors'
import { useAppSelector } from 'state/hooks'

type HistoryPageProps = React.FC & { getLayout: (page: ReactNode) => JSX.Element }
Expand All @@ -21,6 +21,8 @@ const HistoryPage: HistoryPageProps = () => {
const { t } = useTranslation()

usePollDashboardFuturesData()
const tradesCsvData = useAppSelector(selectTradesCsvData)
const positionsCsvData = useAppSelector(selectPositionsCsvData)

const [currentTab, setCurrentTab] = useState(HistoryTab.Positions)

Expand All @@ -31,8 +33,13 @@ const HistoryPage: HistoryPageProps = () => {
[]
)

const csvData = useAppSelector(selectCsvExport)
const file = useMemo(() => `data:text/csv;base64,${btoa(csvData)}`, [csvData])
const file = useMemo(
() =>
`data:text/csv;base64,${btoa(
currentTab === HistoryTab.Positions ? positionsCsvData : tradesCsvData
)}`,
[currentTab, positionsCsvData, tradesCsvData]
)
const fileName = useMemo(
() => (currentTab === HistoryTab.Positions ? 'positions-history.csv' : 'trades-history.csv'),
[currentTab]
Expand All @@ -44,19 +51,16 @@ const HistoryPage: HistoryPageProps = () => {
<title>{t('dashboard-history.page-title')}</title>
</Head>
<MobileHiddenView>
<Spacer height={15} />
<FlexDivRowCentered>
<FlexDivCol>
<Heading variant="h3">{t('dashboard-history.main-title')}</Heading>
<Body color={'secondary'}>{t('dashboard-history.subtitle')}</Body>
</FlexDivCol>
<a href={file} download={fileName}>
<Pill size="large">
<FlexDivRowCentered columnGap="8px">
<span>{t('dashboard-history.export-btn')}</span>
<UploadIcon width={8} style={{ 'margin-bottom': '2px' }} />
</FlexDivRowCentered>
</Pill>
</a>
<ExportButton href={file} download={fileName}>
<span>{t('dashboard-history.export-btn')}</span>
<UploadIcon width={8} style={{ 'margin-bottom': '2px' }} />
</ExportButton>
</FlexDivRowCentered>
<Spacer height={30} />
<HistoryTabs onChangeTab={handleChangeTab} currentTab={currentTab} />
Expand All @@ -69,6 +73,36 @@ const HistoryPage: HistoryPageProps = () => {
)
}

const ExportButton = styled.a`
gap: 8px;
height: 36px;
display: flex;
font-size: 12px;
font-weight: 700;
padding: 10px 15px;
border-radius: 50px;
font-family: ${(props) => props.theme.fonts.regular};
color: ${(props) => props.theme.colors.selectedTheme.newTheme.pill.gray.text};
background: ${(props) => props.theme.colors.selectedTheme.newTheme.pill.gray.background};
svg {
width: 10px;
path {
fill: ${(props) => props.theme.colors.selectedTheme.newTheme.pill.gray.text};
}
}
&:hover {
color: ${(props) => props.theme.colors.selectedTheme.newTheme.pill.gray.hover.text};
background: ${(props) => props.theme.colors.selectedTheme.newTheme.pill.gray.hover.background};
svg {
path {
fill: ${(props) => props.theme.colors.selectedTheme.newTheme.pill.gray.hover.text};
}
}
}
`

HistoryPage.getLayout = (page) => <DashboardLayout>{page}</DashboardLayout>

export default HistoryPage
4 changes: 2 additions & 2 deletions packages/app/src/sections/dashboard/HistoryTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { TabPanel } from 'components/Tab'
import TraderHistory from 'sections/futures/TraderHistory'
import Trades from 'sections/futures/Trades'
import { fetchPositionHistoryForTrader } from 'state/futures/actions'
import { selectUsersPositionHistory } from 'state/futures/selectors'
import { selectPositionsHistoryTableData } from 'state/futures/selectors'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { selectWallet } from 'state/wallet/selectors'
import media from 'styles/media'
Expand All @@ -26,7 +26,7 @@ const HistoryTabs: React.FC<HistoryTabsProp> = ({ currentTab, onChangeTab }) =>
const { t } = useTranslation()
const dispatch = useAppDispatch()
const walletAddress = useAppSelector(selectWallet)
const positionHistory = useAppSelector(selectUsersPositionHistory)
const positionHistory = useAppSelector(selectPositionsHistoryTableData)

useEffect(() => {
dispatch(fetchPositionHistoryForTrader(walletAddress ?? ''))
Expand Down
83 changes: 21 additions & 62 deletions packages/app/src/sections/futures/TraderHistory.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { ZERO_WEI } from '@kwenta/sdk/constants'
import { FuturesPositionHistory } from '@kwenta/sdk/dist/types'
import { getMarketName, MarketKeyByAsset } from '@kwenta/sdk/utils'
import { wei, WeiSource } from '@synthetixio/wei'
import { FuturesMarketKey, FuturesPositionHistory } from '@kwenta/sdk/dist/types'
import Wei, { wei, WeiSource } from '@synthetixio/wei'
import router from 'next/router'
import { FC, memo, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
Expand All @@ -15,17 +13,26 @@ import Table, { TableHeader, TableNoResults } from 'components/Table'
import { Body } from 'components/Text'
import ROUTES from 'constants/routes'
import TimeDisplay from 'sections/futures/Trades/TimeDisplay'
import { setCsvExportData } from 'state/futures/reducer'
import { selectFuturesPositions, selectQueryStatuses } from 'state/futures/selectors'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { selectQueryStatuses } from 'state/futures/selectors'
import { useAppSelector } from 'state/hooks'
import { FetchStatus } from 'state/types'
import { ExternalLink } from 'styles/common'
import media from 'styles/media'

type PositionData = FuturesPositionHistory & {
rank: number
currencyIconKey: FuturesMarketKey
marketShortName: string
status: string
funding: Wei
pnl: Wei
pnlPct: string
}

type TraderHistoryProps = {
trader: string
traderEns?: string | null
positionHistory: FuturesPositionHistory[]
positionHistory: PositionData[]
resetSelection: () => void
compact?: boolean
searchTerm?: string | undefined
Expand All @@ -34,64 +41,16 @@ type TraderHistoryProps = {
const TraderHistory: FC<TraderHistoryProps> = memo(
({ trader, traderEns, positionHistory, resetSelection, compact, searchTerm }) => {
const { t } = useTranslation()
const dispatch = useAppDispatch()
const positions = useAppSelector(selectFuturesPositions)
const { selectedTraderPositionHistory: queryStatus } = useAppSelector(selectQueryStatuses)

let data = useMemo(() => {
const result = positionHistory
.sort((a, b) => b.timestamp - a.timestamp)
.map((stat, i) => {
const totalDeposit = stat.initialMargin.add(stat.totalDeposits)
const thisPosition = stat.isOpen
? positions.find((p) => p.market.marketKey === stat.marketKey)
: null

const funding = stat.netFunding.add(
thisPosition?.activePosition?.accruedFunding ?? ZERO_WEI
)
const pnlWithFeesPaid = stat.pnl.sub(stat.feesPaid).add(funding)

return {
...stat,
rank: i + 1,
currencyIconKey: MarketKeyByAsset[stat.asset],
marketShortName: getMarketName(stat.asset),
status: stat.isOpen ? 'Open' : stat.isLiquidated ? 'Liquidated' : 'Closed',
funding,
pnl: pnlWithFeesPaid,
pnlPct: totalDeposit.gt(0)
? `(${pnlWithFeesPaid
.div(stat.initialMargin.add(stat.totalDeposits))
.mul(100)
.toNumber()
.toFixed(2)}%)`
: '0%',
}
})
.filter((i) =>
searchTerm?.length
? i.marketShortName.toLowerCase().includes(searchTerm) ||
i.status.toLowerCase().includes(searchTerm)
: true
)

// export data to CSV
let csvData =
'Date/Time,Market,Status,Trades,Total Volume,Realized P&L USD,Realized P&L %,Funding,Tx Hash\n'
result.forEach(
(row: (typeof result)[number]) =>
(csvData += `${new Date(row.timestamp).toISOString()},${row.marketShortName},${
row.status
},${row.trades},${row.totalVolume.toNumber()},${row.pnl.toNumber()},${row.pnlPct.slice(
1,
-2
)},${row.funding.toNumber()},${row.transactionHash}\n`)
return positionHistory.filter((i) =>
searchTerm?.length
? i.marketShortName.toLowerCase().includes(searchTerm) ||
i.status.toLowerCase().includes(searchTerm)
: true
)
dispatch(setCsvExportData(csvData))

return result
}, [dispatch, positionHistory, positions, searchTerm])
}, [positionHistory, searchTerm])

return (
<>
Expand Down
58 changes: 8 additions & 50 deletions packages/app/src/sections/futures/Trades/Trades.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatDollars, formatNumber, getDisplayAsset } from '@kwenta/sdk/utils'
import { formatDollars, formatNumber } from '@kwenta/sdk/utils'
import { useRouter } from 'next/router'
import { FC, memo, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
Expand All @@ -14,14 +14,15 @@ import { blockExplorer } from 'containers/Connector/Connector'
import useIsL2 from 'hooks/useIsL2'
import useNetworkSwitcher from 'hooks/useNetworkSwitcher'
import useWindowSize from 'hooks/useWindowSize'
import { selectFuturesType, selectMarketAsset } from 'state/futures/common/selectors'
import { setCsvExportData } from 'state/futures/reducer'
import { selectAllTradesForAccountType } from 'state/futures/selectors'
import { selectFuturesType } from 'state/futures/common/selectors'
import {
selectAllTradesForAccountType,
selectTradesHistoryTableData,
} from 'state/futures/selectors'
import { selectSmartMarginQueryStatuses } from 'state/futures/smartMargin/selectors'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { useAppSelector } from 'state/hooks'
import { FetchStatus } from 'state/types'

import { TradeStatus } from '../types'
import TableMarketDetails from '../UserInfo/TableMarketDetails'

import TimeDisplay from './TimeDisplay'
Expand All @@ -32,62 +33,19 @@ type TradesProps = {
}
const Trades: FC<TradesProps> = memo(({ rounded = false, noBottom = true }) => {
const { t } = useTranslation()
const dispatch = useAppDispatch()
const { switchToL2 } = useNetworkSwitcher()
const router = useRouter()
const { lessThanWidth } = useWindowSize()
const marketAsset = useAppSelector(selectMarketAsset)
const accountType = useAppSelector(selectFuturesType)
const history = useAppSelector(selectAllTradesForAccountType)
const historyData = useAppSelector(selectTradesHistoryTableData)

Check warning on line 41 in packages/app/src/sections/futures/Trades/Trades.tsx

View check run for this annotation

Codecov / codecov/patch

packages/app/src/sections/futures/Trades/Trades.tsx#L41

Added line #L41 was not covered by tests
const { trades } = useAppSelector(selectSmartMarginQueryStatuses)

const isLoading = !history.length && trades.status === FetchStatus.Loading
const isLoaded = trades.status === FetchStatus.Success

const isL2 = useIsL2()

const historyData = useMemo(() => {
dispatch(setCsvExportData('TRADES')) // TODO save csv string
let result = history.map((trade) => {
const pnl = trade?.pnl
const feesPaid = trade?.feesPaid
const netPnl = pnl.sub(feesPaid)

return {
...trade,
pnl,
feesPaid,
netPnl,
notionalValue: trade?.price.mul(trade?.size.abs()),
value: Number(trade?.price),
funding: Number(trade?.fundingAccrued),
amount: trade?.size.abs(),
time: trade?.timestamp * 1000,
id: trade?.txnHash,
asset: marketAsset,
displayAsset: getDisplayAsset(trade?.asset),
type: trade?.orderType,
status: trade?.positionClosed ? TradeStatus.CLOSED : TradeStatus.OPEN,
}
})

// export data to CSV
let csvData = 'Market,Side,Date/Time,Asset Price,Type,Amount,Value,PnL USD,Fees,Tx Hash\n'
result.forEach(
(row: (typeof result)[number]) =>
(csvData += `${row.displayAsset},${row.side},${new Date(
row.time
).toISOString()},${row.price.toNumber()},${
row.orderType
},${row.amount.toNumber()},${row.notionalValue.toNumber()},${row.netPnl.toNumber()},${row.feesPaid.toNumber()},${
row.id
}\n`)
)
dispatch(setCsvExportData(csvData))

return result
}, [dispatch, history, marketAsset])

const columnsDeps = useMemo(() => [historyData], [historyData])

return lessThanWidth('xl') ? (
Expand Down
7 changes: 2 additions & 5 deletions packages/app/src/sections/leaderboard/Leaderboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ import useENS from 'hooks/useENS'
import { CompetitionBanner } from 'sections/shared/components/CompetitionBanner'
import { fetchPositionHistoryForTrader } from 'state/futures/actions'
import { setSelectedTrader } from 'state/futures/reducer'
import {
selectPositionHistoryForSelectedTrader,
selectSelectedTrader,
} from 'state/futures/selectors'
import { selectLeaderBoardTableData, selectSelectedTrader } from 'state/futures/selectors'
import { useAppDispatch, useAppSelector, useFetchAction } from 'state/hooks'
import { fetchLeaderboard } from 'state/stats/actions'
import { setLeaderboardSearchTerm } from 'state/stats/reducer'
Expand Down Expand Up @@ -57,7 +54,7 @@ const Leaderboard: FC<LeaderboardProps> = ({ compact, mobile }) => {
const [searchAddress, setSearchAddress] = useState('')
const wallet = useAppSelector(selectWallet)
const selectedTrader = useAppSelector(selectSelectedTrader)
const positionHistory = useAppSelector(selectPositionHistoryForSelectedTrader)
const positionHistory = useAppSelector(selectLeaderBoardTableData)
const searchEns = useENS(searchTerm)

const leaderboardLoading = useAppSelector(selectLeaderboardLoading)
Expand Down
5 changes: 0 additions & 5 deletions packages/app/src/state/futures/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export const FUTURES_INITIAL_STATE: FuturesState = {
queryStatuses: {
selectedTraderPositionHistory: DEFAULT_QUERY_STATUS,
},
csvExport: '',
}

const futuresSlice = createSlice({
Expand Down Expand Up @@ -72,9 +71,6 @@ const futuresSlice = createSlice({
setHistoricalFundingRatePeriod: (state, action: PayloadAction<Period>) => {
state.historicalFundingRatePeriod = action.payload
},
setCsvExportData: (state, action: PayloadAction<string>) => {
state.csvExport = action.payload
},
},

extraReducers(builder) {
Expand Down Expand Up @@ -111,5 +107,4 @@ export const {
toggleShowTradeHistory,
setSelectedChart,
setHistoricalFundingRatePeriod,
setCsvExportData,
} = futuresSlice.actions
Loading

0 comments on commit 87a50ca

Please sign in to comment.