diff --git a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx index a9bb2b7f224..972a53873bc 100644 --- a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +++ b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx @@ -43,7 +43,7 @@ export function KeyValueInfo({ }: KeyValueProps): React.JSX.Element { return (
-
+
{keyText} {showInfoIcon && }
diff --git a/apps/wallet/src/ui/app/components/Overlay.tsx b/apps/wallet/src/ui/app/components/Overlay.tsx index 5ef8e66b7f5..c90090de085 100644 --- a/apps/wallet/src/ui/app/components/Overlay.tsx +++ b/apps/wallet/src/ui/app/components/Overlay.tsx @@ -6,6 +6,7 @@ import { useCallback } from 'react'; import type { ReactNode } from 'react'; import { Header } from '@iota/apps-ui-kit'; import { Portal } from '../shared/Portal'; +import { useNavigate } from 'react-router-dom'; interface OverlayProps { title?: string; @@ -15,9 +16,17 @@ interface OverlayProps { closeIcon?: ReactNode | null; setShowModal?: (showModal: boolean) => void; background?: 'bg-iota-lightest'; + showBackButton?: boolean; } -export function Overlay({ title, children, showModal, closeOverlay, setShowModal }: OverlayProps) { +export function Overlay({ + title, + children, + showModal, + closeOverlay, + showBackButton, + setShowModal, +}: OverlayProps) { const closeModal = useCallback( (e: React.MouseEvent) => { closeOverlay && closeOverlay(); @@ -25,11 +34,19 @@ export function Overlay({ title, children, showModal, closeOverlay, setShowModal }, [closeOverlay, setShowModal], ); - + const navigate = useNavigate(); + const handleBack = useCallback(() => navigate(-1), [navigate]); return showModal ? (
- {title &&
} + {title && ( +
+ )}
{children}
diff --git a/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx b/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx index 30cc6dd52d9..fd696e387f6 100644 --- a/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx +++ b/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx @@ -2,17 +2,10 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import BottomMenuLayout, { Content } from '_app/shared/bottom-menu-layout'; -import { Button } from '_app/shared/ButtonUI'; -import { Card } from '_app/shared/card'; -import { CardItem } from '_app/shared/card/CardItem'; -import { Text } from '_app/shared/text'; -import { IconTooltip } from '_app/shared/tooltip'; import { Alert, LoadingIndicator } from '_components'; import { useAppSelector } from '_hooks'; import { ampli } from '_src/shared/analytics/ampli'; import { MIN_NUMBER_IOTA_TO_STAKE } from '_src/shared/constants'; -import FaucetRequestButton from '_src/ui/app/shared/faucet/FaucetRequestButton'; import { useBalance, useCoinMetadata, @@ -20,18 +13,30 @@ import { useGetValidatorsApy, DELEGATED_STAKES_QUERY_REFETCH_INTERVAL, DELEGATED_STAKES_QUERY_STALE_TIME, + useFormatCoin, + formatPercentageDisplay, } from '@iota/core'; import { useIotaClientQuery } from '@iota/dapp-kit'; -import { ArrowLeft16, StakeAdd16, StakeRemove16 } from '@iota/icons'; import { Network, type StakeObject } from '@iota/iota-sdk/client'; -import { NANO_PER_IOTA, IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { NANO_PER_IOTA, IOTA_TYPE_ARG, formatAddress } from '@iota/iota-sdk/utils'; import BigNumber from 'bignumber.js'; import { useMemo } from 'react'; import { useActiveAddress } from '../../hooks/useActiveAddress'; -import { Heading } from '../../shared/heading'; import { getDelegationDataByStakeId } from '../getDelegationByStakeId'; -import { StakeAmount } from '../home/StakeAmount'; +import { + CardImage, + CardBody, + Card, + CardType, + Panel, + KeyValueInfo, + Divider, + Button, + ButtonType, +} from '@iota/apps-ui-kit'; +import { ImageIcon } from '../../shared/image-icon'; +import { useNavigate } from 'react-router-dom'; interface DelegationDetailCardProps { validatorAddress: string; @@ -39,6 +44,7 @@ interface DelegationDetailCardProps { } export function DelegationDetailCard({ validatorAddress, stakedId }: DelegationDetailCardProps) { + const navigate = useNavigate(); const { data: system, isPending: loadingValidators, @@ -81,7 +87,6 @@ export function DelegationDetailCard({ validatorAddress, stakedId }: DelegationD }, [allDelegation, stakedId]); const totalStake = BigInt(delegationData?.principal || 0n); - const iotaEarned = BigInt( (delegationData as Extract)?.estimatedReward || 0n, @@ -90,6 +95,9 @@ export function DelegationDetailCard({ validatorAddress, stakedId }: DelegationD apy: 0, }; + const [iotaEarnedFormatted, iotaEarnedSymbol] = useFormatCoin(iotaEarned, IOTA_TYPE_ARG); + const [totalStakeFormatted, totalStakeSymbol] = useFormatCoin(totalStake, IOTA_TYPE_ARG); + const delegationId = delegationData?.status === 'Active' && delegationData?.stakedIotaId; const stakeByValidatorAddress = `/stake/new?${new URLSearchParams({ @@ -122,167 +130,90 @@ export function DelegationDetailCard({ validatorAddress, stakedId }: DelegationD ); } - return ( -
- - -
- {hasInactiveValidatorDelegation ? ( -
- - Unstake IOTA from this inactive validator and stake on an active - validator to start earning rewards again. - -
- ) : null} -
- - - - - - - - -
- } - padding="none" - > -
- - APY -
- -
-
- } - > -
- - {isApyApproxZero ? '~' : ''} - {apy} - - - - % - -
- - - - Commission -
- -
-
- } - > -
- - {commission} - + if (hasInactiveValidatorDelegation) { +
+ + Unstake IOTA from this inactive validator and stake on an active validator to start + earning rewards again. + +
; + } - - % - -
- -
- -
-
- {!hasInactiveValidatorDelegation ? ( -
-
- + function handleUnstake() { + navigate(stakeByValidatorAddress + '&unstake=true'); + ampli.clickedUnstakeIota({ + stakedAmount: Number(totalStake / NANO_PER_IOTA), + validatorAddress, + }); + } - {/* show faucet request button on devnet or testnet whenever there is only one coin */} - {showRequestMoreIotaToken ? ( -
-
- - You need a minimum of {MIN_NUMBER_IOTA_TO_STAKE} IOTA to continue - staking. - -
- + return ( +
+
+ + + + + + + +
+ + + + +
- ) : ( +
+
+
+ {Boolean(totalStake) && delegationId && (
); } diff --git a/apps/wallet/src/ui/app/staking/delegation-detail/index.tsx b/apps/wallet/src/ui/app/staking/delegation-detail/index.tsx index 98f9e7a48df..d51ec4e4fe0 100644 --- a/apps/wallet/src/ui/app/staking/delegation-detail/index.tsx +++ b/apps/wallet/src/ui/app/staking/delegation-detail/index.tsx @@ -7,7 +7,6 @@ import { useGetDelegatedStake } from '@iota/core'; import { Navigate, useNavigate, useSearchParams } from 'react-router-dom'; import { useActiveAddress } from '../../hooks/useActiveAddress'; import { DelegationDetailCard } from './DelegationDetailCard'; -import { formatAddress } from '@iota/iota-sdk/utils'; export function DelegationDetail() { const [searchParams] = useSearchParams(); @@ -20,7 +19,7 @@ export function DelegationDetail() { }); if (!validatorAddressParams || !stakeIdParams) { - return ; + return ; } if (isPending) { @@ -32,12 +31,7 @@ export function DelegationDetail() { } return ( - navigate('/')} - > + navigate('/')}>