From 960e5b4016ee5df01b65d3b2bb901a23f0a61715 Mon Sep 17 00:00:00 2001 From: devsalmon <54852257+devsalmon@users.noreply.github.com> Date: Mon, 26 Sep 2022 09:47:17 +0100 Subject: [PATCH] Your account panel (#1057) * update my account panel * update for plugins * ui update your account details added dao image and conditionally display the withdraw button on the panel * ui updates VSR plugin DAOs * deposit change to secondary button * rename label to 'my governance power' * fix deposit button not appearing * Revert "fix deposit button not appearing" This reverts commit 32185d150083c731f19e4686b978e43d862013ec. * deposit button fix * max width for buttons * Update TokenBalanceCard.tsx * Update TokenBalanceCard.tsx * governance power panel logic * fix governance power bug * availabletokens change * change realm to dao Co-authored-by: Bruno Ceccolini <34370581+BrunoCecco@users.noreply.github.com> --- .../components/Account/Account.tsx | 54 +++-- .../components/Account/LockTokensAccount.tsx | 21 +- .../DepositCommunityTokensBtn.tsx | 21 +- .../LockPluginTokenBalanceCard.tsx | 95 +++++--- .../TokenBalance/VotingPowerBox.tsx | 55 +++-- .../WithdrawCommunityTokensBtn.tsx | 6 +- components/TokenBalance/TokenBalanceCard.tsx | 215 +++++++++++++----- .../TokenBalance/TokenBalanceCardWrapper.tsx | 15 +- 8 files changed, 346 insertions(+), 136 deletions(-) diff --git a/VoteStakeRegistry/components/Account/Account.tsx b/VoteStakeRegistry/components/Account/Account.tsx index 0c90ad9f92..9ac5797e37 100644 --- a/VoteStakeRegistry/components/Account/Account.tsx +++ b/VoteStakeRegistry/components/Account/Account.tsx @@ -3,9 +3,18 @@ import { LinkIcon } from '@heroicons/react/outline' import MyProposalsBtn from 'pages/dao/[symbol]/proposal/components/MyProposalsBtn' import useWalletStore from 'stores/useWalletStore' import DelegateCard from '@components/DelegateCard' +import TokenBalanceCardWrapper from '@components/TokenBalance/TokenBalanceCardWrapper' +import useRealm from '@hooks/useRealm' -const AccountInner = ({ withHeader = true }: { withHeader?: boolean }) => { +const AccountInner = ({ + displayPanel, + withHeader = true, +}: { + displayPanel?: boolean + withHeader?: boolean +}) => { const connected = useWalletStore((s) => s.connected) + const { realmInfo } = useRealm() return (
{withHeader && ( @@ -14,30 +23,49 @@ const AccountInner = ({ withHeader = true }: { withHeader?: boolean }) => {
-

Account

+
+ {realmInfo?.ogImage && ( + + )} +

My governance power

+
+ {connected && }
)} + {!withHeader && connected && } +
- {connected ? ( - - ) : ( -
- - Connect your wallet -
- )} + {displayPanel ? ( + !connected ? ( +
+ + Connect your wallet +
+ ) : ( + + ) + ) : null}
) } -const Account = ({ withHeader = true }: { withHeader?: boolean }) => { +const Account = ({ + displayPanel = true, + withHeader = true, +}: { + displayPanel?: boolean + withHeader?: boolean +}) => { if (withHeader) { return (
- +
@@ -46,7 +74,7 @@ const Account = ({ withHeader = true }: { withHeader?: boolean }) => { } else { return ( <> - +
diff --git a/VoteStakeRegistry/components/Account/LockTokensAccount.tsx b/VoteStakeRegistry/components/Account/LockTokensAccount.tsx index 475d858d6b..f44335970c 100644 --- a/VoteStakeRegistry/components/Account/LockTokensAccount.tsx +++ b/VoteStakeRegistry/components/Account/LockTokensAccount.tsx @@ -213,15 +213,24 @@ const LockTokensAccount = ({ tokenOwnerRecordPk }) => {
-

- Your Account{' '} - - ({realmInfo?.displayName}) + {realmInfo?.ogImage && ( + + )} +

+ + {realmInfo?.displayName} + My governance power{' '}

- +

@@ -372,7 +381,7 @@ const LockTokensAccount = ({ tokenOwnerRecordPk }) => { > )} - {connected && } + {connected && } ) } diff --git a/VoteStakeRegistry/components/TokenBalance/DepositCommunityTokensBtn.tsx b/VoteStakeRegistry/components/TokenBalance/DepositCommunityTokensBtn.tsx index ae410eb1a6..971bbacb29 100644 --- a/VoteStakeRegistry/components/TokenBalance/DepositCommunityTokensBtn.tsx +++ b/VoteStakeRegistry/components/TokenBalance/DepositCommunityTokensBtn.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ -import Button from '@components/Button' +import { SecondaryButton } from '@components/Button' import Loading from '@components/Loading' import useRealm from '@hooks/useRealm' import { getProgramVersionForRealm } from '@models/registry/api' @@ -12,7 +12,7 @@ import { voteRegistryDepositWithoutLockup } from 'VoteStakeRegistry/actions/vote import useDepositStore from 'VoteStakeRegistry/stores/useDepositStore' import useVotePluginsClientStore from 'stores/useVotePluginsClientStore' -const DepositCommunityTokensBtn = ({ className = '' }) => { +const DepositCommunityTokensBtn = ({ className = '', inAccountDetails }) => { const { getOwnedDeposits } = useDepositStore() const { realm, realmInfo, realmTokenAccount, tokenRecords } = useRealm() const client = useVotePluginsClientStore((s) => s.state.vsrClient) @@ -80,16 +80,25 @@ const DepositCommunityTokensBtn = ({ className = '' }) => { ? "You don't have any governance tokens in your wallet to deposit." : '' - return ( - - ) + + ) : inAccountDetails ? ( + + {isLoading ? : 'Deposit'} + + ) : null } export default DepositCommunityTokensBtn diff --git a/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx b/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx index 57d80d7577..751d04ba14 100644 --- a/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx +++ b/VoteStakeRegistry/components/TokenBalance/LockPluginTokenBalanceCard.tsx @@ -22,9 +22,13 @@ import { TokenDeposit } from '@components/TokenBalance/TokenBalanceCard' const LockPluginTokenBalanceCard = ({ proposal, + inAccountDetails, }: { proposal?: Option + inAccountDetails?: boolean }) => { + const [hasGovPower, setHasGovPower] = useState(false) + const { fmtUrlWithCluster } = useQueryContext() const { councilMint, mint, realm, symbol, config } = useRealm() const [tokenOwnerRecordPk, setTokenOwneRecordPk] = useState('') @@ -75,7 +79,7 @@ const LockPluginTokenBalanceCard = ({ return (
-

Your Account

+

My governance power

{hasLoaded ? ( <> + {!hasGovPower && !inAccountDetails && connected && ( +
+ You do not have any governance power in this dao +
+ )} + {!connected && ( +
+ Connect your wallet to see governance power +
+ )} {communityDepositVisible && ( )} {councilDepositVisible && ( @@ -108,6 +124,7 @@ const LockPluginTokenBalanceCard = ({ mint={councilMint} tokenRole={GoverningTokenRole.Council} councilVote={true} + setHasGovPower={setHasGovPower} />
)} @@ -126,10 +143,14 @@ const LockPluginTokenBalanceCard = ({ const TokenDepositLock = ({ mint, tokenRole, + inAccountDetails, + setHasGovPower, }: { mint: MintInfo | undefined tokenRole: GoverningTokenRole councilVote?: boolean + inAccountDetails?: boolean + setHasGovPower: (hasGovPower: boolean) => void }) => { const { realm, realmTokenAccount, councilTokenAccount } = useRealm() const connected = useWalletStore((s) => s.connected) @@ -186,6 +207,12 @@ const TokenDepositLock = ({ ? fmtMintAmount(mint, depositRecord.amountDepositedNative) : '0' + useEffect(() => { + if (availableTokens != '0' || hasTokensDeposited || hasTokensInWallet) { + setHasGovPower(true) + } + }, [availableTokens, hasTokensDeposited, hasTokensInWallet]) + const canShowAvailableTokensMessage = !hasTokensDeposited && hasTokensInWallet && connected const canExecuteAction = !hasTokensDeposited ? 'deposit' : 'withdraw' @@ -207,37 +234,43 @@ const TokenDepositLock = ({ />
) : null} -
- -
-
-

- {depositTokenName} Deposited - - {availableTokens} - -

-

- {depositTokenName} Locked - {lockTokensFmt} -

-
- {/*

- You have {tokensToShow} tokens available to {canExecuteAction}. -

*/} - + {votingPower.toNumber() > 0 && ( +
+ +
+ )} + {(availableTokens != '0' || lockTokensFmt != '0') && ( +
+ {availableTokens != '0' && ( +

+ {depositTokenName} Deposited + + {availableTokens} + +

+ )} + {availableTokens != '0' && ( +

+ {depositTokenName} Locked + + {lockTokensFmt} + +

+ )} +
+ )}
- - + + {inAccountDetails && ( + + )}
) diff --git a/VoteStakeRegistry/components/TokenBalance/VotingPowerBox.tsx b/VoteStakeRegistry/components/TokenBalance/VotingPowerBox.tsx index 4dcea3a375..d7c5e56b82 100644 --- a/VoteStakeRegistry/components/TokenBalance/VotingPowerBox.tsx +++ b/VoteStakeRegistry/components/TokenBalance/VotingPowerBox.tsx @@ -1,8 +1,10 @@ +import BigNumber from 'bignumber.js' import { BN } from '@project-serum/anchor' import { MintInfo } from '@solana/spl-token' import { getMintDecimalAmount } from '@tools/sdk/units' import { LightningBoltIcon } from '@heroicons/react/solid' import Tooltip from '@components/Tooltip' +import VotingPowerPct from '@components/ProposalVotingPower/VotingPowerPct' const VotingPowerBox = ({ votingPower, @@ -22,23 +24,44 @@ const VotingPowerBox = ({ ? getMintDecimalAmount(mint, votingPower).toFormat(0) : '0' + const max: BigNumber = new BigNumber(mint.supply.toString()) + return ( -
-

Votes

- - {votingPowerFmt}{' '} - {!votingPowerFromDeposits.isZero() && !votingPower.isZero() && ( - -
- - {`${( - votingPower.toNumber() / votingPowerFromDeposits.toNumber() - ).toFixed(2)}x`} -
-
- )} -
-
+ <> + {' '} +
+
+

Votes

+ + {votingPowerFmt}{' '} + {!votingPowerFromDeposits.isZero() && !votingPower.isZero() && ( + +
+ + {`${( + votingPower.toNumber() / votingPowerFromDeposits.toNumber() + ).toFixed(2)}x`} +
+
+ )} +
+
+
+ {Number(votingPowerFmt) > 0 + ? max && + !max.isZero() && ( + + ) + : null} +
+
+ ) } diff --git a/VoteStakeRegistry/components/TokenBalance/WithdrawCommunityTokensBtn.tsx b/VoteStakeRegistry/components/TokenBalance/WithdrawCommunityTokensBtn.tsx index e74d3f0fa2..a7f259060b 100644 --- a/VoteStakeRegistry/components/TokenBalance/WithdrawCommunityTokensBtn.tsx +++ b/VoteStakeRegistry/components/TokenBalance/WithdrawCommunityTokensBtn.tsx @@ -1,4 +1,4 @@ -import Button from '@components/Button' +import { SecondaryButton } from '@components/Button' import useRealm from '@hooks/useRealm' import { getUnrelinquishedVoteRecords } from '@models/api' import { BN } from '@project-serum/anchor' @@ -180,7 +180,7 @@ const WithDrawCommunityTokens = () => { ? "You don't have any governance tokens to withdraw." : '' return ( - + ) } diff --git a/components/TokenBalance/TokenBalanceCard.tsx b/components/TokenBalance/TokenBalanceCard.tsx index 27ddc09681..504450a374 100644 --- a/components/TokenBalance/TokenBalanceCard.tsx +++ b/components/TokenBalance/TokenBalanceCard.tsx @@ -1,3 +1,4 @@ +import { BigNumber } from 'bignumber.js' import { ASSOCIATED_TOKEN_PROGRAM_ID, MintInfo, @@ -25,7 +26,7 @@ import { withWithdrawGoverningTokens } from '@solana/spl-governance' import useWalletStore from '../../stores/useWalletStore' import { sendTransaction } from '@utils/send' import { approveTokenTransfer } from '@utils/tokens' -import Button from '../Button' +import Button, { SecondaryButton } from '../Button' import { Option } from '@tools/core/option' import { GoverningTokenRole } from '@solana/spl-governance' import { fmtMintAmount } from '@tools/sdk/units' @@ -47,9 +48,16 @@ import { PythBalance, } from 'pyth-staking-api' import DelegateTokenBalanceCard from '@components/TokenBalance/DelegateTokenBalanceCard' - -type Props = { proposal?: Option } -const TokenBalanceCard: FC = ({ proposal, children }) => { +import getNumTokens from '@components/ProposalVotingPower/getNumTokens' +import VotingPowerPct from '@components/ProposalVotingPower/VotingPowerPct' + +type Props = { proposal?: Option; inAccountDetails?: boolean } +const TokenBalanceCard: FC = ({ + proposal, + inAccountDetails = false, + children, +}) => { + const [hasGovPower, setHasGovPower] = useState(false) const { councilMint, mint, realm, symbol } = useRealm() const connected = useWalletStore((s) => s.connected) const wallet = useWalletStore((s) => s.current) @@ -95,33 +103,55 @@ const TokenBalanceCard: FC = ({ proposal, children }) => { const hasLoaded = mint || councilMint return ( -
- + )} {hasLoaded ? ( -
+
+ {!hasGovPower && !inAccountDetails && connected && ( +
+ You do not have any governance power in this dao +
+ )} + {!connected && ( +
+ Connect your wallet to see governance power +
+ )} {communityDepositVisible && ( )} {councilDepositVisible && ( @@ -129,6 +159,8 @@ const TokenBalanceCard: FC = ({ proposal, children }) => { mint={councilMint} tokenRole={GoverningTokenRole.Council} councilVote={true} + inAccountDetails={inAccountDetails} + setHasGovPower={setHasGovPower} /> )} @@ -148,10 +180,14 @@ export const TokenDeposit = ({ mint, tokenRole, councilVote, + inAccountDetails, + setHasGovPower, }: { mint: MintInfo | undefined tokenRole: GoverningTokenRole councilVote?: boolean + inAccountDetails?: boolean + setHasGovPower: (hasGovPower: boolean) => void }) => { const wallet = useWalletStore((s) => s.current) const connected = useWalletStore((s) => s.connected) @@ -171,6 +207,7 @@ export const TokenDeposit = ({ ownTokenRecord, ownCouncilTokenRecord, ownVoterWeight, + councilMint, councilTokenAccount, proposals, governances, @@ -183,6 +220,21 @@ export const TokenDeposit = ({ return null } + const amount = + councilMint && tokenRole === GoverningTokenRole.Council + ? getNumTokens( + ownVoterWeight, + ownCouncilTokenRecord, + councilMint, + realmInfo + ) + : getNumTokens(ownVoterWeight, ownCouncilTokenRecord, mint, realmInfo) + + const max: BigNumber = + councilMint && tokenRole === GoverningTokenRole.Council + ? new BigNumber(councilMint.supply.toString()) + : new BigNumber(mint.supply.toString()) + const depositTokenRecord = tokenRole === GoverningTokenRole.Community ? ownTokenRecord @@ -416,6 +468,12 @@ export const TokenDeposit = ({ ) : '0' + useEffect(() => { + if (availableTokens != '0' || hasTokensDeposited || hasTokensInWallet) { + setHasGovPower(true) + } + }, [availableTokens, hasTokensDeposited, hasTokensInWallet]) + const canShowAvailableTokensMessage = !hasTokensDeposited && hasTokensInWallet && connected const canExecuteAction = !hasTokensDeposited ? 'deposit' : 'withdraw' @@ -428,17 +486,31 @@ export const TokenDeposit = ({ : 0 return ( - <> -
-
-
-

{depositTokenName} Votes

-

- {availableTokens} -

+ + {inAccountDetails && ( +

+ {tokenRole === GoverningTokenRole.Community ? `Community` : `Council`} +

+ )} + + {(availableTokens != '0' || inAccountDetails) && ( +
+
+
+

{depositTokenName} Votes

+
+

+ {availableTokens} +

+
+
+ {Number(availableTokens) > 0 + ? max && + !max.isZero() && + : null}
-
+ )} {!isPyth && ( <> @@ -451,30 +523,43 @@ export const TokenDeposit = ({

- - - + {hasTokensInWallet && !inAccountDetails ? ( + + Deposit + + ) : inAccountDetails ? ( + + ) : null} + {inAccountDetails && ( + + Withdraw + + )}
)} @@ -489,8 +574,22 @@ export const TokenDeposit = ({ power )} - + ) } +const TokenDepositWrapper = ({ + inAccountDetails, + children, +}: { + inAccountDetails?: boolean + children: React.ReactNode +}) => { + if (inAccountDetails) { + return
{children}
+ } else { + return <>{children} + } +} + export default TokenBalanceCard diff --git a/components/TokenBalance/TokenBalanceCardWrapper.tsx b/components/TokenBalance/TokenBalanceCardWrapper.tsx index b9c6ddd51d..22c0924a1b 100644 --- a/components/TokenBalance/TokenBalanceCardWrapper.tsx +++ b/components/TokenBalance/TokenBalanceCardWrapper.tsx @@ -24,8 +24,10 @@ const SwitchboardPermissionCard = dynamic( const TokenBalanceCardWrapper = ({ proposal, + inAccountDetails, }: { proposal?: Option + inAccountDetails?: boolean }) => { const { ownTokenRecord, @@ -51,7 +53,11 @@ const TokenBalanceCardWrapper = ({ (!ownTokenRecord || ownTokenRecord.account.governingTokenDepositAmount.isZero()) ) { - return + return ( + + ) } if ( isNftMode && @@ -65,7 +71,10 @@ const TokenBalanceCardWrapper = ({ !ownCouncilTokenRecord?.account.governingTokenDepositAmount.isZero()) || (councilTokenAccount && !councilTokenAccount?.account.amount.isZero())) && ( - + )} ) @@ -79,7 +88,7 @@ const TokenBalanceCardWrapper = ({ } //Default return ( - + {/*Add the gateway card if this is a gated DAO*/} {isGatewayMode && }