Skip to content

Commit

Permalink
feat(fee-tier): Add card to display fee tier bonus (#1316)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredvu authored Nov 21, 2024
1 parent 5db9d49 commit 4b81289
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 21 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"@datadog/browser-logs": "^5.23.3",
"@dydxprotocol/v4-abacus": "1.13.34",
"@dydxprotocol/v4-client-js": "1.12.2",
"@dydxprotocol/v4-localization": "^1.1.250",
"@dydxprotocol/v4-localization": "^1.1.251",
"@dydxprotocol/v4-proto": "^7.0.0-dev.0",
"@funkit/connect": "^3.4.9",
"@emotion/is-prop-valid": "^1.3.0",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/hooks/useSubaccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,7 @@ const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: LocalWall

// affiliates
registerAffiliate,
referredBy: referredBy?.affiliateAddress,

// vaults
getVaultAccountInfo,
Expand Down
85 changes: 69 additions & 16 deletions src/pages/portfolio/Fees.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback, useMemo } from 'react';

import { Nullable } from '@dydxprotocol/v4-abacus';
import { DoubleArrowUpIcon } from '@radix-ui/react-icons';
import { shallowEqual } from 'react-redux';
import styled from 'styled-components';
import tw from 'twin.macro';
Expand All @@ -11,13 +12,16 @@ import { FEE_DECIMALS } from '@/constants/numbers';

import { useBreakpoints } from '@/hooks/useBreakpoints';
import { useStringGetter } from '@/hooks/useStringGetter';
import { useSubaccount } from '@/hooks/useSubaccount';
import { useURLConfigs } from '@/hooks/useURLConfigs';

import breakpoints from '@/styles/breakpoints';
import { layoutMixins } from '@/styles/layoutMixins';

import { AttachedExpandingSection } from '@/components/ContentSection';
import { ContentSectionHeader } from '@/components/ContentSectionHeader';
import { Details } from '@/components/Details';
import { Link } from '@/components/Link';
import { Output, OutputType } from '@/components/Output';
import { ColumnDef, Table } from '@/components/Table';
import { Tag, TagSize } from '@/components/Tag';
Expand All @@ -27,6 +31,8 @@ import { useAppSelector } from '@/state/appTypes';
import { getFeeTiers } from '@/state/configsSelectors';

import { isTruthy } from '@/lib/isTruthy';
import { MustBigNumber } from '@/lib/numbers';
import { truncateAddress } from '@/lib/wallet';

const MARKET_SHARE_PERCENTAGE_FRACTION_DIGITS = 1;

Expand All @@ -41,6 +47,8 @@ export const Fees = () => {
const userFeeTier = useAppSelector(getUserFeeTier, shallowEqual);
const userStats = useAppSelector(getUserStats, shallowEqual);
const feeTiers = useAppSelector(getFeeTiers, shallowEqual);
const { referredBy } = useSubaccount();
const { affiliateProgramFaq } = useURLConfigs();

const volume = useMemo(() => {
if (userStats.makerVolume30D !== undefined && userStats.takerVolume30D !== undefined) {
Expand All @@ -49,6 +57,11 @@ export const Fees = () => {
return null;
}, [userStats]);

const hasReceivedFeeTierBonus =
userFeeTier === '3' &&
referredBy !== undefined &&
MustBigNumber(volume).lt(feeTiers?.[2]?.volume ?? 0);

const AdditionalConditions = useCallback(
(conditions: {
totalShare: Nullable<number>;
Expand Down Expand Up @@ -93,21 +106,58 @@ export const Fees = () => {
<AttachedExpandingSection>
{isNotTablet && <ContentSectionHeader title={stringGetter({ key: STRING_KEYS.FEES })} />}
<div tw="flexColumn max-w-[100vw] gap-1.5">
<$FeesDetails
layout="grid"
items={[
{
key: 'volume',
label: (
<$CardLabel>
<span>{stringGetter({ key: STRING_KEYS.TRAILING_VOLUME })}</span>
<span>{stringGetter({ key: STRING_KEYS._30D })}</span>
</$CardLabel>
),
value: <Output type={OutputType.Fiat} value={volume} />,
},
]}
/>
<div tw="flex flex-row">
<$FeesDetails
layout="grid"
hasReceivedFeeTierBonus={hasReceivedFeeTierBonus}
items={[
{
key: 'volume',
label: (
<$CardLabel>
<span>{stringGetter({ key: STRING_KEYS.TRAILING_VOLUME })}</span>
<span>{stringGetter({ key: STRING_KEYS._30D })}</span>
</$CardLabel>
),
value: <Output type={OutputType.Fiat} value={volume} />,
},
hasReceivedFeeTierBonus && {
key: 'bonus',
label: (
<$CardLabel>
{stringGetter({
key: STRING_KEYS.YOUR_FEE_TIER,
params: {
TIER: (
<span tw="text-color-text-2">
{userFeeTier}{' '}
<DoubleArrowUpIcon tw="mb-[-1px] inline h-0.75 w-0.75 text-color-positive" />
</span>
),
},
})}
</$CardLabel>
),
value: (
<span tw="font-mini-book">
{stringGetter({
key: STRING_KEYS.GIFTED_FEE_TIER_BONUS,
params: {
AFFILIATE: truncateAddress(referredBy),
},
})}{' '}
<Link
tw="inline-flex text-color-accent visited:text-color-accent"
href={affiliateProgramFaq}
>
{stringGetter({ key: STRING_KEYS.LEARN_MORE })}
</Link>
</span>
),
},
].filter(isTruthy)}
/>
</div>

<$FeeTable
label={stringGetter({ key: STRING_KEYS.FEE_TIERS })}
Expand Down Expand Up @@ -230,8 +280,9 @@ const $AdditionalConditionsText = styled.span`
}
`;

const $FeesDetails = styled(Details)`
const $FeesDetails = styled(Details)<{ hasReceivedFeeTierBonus?: boolean }>`
gap: 1rem;
--details-grid-numColumns: ${({ hasReceivedFeeTierBonus }) => (hasReceivedFeeTierBonus ? 2 : 1)};
@media ${breakpoints.notTablet} {
margin: 0 1.25rem;
Expand All @@ -244,6 +295,7 @@ const $FeesDetails = styled(Details)`
> div {
max-width: 16rem;
align-content: normal;
gap: 1rem;
Expand Down Expand Up @@ -271,6 +323,7 @@ const $TextRow = styled.div`
`;

const $CardLabel = styled($TextRow)`
height: 1.5rem;
font: var(--font-small-book);
color: var(--color-text-1);
Expand Down

0 comments on commit 4b81289

Please sign in to comment.