more rewards page panels

This commit is contained in:
Bill He 2023-09-27 10:29:08 -04:00
parent f1a16f9de8
commit cd7e6298d8
No known key found for this signature in database
GPG Key ID: 73AEEF9D79E5BBF8
9 changed files with 109 additions and 14 deletions

View File

@ -5,6 +5,7 @@ export enum DialogTypes {
ExchangeOffline = 'ExchangeOffline',
FillDetails = 'FillDetails',
Help = 'Help',
Keplr = 'Keplr',
MnemonicExport = 'MnemonicExport',
MobileSignIn = 'MobileSignIn',
Onboarding = 'Onboarding',

View File

@ -14,7 +14,7 @@ import { EvmAddress } from '@/constants/wallets';
import { convertBech32Address } from '@/lib/addressUtils';
import { MustBigNumber } from '@/lib/numbers';
import { getBalances } from '@/state/accountSelectors';
import { getBalances, getStakingBalances } from '@/state/accountSelectors';
import { getSelectedNetwork } from '@/state/appSelectors';
import { useAccounts } from './useAccounts';
@ -53,6 +53,7 @@ export const useAccountBalance = ({
const selectedNetwork = useSelector(getSelectedNetwork);
const balances = useSelector(getBalances, shallowEqual);
const evmChainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId);
const stakingBalances = useSelector(getStakingBalances, shallowEqual);
const evmQuery = useBalance({
enabled: Boolean(!isCosmosChain && addressOrDenom?.startsWith('0x')),
@ -100,9 +101,15 @@ export const useAccountBalance = ({
const usdcCoinBalance = balances?.[USDC_DENOM];
const usdcBalance = MustBigNumber(usdcCoinBalance?.amount).div(QUANTUM_MULTIPLIER).toNumber();
const nativeStakingCoinBalanace = stakingBalances?.[DYDX_DENOM];
const nativeStakingBalance = MustBigNumber(nativeStakingCoinBalanace?.amount)
.div(QUANTUM_MULTIPLIER)
.toNumber();
return {
balance,
nativeTokenBalance,
nativeStakingBalance,
usdcBalance,
queryStatus: isCosmosChain ? cosmosQuery.status : evmQuery.status,
isQueryFetching: isCosmosChain ? cosmosQuery.isFetching : evmQuery.fetchStatus === 'fetching',

View File

@ -11,6 +11,7 @@ import { DepositDialog } from '@/views/dialogs/DepositDialog';
import { DisconnectDialog } from '@/views/dialogs/DisconnectDialog';
import { ExchangeOfflineDialog } from '@/views/dialogs/ExchangeOfflineDialog';
import { HelpDialog } from '@/views/dialogs/HelpDialog';
import { KeplrDialog } from '@/views/dialogs/KeplrDialog';
import { MnemonicExportDialog } from '@/views/dialogs/MnemonicExportDialog';
import { MobileSignInDialog } from '@/views/dialogs/MobileSignInDialog';
import { OnboardingDialog } from '@/views/dialogs/OnboardingDialog';
@ -47,6 +48,7 @@ export const DialogManager = () => {
[DialogTypes.ExchangeOffline]: <ExchangeOfflineDialog {...modalProps} />,
[DialogTypes.FillDetails]: <FillDetailsDialog {...modalProps} />,
[DialogTypes.Help]: <HelpDialog {...modalProps} />,
[DialogTypes.Keplr]: <KeplrDialog {...modalProps} />,
[DialogTypes.MnemonicExport]: <MnemonicExportDialog {...modalProps} />,
[DialogTypes.MobileSignIn]: <MobileSignInDialog {...modalProps} />,
[DialogTypes.Onboarding]: <OnboardingDialog {...modalProps} />,

View File

@ -20,6 +20,7 @@ import type { RootStore } from '@/state/_store';
import {
setBalances,
setStakingBalances,
setFills,
setFundingPayments,
setHistoricalPnl,
@ -82,6 +83,13 @@ class AbacusStateNotifier implements AbacusStateNotificationProtocol {
}
dispatch(setBalances(balances));
}
if (updatedState.account?.stakingBalances) {
const stakingBalances: Record<string, AccountBalance> = {}
for (const { k, v } of updatedState.account.stakingBalances.toArray()) {
stakingBalances[k] = v;
}
dispatch(setStakingBalances(stakingBalances));
}
}
if (changes.has(Changes.configs)) {

View File

@ -29,7 +29,7 @@ export const DYDXBalancePanel = () => {
const { walletType } = useAccounts();
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
const { nativeTokenBalance } = useAccountBalance();
const { nativeTokenBalance, nativeStakingBalance } = useAccountBalance();
return (
<Panel
@ -97,7 +97,7 @@ export const DYDXBalancePanel = () => {
</Styled.Label>
),
value: <Output type={OutputType.Asset} value={undefined} />,
value: <Output type={OutputType.Asset} value={nativeStakingBalance} />,
},
]}
/>
@ -106,7 +106,7 @@ export const DYDXBalancePanel = () => {
{
key: 'totalBalance',
label: 'Total balance',
value: <Output type={OutputType.Asset} value={nativeTokenBalance} tag="Dv4TNT" />,
value: <Output type={OutputType.Asset} value={nativeTokenBalance + nativeStakingBalance} tag="Dv4TNT" />,
},
]}
/>

View File

@ -1,9 +1,11 @@
import styled, { AnyStyledComponent } from 'styled-components';
import { useDispatch } from 'react-redux';
import { STRING_KEYS } from '@/constants/localization';
import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs';
import { useAccounts, useBreakpoints, useStringGetter } from '@/hooks';
import { useStringGetter } from '@/hooks';
import { layoutMixins } from '@/styles/layoutMixins';
@ -11,9 +13,12 @@ import { Panel } from '@/components/Panel';
import { IconName } from '@/components/Icon';
import { IconButton } from '@/components/IconButton';
import { openDialog } from '@/state/dialogs';
import { DYDXBalancePanel } from './DYDXBalancePanel';
export const RewardsPage = () => {
const dispatch = useDispatch();
const stringGetter = useStringGetter();
return (
@ -23,20 +28,26 @@ export const RewardsPage = () => {
slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.GOVERNANCE })}</Styled.Title>}
>
<Styled.Row>
<div>
{stringGetter({ key: STRING_KEYS.GOVERNANCE_DESCRIPTION })}
</div>
<IconButton action={ButtonAction.Base} iconName={IconName.Arrow} size={ButtonSize.Small} />
<div>{stringGetter({ key: STRING_KEYS.GOVERNANCE_DESCRIPTION })}</div>
<IconButton
action={ButtonAction.Base}
iconName={IconName.Arrow}
onClick={() => dispatch(openDialog({ type: DialogTypes.Keplr }))}
size={ButtonSize.Small}
/>
</Styled.Row>
</Styled.Panel>
<Styled.Panel
slotHeader={<Styled.Title>{stringGetter({ key: STRING_KEYS.STAKING })}</Styled.Title>}
>
<Styled.Row>
<div>
{stringGetter({ key: STRING_KEYS.STAKING_DESCRIPTION })}
</div>
<IconButton action={ButtonAction.Base} iconName={IconName.Arrow} size={ButtonSize.Small} />
<div>{stringGetter({ key: STRING_KEYS.STAKING_DESCRIPTION })}</div>
<IconButton
action={ButtonAction.Base}
iconName={IconName.Arrow}
onClick={() => dispatch(openDialog({ type: DialogTypes.Keplr }))}
size={ButtonSize.Small}
/>
</Styled.Row>
</Styled.Panel>
<Styled.BalancePanelContainer>
@ -78,4 +89,4 @@ Styled.Title = styled.h3`
Styled.Panel = styled(Panel)`
padding: 0 1.5rem 1rem;
`
`;

View File

@ -37,6 +37,7 @@ export type AccountState = {
walletType?: WalletType;
historicalPnlPeriod?: HistoricalPnlPeriods;
balances?: Record<string, AccountBalance>;
stakingBalances?: Record<string, AccountBalance>;
};
const initialState: AccountState = {
@ -154,6 +155,9 @@ export const accountSlice = createSlice({
setBalances: (state, action: PayloadAction<Record<string, AccountBalance>>) => {
state.balances = action.payload;
},
setStakingBalances: (state, action: PayloadAction<Record<string, AccountBalance>>) => {
state.stakingBalances = action.payload;
},
addUncommittedOrderClientId: (state, action: PayloadAction<number>) => {
state.uncommittedOrderClientIds.push(action.payload);
},
@ -179,6 +183,7 @@ export const {
viewedFills,
viewedOrders,
setBalances,
setStakingBalances,
addUncommittedOrderClientId,
removeUncommittedOrderClientId,
} = accountSlice.actions;

View File

@ -337,3 +337,8 @@ export const getUserStats = (state: RootState) => ({
* @returns user wallet balances
*/
export const getBalances = (state: RootState) => state.account?.balances;
/**
* @returns user wallet staking balances
* */
export const getStakingBalances = (state: RootState) => state.account?.stakingBalances;

View File

@ -0,0 +1,56 @@
import styled, { type AnyStyledComponent } from 'styled-components';
import { STRING_KEYS } from '@/constants/localization';
import { useBreakpoints, useStringGetter } from '@/hooks';
import { Dialog, DialogPlacement } from '@/components/Dialog';
import { WithdrawForm } from '@/views/forms/AccountManagementForms/WithdrawForm';
import { layoutMixins } from '@/styles/layoutMixins';
type ElementProps = {
setIsOpen: (open: boolean) => void;
};
export const KeplrDialog = ({ setIsOpen }: ElementProps) => {
const stringGetter = useStringGetter();
const { isTablet } = useBreakpoints();
return (
<Dialog
isOpen
setIsOpen={setIsOpen}
title={stringGetter({ key: STRING_KEYS.WITHDRAW })}
placement={isTablet ? DialogPlacement.FullScreen : DialogPlacement.Default}
>
<Styled.Content>
TEST
</Styled.Content>
</Dialog>
);
};
const Styled: Record<string, AnyStyledComponent> = {};
Styled.TextToggle = styled.div`
${layoutMixins.stickyFooter}
color: var(--color-accent);
cursor: pointer;
margin-top: auto;
&:hover {
text-decoration: underline;
}
`;
Styled.Content = styled.div`
${layoutMixins.stickyArea0}
--stickyArea0-bottomHeight: 2rem;
--stickyArea0-bottomGap: 1rem;
--stickyArea0-totalInsetBottom: 0.5rem;
${layoutMixins.flexColumn}
gap: 1rem;
`;