From 5815a0e50f1d4550bdaafa148a24f4ded07d9f19 Mon Sep 17 00:00:00 2001 From: James Morris <96435344+james-a-morris@users.noreply.github.com> Date: Thu, 18 Aug 2022 15:01:18 -0400 Subject: [PATCH] feat: staking and claim pages Co-authored-by: Tulun Co-authored-by: Dong-Ha Kim --- package.json | 1 + src/Routes.tsx | 25 +- src/assets/acx.svg | 4 + src/assets/airdrop-gift-bg.svg | 22 + src/assets/airdrop-waves-bg.svg | 14 + src/assets/airdrop-x.svg | 4 + src/assets/check-star-ring-filled.svg | 4 + src/assets/check-star-ring.svg | 4 + src/assets/claim-heart-wave.svg | 28 + src/assets/claim-pie-chart-wave.svg | 27 + src/assets/eth-white.svg | 9 + src/assets/icons/chevron-left-vector.svg | 3 + src/assets/icons/heart-crack.svg | 4 + src/assets/icons/usdc-24.svg | 5 + src/assets/icons/usdc-green-16.svg | 5 + src/components/ExternalLink/ExternalLink.tsx | 47 ++ src/components/ExternalLink/index.ts | 1 + src/components/GlobalStyles/GlobalStyles.tsx | 4 +- src/components/Header/Header.styles.tsx | 12 + src/components/Header/Header.tsx | 10 + src/components/IconPair/IconPair.tsx | 40 ++ src/components/IconPair/index.ts | 1 + src/components/Layout/Layout.tsx | 3 +- src/components/LayoutV2/LayoutV2.tsx | 45 ++ src/components/LayoutV2/index.ts | 2 + src/components/Loader/Loader.tsx | 23 + src/components/Loader/index.tsx | 1 + src/components/index.ts | 2 + ...A832B994f796452e4FaF191a041F791AD8A0A.json | 2 +- src/utils/bridge.ts | 4 +- src/utils/config.ts | 17 + src/utils/constants.ts | 12 + src/utils/format.ts | 49 +- src/utils/math.ts | 46 ++ src/utils/ternary.ts | 24 + src/utils/types.ts | 14 + src/views/Claim/Claim.styles.tsx | 115 ++++- src/views/Claim/Claim.tsx | 58 ++- src/views/Claim/components/Card.tsx | 25 + src/views/Claim/components/ClaimAirdrop.tsx | 214 ++++++++ .../Claim/components/DisconnectedWallet.tsx | 53 ++ src/views/Claim/components/EarnOptionCard.tsx | 80 +++ src/views/Claim/components/EligibleWallet.tsx | 78 +++ .../Claim/components/NotEligibleWallet.tsx | 55 ++ src/views/Claim/components/StepCard.tsx | 118 +++++ src/views/Claim/components/WaysToEarn.tsx | 60 +++ src/views/Claim/hooks/useAirdropRecipient.tsx | 40 ++ src/views/Claim/hooks/useClaimView.tsx | 37 ++ .../Claim/hooks/useMerkleDistributor.tsx | 126 +++++ src/views/NotFound/NotFound.styles.tsx | 4 +- .../RewardReferral/RewardReferral.styles.tsx | 5 - .../comp/RewardReferral/RewardReferral.tsx | 12 +- src/views/Staking/Staking.styles.tsx | 51 ++ src/views/Staking/Staking.tsx | 108 ++++ .../StakingExitAction.styles.tsx | 56 ++ .../StakingExitAction/StakingExitAction.tsx | 31 ++ .../components/StakingExitAction/index.tsx | 1 + .../StakingForm/StakingForm.styles.tsx | 193 +++++++ .../components/StakingForm/StakingForm.tsx | 263 ++++++++++ .../Staking/components/StakingForm/index.ts | 1 + .../StakingInputBlock.styles.tsx | 133 +++++ .../StakingInputBlock/StakingInputBlock.tsx | 86 ++++ .../components/StakingInputBlock/index.ts | 1 + .../components/StakingReward/AlertInfo.tsx | 23 + .../StakingReward/StakingReward.styles.tsx | 140 +++++ .../StakingReward/StakingReward.tsx | 108 ++++ .../Staking/components/StakingReward/index.ts | 1 + src/views/Staking/components/index.ts | 3 + .../hooks/useStakingActionsResolver.ts | 369 +++++++++++++ .../Staking/hooks/useStakingPoolResolver.ts | 25 + src/views/Staking/hooks/useStakingView.ts | 32 ++ src/views/Staking/index.ts | 1 + src/views/Staking/types.ts | 34 ++ src/views/Transactions/MyTransactions.tsx | 2 +- src/views/index.ts | 1 + yarn.lock | 483 +++++++++++++++++- 76 files changed, 3694 insertions(+), 50 deletions(-) create mode 100644 src/assets/acx.svg create mode 100644 src/assets/airdrop-gift-bg.svg create mode 100644 src/assets/airdrop-waves-bg.svg create mode 100644 src/assets/airdrop-x.svg create mode 100644 src/assets/check-star-ring-filled.svg create mode 100644 src/assets/check-star-ring.svg create mode 100644 src/assets/claim-heart-wave.svg create mode 100644 src/assets/claim-pie-chart-wave.svg create mode 100644 src/assets/eth-white.svg create mode 100644 src/assets/icons/chevron-left-vector.svg create mode 100644 src/assets/icons/heart-crack.svg create mode 100644 src/assets/icons/usdc-24.svg create mode 100644 src/assets/icons/usdc-green-16.svg create mode 100644 src/components/ExternalLink/ExternalLink.tsx create mode 100644 src/components/ExternalLink/index.ts create mode 100644 src/components/IconPair/IconPair.tsx create mode 100644 src/components/IconPair/index.ts create mode 100644 src/components/LayoutV2/LayoutV2.tsx create mode 100644 src/components/LayoutV2/index.ts create mode 100644 src/components/Loader/Loader.tsx create mode 100644 src/components/Loader/index.tsx create mode 100644 src/utils/ternary.ts create mode 100644 src/utils/types.ts create mode 100644 src/views/Claim/components/Card.tsx create mode 100644 src/views/Claim/components/ClaimAirdrop.tsx create mode 100644 src/views/Claim/components/DisconnectedWallet.tsx create mode 100644 src/views/Claim/components/EarnOptionCard.tsx create mode 100644 src/views/Claim/components/EligibleWallet.tsx create mode 100644 src/views/Claim/components/NotEligibleWallet.tsx create mode 100644 src/views/Claim/components/StepCard.tsx create mode 100644 src/views/Claim/components/WaysToEarn.tsx create mode 100644 src/views/Claim/hooks/useAirdropRecipient.tsx create mode 100644 src/views/Claim/hooks/useClaimView.tsx create mode 100644 src/views/Claim/hooks/useMerkleDistributor.tsx create mode 100644 src/views/Staking/Staking.styles.tsx create mode 100644 src/views/Staking/Staking.tsx create mode 100644 src/views/Staking/components/StakingExitAction/StakingExitAction.styles.tsx create mode 100644 src/views/Staking/components/StakingExitAction/StakingExitAction.tsx create mode 100644 src/views/Staking/components/StakingExitAction/index.tsx create mode 100644 src/views/Staking/components/StakingForm/StakingForm.styles.tsx create mode 100644 src/views/Staking/components/StakingForm/StakingForm.tsx create mode 100644 src/views/Staking/components/StakingForm/index.ts create mode 100644 src/views/Staking/components/StakingInputBlock/StakingInputBlock.styles.tsx create mode 100644 src/views/Staking/components/StakingInputBlock/StakingInputBlock.tsx create mode 100644 src/views/Staking/components/StakingInputBlock/index.ts create mode 100644 src/views/Staking/components/StakingReward/AlertInfo.tsx create mode 100644 src/views/Staking/components/StakingReward/StakingReward.styles.tsx create mode 100644 src/views/Staking/components/StakingReward/StakingReward.tsx create mode 100644 src/views/Staking/components/StakingReward/index.ts create mode 100644 src/views/Staking/components/index.ts create mode 100644 src/views/Staking/hooks/useStakingActionsResolver.ts create mode 100644 src/views/Staking/hooks/useStakingPoolResolver.ts create mode 100644 src/views/Staking/hooks/useStakingView.ts create mode 100644 src/views/Staking/index.ts create mode 100644 src/views/Staking/types.ts diff --git a/package.json b/package.json index 3479a5cbf..d231055d9 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@across-protocol/across-token": "^0.0.1", "@across-protocol/contracts-v2": "^0.0.34", "@across-protocol/sdk-v2": "^0.1.24", "@datapunt/matomo-tracker-js": "^0.5.1", diff --git a/src/Routes.tsx b/src/Routes.tsx index d4a53ee83..30e92c061 100644 --- a/src/Routes.tsx +++ b/src/Routes.tsx @@ -1,5 +1,6 @@ import { useState, useEffect } from "react"; import { Switch, Route, useLocation, useHistory } from "react-router-dom"; + import { Send, Pool, @@ -7,6 +8,7 @@ import { MyTransactions, AllTransactions, Rewards, + Staking, Claim, NotFound, } from "views"; @@ -20,6 +22,8 @@ import { WrongNetworkError, rewardsBannerWarning, generalMaintenanceMessage, + stringValueInArray, + getConfig, } from "utils"; import { ReactComponent as InfoLogo } from "assets/icons/info-24.svg"; import Toast from "components/Toast"; @@ -36,6 +40,7 @@ function useRoutes() { const location = useLocation(); const history = useHistory(); const { error, removeError } = useError(); + const config = getConfig(); // force the user on /pool page if showMigrationPage is active. useEffect(() => { if (enableMigration && location.pathname !== "/pool") { @@ -51,6 +56,7 @@ function useRoutes() { removeError, location, isContractAddress, + config, }; } // Need this component for useLocation hook @@ -61,6 +67,7 @@ const Routes: React.FC = () => { error, removeError, location, + config, isContractAddress, } = useRoutes(); @@ -105,7 +112,23 @@ const Routes: React.FC = () => { - + + { + const poolIdFound = stringValueInArray( + match.params.poolId.toLowerCase(), + config.getPoolSymbols() + ); + + if (poolIdFound) { + return ; + } else { + return ; + } + }} + /> diff --git a/src/assets/acx.svg b/src/assets/acx.svg new file mode 100644 index 000000000..e4e19df02 --- /dev/null +++ b/src/assets/acx.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/airdrop-gift-bg.svg b/src/assets/airdrop-gift-bg.svg new file mode 100644 index 000000000..2f8a224f1 --- /dev/null +++ b/src/assets/airdrop-gift-bg.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/airdrop-waves-bg.svg b/src/assets/airdrop-waves-bg.svg new file mode 100644 index 000000000..20d4913d7 --- /dev/null +++ b/src/assets/airdrop-waves-bg.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/airdrop-x.svg b/src/assets/airdrop-x.svg new file mode 100644 index 000000000..c893ec600 --- /dev/null +++ b/src/assets/airdrop-x.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/check-star-ring-filled.svg b/src/assets/check-star-ring-filled.svg new file mode 100644 index 000000000..c1acce71c --- /dev/null +++ b/src/assets/check-star-ring-filled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/check-star-ring.svg b/src/assets/check-star-ring.svg new file mode 100644 index 000000000..50291292f --- /dev/null +++ b/src/assets/check-star-ring.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/claim-heart-wave.svg b/src/assets/claim-heart-wave.svg new file mode 100644 index 000000000..a59f15815 --- /dev/null +++ b/src/assets/claim-heart-wave.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/claim-pie-chart-wave.svg b/src/assets/claim-pie-chart-wave.svg new file mode 100644 index 000000000..7171ac583 --- /dev/null +++ b/src/assets/claim-pie-chart-wave.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/eth-white.svg b/src/assets/eth-white.svg new file mode 100644 index 000000000..56879e1f6 --- /dev/null +++ b/src/assets/eth-white.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icons/chevron-left-vector.svg b/src/assets/icons/chevron-left-vector.svg new file mode 100644 index 000000000..0b485ef7c --- /dev/null +++ b/src/assets/icons/chevron-left-vector.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/heart-crack.svg b/src/assets/icons/heart-crack.svg new file mode 100644 index 000000000..ff49e69a5 --- /dev/null +++ b/src/assets/icons/heart-crack.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icons/usdc-24.svg b/src/assets/icons/usdc-24.svg new file mode 100644 index 000000000..bac4cac14 --- /dev/null +++ b/src/assets/icons/usdc-24.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/usdc-green-16.svg b/src/assets/icons/usdc-green-16.svg new file mode 100644 index 000000000..4011ca82f --- /dev/null +++ b/src/assets/icons/usdc-green-16.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/ExternalLink/ExternalLink.tsx b/src/components/ExternalLink/ExternalLink.tsx new file mode 100644 index 000000000..5d8eb1cfc --- /dev/null +++ b/src/components/ExternalLink/ExternalLink.tsx @@ -0,0 +1,47 @@ +import styled from "@emotion/styled"; + +import { ReactComponent as ExternalLink12Icon } from "assets/icons/external-link-12.svg"; + +type Props = { + text: string; + href: string; +}; + +export function ExternalLink(props: Props) { + return ( + + {props.text} + + ); +} + +const Link = styled.a` + display: flex; + align-items: center; + font-size: ${16 / 16}rem; + line-height: ${20 / 16}rem; + font-weight: 500; + text-decoration: none; + color: #e0f3ff; + transition: opacity 0.1s; + cursor: pointer; + + svg { + path { + fill: #e0f3ff; + } + } + + &:hover { + opacity: 0.8; + } + + @media (max-width: 428px) { + font-size: ${14 / 16}rem; + line-height: ${18 / 16}rem; + } +`; + +export const ExternalLinkIcon = styled(ExternalLink12Icon)` + margin: 2px 0 0 4px; +`; diff --git a/src/components/ExternalLink/index.ts b/src/components/ExternalLink/index.ts new file mode 100644 index 000000000..094bf8d13 --- /dev/null +++ b/src/components/ExternalLink/index.ts @@ -0,0 +1 @@ +export { ExternalLink } from "./ExternalLink"; diff --git a/src/components/GlobalStyles/GlobalStyles.tsx b/src/components/GlobalStyles/GlobalStyles.tsx index 1e1dd86ca..4019530f7 100644 --- a/src/components/GlobalStyles/GlobalStyles.tsx +++ b/src/components/GlobalStyles/GlobalStyles.tsx @@ -91,14 +91,14 @@ const globalStyles = css` } html, body { - height: 100%; + min-height: 100vh; } body { background-color: var(--color-gray); color: var(--color-white); } #root { - height: 100%; + min-height: 100vh; isolation: isolate; } // iphone query diff --git a/src/components/Header/Header.styles.tsx b/src/components/Header/Header.styles.tsx index 126f67162..bd4deee6d 100644 --- a/src/components/Header/Header.styles.tsx +++ b/src/components/Header/Header.styles.tsx @@ -71,6 +71,10 @@ export const Item = styled.li` background-color: #e0f3ff; transform: translateX(-50%); } + + svg { + stroke-width: 2px; + } } :hover { @@ -103,3 +107,11 @@ export const MobileNavigation = styled(motion.nav)` margin-left: 8px; } `; + +export const TextWithIcon = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 8px; +`; diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 97fe727a7..a28c58b6d 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,5 +1,6 @@ import { useLocation } from "react-router"; import { Link as UnstyledLink } from "react-router-dom"; +import { Gift } from "react-feather"; import Wallet from "../Wallet"; import { Wrapper, @@ -10,6 +11,7 @@ import { Item, WalletWrapper, Spacing, + TextWithIcon, } from "./Header.styles"; import MenuToggle from "./MenuToggle"; import { enableMigration } from "utils"; @@ -23,6 +25,14 @@ const LINKS = !enableMigration { href: "/pool", name: "Pool" }, { href: "/rewards", name: "Rewards" }, { href: "/transactions", name: "Transactions" }, + { + href: "/airdrop", + name: ( + + Airdrop + + ), + }, ] : []; diff --git a/src/components/IconPair/IconPair.tsx b/src/components/IconPair/IconPair.tsx new file mode 100644 index 000000000..959ba217f --- /dev/null +++ b/src/components/IconPair/IconPair.tsx @@ -0,0 +1,40 @@ +import styled from "@emotion/styled"; +import React from "react"; + +type Props = { + MainIcon: React.ReactElement; + SmallIcon?: React.ReactElement; +}; + +export function IconPair(props: Props) { + return ( + + {props.MainIcon} + {props.SmallIcon && ( + {props.SmallIcon} + )} + + ); +} + +const Container = styled.div` + position: relative; +`; + +const MainIconContainer = styled.div` + height: 32px; + width: 32px; +`; + +const SmallIconContainer = styled.div` + position: absolute; + right: -8px; + bottom: -1px; + height: 18px; + width: 18px; + + svg { + border: 2px solid #3e4047; + border-radius: 50%; + } +`; diff --git a/src/components/IconPair/index.ts b/src/components/IconPair/index.ts new file mode 100644 index 000000000..8b5596d24 --- /dev/null +++ b/src/components/IconPair/index.ts @@ -0,0 +1 @@ +export { IconPair } from "./IconPair"; diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 4812a41b1..7715f9058 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -127,8 +127,7 @@ const Wrapper = styled.div` display: grid; padding: 0 10px; grid-template-columns: 1fr min(var(--central-content), 100%) 1fr; - min-height: 100%; - height: fit-content; + min-height: 100vh; @media ${QUERIES.tabletAndUp} { padding: 0 30px; } diff --git a/src/components/LayoutV2/LayoutV2.tsx b/src/components/LayoutV2/LayoutV2.tsx new file mode 100644 index 000000000..ae5fa48a6 --- /dev/null +++ b/src/components/LayoutV2/LayoutV2.tsx @@ -0,0 +1,45 @@ +import styled from "@emotion/styled"; +import Footer from "components/Footer"; +import { QUERIESV2 } from "utils"; + +const LayoutV2: React.FC = ({ children }) => { + return ( + + {children} +