diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 1ab046f05..e0fd4f277 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -1,5 +1,9 @@ import { FC } from "react" -import { As, Icon as ChakraIcon, IconProps } from "@chakra-ui/react" +import { + As, + Icon as ChakraIcon, + IconProps, +} from "@threshold-network/components" import IconEnum from "../enums/icon" import iconMap from "../static/icons/iconMap" @@ -10,7 +14,7 @@ const Icon: FC = ({ as, ...props }) => { } // @ts-ignore - return + return } export default Icon diff --git a/src/components/tBTC/BridgeActivity.tsx b/src/components/tBTC/BridgeActivity.tsx new file mode 100644 index 000000000..a999c19ef --- /dev/null +++ b/src/components/tBTC/BridgeActivity.tsx @@ -0,0 +1,201 @@ +import { FC, createContext, useContext, ReactElement } from "react" +import { + Badge, + BodyMd, + Image, + List, + useColorModeValue, + Box, + LinkBox, + LinkOverlay, + Stack, + Skeleton, + ListProps, + HStack, + StackProps, + LabelSm, +} from "@threshold-network/components" +import { + BridgeActivityStatus, + BridgeActivity as BridgeActivityType, +} from "../../threshold-ts/tbtc" +import emptyHistoryImageSrcDark from "../../static/images/tBTC-bridge-no-history-dark.svg" +import emptyHistoryImageSrcLight from "../../static/images/tBTC-bridge-no-history-light.svg" +import { InlineTokenBalance } from "../TokenBalance" +import Link from "../Link" +import { OutlineListItem } from "../OutlineListItem" + +export type BridgeActivityProps = { + data: BridgeActivityType[] + isFetching: boolean + emptyState?: ReactElement +} + +type BridgeActivityContextValue = { + [Property in keyof BridgeActivityProps]-?: BridgeActivityProps[Property] +} & { isBridgeHistoryEmpty: boolean } + +const BridgeActivityContext = createContext< + BridgeActivityContextValue | undefined +>(undefined) + +const useBridgeActivityContext = () => { + const context = useContext(BridgeActivityContext) + if (!context) { + throw new Error( + "BridgeActivityContext used outside of the BridgeActivity component." + ) + } + + return context +} + +export const BridgeActivity: FC = ({ + data, + isFetching, + emptyState, + children, +}) => { + const isBridgeHistoryEmpty = data.length === 0 + + return ( + , + }} + > + {children} + + ) +} + +export const BridgeAcivityHeader: FC = (props) => { + return ( + + tBTC + state + + ) +} + +export const BridgeActivityData: FC = (props) => { + const { data, isBridgeHistoryEmpty, isFetching, emptyState } = + useBridgeActivityContext() + + return isFetching ? ( + + ) : ( + + {isBridgeHistoryEmpty ? emptyState : data.map(renderActivityItem)} + + ) +} + +const ActivityItem: FC = ({ + amount, + status, + depositKey, +}) => { + return ( + + + + + + + ) +} + +const renderActivityItem = (item: BridgeActivityType) => ( + +) + +const bridgeActivityStatusToBadgeProps: Record< + BridgeActivityStatus, + { colorScheme: string } +> = { + [BridgeActivityStatus.MINTED]: { + colorScheme: "green", + }, + [BridgeActivityStatus.PENDING]: { + colorScheme: "yellow", + }, + [BridgeActivityStatus.ERROR]: { + colorScheme: "red", + }, +} + +const TBTCStatusBadge: FC<{ status: BridgeActivityStatus }> = ({ status }) => { + return ( + + {status} + + ) +} + +export const ActivityItemWrapper: FC = ({ children }) => ( + + {children} + +) + +export const BridgeActivityEmptyHistoryImg: FC = () => { + const { isBridgeHistoryEmpty, isFetching } = useBridgeActivityContext() + const epmtyHistoryImg = useColorModeValue( + emptyHistoryImageSrcLight, + emptyHistoryImageSrcDark + ) + + return isBridgeHistoryEmpty && !isFetching ? ( + <> + no-history + You have no history yet. + + ) : ( + <> + ) +} + +const EmptyActivityItem: FC = () => ( + + + -.-- + + + -.-- + + +) +const EmptyActivity: FC = () => { + return ( + <> + + + + ) +} + +const BridgeActivityLoadingState = () => { + return ( + + + + + + ) +} diff --git a/src/components/tBTC/index.ts b/src/components/tBTC/index.ts index 564c7c00d..2787366df 100644 --- a/src/components/tBTC/index.ts +++ b/src/components/tBTC/index.ts @@ -1,3 +1,5 @@ export * from "./TakeNoteList" export * from "./Links" export * from "./Stats" +export * from "./tBTCText" +export * from "./BridgeActivity" diff --git a/src/components/tBTC/tBTCText.tsx b/src/components/tBTC/tBTCText.tsx new file mode 100644 index 000000000..2ceaa1ccb --- /dev/null +++ b/src/components/tBTC/tBTCText.tsx @@ -0,0 +1,13 @@ +import { FC } from "react" +import { Box, BoxProps } from "@threshold-network/components" + +export const TBTCText: FC = (props) => { + return ( + + + t + + BTC + + ) +} diff --git a/src/pages/Overview/Network/CardTemplate.tsx b/src/pages/Overview/Network/CardTemplate.tsx index c523a33ed..36cab6c7c 100644 --- a/src/pages/Overview/Network/CardTemplate.tsx +++ b/src/pages/Overview/Network/CardTemplate.tsx @@ -1,6 +1,5 @@ import { FC } from "react" -import { LabelSm, Card, LineDivider } from "@threshold-network/components" -import { BoxProps } from "@chakra-ui/react" +import { LabelSm, Card, BoxProps } from "@threshold-network/components" const CardTemplate: FC<{ title: string | JSX.Element } & BoxProps> = ({ title, @@ -10,7 +9,6 @@ const CardTemplate: FC<{ title: string | JSX.Element } & BoxProps> = ({ return ( {typeof title === "string" ? {title} : title} - {children} ) diff --git a/src/pages/Overview/Network/StakingOverview.tsx b/src/pages/Overview/Network/StakingOverview.tsx index cf7605d3b..2720ddaa4 100644 --- a/src/pages/Overview/Network/StakingOverview.tsx +++ b/src/pages/Overview/Network/StakingOverview.tsx @@ -16,8 +16,10 @@ const StakingOverview: FC = () => { return ( - Staked Balance - + + My Staked Balance + + = ({ const tvl = formatFiatCurrencyAmount(totalValueLocked) return ( - - -

- {tvl} -

-
+ +

+ {tvl} +

) } diff --git a/src/pages/Overview/Network/index.tsx b/src/pages/Overview/Network/index.tsx index 2e714ea29..33d4994ed 100644 --- a/src/pages/Overview/Network/index.tsx +++ b/src/pages/Overview/Network/index.tsx @@ -1,15 +1,46 @@ import { useEffect } from "react" -import { SimpleGrid, Stack } from "@threshold-network/components" +import { + Box, + Card, + HStack, + SimpleGrid, + Image, + H5, + BodyMd, + VStack, +} from "@threshold-network/components" +import { useWeb3React } from "@web3-react/core" import TotalValueLocked from "./TotalValueLocked" import StakingOverview from "./StakingOverview" import { useFetchTvl } from "../../../hooks/useFetchTvl" import { PageComponent } from "../../../types" import { TBTCBrdigeStats } from "./tBTCBridgeStats" import { useFetchRecentDeposits } from "../../../hooks/tbtc" +import { TBTCUserStats } from "./tBTCUserStats" +import { useAppDispatch, useAppSelector } from "../../../hooks/store" +import { selectBridgeActivity, tbtcSlice } from "../../../store/tbtc" +import ButtonLink from "../../../components/ButtonLink" +import upgradeToTIcon from "../../../static/images/upgrade-to-t.svg" const Network: PageComponent = () => { const [tvlInUSD, fetchtTvlData, tvlInTokenUnits] = useFetchTvl() const [deposits, isFetching, error] = useFetchRecentDeposits() + const { account } = useWeb3React() + const dispatch = useAppDispatch() + const bridgeActivity = useAppSelector(selectBridgeActivity) + const isBridgeActivityFetching = useAppSelector( + (state) => state.tbtc.bridgeActivity.isFetching + ) + + useEffect(() => { + if (!account) return + + dispatch( + tbtcSlice.actions.requestBridgeActivity({ + depositor: account, + }) + ) + }, [dispatch, account]) useEffect(() => { fetchtTvlData() @@ -22,10 +53,32 @@ const Network: PageComponent = () => { tvlInUSD={tvlInUSD.tBTC} deposits={deposits} /> - - + + - + + + + +
Do you own KEEP or NU tokens?
+ Upgrade your tokens to T. +
+
+ + Upgrade + +
+ + ) } diff --git a/src/pages/Overview/Network/tBTCBridgeStats.tsx b/src/pages/Overview/Network/tBTCBridgeStats.tsx index 0b5da69aa..de8be4e65 100644 --- a/src/pages/Overview/Network/tBTCBridgeStats.tsx +++ b/src/pages/Overview/Network/tBTCBridgeStats.tsx @@ -3,6 +3,7 @@ import { Card, Divider, LabelSm } from "@threshold-network/components" import { DefaultProtocolHistory, ProtocolHistoryProps, + TBTCText, TVL, TVLProps, } from "../../../components/tBTC" @@ -16,7 +17,9 @@ export const TBTCBrdigeStats: FC = ({ }) => { return ( - tBTC Bridge Stats + + Bridge Stats + diff --git a/src/pages/Overview/Network/tBTCUserStats.tsx b/src/pages/Overview/Network/tBTCUserStats.tsx new file mode 100644 index 000000000..9d53c349c --- /dev/null +++ b/src/pages/Overview/Network/tBTCUserStats.tsx @@ -0,0 +1,94 @@ +import { FC } from "react" +import { + Badge, + BodyMd, + Box, + Card, + Divider, + LabelSm, +} from "@threshold-network/components" +import InfoBox from "../../../components/InfoBox" +import TokenBalance from "../../../components/TokenBalance" +import ButtonLink from "../../../components/ButtonLink" +import { useTokenState } from "../../../hooks/useTokenState" +import { + ActivityItemWrapper, + BridgeActivity, + BridgeActivityData, + BridgeActivityProps, + TBTCText, +} from "../../../components/tBTC" +import { tBTCFillBlack } from "../../../static/icons/tBTCFillBlack" +import Link from "../../../components/Link" + +type TBTCUserStatsProps = { + bridgeActivity: BridgeActivityProps["data"] + isBridgeActivityFetching: BridgeActivityProps["isFetching"] +} + +export const TBTCUserStats: FC = ({ + bridgeActivity, + isBridgeActivityFetching, +}) => { + const { tbtcv2 } = useTokenState() + const _bridgeActivity = bridgeActivity.slice(0, 2) + + return ( + + + My Stats + + + My Balance + + + + + + New Mint + + + My Activity + } + > + + + + + View All + + + + ) +} + +const BridgeActivityCustomEmptyStateItem = () => { + return ( + + + -.-- tBTC + + + connect your wallet + + + ) +} + +const BridgeActivityCustomEmptyState = () => { + return ( + <> + + + + ) +} diff --git a/src/pages/tBTC/Bridge/BridgeActivity/index.tsx b/src/pages/tBTC/Bridge/BridgeActivity/index.tsx deleted file mode 100644 index ac37bad42..000000000 --- a/src/pages/tBTC/Bridge/BridgeActivity/index.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import { ComponentProps, FC } from "react" -import { - Badge, - BodyMd, - Card, - HStack, - Image, - LabelSm, - List, - useColorModeValue, - Box, - LinkBox, - LinkOverlay, -} from "@threshold-network/components" -import { - BridgeActivityStatus, - BridgeActivity as BridgeActivityType, -} from "../../../../threshold-ts/tbtc" -import emptyHistoryImageSrcDark from "../../../../static/images/tBTC-bridge-no-history-dark.svg" -import emptyHistoryImageSrcLight from "../../../../static/images/tBTC-bridge-no-history-light.svg" -import { InlineTokenBalance } from "../../../../components/TokenBalance" -import Link from "../../../../components/Link" -import { OutlineListItem } from "../../../../components/OutlineListItem" - -const bridgeActivityStatusToBadgeProps: Record< - BridgeActivityStatus, - { colorScheme: string } -> = { - [BridgeActivityStatus.MINTED]: { - colorScheme: "green", - }, - [BridgeActivityStatus.PENDING]: { - colorScheme: "yellow", - }, - [BridgeActivityStatus.ERROR]: { - colorScheme: "red", - }, -} - -const TBTCStatusBadge: FC<{ status: BridgeActivityStatus }> = ({ status }) => { - return ( - - {status} - - ) -} - -export const BridgeActivityCard: FC> = ({ - children, - ...props -}) => { - return ( - - my activity - {children} - - ) -} - -const ActivityItemWrapper: FC = ({ children }) => ( - - {children} - -) - -const ActivityItem: FC = ({ - amount, - status, - depositKey, -}) => { - return ( - - - - - - - ) -} - -const renderActivityItem = (item: BridgeActivityType) => ( - -) - -export const BridgeActivity: FC<{ - data: BridgeActivityType[] -}> = ({ data }) => { - const epmtyHistoryImg = useColorModeValue( - emptyHistoryImageSrcLight, - emptyHistoryImageSrcDark - ) - - const isHistoryEmpty = data.length === 0 - - return ( - <> - - tBTC - state - - - {isHistoryEmpty ? : data.map(renderActivityItem)} - - {isHistoryEmpty && ( - <> - no-history - You have no history yet. - - )} - - ) -} - -const EmptyActivity: FC = () => { - return ( - <> - - -.-- - -.-- - - - -.-- - -.-- - - - ) -} diff --git a/src/pages/tBTC/Bridge/BridgeActivityCard/index.tsx b/src/pages/tBTC/Bridge/BridgeActivityCard/index.tsx new file mode 100644 index 000000000..ab5c19ec5 --- /dev/null +++ b/src/pages/tBTC/Bridge/BridgeActivityCard/index.tsx @@ -0,0 +1,24 @@ +import { ComponentProps, FC } from "react" +import { Card, LabelSm } from "@threshold-network/components" +import { + BridgeAcivityHeader, + BridgeActivity, + BridgeActivityData, + BridgeActivityEmptyHistoryImg, + BridgeActivityProps, +} from "../../../../components/tBTC" + +export const BridgeActivityCard: FC< + ComponentProps & BridgeActivityProps +> = ({ isFetching, data, children, ...props }) => { + return ( + + my activity + + + + + + + ) +} diff --git a/src/pages/tBTC/Bridge/index.tsx b/src/pages/tBTC/Bridge/index.tsx index 3cd643f3d..6b1614358 100644 --- a/src/pages/tBTC/Bridge/index.tsx +++ b/src/pages/tBTC/Bridge/index.tsx @@ -3,7 +3,7 @@ import { Grid, Box, Skeleton, Stack } from "@threshold-network/components" import { PageComponent } from "../../../types" import { TbtcBalanceCard } from "./TbtcBalanceCard" import { MintUnmintNav } from "./MintUnmintNav" -import { BridgeActivityCard, BridgeActivity } from "./BridgeActivity" +import { BridgeActivityCard } from "./BridgeActivityCard" import { useModal } from "../../../hooks/useModal" import { ModalType } from "../../../enums" import { useTBTCTerms } from "../../../hooks/useTBTCTerms" @@ -58,17 +58,10 @@ const TBTCBridge: PageComponent = (props) => { - - {isBridgeActivityFetching ? ( - - - - - - ) : ( - - )} - + ) diff --git a/src/static/images/upgrade-to-t.svg b/src/static/images/upgrade-to-t.svg new file mode 100644 index 000000000..bb91b92c2 --- /dev/null +++ b/src/static/images/upgrade-to-t.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/theme/Badge.ts b/src/theme/Badge.ts index 6f9e725eb..93b7b7586 100644 --- a/src/theme/Badge.ts +++ b/src/theme/Badge.ts @@ -23,7 +23,12 @@ const variants = { const { colorScheme: c, theme } = props const whiteAlpha200 = "rgba(255, 255, 255, 0.08);" - const bgVariant = c === "brand" ? "75" : "50" + let bgVariant = "50" + if (c === "brand") { + bgVariant = "75" + } else if (c === "gray") { + bgVariant = "100" + } // The `brand.75` color is already defined in the default theme but for some // reason chakra can't find the `brand.75` color. const brand75 = "#F2EDFF"