Skip to content

Commit

Permalink
feat: Affiliates banner and share dialog ui (#985)
Browse files Browse the repository at this point in the history
  • Loading branch information
rosepuppy authored Sep 5, 2024
1 parent 9d642ce commit 0d07c65
Show file tree
Hide file tree
Showing 14 changed files with 297 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@datadog/browser-logs": "^5.23.3",
"@dydxprotocol/v4-abacus": "1.9.7",
"@dydxprotocol/v4-client-js": "^1.1.27",
"@dydxprotocol/v4-localization": "^1.1.187",
"@dydxprotocol/v4-localization": "^1.1.189",
"@emotion/is-prop-valid": "^1.3.0",
"@ethersproject/providers": "^5.7.2",
"@hugocxl/react-to-image": "^0.0.9",
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.

Binary file added public/affiliates-hedgie.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/affiliates-share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions public/configs/v1/env.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
"discoveryProgram": "https://www.dydx.foundation/blog/dydx-discovery-user-interviews?utm_source=dYdXTelegram&utm_medium=GlobalSocial&utm_campaign=GlobalSocial",
"getInTouch": "",
"deployerTermsAndConditions": "",
"dydxLearnMore": "https://www.mintscan.io/dydx"
"dydxLearnMore": "https://www.mintscan.io/dydx",
"affiliateProgram": ""
},
"dydx-testnet-4": {
"tos": "https://dydx.exchange/v4-terms",
Expand Down Expand Up @@ -126,7 +127,8 @@
"discoveryProgram": "https://www.dydx.foundation/blog/dydx-discovery-user-interviews?utm_source=dYdXTelegram&utm_medium=GlobalSocial&utm_campaign=GlobalSocial",
"getInTouch": "",
"deployerTermsAndConditions": "",
"dydxLearnMore": "https://www.mintscan.io/dydx"
"dydxLearnMore": "https://www.mintscan.io/dydx",
"affiliateProgram": ""
},
"[mainnet chain id]": {
"tos": "[HTTP link to TOS]",
Expand Down Expand Up @@ -164,7 +166,8 @@
"discoveryProgram": "[HTTP link to discovery program learn more]",
"getInTouch": "[HTTP link to get in touch with traders]",
"deployerTermsAndConditions": "[HTTP link to terms and conditions, can be null]",
"dydxLearnMore": "[HTTP link to information about the dYdX blockchain]"
"dydxLearnMore": "[HTTP link to information about the dYdX blockchain]",
"affiliateProgram": "[HTTP link to information about the affiliate program]"
}
},
"wallets": {
Expand Down
9 changes: 9 additions & 0 deletions public/grid-background.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/constants/affiliates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const AFFILIATES_EARN_PER_MONTH = 1500;

export const AFFILIATES_FEE_DISCOUNT = 500;
2 changes: 2 additions & 0 deletions src/constants/dialogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export type RateLimitDialogProps = { preventClose?: boolean };
export type RestrictedGeoDialogProps = { preventClose?: boolean };
export type RestrictedWalletDialogProps = { preventClose?: boolean };
export type SelectMarginModeDialogProps = {};
export type ShareAffiliateDialogProps = {};
export type SharePNLAnalyticsDialogProps = {
marketId: string;
assetId: string;
Expand Down Expand Up @@ -124,6 +125,7 @@ export const DialogTypes = unionize(
RestrictedGeo: ofType<RestrictedGeoDialogProps>(),
RestrictedWallet: ofType<RestrictedWalletDialogProps>(),
SelectMarginMode: ofType<SelectMarginModeDialogProps>(),
ShareAffiliate: ofType<ShareAffiliateDialogProps>(),
SharePNLAnalytics: ofType<SharePNLAnalyticsDialogProps>(),
Stake: ofType<StakeDialogProps>(),
StakingReward: ofType<StakingRewardDialogProps>(),
Expand Down
1 change: 1 addition & 0 deletions src/constants/statsig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export enum StatSigFlags {
ffShowPredictionMarketsUi = 'ff_show_prediction_markets_ui',
ffEnableEvmSwaps = 'ff_enable_evm_swaps',
ffEnableKeplr = 'ff_enable_keplr',
ffEnableAffiliates = 'ff_enable_affiliates',
}

export type StatsigDynamicConfigType = Record<StatsigDynamicConfigs, any>;
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/useURLConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface LinksConfigs {
getInTouch?: string;
deployerTermsAndConditions?: string;
dydxLearnMore?: string;
affiliateProgram?: string;
}

export const useURLConfigs = (): LinksConfigs => {
Expand Down Expand Up @@ -89,5 +90,6 @@ export const useURLConfigs = (): LinksConfigs => {
getInTouch: linksConfigs.getInTouch,
deployerTermsAndConditions: linksConfigs.deployerTermsAndConditions,
dydxLearnMore: linksConfigs.dydxLearnMore ?? FALLBACK_URL,
affiliateProgram: linksConfigs.affiliateProgram,
};
};
2 changes: 2 additions & 0 deletions src/layout/DialogManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { RateLimitDialog } from '@/views/dialogs/RateLimitDialog';
import { RestrictedGeoDialog } from '@/views/dialogs/RestrictedGeoDialog';
import { RestrictedWalletDialog } from '@/views/dialogs/RestrictedWalletDialog';
import { SelectMarginModeDialog } from '@/views/dialogs/SelectMarginModeDialog';
import { ShareAffiliateDialog } from '@/views/dialogs/ShareAffiliateDialog';
import { SharePNLAnalyticsDialog } from '@/views/dialogs/SharePNLAnalyticsDialog';
import { StakeDialog } from '@/views/dialogs/StakeDialog';
import { StakingRewardDialog } from '@/views/dialogs/StakingRewardDialog';
Expand Down Expand Up @@ -93,6 +94,7 @@ export const DialogManager = () => {
RestrictedGeo: (args) => <RestrictedGeoDialog {...args} {...modalProps} />,
RestrictedWallet: (args) => <RestrictedWalletDialog {...args} {...modalProps} />,
SelectMarginMode: (args) => <SelectMarginModeDialog {...args} {...modalProps} />,
ShareAffiliate: (args) => <ShareAffiliateDialog {...args} {...modalProps} />,
SharePNLAnalytics: (args) => <SharePNLAnalyticsDialog {...args} {...modalProps} />,
Stake: (args) => <StakeDialog {...args} {...modalProps} />,
StakingReward: (args) => <StakingRewardDialog {...args} {...modalProps} />,
Expand Down
10 changes: 10 additions & 0 deletions src/pages/portfolio/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ import styled from 'styled-components';

import { STRING_KEYS } from '@/constants/localization';
import { AppRoute, PortfolioRoute } from '@/constants/routes';
import { StatSigFlags } from '@/constants/statsig';

import { useBreakpoints } from '@/hooks/useBreakpoints';
import { useParameterizedSelector } from '@/hooks/useParameterizedSelector';
import { useShouldShowTriggers } from '@/hooks/useShouldShowTriggers';
import { useStatsigGateValue } from '@/hooks/useStatsig';
import { useStringGetter } from '@/hooks/useStringGetter';

import { AttachedExpandingSection, DetachedSection } from '@/components/ContentSection';
import { ContentSectionHeader } from '@/components/ContentSectionHeader';
import { Icon, IconName } from '@/components/Icon';
import { Link } from '@/components/Link';
import { AffiliatesBanner } from '@/views/AffiliatesBanner';
import { PositionsTable, PositionsTableColumnKey } from '@/views/tables/PositionsTable';

import { calculateShouldRenderActionsInPositionsTable } from '@/state/accountCalculators';
Expand All @@ -29,6 +32,7 @@ export const Overview = () => {
const stringGetter = useStringGetter();
const { isTablet } = useBreakpoints();
const navigate = useNavigate();
const affiliatesEnabled = useStatsigGateValue(StatSigFlags.ffEnableAffiliates);

const handleViewUnopenedIsolatedOrders = useCallback(() => {
navigate(`${AppRoute.Portfolio}/${PortfolioRoute.Orders}`, {
Expand All @@ -53,6 +57,12 @@ export const Overview = () => {
<AccountDetailsAndHistory />
</DetachedSection>

{affiliatesEnabled && (
<DetachedSection>
<AffiliatesBanner />
</DetachedSection>
)}

<AttachedExpandingSection tw="mt-1">
<ContentSectionHeader title={stringGetter({ key: STRING_KEYS.OPEN_POSITIONS })} />

Expand Down
88 changes: 88 additions & 0 deletions src/views/AffiliatesBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { styled } from 'twin.macro';

import { AFFILIATES_EARN_PER_MONTH, AFFILIATES_FEE_DISCOUNT } from '@/constants/affiliates';
import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization';

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

import { Button } from '@/components/Button';
import { Icon, IconName } from '@/components/Icon';
import { Link } from '@/components/Link';

import { useAppDispatch } from '@/state/appTypes';
import { openDialog } from '@/state/dialogs';

export const AffiliatesBanner = () => {
const stringGetter = useStringGetter();
const { affiliateProgram } = useURLConfigs();

const dispatch = useAppDispatch();
return (
<$Background tw="row m-1 justify-between gap-0.5 rounded-0.5 bg-color-layer-1 pl-1 pr-2">
<div tw="row">
<img src="/affiliates-hedgie.png" alt="affiliates hedgie" tw="mt-1 h-8" />
<div tw="column items-start gap-0.5">
<div tw="row">
<$Triangle />
<div tw="inline-block rounded-0.5 bg-color-layer-6 px-1 py-0.5 font-bold text-color-text-2">
{stringGetter({
key: STRING_KEYS.EARN_FOR_EACH_TRADER,
params: { AMOUNT_USD: AFFILIATES_EARN_PER_MONTH.toLocaleString() },
})}
</div>
</div>
<div tw="ml-0.5">
{stringGetter({
key: STRING_KEYS.REFER_FOR_DISCOUNTS_FIRST_ORDER,
params: {
AMOUNT_USD: AFFILIATES_FEE_DISCOUNT.toLocaleString(),
},
})}{' '}
<br />
{stringGetter({
key: STRING_KEYS.WANT_TO_VIEW_EARNINGS,
params: {
LINK: (
<Link href={affiliateProgram} isInline isAccent>
{stringGetter({ key: STRING_KEYS.AFFILIATES_PROGRAM })}
</Link>
),
},
})}
</div>
</div>
</div>
<div>
<Button
action={ButtonAction.Primary}
slotLeft={<Icon iconName={IconName.Giftbox} />}
size={ButtonSize.Medium}
onClick={() => {
dispatch(openDialog(DialogTypes.ShareAffiliate()));
}}
>
{stringGetter({ key: STRING_KEYS.INVITE_FRIENDS })}
</Button>
</div>
</$Background>
);
};

const $Background = styled.div`
background-image: url('/grid-background.svg');
background-repeat: no-repeat;
background-position-x: 100%;
background-size: contain;
`;

const $Triangle = styled.div`
width: 0;
height: 0;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-right: 0.5rem solid var(--color-layer-6);
`;
Loading

0 comments on commit 0d07c65

Please sign in to comment.