diff --git a/src/api/farms.ts b/src/api/farms.ts index 313660549..f7e9af55d 100644 --- a/src/api/farms.ts +++ b/src/api/farms.ts @@ -280,10 +280,6 @@ function getFarmApr( apr = poolYieldPerPeriod.times(periodsPerYear) } - // multiply by 100 since APR should be a percentage - apr = apr.times(100) - - const minApr = loyaltyFactor ? apr.times(loyaltyFactor) : null // max distribution of rewards // https://www.notion.so/Screen-elements-mapping-Farms-baee6acc456542ca8d2cccd1cc1548ae?p=4a2f16a9f2454095945dbd9ce0eb1b6b&pm=s const distributedRewards = globalFarm.pendingRewards @@ -314,6 +310,13 @@ function getFarmApr( .times(100) .times(priceAdjustment.shiftedBy(-18)) + const isDistributed = distributedRewards.gte(maxRewards) + + // multiply by 100 since APR should be a percentage + apr = isDistributed ? BN_0 : apr.times(100) + + const minApr = loyaltyFactor ? apr.times(loyaltyFactor) : null + return { apr, minApr, @@ -327,6 +330,7 @@ function getFarmApr( rewardCurrency, incentivizedAsset, yieldFarmId: yieldFarm.id.toString(), + isDistributed, } } diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index c912d0f90..aa39a7ab3 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -1,6 +1,6 @@ -import { Spinner } from "components/Spinner/Spinner.styled" import { ComponentProps, forwardRef } from "react" import { SButton, SButtonTransparent, SContent } from "./Button.styled" +import { Spinner } from "components/Spinner/Spinner" export type ButtonVariant = | "primary" @@ -34,7 +34,7 @@ export const Button: React.FC = ({ return ( - {props.isLoading && } + {props.isLoading && } {props.text || props.children} diff --git a/src/components/Input/Input.stories.tsx b/src/components/Input/Input.stories.tsx index 3795f28ef..d756f35ed 100644 --- a/src/components/Input/Input.stories.tsx +++ b/src/components/Input/Input.stories.tsx @@ -2,6 +2,8 @@ import { Meta, StoryObj } from "@storybook/react" import { ComponentPropsWithoutRef, useState } from "react" import { Provider as TooltipProvider } from "@radix-ui/react-tooltip" import { Input } from "./Input" +import Percentage from "assets/icons/Percentage.svg?react" +import IconSearch from "assets/icons/IconSearch.svg?react" export default { component: Input, @@ -57,3 +59,17 @@ export const WithTooltip: Story = { tooltip: "Enter amount to swap", }, } + +export const WithIconStart: Story = { + render: Template, + args: { + iconStart: , + }, +} + +export const WithIconEnd: Story = { + render: Template, + args: { + iconEnd: , + }, +} diff --git a/src/components/Input/Input.styled.ts b/src/components/Input/Input.styled.ts index 9ff54b7dc..cf92630ec 100644 --- a/src/components/Input/Input.styled.ts +++ b/src/components/Input/Input.styled.ts @@ -26,6 +26,32 @@ export const SWrapper = styled.div<{ color: ${theme.colors.white}; } `}; + + & > svg { + position: absolute; + top: 50%; + + transform: translateY(-50%); + color: rgba(${theme.rgbColors.white}, 0.4); + } + + &:has(svg + input) { + & > svg { + left: 12px; + } + input[type="text"] { + padding-left: 48px; + } + } + + &:has(input + svg) { + & > svg { + right: 12px; + } + input[type="text"] { + padding-right: 48px; + } + } ` export const SInput = styled.input<{ error?: string; unit?: string }>` diff --git a/src/components/Input/Input.tsx b/src/components/Input/Input.tsx index e2cc29f0c..0c811b610 100644 --- a/src/components/Input/Input.tsx +++ b/src/components/Input/Input.tsx @@ -1,5 +1,5 @@ import { Label } from "components/Label/Label" -import React, { FC } from "react" +import React, { FC, ReactNode } from "react" import { SWrapper, SInput } from "./Input.styled" // Error handling should be added once we implement forms and validation, for now the input accepts error props @@ -16,6 +16,8 @@ export type InputProps = { withLabel?: boolean className?: string tooltip?: string + iconStart?: ReactNode + iconEnd?: ReactNode } export const Input: FC = ({ @@ -27,6 +29,8 @@ export const Input: FC = ({ name, withLabel, tooltip, + iconStart, + iconEnd, ...p }) => { return ( @@ -40,6 +44,7 @@ export const Input: FC = ({ {...p} > + {iconStart} ) => onChange(e.target.value) @@ -53,6 +58,7 @@ export const Input: FC = ({ role="presentation" autoComplete="off" /> + {iconEnd} diff --git a/src/components/Layout/Header/toolbar/buttons/Bell.tsx b/src/components/Layout/Header/toolbar/buttons/Bell.tsx index 7c32659fd..e61cbd4b7 100644 --- a/src/components/Layout/Header/toolbar/buttons/Bell.tsx +++ b/src/components/Layout/Header/toolbar/buttons/Bell.tsx @@ -1,4 +1,3 @@ -import { Spinner } from "components/Spinner/Spinner.styled" import { SMaskContainer, SActiveReferendumIcon } from "./Bell.styled" import { InfoTooltip } from "components/InfoTooltip/InfoTooltip" import { useToast } from "state/toasts" @@ -10,6 +9,7 @@ import { SToolbarIcon, } from "components/Layout/Header/toolbar/HeaderToolbar.styled" import BellIcon from "assets/icons/BellIcon.svg?react" +import { Spinner } from "components/Spinner/Spinner" export const Bell = () => { const { setSidebar, toasts } = useToast() @@ -38,9 +38,7 @@ export const Bell = () => { asChild > setSidebar(true)}> - {isLoading && ( - - )} + {isLoading && } @@ -9,14 +9,20 @@ export default { } as Meta const SContainer = styled.div` - width: 300px; + width: 100%; height: 200px; + + display: flex; + align-items: center; + gap: 24px; ` const Template = () => { return ( - + + + ) } diff --git a/src/components/Spinner/Spinner.styled.ts b/src/components/Spinner/Spinner.styled.ts index 0065a77f3..f0252df16 100644 --- a/src/components/Spinner/Spinner.styled.ts +++ b/src/components/Spinner/Spinner.styled.ts @@ -1,6 +1,5 @@ import { keyframes } from "@emotion/react" import styled from "@emotion/styled" -import { theme } from "theme" import { getResponsiveStyles, ResponsiveValue } from "utils/responsive" const spin = keyframes` @@ -13,56 +12,27 @@ const spin = keyframes` } ` -export const Spinner = styled.span<{ - width?: ResponsiveValue - height?: ResponsiveValue +export const SSpinnerContainer = styled.div<{ + size: ResponsiveValue }>` - --spinner-width: 3px; - - display: block; - position: relative; - - border-radius: 9999px; - mask: radial-gradient( - farthest-side, - rgba(255, 255, 255, 0) calc(100% - var(--spinner-width)), - rgba(255, 255, 255, 1) calc(100% - var(--spinner-width) + 1px) - ); - - animation: ${spin} 0.6s linear infinite; - - overflow: hidden; - - background: ${theme.gradients.spinner}; - - &:before { - content: ""; - position: absolute; - - width: var(--spinner-width); - height: var(--spinner-width); - - border-radius: 9999px; - top: 0; - left: 50%; - - transform: translateX(calc(var(--spinner-width) / -2)); - } - ${(p) => [ - getResponsiveStyles(p.width, (width) => ({ width })), - getResponsiveStyles(p.height, (height) => ({ height })), + getResponsiveStyles(p.size, (size) => ({ width: size })), + getResponsiveStyles(p.size, (size) => ({ height: size })), ]} + + animation: ${spin} 0.6s linear infinite; ` -export const ToastSpinner = styled(Spinner)` +export const Gradient = styled.div` + width: 100%; + height: 100%; background: conic-gradient( - from 0deg, - rgba(10, 13, 26, 0) 28.46deg, - rgba(43, 166, 255, 0.14) 44.98deg, - rgba(146, 183, 255, 0.38) 57.63deg, - #ffffff 88deg, - #ffffff 100deg, - #ffffff 200deg + from 1deg at 50% 50%, + rgba(10, 13, 26, 0) 90deg, + rgba(255, 255, 255, 0.2) 99deg, + #00c2ff 160deg, + #b6cfff 249deg, + #ffffff 353deg, + rgba(10, 13, 26, 0) 358deg ); ` diff --git a/src/components/Spinner/Spinner.tsx b/src/components/Spinner/Spinner.tsx new file mode 100644 index 000000000..6400fe5d9 --- /dev/null +++ b/src/components/Spinner/Spinner.tsx @@ -0,0 +1,71 @@ +import { ResponsiveValue } from "utils/responsive" +import { Gradient, SSpinnerContainer } from "./Spinner.styled" + +export const Spinner = ({ + size = 34, + className, +}: { + size?: ResponsiveValue + className?: string +}) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/src/components/Toast/Toast.styled.ts b/src/components/Toast/Toast.styled.ts index 6dc67c0e3..7fb534632 100644 --- a/src/components/Toast/Toast.styled.ts +++ b/src/components/Toast/Toast.styled.ts @@ -36,7 +36,7 @@ export const SIcon = styled.div` align-items: center; justify-content: center; - svg { + & > svg { width: 16px; height: 16px; } diff --git a/src/components/Toast/ToastContent.tsx b/src/components/Toast/ToastContent.tsx index cb4ef99d8..431f31680 100644 --- a/src/components/Toast/ToastContent.tsx +++ b/src/components/Toast/ToastContent.tsx @@ -6,12 +6,12 @@ import InfoIcon from "assets/icons/InfoIcon.svg?react" import LinkIcon from "assets/icons/LinkIcon.svg?react" import UnknownIcon from "assets/icons/Unknown.svg?react" import { Text } from "components/Typography/Text/Text" -import { Spinner } from "components/Spinner/Spinner.styled" import { Maybe, useNow } from "utils/helpers" import { useTranslation } from "react-i18next" import { theme } from "theme" import { ToastVariant } from "state/toasts" import ChainlinkIcon from "assets/icons/ChainlinkIcon.svg?react" +import { Spinner } from "components/Spinner/Spinner" export function ToastContent(props: { variant: Maybe @@ -34,7 +34,7 @@ export function ToastContent(props: { ) : props.variant === "error" ? ( ) : props.variant === "progress" ? ( - + ) : props.variant === "unknown" ? ( ) : props.variant === "temporary" ? ( diff --git a/src/i18n/locales/en/translations.json b/src/i18n/locales/en/translations.json index b17a5aa96..09d648d0c 100644 --- a/src/i18n/locales/en/translations.json +++ b/src/i18n/locales/en/translations.json @@ -7,6 +7,8 @@ "price": "Price", "tvl": "Total value locked", "fee": "Fee", + "details": "Details", + "manage": "Manage", "24Volume": "24h volume", "duration.left": "{{duration}} left", "duration.ago": "{{duration}} ago", @@ -213,6 +215,8 @@ "liquidity.asset.actions.joinFarms": "Join Farms", "liquidity.asset.actions.header": "{{tokens}} actions", "liquidity.asset.actions.myPositions": "My positions", + "liquidity.asset.actions.myPositions.amount_one": "{{count}} Position", + "liquidity.asset.actions.myPositions.amount_other": "{{count}} Positions", "liquidity.asset.actions.farmDetails_one": "Farm Details", "liquidity.asset.actions.farmDetails_other": "Farms Details", "liquidity.asset.claim.button": "Claim all", diff --git a/src/sections/pools/PoolsPage.utils.ts b/src/sections/pools/PoolsPage.utils.ts index 027d8b712..0c939e5b3 100644 --- a/src/sections/pools/PoolsPage.utils.ts +++ b/src/sections/pools/PoolsPage.utils.ts @@ -227,10 +227,14 @@ export const usePools = () => { ?.projected_apr_perc ?? BN_NAN, ) + const filteredOmnipoolPositions = omnipoolPositions.data.filter( + (omnipoolPosition) => omnipoolPosition.assetId === assetId, + ) + + const filteredMiningPositions = miningPositions.data?.[assetId] ?? [] + const isPositions = - omnipoolPositions.data.some( - (omnipoolPosition) => omnipoolPosition.assetId === assetId, - ) || !!miningPositions.data?.[assetId]?.length + !!filteredOmnipoolPositions.length || !!filteredMiningPositions?.length return { id: assetId, @@ -244,6 +248,8 @@ export const usePools = () => { isVolumeLoading: volumes.isLoading, fee, isFeeLoading: fees.isLoading, + omnipoolPositions: filteredOmnipoolPositions, + miningPositions: filteredMiningPositions, isPositions, } }) diff --git a/src/sections/pools/farms/components/detailsCard/FarmDetailsCard.tsx b/src/sections/pools/farms/components/detailsCard/FarmDetailsCard.tsx index f5ea30f91..c67873371 100644 --- a/src/sections/pools/farms/components/detailsCard/FarmDetailsCard.tsx +++ b/src/sections/pools/farms/components/detailsCard/FarmDetailsCard.tsx @@ -102,7 +102,7 @@ export const FarmDetailsCard = ({ - {apr.data.minApr + {apr.data.minApr && apr.data?.apr.gt(0) ? t("value.APR.range", { from: apr.data.minApr, to: apr.data?.apr }) : t("value.APR", { apr: apr.data?.apr })} diff --git a/src/sections/pools/farms/components/globalFarm/GlobalFarmRowMulti.tsx b/src/sections/pools/farms/components/globalFarm/GlobalFarmRowMulti.tsx index 4ab6be057..545f7e0e2 100644 --- a/src/sections/pools/farms/components/globalFarm/GlobalFarmRowMulti.tsx +++ b/src/sections/pools/farms/components/globalFarm/GlobalFarmRowMulti.tsx @@ -29,13 +29,16 @@ export const GlobalFarmRowMulti = ({ if (!farmAprs.data) return null + const { minApr, maxApr } = getMinAndMaxAPR(farmAprs) + return (
- {!!farmAprs.data && ( - - {t(`value.multiAPR`, getMinAndMaxAPR(farmAprs))} - - )} + + {maxApr.gt(0) + ? t(`value.multiAPR`, { minApr, maxApr }) + : t(`value.percentage`, { value: maxApr })} + + ({ diff --git a/src/sections/pools/farms/components/loyaltyGraph/LoyaltyGraph.tsx b/src/sections/pools/farms/components/loyaltyGraph/LoyaltyGraph.tsx index 98585fb77..b295b4cdc 100644 --- a/src/sections/pools/farms/components/loyaltyGraph/LoyaltyGraph.tsx +++ b/src/sections/pools/farms/components/loyaltyGraph/LoyaltyGraph.tsx @@ -1,6 +1,6 @@ import { useTranslation } from "react-i18next" import { Graph } from "components/Graph/Graph" -import { Spinner } from "components/Spinner/Spinner.styled" +import { Spinner } from "components/Spinner/Spinner" import { useLoyaltyRates } from "./LoyaltyGraph.utils" import { PalletLiquidityMiningLoyaltyCurve } from "@polkadot/types/lookup" import BigNumber from "bignumber.js" @@ -41,7 +41,7 @@ export const LoyaltyGraph = ({ data={rates.data} /> ) : ( - + )}
diff --git a/src/sections/pools/pool/myPositions/MyPositions.tsx b/src/sections/pools/pool/myPositions/MyPositions.tsx index 78bceeb67..48038145c 100644 --- a/src/sections/pools/pool/myPositions/MyPositions.tsx +++ b/src/sections/pools/pool/myPositions/MyPositions.tsx @@ -2,6 +2,7 @@ import { useQueryClient } from "@tanstack/react-query" import { useTokenBalance } from "api/balances" import { SSeparator } from "components/Separator/Separator.styled" import { Text } from "components/Typography/Text/Text" +import { useRpcProvider } from "providers/rpcProvider" import { useMemo } from "react" import { useTranslation } from "react-i18next" import { TPoolFullData, TXYKPool } from "sections/pools/PoolsPage.utils" @@ -15,8 +16,12 @@ import { BN_0 } from "utils/constants" import { QUERY_KEYS } from "utils/queryKeys" export const MyPositions = ({ pool }: { pool: TPoolFullData }) => { + const { assets } = useRpcProvider() const { account } = useAccount() const { t } = useTranslation() + const meta = assets.getAsset(pool.id) + const queryClient = useQueryClient() + const miningPositions = useAllUserDepositShare() const stablepoolBalance = useTokenBalance( @@ -24,7 +29,11 @@ export const MyPositions = ({ pool }: { pool: TPoolFullData }) => { account?.address, ) - const queryClient = useQueryClient() + const spotPrice = pool.spotPrice + const stablepoolAmount = stablepoolBalance.data?.freeBalance ?? BN_0 + const stablepoolAmountPrice = spotPrice + ? stablepoolAmount.multipliedBy(spotPrice).shiftedBy(-meta.decimals) + : BN_0 const totalOmnipool = useMemo(() => { if (pool.omnipoolNftPositions) { @@ -56,6 +65,8 @@ export const MyPositions = ({ pool }: { pool: TPoolFullData }) => { ) } + const totalStableAndOmni = totalOmnipool.plus(stablepoolAmountPrice) + return (
@@ -75,7 +86,7 @@ export const MyPositions = ({ pool }: { pool: TPoolFullData }) => { {t("liquidity.pool.positions.omnipool")} - {t("value.usd", { amount: totalOmnipool })} + {t("value.usd", { amount: totalStableAndOmni })}
{!totalFarms.isZero() && ( @@ -96,7 +107,12 @@ export const MyPositions = ({ pool }: { pool: TPoolFullData }) => { {pool.isStablePool && ( - + )} void } -export const StablepoolPosition = ({ pool, refetchPositions }: Props) => { +export const StablepoolPosition = ({ + pool, + refetchPositions, + amount, + amountPrice, +}: Props) => { const { t } = useTranslation() const { assets } = useRpcProvider() - const { account } = useAccount() const isDesktop = useMedia(theme.viewport.gte.sm) const [transferOpen, setTransferOpen] = useState() const meta = assets.getAsset(pool.id) as TStableSwap - const shareTokensBalance = useTokenBalance(pool.id, account?.address) - - const amount = shareTokensBalance.data?.freeBalance ?? BN_0 - if (amount.isZero()) return null - const spotPrice = pool.spotPrice - const providedAmountPrice = spotPrice - ? amount.multipliedBy(spotPrice).shiftedBy(-meta.decimals) - : BN_0 - return ( <>
{ })} ( {children} )} > - +
@@ -138,14 +134,14 @@ export const StablepoolPosition = ({ pool, refetchPositions }: Props) => { })} ( {children} )} > - + diff --git a/src/sections/pools/stablepool/removeLiquidity/RemoveLiquidityModal.tsx b/src/sections/pools/stablepool/removeLiquidity/RemoveLiquidityModal.tsx index 95c807f5b..07d22d71b 100644 --- a/src/sections/pools/stablepool/removeLiquidity/RemoveLiquidityModal.tsx +++ b/src/sections/pools/stablepool/removeLiquidity/RemoveLiquidityModal.tsx @@ -13,12 +13,12 @@ import { RemoveOption, RemoveOptions } from "./RemoveOptions" import { Button } from "components/Button/Button" import { BN_0 } from "utils/constants" import BigNumber from "bignumber.js" -import { Spinner } from "components/Spinner/Spinner.styled" import { Text } from "components/Typography/Text/Text" import { useTokenBalance } from "api/balances" import { useAccount } from "sections/web3-connect/Web3Connect.utils" import { useRpcProvider } from "providers/rpcProvider" import { TStableSwap } from "api/assetDetails" +import { Spinner } from "components/Spinner/Spinner" enum RemoveStablepoolLiquidityPage { OPTIONS, @@ -191,7 +191,7 @@ export const RemoveLiquidityModal = ({ height: 240, }} > - + {t("liquidity.stablepool.remove.removing")} diff --git a/src/sections/pools/stablepool/transfer/TransferModal.tsx b/src/sections/pools/stablepool/transfer/TransferModal.tsx index b9372dded..41ac925a3 100644 --- a/src/sections/pools/stablepool/transfer/TransferModal.tsx +++ b/src/sections/pools/stablepool/transfer/TransferModal.tsx @@ -8,7 +8,6 @@ import { AddStablepoolLiquidity } from "./AddStablepoolLiquidity" import { AssetsModalContent } from "sections/assets/AssetsModal" import { Stepper } from "components/Stepper/Stepper" import { AddLiquidityForm } from "sections/pools/modals/AddLiquidity/AddLiquidityForm" -import { Spinner } from "components/Spinner/Spinner.styled" import { Text } from "components/Typography/Text/Text" import { useRpcProvider } from "providers/rpcProvider" import { useModalPagination } from "components/Modal/Modal.utils" @@ -18,6 +17,7 @@ import { TStableSwap } from "api/assetDetails" import { useQueryClient } from "@tanstack/react-query" import { useAccount } from "sections/web3-connect/Web3Connect.utils" import { QUERY_KEYS } from "utils/queryKeys" +import { Spinner } from "components/Spinner/Spinner" export enum Page { OPTIONS, @@ -197,7 +197,7 @@ export const TransferModal = ({ height: 240, }} > - + {t("liquidity.stablepool.transfer.adding")} diff --git a/src/sections/pools/table/PoolsTable.tsx b/src/sections/pools/table/PoolsTable.tsx index eb79f11d6..15727a17d 100644 --- a/src/sections/pools/table/PoolsTable.tsx +++ b/src/sections/pools/table/PoolsTable.tsx @@ -12,6 +12,17 @@ import { usePoolTable } from "./PoolsTable.utils" import { TPool, TXYKPool } from "sections/pools/PoolsPage.utils" import { useNavigate, useSearch } from "@tanstack/react-location" import { assetsTableStyles } from "sections/wallet/assets/table/WalletAssetsTable.styled" +import { theme } from "theme" +import { css } from "@emotion/react" + +const styles = css` + @media ${theme.viewport.gte.sm} { + &:last-of-type { + padding-right: 30px; + padding-left: 0px; + } + } +` export const PoolsTable = ({ data, @@ -65,15 +76,7 @@ export const PoolsTable = ({ css={{ cursor: "pointer" }} > {row.getVisibleCells().map((cell) => ( - + {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} diff --git a/src/sections/pools/table/PoolsTable.utils.tsx b/src/sections/pools/table/PoolsTable.utils.tsx index ae8b8f3e5..800778c3b 100644 --- a/src/sections/pools/table/PoolsTable.utils.tsx +++ b/src/sections/pools/table/PoolsTable.utils.tsx @@ -16,28 +16,14 @@ import { theme } from "theme" import { useRpcProvider } from "providers/rpcProvider" import { MultipleIcons } from "components/MultipleIcons/MultipleIcons" import { AssetLogo } from "components/AssetIcon/AssetIcon" -import { - TPool, - TXYKPool, - derivePoolAccount, - isXYKPoolType, -} from "sections/pools/PoolsPage.utils" -import { Farm, useFarmAprs, useFarms } from "api/farms" +import { TPool, TXYKPool, isXYKPoolType } from "sections/pools/PoolsPage.utils" +import { Farm, getMinAndMaxAPR, useFarmAprs, useFarms } from "api/farms" import { GlobalFarmRowMulti } from "sections/pools/farms/components/globalFarm/GlobalFarmRowMulti" import { Button, ButtonTransparent } from "components/Button/Button" import ChevronRightIcon from "assets/icons/ChevronRight.svg?react" -import PlusIcon from "assets/icons/PlusIcon.svg?react" import ManageIcon from "assets/icons/IconEdit.svg?react" -import { BN_0, BN_1, BN_MILL } from "utils/constants" +import { BN_0, BN_1 } from "utils/constants" import Skeleton from "react-loading-skeleton" -import { - Page, - TransferModal, -} from "sections/pools/stablepool/transfer/TransferModal" -import { AddLiquidity } from "sections/pools/modals/AddLiquidity/AddLiquidity" -import { useAccountBalances } from "api/accountBalances" -import { useStableswapPool } from "api/stableswap" -import { normalizeBigNumber } from "utils/balance" import { useAccount } from "sections/web3-connect/Web3Connect.utils" import BN from "bignumber.js" import { CellSkeleton } from "components/Skeleton/CellSkeleton" @@ -147,23 +133,11 @@ const AddLiqduidityButton = ({ const { t } = useTranslation() const { assets } = useRpcProvider() - const [addLiquidityPool, setAddLiquidityPool] = useState< - TPool | TXYKPool | undefined - >(undefined) - - const [addLiquidityStablepool, setLiquidityStablepool] = useState() - const isXykPool = isXYKPoolType(pool) const assetMeta = assets.getAsset(pool.id) const isStablePool = assets.isStableSwap(assetMeta) - const poolAccountAddress = derivePoolAccount(assetMeta.id) - - const stablePoolBalance = useAccountBalances( - isStablePool ? poolAccountAddress : undefined, - ) - const userStablePoolBalance = useTokenBalance( isStablePool ? pool.id : undefined, account?.address, @@ -172,40 +146,28 @@ const AddLiqduidityButton = ({ const isPosition = userStablePoolBalance.data?.freeBalance.gt(0) || (isXykPool ? pool.shareTokenIssuance?.myPoolShare?.gt(0) : pool.isPositions) - const stablepool = useStableswapPool(isStablePool ? assetMeta.id : undefined) - - const reserves = isStablePool - ? (stablePoolBalance.data?.balances ?? []).map((balance) => { - const id = balance.id.toString() - const meta = assets.getAsset(id) - - return { - asset_id: Number(id), - decimals: meta.decimals, - amount: balance.freeBalance.toString(), - } - }) - : [] - - const onClick = () => { - if (isPosition) { - onRowSelect(pool.id) - } else { - isStablePool - ? setLiquidityStablepool(Page.OPTIONS) - : setAddLiquidityPool(pool) - } - } + + const positionsAmount = isPosition + ? !isXykPool + ? BN(pool.omnipoolPositions.length) + .plus(pool.miningPositions.length) + .plus(userStablePoolBalance.data?.freeBalance.gt(0) ? 1 : 0) + : pool.shareTokenIssuance?.myPoolShare?.gt(0) + ? BN_1 + : undefined + : undefined + + const onClick = () => onRowSelect(pool.id) return (
{ e.stopPropagation() }} + css={{ position: "relative" }} > - {addLiquidityPool && ( - setAddLiquidityPool(undefined)} - pool={addLiquidityPool} - /> - )} - {addLiquidityStablepool !== undefined && !isXykPool && ( - setLiquidityStablepool(undefined)} - /> + color="whiteish500" + > + {t("liquidity.asset.actions.myPositions.amount", { + count: positionsAmount.toNumber(), + })} + )}
) @@ -255,27 +212,14 @@ const APYFarming = ({ farms, apy }: { farms: Farm[]; apy: number }) => { const percentage = useMemo(() => { if (farmAprs.data?.length) { - const aprs = farmAprs.data - ? farmAprs.data.reduce((memo, { apr }) => memo.plus(apr), BN_0) - : BN_0 - const minAprs = farmAprs.data - ? farmAprs.data.map(({ minApr, apr }) => (minApr ? minApr : apr)) - : [BN_0] - - const minApr = BN.minimum(...minAprs) - const maxApr = aprs - - return { - minApr, - maxApr, - } + return getMinAndMaxAPR(farmAprs) } return { minApr: BN_0, maxApr: BN_0, } - }, [farmAprs.data]) + }, [farmAprs]) const isLoading = farmAprs.isInitialLoading @@ -284,10 +228,12 @@ const APYFarming = ({ farms, apy }: { farms: Farm[]; apy: number }) => { return ( - {t("value.percentage.range", { - from: percentage.minApr.lt(apy) ? percentage.minApr : BN(apy), - to: percentage.maxApr.plus(apy), - })} + {percentage.maxApr.gt(0) + ? t("value.percentage.range", { + from: percentage.minApr.lt(apy) ? percentage.minApr : BN(apy), + to: percentage.maxApr.plus(apy), + }) + : t("value.percentage", { value: BN(apy) })} ) @@ -474,9 +420,6 @@ export const usePoolTable = ( pool={row.original} onRowSelect={onRowSelect} /> - - } /> - ), }), diff --git a/src/sections/stats/sections/omnipoolAsset/stats/AssetStats.tsx b/src/sections/stats/sections/omnipoolAsset/stats/AssetStats.tsx index 61ad234cb..6cc03cbc8 100644 --- a/src/sections/stats/sections/omnipoolAsset/stats/AssetStats.tsx +++ b/src/sections/stats/sections/omnipoolAsset/stats/AssetStats.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next" import { AssetStatsCard } from "./AssetStatsCard" import BN from "bignumber.js" -import { Farm, useFarmAprs, useFarms } from "api/farms" +import { Farm, getMinAndMaxAPR, useFarmAprs, useFarms } from "api/farms" import { useMemo } from "react" import { BN_0 } from "utils/constants" import { useRpcProvider } from "providers/rpcProvider" @@ -12,35 +12,26 @@ const APYFarmStatsCard = ({ farms, apy }: { farms: Farm[]; apy: number }) => { const percentage = useMemo(() => { if (farmAprs.data?.length) { - const aprs = farmAprs.data - ? farmAprs.data.reduce((memo, { apr }) => memo.plus(apr), BN_0) - : BN_0 - const minAprs = farmAprs.data - ? farmAprs.data.map(({ minApr, apr }) => (minApr ? minApr : apr)) - : [BN_0] - - const minApr = BN.minimum(...minAprs) - const maxApr = aprs - - return { - minApr, - maxApr, - } + return getMinAndMaxAPR(farmAprs) } return { minApr: BN_0, maxApr: BN_0, } - }, [farmAprs.data]) + }, [farmAprs]) return ( diff --git a/src/sections/stats/sections/overview/components/OmnipoolAssetsTableWrapper/OmnipoolAssetsTableWrapper.utils.tsx b/src/sections/stats/sections/overview/components/OmnipoolAssetsTableWrapper/OmnipoolAssetsTableWrapper.utils.tsx index 87d51f2d5..22a97caff 100644 --- a/src/sections/stats/sections/overview/components/OmnipoolAssetsTableWrapper/OmnipoolAssetsTableWrapper.utils.tsx +++ b/src/sections/stats/sections/overview/components/OmnipoolAssetsTableWrapper/OmnipoolAssetsTableWrapper.utils.tsx @@ -12,7 +12,7 @@ import { OmnipoolAssetsTableColumn } from "sections/stats/components/OmnipoolAss import { useMedia } from "react-use" import { MultipleIcons } from "components/MultipleIcons/MultipleIcons" import { CellSkeleton } from "components/Skeleton/CellSkeleton" -import { Farm, useFarmAprs, useFarms } from "api/farms" +import { Farm, getMinAndMaxAPR, useFarmAprs, useFarms } from "api/farms" import { useMemo } from "react" import { BN_0 } from "utils/constants" import BigNumber from "bignumber.js" @@ -27,27 +27,14 @@ const APYFarming = ({ farms, apy }: { farms: Farm[]; apy: number }) => { const percentage = useMemo(() => { if (farmAprs.data?.length) { - const aprs = farmAprs.data - ? farmAprs.data.reduce((memo, { apr }) => memo.plus(apr), BN_0) - : BN_0 - const minAprs = farmAprs.data - ? farmAprs.data.map(({ minApr, apr }) => (minApr ? minApr : apr)) - : [BN_0] - - const minApr = BigNumber.minimum(...minAprs) - const maxApr = aprs - - return { - minApr, - maxApr, - } + return getMinAndMaxAPR(farmAprs) } return { minApr: BN_0, maxApr: BN_0, } - }, [farmAprs.data]) + }, [farmAprs]) const isLoading = farmAprs.isInitialLoading @@ -55,10 +42,14 @@ const APYFarming = ({ farms, apy }: { farms: Farm[]; apy: number }) => { return ( - {t("value.percentage.range", { - from: percentage.minApr.lt(apy) ? percentage.minApr : BigNumber(apy), - to: percentage.maxApr.plus(apy), - })} + {percentage.maxApr.gt(0) + ? t("value.percentage.range", { + from: percentage.minApr.lt(apy) + ? percentage.minApr + : BigNumber(apy), + to: percentage.maxApr.plus(apy), + }) + : t("value.percentage", { value: BigNumber(apy) })} ) } diff --git a/src/sections/transaction/ReviewTransactionPending.tsx b/src/sections/transaction/ReviewTransactionPending.tsx index a5cf00388..4a06ddbd0 100644 --- a/src/sections/transaction/ReviewTransactionPending.tsx +++ b/src/sections/transaction/ReviewTransactionPending.tsx @@ -1,11 +1,11 @@ import { ExtrinsicStatus } from "@polkadot/types/interfaces/author" import { Button } from "components/Button/Button" import { Spacer } from "components/Spacer/Spacer" -import { Spinner } from "components/Spinner/Spinner.styled" import { Heading } from "components/Typography/Heading/Heading" import { Text } from "components/Typography/Text/Text" import { useTranslation } from "react-i18next" import { ReviewTransactionProgress } from "./ReviewTransactionProgress" +import { Spinner } from "components/Spinner/Spinner" type Props = { onClose: () => void @@ -24,7 +24,7 @@ export const ReviewTransactionPending = ({ onClose, txState }: Props) => { width: "100%", }} > - + {t("liquidity.reviewTransaction.modal.pending.title")} diff --git a/src/sections/wallet/vesting/WalletVestingBox.tsx b/src/sections/wallet/vesting/WalletVestingBox.tsx index f22a5763f..e730050a9 100644 --- a/src/sections/wallet/vesting/WalletVestingBox.tsx +++ b/src/sections/wallet/vesting/WalletVestingBox.tsx @@ -5,9 +5,9 @@ import { WalletVestingSchedule } from "./WalletVestingSchedule" import { WalletVestingEmpty } from "./WalletVestingEmpty" import { useVestingSchedules } from "api/vesting" import { useAccount } from "sections/web3-connect/Web3Connect.utils" -import { Spinner } from "components/Spinner/Spinner.styled" import { isApiLoaded } from "utils/helpers" import { useRpcProvider } from "providers/rpcProvider" +import { Spinner } from "components/Spinner/Spinner" const VestingBoxContent = () => { const { account } = useAccount() @@ -18,7 +18,7 @@ const VestingBoxContent = () => {
- +
) } diff --git a/src/sections/web3-connect/providers/Web3ConnectProviderPending.tsx b/src/sections/web3-connect/providers/Web3ConnectProviderPending.tsx index c1421bc1f..678405a12 100644 --- a/src/sections/web3-connect/providers/Web3ConnectProviderPending.tsx +++ b/src/sections/web3-connect/providers/Web3ConnectProviderPending.tsx @@ -1,12 +1,12 @@ import { css } from "@emotion/react" import { Text } from "components/Typography/Text/Text" -import { Spinner } from "components/Spinner/Spinner.styled" import { useTranslation } from "react-i18next" import { WalletProviderType, getWalletProviderByType, } from "sections/web3-connect/Web3Connect.utils" import { FC } from "react" +import { Spinner } from "components/Spinner/Spinner" type Props = { provider: WalletProviderType } @@ -33,7 +33,7 @@ export const Web3ConnectProviderPending: FC = ({ provider }) => { } `} > - +