reward history table, polish etc
This commit is contained in:
parent
340e124016
commit
7eae69137b
@ -41,7 +41,7 @@
|
||||
"@cosmjs/tendermint-rpc": "^0.31.0",
|
||||
"@dydxprotocol/v4-abacus": "^1.1.33",
|
||||
"@dydxprotocol/v4-client-js": "^1.0.11",
|
||||
"@dydxprotocol/v4-localization": "^1.1.6",
|
||||
"@dydxprotocol/v4-localization": "^1.1.7",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@js-joda/core": "^5.5.3",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -33,8 +33,8 @@ dependencies:
|
||||
specifier: ^1.0.11
|
||||
version: 1.0.11
|
||||
'@dydxprotocol/v4-localization':
|
||||
specifier: ^1.1.6
|
||||
version: 1.1.6
|
||||
specifier: ^1.1.7
|
||||
version: 1.1.7
|
||||
'@ethersproject/providers':
|
||||
specifier: ^5.7.2
|
||||
version: 5.7.2
|
||||
@ -1023,8 +1023,8 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@dydxprotocol/v4-localization@1.1.6:
|
||||
resolution: {integrity: sha512-Bon6NSRU4/FqneAbnP2G28EAPr0hp4LhvAayX61o0O1PGkxnLzAHkXeFppdM0Zn0fOcp1S1MJ+gvz138ZDephQ==}
|
||||
/@dydxprotocol/v4-localization@1.1.7:
|
||||
resolution: {integrity: sha512-pmRZTszmoee9Ml2v7E1wmIiaZCZpqQE66d/20I/xdnwwEIPt0iOriP59nlep+O/P1r9/Qxf/l+ZzvVbO720xjg==}
|
||||
dev: false
|
||||
|
||||
/@dydxprotocol/v4-proto@0.4.1:
|
||||
|
||||
@ -23,4 +23,4 @@ Accordion.args = {
|
||||
content: 'Answer 2.',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
@ -66,7 +66,6 @@ type ElementProps = {
|
||||
stripRelativeWords?: boolean;
|
||||
};
|
||||
timeOptions?: {
|
||||
format?: 'long' | 'short' | 'narrow' | 'singleCharacter';
|
||||
useUTC?: boolean;
|
||||
};
|
||||
tag?: React.ReactNode;
|
||||
|
||||
@ -44,6 +44,8 @@ import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { Icon, IconName } from './Icon';
|
||||
import { Tag } from './Tag';
|
||||
import { MustBigNumber } from '@/lib/numbers';
|
||||
import { Button } from './Button';
|
||||
import { CaretIcon } from '@/icons';
|
||||
|
||||
export { TableCell } from './Table/TableCell';
|
||||
export { TableColumnHeader } from './Table/TableColumnHeader';
|
||||
@ -92,6 +94,7 @@ type ElementProps<TableRowData extends object | CustomRowConfig, TableRowKey ext
|
||||
selectionBehavior?: 'replace' | 'toggle';
|
||||
onRowAction?: (key: TableRowKey, row: TableRowData) => void;
|
||||
slotEmpty?: React.ReactNode;
|
||||
initialNumRowsToShow?: number;
|
||||
// collection: TableCollection<string>;
|
||||
// children: React.ReactNode;
|
||||
};
|
||||
@ -121,6 +124,7 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
selectionMode = 'single',
|
||||
selectionBehavior = 'toggle',
|
||||
slotEmpty,
|
||||
initialNumRowsToShow = data.length,
|
||||
// shouldRowRender,
|
||||
|
||||
// collection,
|
||||
@ -136,6 +140,7 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
style,
|
||||
}: ElementProps<TableRowData, TableRowKey> & StyleProps) => {
|
||||
const [selectedKeys, setSelectedKeys] = useState(new Set<TableRowKey>());
|
||||
const [numRowsToShow, setNumRowsToShow] = useState(initialNumRowsToShow);
|
||||
|
||||
const currentBreakpoints = useBreakpoints();
|
||||
const shownColumns = columns.filter(
|
||||
@ -188,67 +193,77 @@ export const Table = <TableRowData extends object, TableRowKey extends Key>({
|
||||
const isEmpty = data.length === 0;
|
||||
|
||||
return (
|
||||
<Styled.TableWrapper
|
||||
className={className}
|
||||
style={style}
|
||||
isEmpty={isEmpty}
|
||||
withGradientCardRows={withGradientCardRows}
|
||||
withOuterBorder={withOuterBorder}
|
||||
>
|
||||
{!isEmpty ? (
|
||||
<TableRoot
|
||||
aria-label={label}
|
||||
sortDescriptor={list.sortDescriptor}
|
||||
onSortChange={list.sort}
|
||||
selectedKeys={selectedKeys}
|
||||
setSelectedKeys={setSelectedKeys}
|
||||
selectionMode={selectionMode}
|
||||
selectionBehavior={selectionBehavior}
|
||||
getRowAttributes={getRowAttributes}
|
||||
onRowAction={
|
||||
onRowAction &&
|
||||
((key: TableRowKey) => onRowAction(key, data.find((row) => getRowKey(row) === key)!))
|
||||
}
|
||||
// shouldRowRender={shouldRowRender}
|
||||
hideHeader={hideHeader}
|
||||
withGradientCardRows={withGradientCardRows}
|
||||
withFocusStickyRows={withFocusStickyRows}
|
||||
withOuterBorder={withOuterBorder}
|
||||
withInnerBorders={withInnerBorders}
|
||||
withScrollSnapColumns={withScrollSnapColumns}
|
||||
withScrollSnapRows={withScrollSnapRows}
|
||||
>
|
||||
<TableHeader columns={shownColumns}>
|
||||
{(column) => (
|
||||
<Column
|
||||
key={column.columnKey}
|
||||
childColumns={column.childColumns}
|
||||
allowsSorting={column.allowsSorting ?? true}
|
||||
allowsResizing={column.allowsResizing}
|
||||
width={column.width}
|
||||
>
|
||||
{column.label}
|
||||
{column.tag && <Tag>{column.tag}</Tag>}
|
||||
</Column>
|
||||
)}
|
||||
</TableHeader>
|
||||
<>
|
||||
<Styled.TableWrapper
|
||||
className={className}
|
||||
style={style}
|
||||
isEmpty={isEmpty}
|
||||
withGradientCardRows={withGradientCardRows}
|
||||
withOuterBorder={withOuterBorder}
|
||||
>
|
||||
{!isEmpty ? (
|
||||
<TableRoot
|
||||
aria-label={label}
|
||||
sortDescriptor={list.sortDescriptor}
|
||||
onSortChange={list.sort}
|
||||
selectedKeys={selectedKeys}
|
||||
setSelectedKeys={setSelectedKeys}
|
||||
selectionMode={selectionMode}
|
||||
selectionBehavior={selectionBehavior}
|
||||
getRowAttributes={getRowAttributes}
|
||||
onRowAction={
|
||||
onRowAction &&
|
||||
((key: TableRowKey) => onRowAction(key, data.find((row) => getRowKey(row) === key)!))
|
||||
}
|
||||
// shouldRowRender={shouldRowRender}
|
||||
hideHeader={hideHeader}
|
||||
withGradientCardRows={withGradientCardRows}
|
||||
withFocusStickyRows={withFocusStickyRows}
|
||||
withOuterBorder={withOuterBorder}
|
||||
withInnerBorders={withInnerBorders}
|
||||
withScrollSnapColumns={withScrollSnapColumns}
|
||||
withScrollSnapRows={withScrollSnapRows}
|
||||
>
|
||||
<TableHeader columns={shownColumns}>
|
||||
{(column) => (
|
||||
<Column
|
||||
key={column.columnKey}
|
||||
childColumns={column.childColumns}
|
||||
allowsSorting={column.allowsSorting ?? true}
|
||||
allowsResizing={column.allowsResizing}
|
||||
width={column.width}
|
||||
>
|
||||
{column.label}
|
||||
{column.tag && <Tag>{column.tag}</Tag>}
|
||||
</Column>
|
||||
)}
|
||||
</TableHeader>
|
||||
|
||||
<TableBody items={list.items}>
|
||||
{(item) => (
|
||||
<Row key={getRowKey(item)}>
|
||||
{(columnKey) => (
|
||||
<Cell key={`${getRowKey(item)}-${columnKey}`}>
|
||||
{columns.find((column) => column.columnKey === columnKey)?.renderCell?.(item)}
|
||||
</Cell>
|
||||
)}
|
||||
</Row>
|
||||
)}
|
||||
</TableBody>
|
||||
</TableRoot>
|
||||
) : (
|
||||
<Styled.Empty withOuterBorder={withOuterBorder}>{slotEmpty}</Styled.Empty>
|
||||
<TableBody items={list.items.slice(0, numRowsToShow)}>
|
||||
{(item) => (
|
||||
<Row key={getRowKey(item)}>
|
||||
{(columnKey) => (
|
||||
<Cell key={`${getRowKey(item)}-${columnKey}`}>
|
||||
{columns.find((column) => column.columnKey === columnKey)?.renderCell?.(item)}
|
||||
</Cell>
|
||||
)}
|
||||
</Row>
|
||||
)}
|
||||
</TableBody>
|
||||
</TableRoot>
|
||||
) : (
|
||||
<Styled.Empty withOuterBorder={withOuterBorder}>{slotEmpty}</Styled.Empty>
|
||||
)}
|
||||
</Styled.TableWrapper>
|
||||
{numRowsToShow !== undefined && numRowsToShow < data.length && (
|
||||
<Styled.ViewMoreButton
|
||||
onClick={() => setNumRowsToShow(data.length)}
|
||||
slotRight={<CaretIcon />}
|
||||
>
|
||||
View more
|
||||
</Styled.ViewMoreButton>
|
||||
)}
|
||||
</Styled.TableWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -922,3 +937,8 @@ Styled.Row = styled.div`
|
||||
${layoutMixins.inlineRow}
|
||||
padding: var(--tableCell-padding);
|
||||
`;
|
||||
|
||||
Styled.ViewMoreButton = styled(Button)`
|
||||
--button-backgroundColor: var(--color-layer-2);
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
@ -121,6 +121,11 @@ export type Wallet = Abacus.exchange.dydx.abacus.output.Wallet;
|
||||
export type AccountBalance = Abacus.exchange.dydx.abacus.output.AccountBalance;
|
||||
export type TradingRewards = Abacus.exchange.dydx.abacus.output.TradingRewards;
|
||||
export type HistoricalTradingReward = Abacus.exchange.dydx.abacus.output.HistoricalTradingReward;
|
||||
export const HistoricaTradingRewardsPeriod =
|
||||
Abacus.exchange.dydx.abacus.state.manager.HistoricaTradingRewardsPeriod;
|
||||
const historicalTradingRewardsPeriod = [...HistoricaTradingRewardsPeriod.values()] as const;
|
||||
export type HistoricaTradingRewardsPeriods = (typeof historicalTradingRewardsPeriod)[number];
|
||||
|
||||
export type Subaccount = Abacus.exchange.dydx.abacus.output.Subaccount;
|
||||
export type SubaccountPosition = Abacus.exchange.dydx.abacus.output.SubaccountPosition;
|
||||
export type SubaccountOrder = Abacus.exchange.dydx.abacus.output.SubaccountOrder;
|
||||
@ -238,6 +243,16 @@ export const HISTORICAL_PNL_PERIODS: Record<
|
||||
[HistoricalPnlPeriod.Period90d.name]: HistoricalPnlPeriod.Period90d,
|
||||
};
|
||||
|
||||
export const HISTORICAL_TRADING_REWARDS_PERIODS: Record<
|
||||
KotlinIrEnumValues<typeof HistoricaTradingRewardsPeriod>,
|
||||
HistoricaTradingRewardsPeriods
|
||||
> = {
|
||||
[HistoricaTradingRewardsPeriod.MONTHLY.name]: HistoricaTradingRewardsPeriod.MONTHLY,
|
||||
[HistoricaTradingRewardsPeriod.WEEKLY.name]: HistoricaTradingRewardsPeriod.WEEKLY,
|
||||
[HistoricaTradingRewardsPeriod.DAILY.name]: HistoricaTradingRewardsPeriod.DAILY,
|
||||
[HistoricaTradingRewardsPeriod.BLOCK.name]: HistoricaTradingRewardsPeriod.BLOCK,
|
||||
};
|
||||
|
||||
export const ORDER_STATUS_STRINGS: Record<KotlinIrEnumValues<typeof AbacusOrderStatus>, string> = {
|
||||
[AbacusOrderStatus.open.name]: STRING_KEYS.OPEN_STATUS,
|
||||
[AbacusOrderStatus.open.rawValue]: STRING_KEYS.OPEN_STATUS,
|
||||
|
||||
@ -1 +1 @@
|
||||
<svg fill="none" height="10" viewBox="0 0 15 10" width="15" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m.321829 1.09389c.200562-.192959.469529-.298401.747791-.29315.27827.00525.54307.120763.73621.32115l5.194 5.5132 5.19397-5.5132c.0944-.10408.2088-.188152.3363-.247234.1275-.059081.2655-.091968.406-.096713.1404-.004746.2804.018748.4116.069088s.2509.126504.3522.223979c.1012.09747.1818.21427.2371.34347.0552.12921.084.26819.0845.40871.0006.14052-.0271.27972-.0813.40936s-.1339.24707-.2344.34534l-5.94997 6.3c-.09795.10163-.21538.18245-.34527.23766-.1299.05521-.26959.08367-.41073.08367s-.28083-.02846-.41073-.08367c-.12989-.05521-.24732-.13603-.34527-.23766l-5.950001-6.3c-.192962-.20056-.29840394-.46953-.29315364-.74779.00525031-.27827.12076264-.54307.32115364-.73621z" fill="currentColor" fill-rule="evenodd"/></svg>
|
||||
<svg fill="none" height="10" viewBox="0 0 15 10" width="15" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m.321829 1.09389c.200562-.192959.469529-.298401.747791-.29315.27827.00525.54307.120763.73621.32115l5.194 5.5132 5.19397-5.5132c.0944-.10408.2088-.188152.3363-.247234.1275-.059081.2655-.091968.406-.096713.1404-.004746.2804.018748.4116.069088s.2509.126504.3522.223979c.1012.09747.1818.21427.2371.34347.0552.12921.084.26819.0845.40871.0006.14052-.0271.27972-.0813.40936s-.1339.24707-.2344.34534l-5.94997 6.3c-.09795.10163-.21538.18245-.34527.23766-.1299.05521-.26959.08367-.41073.08367s-.28083-.02846-.41073-.08367c-.12989-.05521-.24732-.13603-.34527-.23766l-5.950001-6.3c-.192962-.20056-.29840394-.46953-.29315364-.74779.00525031-.27827.12076264-.54307.32115364-.73621z" fill="currentColor" fill-rule="evenodd"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 840 B After Width: | Height: | Size: 841 B |
@ -9,6 +9,8 @@ import type {
|
||||
TransferInputFields,
|
||||
HistoricalPnlPeriods,
|
||||
ParsingError,
|
||||
HistoricaTradingRewardsPeriods,
|
||||
HistoricaTradingRewardsPeriod,
|
||||
} from '@/constants/abacus';
|
||||
|
||||
import {
|
||||
@ -218,6 +220,12 @@ class AbacusStateManager {
|
||||
this.stateManager.historicalPnlPeriod = period;
|
||||
};
|
||||
|
||||
setHistoricalTradingRewardPeriod = (
|
||||
period: (typeof HistoricaTradingRewardsPeriod)[keyof typeof HistoricaTradingRewardsPeriod]
|
||||
) => {
|
||||
this.stateManager.historicalTradingRewardPeriod = period;
|
||||
};
|
||||
|
||||
switchNetwork = (network: DydxNetwork) => {
|
||||
this.stateManager.environmentId = network;
|
||||
|
||||
@ -262,17 +270,16 @@ class AbacusStateManager {
|
||||
) => this.stateManager.cancelOrder(orderId, callback);
|
||||
|
||||
cctpWithdraw = (
|
||||
callback: (
|
||||
success: boolean,
|
||||
parsingError: Nullable<ParsingError>,
|
||||
data: string,
|
||||
) => void
|
||||
callback: (success: boolean, parsingError: Nullable<ParsingError>, data: string) => void
|
||||
): void => this.stateManager.commitCCTPWithdraw(callback);
|
||||
|
||||
// ------ Utils ------ //
|
||||
getHistoricalPnlPeriod = (): Nullable<HistoricalPnlPeriods> =>
|
||||
this.stateManager.historicalPnlPeriod;
|
||||
|
||||
getHistoricalTradingRewardPeriod = (): HistoricaTradingRewardsPeriods =>
|
||||
this.stateManager.historicalTradingRewardPeriod;
|
||||
|
||||
handleCandlesSubscription = ({
|
||||
channelId,
|
||||
subscribe,
|
||||
|
||||
@ -146,14 +146,15 @@ Styled.Title = styled.h3`
|
||||
color: var(--color-text-2);
|
||||
|
||||
padding: var(--panel-paddingY) var(--panel-paddingX) 0;
|
||||
margin-bottom: -0.5rem;
|
||||
`;
|
||||
|
||||
Styled.MigrateAction = styled.div`
|
||||
${layoutMixins.flexEqualColumns}
|
||||
align-items: center;
|
||||
margin: 1rem;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
margin: 1rem;
|
||||
width: 100%;
|
||||
|
||||
background-color: var(--color-layer-2);
|
||||
|
||||
111
src/pages/rewards/RewardHistoryPanel.tsx
Normal file
111
src/pages/rewards/RewardHistoryPanel.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
import styled, { AnyStyledComponent } from 'styled-components';
|
||||
import { shallowEqual, useSelector } from 'react-redux';
|
||||
|
||||
import breakpoints from '@/styles/breakpoints';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { useStringGetter } from '@/hooks';
|
||||
|
||||
import {
|
||||
HISTORICAL_TRADING_REWARDS_PERIODS,
|
||||
HistoricaTradingRewardsPeriod,
|
||||
HistoricaTradingRewardsPeriods,
|
||||
} from '@/constants/abacus';
|
||||
|
||||
import { ComingSoon } from '@/components/ComingSoon';
|
||||
import { Panel } from '@/components/Panel';
|
||||
import { ToggleGroup } from '@/components/ToggleGroup';
|
||||
import { TradingRewardHistoryTable } from '@/views/tables/TradingRewardHistoryTable';
|
||||
|
||||
import { getHistoricalTradingRewards } from '@/state/accountSelectors';
|
||||
import abacusStateManager from '@/lib/abacus';
|
||||
|
||||
export const RewardHistoryPanel = () => {
|
||||
const stringGetter = useStringGetter();
|
||||
const historicalTradingRewards = useSelector(getHistoricalTradingRewards, shallowEqual);
|
||||
|
||||
const [selectedPeriod, setSelectedPeriod] = useState<HistoricaTradingRewardsPeriods>(
|
||||
abacusStateManager.getHistoricalTradingRewardPeriod() || HistoricaTradingRewardsPeriod.WEEKLY
|
||||
);
|
||||
|
||||
const onSelectPeriod = useCallback(
|
||||
(periodName: string) => {
|
||||
setSelectedPeriod(
|
||||
HISTORICAL_TRADING_REWARDS_PERIODS[
|
||||
periodName as keyof typeof HISTORICAL_TRADING_REWARDS_PERIODS
|
||||
]
|
||||
);
|
||||
},
|
||||
[setSelectedPeriod, selectedPeriod]
|
||||
);
|
||||
|
||||
return (
|
||||
<Styled.Panel
|
||||
slotHeader={
|
||||
<Styled.Header>
|
||||
<Styled.Title>
|
||||
<h3>Reward History</h3>
|
||||
<span>Rewards are distrubted after every block.</span>
|
||||
</Styled.Title>
|
||||
<ToggleGroup
|
||||
items={[
|
||||
{
|
||||
value: HistoricaTradingRewardsPeriod.MONTHLY.name,
|
||||
label: 'Monthly',
|
||||
},
|
||||
{
|
||||
value: HistoricaTradingRewardsPeriod.WEEKLY.name,
|
||||
label: 'Weekly',
|
||||
},
|
||||
{
|
||||
value: HistoricaTradingRewardsPeriod.DAILY.name,
|
||||
label: 'Daily',
|
||||
},
|
||||
]}
|
||||
value={selectedPeriod.name}
|
||||
onValueChange={onSelectPeriod}
|
||||
/>
|
||||
</Styled.Header>
|
||||
}
|
||||
>
|
||||
{historicalTradingRewards ? (
|
||||
<TradingRewardHistoryTable period={selectedPeriod} />
|
||||
) : (
|
||||
<ComingSoon />
|
||||
)}
|
||||
</Styled.Panel>
|
||||
);
|
||||
};
|
||||
|
||||
const Styled: Record<string, AnyStyledComponent> = {};
|
||||
|
||||
Styled.Panel = styled(Panel)`
|
||||
--panel-paddingX: 1.5rem;
|
||||
--panel-paddingY: 1.25rem;
|
||||
|
||||
@media ${breakpoints.tablet} {
|
||||
--panel-paddingY: 1.5rem;
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Header = styled.div`
|
||||
${layoutMixins.spacedRow}
|
||||
|
||||
padding: 1rem 1.5rem 0;
|
||||
margin-bottom: -0.5rem;
|
||||
`;
|
||||
|
||||
Styled.Title = styled.div`
|
||||
color: var(--color-text-0);
|
||||
font: var(--font-small-book);
|
||||
|
||||
h3 {
|
||||
font: var(--font-medium-book);
|
||||
color: var(--color-text-2);
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Content = styled.div`
|
||||
${layoutMixins.flexColumn}
|
||||
gap: 0.75rem;
|
||||
`;
|
||||
@ -25,7 +25,7 @@ import { MigratePanel } from './MigratePanel';
|
||||
import { LaunchIncentivesPanel } from './LaunchIncentivesPanel';
|
||||
import { RewardsHelpPanel } from './RewardsHelpPanel';
|
||||
import { TradingRewardsSummaryPanel } from './TradingRewardsSummaryPanel';
|
||||
import { RewardsHelpPanel } from './RewardsHelpPanel';
|
||||
import { RewardHistoryPanel } from './RewardHistoryPanel';
|
||||
|
||||
const RewardsPage = () => {
|
||||
const dispatch = useDispatch();
|
||||
@ -58,7 +58,7 @@ const RewardsPage = () => {
|
||||
<Styled.TradingRewardsColumn>
|
||||
<TradingRewardsSummaryPanel />
|
||||
{isTablet && <RewardsHelpPanel />}
|
||||
<Styled.Panel slotHeader={<Styled.Title>Reward History</Styled.Title>} />
|
||||
<RewardHistoryPanel/>
|
||||
</Styled.TradingRewardsColumn>
|
||||
|
||||
{isNotTablet && (
|
||||
@ -190,6 +190,16 @@ Styled.OtherColumn = styled.div`
|
||||
${layoutMixins.flexColumn}
|
||||
`;
|
||||
|
||||
Styled.RewardHistoryHeader = styled.div`
|
||||
h3 {
|
||||
font: var(--font-medium-book);
|
||||
color: var(--color-text-2);
|
||||
}
|
||||
|
||||
padding: 1rem 1.5rem 0;
|
||||
margin-bottom: -0.5rem;
|
||||
`;
|
||||
|
||||
Styled.Title = styled.h3`
|
||||
font: var(--font-medium-book);
|
||||
color: var(--color-text-2);
|
||||
|
||||
@ -7,12 +7,12 @@ import { layoutMixins } from '@/styles/layoutMixins';
|
||||
import { useStringGetter, useTokenConfigs } from '@/hooks';
|
||||
|
||||
import { AssetIcon } from '@/components/AssetIcon';
|
||||
import { ComingSoon } from '@/components/ComingSoon';
|
||||
import { Details } from '@/components/Details';
|
||||
import { Output, OutputType } from '@/components/Output';
|
||||
import { Panel } from '@/components/Panel';
|
||||
|
||||
import { getHistoricalTradingRewards } from '@/state/accountSelectors';
|
||||
import { HistoricalTradingReward } from '@/constants/abacus';
|
||||
|
||||
export const TradingRewardsSummaryPanel = () => {
|
||||
const stringGetter = useStringGetter();
|
||||
@ -29,8 +29,7 @@ export const TradingRewardsSummaryPanel = () => {
|
||||
}
|
||||
>
|
||||
<Styled.Content>
|
||||
<Styled.ComingSoon>{stringGetter({ key: STRING_KEYS.COMING_SOON })}</Styled.ComingSoon>
|
||||
{
|
||||
{currentWeekTradingReward ? (
|
||||
<Styled.TradingRewardsDetails
|
||||
layout="grid"
|
||||
items={[
|
||||
@ -44,20 +43,20 @@ export const TradingRewardsSummaryPanel = () => {
|
||||
value: (
|
||||
<Styled.Column>
|
||||
<Output
|
||||
slotRight={<AssetIcon symbol={chainTokenLabel} />}
|
||||
slotRight={<Styled.AssetIcon symbol={chainTokenLabel} />}
|
||||
type={OutputType.Asset}
|
||||
value={currentWeekTradingReward?.amount}
|
||||
value={currentWeekTradingReward.amount}
|
||||
/>
|
||||
<Styled.TimePeriod>
|
||||
<Output
|
||||
type={OutputType.Date}
|
||||
value={1701388800000} // {currentWeekTradingReward?.startedAtInMilliseconds}
|
||||
value={currentWeekTradingReward.startedAtInMilliseconds}
|
||||
timeOptions={{ useUTC: true }}
|
||||
/>
|
||||
→
|
||||
<Output
|
||||
type={OutputType.Date}
|
||||
value={1704067199000} // {currentWeekTradingReward?.endedAtInMilliseconds}
|
||||
value={currentWeekTradingReward.endedAtInMilliseconds}
|
||||
timeOptions={{ useUTC: true }}
|
||||
/>
|
||||
</Styled.TimePeriod>
|
||||
@ -67,7 +66,9 @@ export const TradingRewardsSummaryPanel = () => {
|
||||
// TODO(@aforaleka): add all-time when supported
|
||||
]}
|
||||
/>
|
||||
}
|
||||
) : (
|
||||
<ComingSoon />
|
||||
)}
|
||||
</Styled.Content>
|
||||
</Styled.Panel>
|
||||
);
|
||||
@ -94,6 +95,7 @@ Styled.Title = styled.h3`
|
||||
${layoutMixins.inlineRow}
|
||||
font: var(--font-medium-book);
|
||||
color: var(--color-text-2);
|
||||
margin-bottom: -0.5rem;
|
||||
|
||||
img {
|
||||
font-size: 1.5rem;
|
||||
@ -112,10 +114,8 @@ Styled.TradingRewardsDetails = styled(Details)`
|
||||
gap: 1rem;
|
||||
|
||||
> div {
|
||||
gap: 1rem;
|
||||
|
||||
gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
|
||||
border-radius: 0.75em;
|
||||
background-color: var(--color-layer-5);
|
||||
}
|
||||
@ -152,5 +152,9 @@ Styled.TimePeriod = styled.div`
|
||||
|
||||
Styled.Column = styled.div`
|
||||
${layoutMixins.flexColumn}
|
||||
gap: 0.5rem;
|
||||
gap: 0.33rem;
|
||||
`;
|
||||
|
||||
Styled.AssetIcon = styled(AssetIcon)`
|
||||
margin-left: 0.5ch;
|
||||
`;
|
||||
|
||||
141
src/views/tables/TradingRewardHistoryTable.tsx
Normal file
141
src/views/tables/TradingRewardHistoryTable.tsx
Normal file
@ -0,0 +1,141 @@
|
||||
import styled, { type AnyStyledComponent } from 'styled-components';
|
||||
import { shallowEqual, useSelector } from 'react-redux';
|
||||
|
||||
import { HistoricaTradingRewardsPeriods } from '@/constants/abacus';
|
||||
import { useTokenConfigs } from '@/hooks';
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
|
||||
import { AssetIcon } from '@/components/AssetIcon';
|
||||
import { Output, OutputType } from '@/components/Output';
|
||||
import { Table, TableCell, type ColumnDef } from '@/components/Table';
|
||||
|
||||
import { getHistoricalTradingRewards } from '@/state/accountSelectors';
|
||||
|
||||
export enum TradingRewardHistoryTableColumnKey {
|
||||
Event = 'Event',
|
||||
Earned = 'Earned',
|
||||
}
|
||||
|
||||
const getTradingRewardHistoryTableColumnDef = ({
|
||||
key,
|
||||
chainTokenLabel,
|
||||
}: {
|
||||
key: TradingRewardHistoryTableColumnKey;
|
||||
chainTokenLabel: string;
|
||||
}): ColumnDef<any> => ({
|
||||
...(
|
||||
{
|
||||
[TradingRewardHistoryTableColumnKey.Event]: {
|
||||
columnKey: TradingRewardHistoryTableColumnKey.Event,
|
||||
getCellValue: (row) => row.startedAtInMilliseconds,
|
||||
label: 'Event',
|
||||
renderCell: ({ startedAtInMilliseconds, endedAtInMilliseconds }) => (
|
||||
<TableCell stacked>
|
||||
<Styled.Rewarded>Rewarded</Styled.Rewarded>
|
||||
<Styled.TimePeriod>
|
||||
For trading
|
||||
<Output
|
||||
type={OutputType.Date}
|
||||
value={startedAtInMilliseconds}
|
||||
timeOptions={{ useUTC: true }}
|
||||
/>
|
||||
→
|
||||
<Output
|
||||
type={OutputType.Date}
|
||||
value={endedAtInMilliseconds}
|
||||
timeOptions={{ useUTC: true }}
|
||||
/>
|
||||
</Styled.TimePeriod>
|
||||
</TableCell>
|
||||
),
|
||||
},
|
||||
[TradingRewardHistoryTableColumnKey.Earned]: {
|
||||
columnKey: TradingRewardHistoryTableColumnKey.Earned,
|
||||
getCellValue: (row) => row.amount,
|
||||
label: 'Earned',
|
||||
renderCell: ({ amount }) => (
|
||||
<Output
|
||||
type={OutputType.Asset}
|
||||
value={amount}
|
||||
slotRight={<Styled.AssetIcon symbol={chainTokenLabel} />}
|
||||
/>
|
||||
),
|
||||
},
|
||||
} as Record<TradingRewardHistoryTableColumnKey, ColumnDef<any>>
|
||||
)[key],
|
||||
});
|
||||
|
||||
type ElementProps = {
|
||||
columnKeys?: TradingRewardHistoryTableColumnKey[];
|
||||
period: HistoricaTradingRewardsPeriods;
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
withOuterBorder?: boolean;
|
||||
withInnerBorders?: boolean;
|
||||
};
|
||||
|
||||
export const TradingRewardHistoryTable = ({
|
||||
period,
|
||||
columnKeys = Object.values(TradingRewardHistoryTableColumnKey),
|
||||
withOuterBorder,
|
||||
withInnerBorders = true,
|
||||
}: ElementProps & StyleProps) => {
|
||||
const historicalTradingRewards = useSelector(getHistoricalTradingRewards, shallowEqual);
|
||||
const periodTradingRewards = historicalTradingRewards?.get(period.name) ?? [];
|
||||
const { chainTokenLabel } = useTokenConfigs();
|
||||
|
||||
return (
|
||||
<Styled.Table
|
||||
label="Reward History"
|
||||
data={periodTradingRewards}
|
||||
getRowKey={(row: any) => row.startedAtInMilliseconds}
|
||||
columns={columnKeys.map((key: TradingRewardHistoryTableColumnKey) =>
|
||||
getTradingRewardHistoryTableColumnDef({
|
||||
key,
|
||||
chainTokenLabel,
|
||||
})
|
||||
)}
|
||||
selectionBehavior="replace"
|
||||
withOuterBorder={withOuterBorder}
|
||||
withInnerBorders={withInnerBorders}
|
||||
initialNumRowsToShow={5}
|
||||
withScrollSnapColumns
|
||||
withScrollSnapRows
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Styled: Record<string, AnyStyledComponent> = {};
|
||||
|
||||
Styled.Table = styled(Table)`
|
||||
--tableCell-padding: 0.5rem 0;
|
||||
--tableHeader-backgroundColor: var(--color-layer-3);
|
||||
--tableRow-backgroundColor: var(--color-layer-3);
|
||||
|
||||
tbody {
|
||||
font: var(--font-medium-book);
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.Rewarded = styled.span`
|
||||
color: var(--color-text-2);
|
||||
`;
|
||||
|
||||
Styled.TimePeriod = styled.div`
|
||||
${layoutMixins.inlineRow}
|
||||
|
||||
&& {
|
||||
color: var(--color-text-0);
|
||||
font: var(--font-base-book);
|
||||
}
|
||||
|
||||
output {
|
||||
color: var(--color-text-1);
|
||||
font: var(--font-base-book);
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.AssetIcon = styled(AssetIcon)`
|
||||
margin-left: 0.5ch;
|
||||
`;
|
||||
Loading…
Reference in New Issue
Block a user