From c80ee2bcdb62403a5699b2615f5a6fcf783ee87e Mon Sep 17 00:00:00 2001 From: katty barroso Date: Tue, 12 Nov 2024 14:35:05 +0100 Subject: [PATCH 01/13] Assets page fixes --- .../src/pages/Loan/ExternalFinanceForm.tsx | 2 +- .../src/pages/Loan/ExternalRepayForm.tsx | 6 ++--- centrifuge-app/src/pages/Loan/FinanceForm.tsx | 24 +++++++++++++++++-- centrifuge-app/src/pages/Loan/RepayForm.tsx | 4 ++-- centrifuge-app/src/pages/Loan/index.tsx | 2 +- .../src/pages/Pool/Assets/index.tsx | 2 +- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/centrifuge-app/src/pages/Loan/ExternalFinanceForm.tsx b/centrifuge-app/src/pages/Loan/ExternalFinanceForm.tsx index da9a58140f..7723d911bf 100644 --- a/centrifuge-app/src/pages/Loan/ExternalFinanceForm.tsx +++ b/centrifuge-app/src/pages/Loan/ExternalFinanceForm.tsx @@ -248,7 +248,7 @@ export function ExternalFinanceForm({ Liquidity tab. - + Transaction summary diff --git a/centrifuge-app/src/pages/Loan/ExternalRepayForm.tsx b/centrifuge-app/src/pages/Loan/ExternalRepayForm.tsx index c286192fda..01309f884d 100644 --- a/centrifuge-app/src/pages/Loan/ExternalRepayForm.tsx +++ b/centrifuge-app/src/pages/Loan/ExternalRepayForm.tsx @@ -323,10 +323,10 @@ export function ExternalRepayForm({ outstanding interest ({formatBalance(maxInterest, displayCurrency, 2)}). - + Transaction summary - + - + {destination === 'reserve' ? ( diff --git a/centrifuge-app/src/pages/Loan/FinanceForm.tsx b/centrifuge-app/src/pages/Loan/FinanceForm.tsx index d13c48df9b..c282895287 100644 --- a/centrifuge-app/src/pages/Loan/FinanceForm.tsx +++ b/centrifuge-app/src/pages/Loan/FinanceForm.tsx @@ -281,9 +281,9 @@ function InternalFinanceForm({ - + Transaction summary - + + + + + + + + Available balance + + + + {maxAvailable === UNLIMITED ? 'No limit' : formatBalance(maxAvailable, displayCurrency, 2)} + + diff --git a/centrifuge-app/src/pages/Loan/RepayForm.tsx b/centrifuge-app/src/pages/Loan/RepayForm.tsx index 1c31332001..78f5364b89 100644 --- a/centrifuge-app/src/pages/Loan/RepayForm.tsx +++ b/centrifuge-app/src/pages/Loan/RepayForm.tsx @@ -368,9 +368,9 @@ function InternalRepayForm({ - + Transaction summary - + ) : null} {loan.outstandingDebt.gtn(0) && ( - )} diff --git a/centrifuge-app/src/pages/Pool/Assets/index.tsx b/centrifuge-app/src/pages/Pool/Assets/index.tsx index 41c735f452..61c8ec2514 100644 --- a/centrifuge-app/src/pages/Pool/Assets/index.tsx +++ b/centrifuge-app/src/pages/Pool/Assets/index.tsx @@ -118,7 +118,7 @@ export function PoolDetailAssets() { }, { label: `Accrued fees (${pool.currency.symbol})`, - value: `-${formatBalance(pool.fees.totalPaid)}`, + value: `${pool.fees.totalPaid.isZero() ? '' : '-'}${formatBalance(pool.fees.totalPaid)}`, heading: false, }, ] From 669baef0a7a81633604ef50821c8763108b9bbd4 Mon Sep 17 00:00:00 2001 From: katty barroso Date: Fri, 8 Nov 2024 11:12:58 +0100 Subject: [PATCH 02/13] Add new design for wallet menu --- .../src/components/WalletMenu/WalletMenu.tsx | 192 +++++++++--------- fabric/src/components/Button/IconAction.tsx | 19 +- fabric/src/components/Button/WalletButton.tsx | 8 +- fabric/src/icon-svg/icon-centrifuge.svg | 17 +- fabric/src/icon-svg/icon-copy.svg | 5 +- 5 files changed, 123 insertions(+), 118 deletions(-) diff --git a/centrifuge-react/src/components/WalletMenu/WalletMenu.tsx b/centrifuge-react/src/components/WalletMenu/WalletMenu.tsx index f1b3b6fc15..779148c730 100644 --- a/centrifuge-react/src/components/WalletMenu/WalletMenu.tsx +++ b/centrifuge-react/src/components/WalletMenu/WalletMenu.tsx @@ -1,5 +1,7 @@ import { Box, + Button, + Card, IconAnchor, IconButton, IconCopy, @@ -7,7 +9,6 @@ import { IconPower, IconSwitch, Menu, - MenuItem, MenuItemGroup, Popover, Shelf, @@ -18,7 +19,6 @@ import { import { getAddress } from 'ethers' import * as React from 'react' import { Link } from 'react-router-dom' -import styled from 'styled-components' import { useBalances } from '../../hooks/useBalances' import { useEns } from '../../hooks/useEns' import { copyToClipboard } from '../../utils/copyToClipboard' @@ -86,8 +86,7 @@ function ConnectedMenu({ menuItems }: WalletMenuProps) { )} renderContent={(props, ref, state) => ( - - + + - {!isEvmOnSubstrate && ( - - - - - {truncateAddress(formattedAddress)} - - - - - copyToClipboard(formattedAddress)} title="Copy address to clipboard"> - - - {subScanUrl && ( - - - - )} - + + + + {truncateAddress(formattedAddress)} - - )} - - + + copyToClipboard(formattedAddress)} + title="Copy address to clipboard" + > + + + {subScanUrl && ( + + + + )} + + + + + + + Balance - state.close()}> - - {balance && formatBalanceAbbreviated(balance, symbol)} - - + + state.close()}> + {balance && formatBalanceAbbreviated(balance)} + + + {symbol} + + {!!menuItems?.length && menuItems.map((item, index) => {item})} - - - - Network - - - - {connectedNetworkName} - - - - - - {wallet && ( - - - Wallet + + + + + Network - - {wallet.title} + + {connectedNetworkName} - )} - {connectedType === 'substrate' || (evm.accounts && evm.accounts.length > 1) ? ( - } - minHeight={0} - onClick={() => { - state.close() - showAccounts() - }} - /> - ) : ( - } - minHeight={0} + + + + {wallet && ( + + + Wallet + + + + {wallet.title} + + + )} + + + + + + + )} /> ) } - -const BalanceLink = styled(Text)` - &:hover { - color: ${({ theme }) => theme.colors.textInteractive}; - } -` diff --git a/fabric/src/components/Button/IconAction.tsx b/fabric/src/components/Button/IconAction.tsx index 524e851865..a18168615c 100644 --- a/fabric/src/components/Button/IconAction.tsx +++ b/fabric/src/components/Button/IconAction.tsx @@ -1,7 +1,11 @@ import styled, { css } from 'styled-components' +interface IconActionProps { + size?: string +} -export const iconActionStyles = css` - --size: 22px; +export const iconActionStyles = css` + --size: ${({ size }) => size || '22px'}; + --icon-size: calc(var(--size) - 4px); appearance: none; display: block; @@ -16,18 +20,18 @@ export const iconActionStyles = css` cursor: pointer; svg { - display: block; - width: 100%; - height: 100%; + width: var(--icon-size); + height: var(--icon-size); stroke: currentColor; } &:focus-visible, &:hover { - background-color: ${({ theme }) => theme.colors.blueScale[100]}; - color: ${({ theme }) => theme.colors.accentPrimary}; + background-color: ${({ theme }) => theme.colors.yellowScale[50]}; + color: ${({ theme }) => theme.colors.textPrimary}; } ` + export const IconAnchor = styled.a` ${iconActionStyles} ` @@ -37,4 +41,5 @@ export const IconButton = styled.button` ` IconButton.defaultProps = { type: 'button', + size: '22px', } diff --git a/fabric/src/components/Button/WalletButton.tsx b/fabric/src/components/Button/WalletButton.tsx index 2ced79aab2..e47ce45b0b 100644 --- a/fabric/src/components/Button/WalletButton.tsx +++ b/fabric/src/components/Button/WalletButton.tsx @@ -18,6 +18,7 @@ export type WalletButtonProps = Omit< alias?: string balance?: string icon?: IconTheme | React.ReactElement + title: string } const StyledButton = styled.button` @@ -50,6 +51,7 @@ export function WalletButton({ displayAddress = address, alias, balance, + title, ...buttonProps }: WalletButtonProps) { return ( @@ -69,7 +71,7 @@ export function WalletButton({ loadingMessage={loadingMessage} active={active} > - {address && alias ? ( + {title && alias ? ( - {displayAddress ? truncate(displayAddress) : connectLabel} + {title || connectLabel} )} - {address && balance && ( + {title && balance && ( {balance} diff --git a/fabric/src/icon-svg/icon-centrifuge.svg b/fabric/src/icon-svg/icon-centrifuge.svg index 2354a3b399..4f643da94b 100644 --- a/fabric/src/icon-svg/icon-centrifuge.svg +++ b/fabric/src/icon-svg/icon-centrifuge.svg @@ -1,10 +1,9 @@ - - - - - - - - - + + + + + + + + diff --git a/fabric/src/icon-svg/icon-copy.svg b/fabric/src/icon-svg/icon-copy.svg index 3342fddba3..761ec46045 100644 --- a/fabric/src/icon-svg/icon-copy.svg +++ b/fabric/src/icon-svg/icon-copy.svg @@ -1,4 +1,3 @@ - - - + + From b2deb63bf12e729ff01ac034f4f9f25744128226 Mon Sep 17 00:00:00 2001 From: katty barroso Date: Fri, 8 Nov 2024 13:05:09 +0100 Subject: [PATCH 03/13] Redesign dialog --- .../components/WalletMenu/ConnectButton.tsx | 8 +- .../WalletProvider/SelectButton.tsx | 10 +- .../WalletProvider/SelectionStep.tsx | 71 ++--- .../WalletProvider/WalletDialog.tsx | 254 +++++++----------- .../src/components/WalletProvider/utils.ts | 6 +- fabric/src/components/Button/WalletButton.tsx | 1 - fabric/src/components/Dialog/index.tsx | 14 +- fabric/src/components/Menu/index.tsx | 4 +- fabric/src/icon-svg/icon-crosschair.svg | 3 + 9 files changed, 159 insertions(+), 212 deletions(-) create mode 100644 fabric/src/icon-svg/icon-crosschair.svg diff --git a/centrifuge-react/src/components/WalletMenu/ConnectButton.tsx b/centrifuge-react/src/components/WalletMenu/ConnectButton.tsx index 4cb6592e25..7cc939d4a8 100644 --- a/centrifuge-react/src/components/WalletMenu/ConnectButton.tsx +++ b/centrifuge-react/src/components/WalletMenu/ConnectButton.tsx @@ -1,12 +1,8 @@ -import { WalletButton, WalletButtonProps } from '@centrifuge/fabric' +import { WalletButton } from '@centrifuge/fabric' import * as React from 'react' import { useWallet } from '../WalletProvider' -type Props = WalletButtonProps & { - label?: string -} - -export function ConnectButton({ label = 'Connect wallet', ...rest }: Props) { +export function ConnectButton({ label = 'Connect wallet', ...rest }) { const { showNetworks, pendingConnect } = useWallet() return ( diff --git a/centrifuge-react/src/components/WalletProvider/SelectButton.tsx b/centrifuge-react/src/components/WalletProvider/SelectButton.tsx index de61d16aca..0353f2d5f1 100644 --- a/centrifuge-react/src/components/WalletProvider/SelectButton.tsx +++ b/centrifuge-react/src/components/WalletProvider/SelectButton.tsx @@ -16,13 +16,16 @@ type SelectButtonProps = { iconRight?: React.ReactNode } -const Root = styled(Box)<{ disabled: boolean; muted?: boolean }>` +const Root = styled(Box)<{ disabled: boolean; muted?: boolean; active?: boolean }>` display: flex; flex-direction: column; align-items: center; gap: 10px; appearance: none; outline: none; + padding: 12px 8px; + height: 86px; + border: ${({ theme, active }) => `1px solid ${active ? theme.colors.textPrimary : theme.colors.borderPrimary}`}; opacity: ${({ disabled, muted }) => (disabled || muted ? 0.2 : 1)}; cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; @@ -36,6 +39,10 @@ const Root = styled(Box)<{ disabled: boolean; muted?: boolean }>` &:focus-visible:not(:disabled) { outline: ${({ theme }) => `solid ${theme.colors.borderSelected}`}; } + + & > span { + font-weight: ${({ active }) => `${active ? 700 : 500}`}; + } ` export function SelectButton({ @@ -58,6 +65,7 @@ export function SelectButton({ backgroundColor={active ? 'backgroundSecondary' : 'backgroundPrimary'} muted={muted} position="relative" + active={active} > diff --git a/centrifuge-react/src/components/WalletProvider/SelectionStep.tsx b/centrifuge-react/src/components/WalletProvider/SelectionStep.tsx index 93d583164b..36c60a3f96 100644 --- a/centrifuge-react/src/components/WalletProvider/SelectionStep.tsx +++ b/centrifuge-react/src/components/WalletProvider/SelectionStep.tsx @@ -1,55 +1,56 @@ -import { Box, Flex, IconCheck, IconInfoFilled, Shelf, Stack, Text, Tooltip } from '@centrifuge/fabric' +import { + Box, + IconButton, + IconCheckInCircle, + IconChevronDown, + IconChevronUp, + IconCrosschair, + IconInfoFilled, + Shelf, + Stack, + Text, + Tooltip, +} from '@centrifuge/fabric' import * as React from 'react' -import styled from 'styled-components' +import styled, { useTheme } from 'styled-components' import { Network } from './types' import { useGetNetworkName } from './utils' type SelectionStepProps = { - step: number title: string - expanded?: boolean children?: React.ReactNode tooltip?: React.ReactNode - titleElement?: React.ReactNode - rightElement?: React.ReactNode + done: boolean + expanded: boolean + toggleExpanded: () => void } -const Marker = styled(Flex)<{ $done: boolean }>` - border-radius: 50%; - background-color: ${({ theme, $done }) => ($done ? theme.colors.accentPrimary : theme.colors.textPrimary)}; -` - -export function SelectionStep({ - step, - title, - titleElement, - expanded = true, - children, - tooltip, - rightElement, -}: SelectionStepProps) { +export function SelectionStep({ title, children, tooltip, done, toggleExpanded, expanded }: SelectionStepProps) { + const theme = useTheme() return ( - + - - {expanded ? ( - - {step} - - ) : ( - - )} - - - + + {done ? : } + {title} {tooltip} - {!expanded && titleElement} - + - {rightElement} + + + {expanded ? : } + + {expanded && children} diff --git a/centrifuge-react/src/components/WalletProvider/WalletDialog.tsx b/centrifuge-react/src/components/WalletProvider/WalletDialog.tsx index 569c0622ed..9e704046f9 100644 --- a/centrifuge-react/src/components/WalletProvider/WalletDialog.tsx +++ b/centrifuge-react/src/components/WalletProvider/WalletDialog.tsx @@ -1,31 +1,16 @@ import { getSupportedBrowser } from '@centrifuge/centrifuge-app/src/utils/getSupportedBrowser' -import { - Button, - Card, - Dialog, - Divider, - Grid, - IconAlertCircle, - IconDownload, - IconEdit, - IconExternalLink, - MenuItemGroup, - Shelf, - Stack, - Text, -} from '@centrifuge/fabric' +import { Box, Card, Dialog, Grid, IconAlertCircle, IconDownload, MenuItemGroup, Stack, Text } from '@centrifuge/fabric' import centrifugeLogo from '@centrifuge/fabric/assets/logos/centrifuge.svg' import { Wallet } from '@subwallet/wallet-connect/types' -import { MetaMask } from '@web3-react/metamask' import * as React from 'react' +import { useTheme } from 'styled-components' import { Network } from '.' import { AccountButton, AccountIcon, AccountName } from './AccountButton' -import { Logo, NetworkIcon, SelectAnchor, SelectButton } from './SelectButton' +import { Logo, SelectAnchor, SelectButton } from './SelectButton' import { SelectionStep, SelectionStepTooltip } from './SelectionStep' import { useCentEvmChainId, useWallet, wallets } from './WalletProvider' import { EvmChains, getChainInfo } from './evm/chains' import { EvmConnectorMeta } from './evm/connectors' -import { isSubWallet, isTalismanWallet } from './evm/utils' import { sortCentrifugeWallets, sortEvmWallets, useGetNetworkName } from './utils' type Props = { @@ -66,6 +51,7 @@ const getAdjustedInstallUrl = (wallet: WalletFn): string => { } export function WalletDialog({ evmChains: allEvmChains, showAdvancedAccounts, showTestNets, showFinoa }: Props) { + const [step, setStep] = React.useState(1) const evmChains = Object.keys(allEvmChains) .filter((chainId) => (!showTestNets ? !(allEvmChains as any)[chainId].isTestnet : true)) .reduce((obj, chainId) => { @@ -79,12 +65,11 @@ export function WalletDialog({ evmChains: allEvmChains, showAdvancedAccounts, sh pendingConnect: { isConnecting, wallet: pendingWallet, isError: isConnectError }, walletDialog: { view, network: selectedNetwork, wallet: selectedWallet }, dispatch, - showNetworks, showWallets, connect: doConnect, evm, scopedNetworks, - substrate: { evmChainId }, + substrate: { evmChainId, selectedAddress }, } = ctx const getNetworkName = useGetNetworkName() @@ -126,29 +111,15 @@ export function WalletDialog({ evmChains: allEvmChains, showAdvancedAccounts, sh title={view ? title[view] : undefined} isOpen={!!view} onClose={close} - subtitle={view === 'networks' ? 'Choose your network and wallet to connect with Centrifuge' : undefined} + subtitle="Choose your network and wallet to connect with Centrifuge" > } - expanded={view === 'networks'} - titleElement={ - selectedNetwork && ( - - - {getNetworkName(selectedNetwork)} - - ) - } - rightElement={ - view !== 'networks' && ( - - ) - } + done={!!selectedNetwork} + expanded={step === 1} + toggleExpanded={() => setStep(step === 1 ? 0 : 1)} > {/* ethereum mainnet */} @@ -194,107 +165,63 @@ export function WalletDialog({ evmChains: allEvmChains, showAdvancedAccounts, sh - {(!!selectedWallet || view === 'wallets' || view === 'accounts') && ( - <> - - - - {selectedWallet.title} - - ) - } - rightElement={ - view === 'accounts' && ( - - ) - } - > - - {shownWallets.map((wallet) => { - return wallet.installed ? ( - } - iconRight={ - selectedWallet && isConnectError && selectedWallet === wallet ? ( - - ) : undefined - } - onClick={() => { - showWallets(selectedNetwork, wallet) - connect(wallet) - }} - loading={isConnecting && wallet === pendingWallet} - active={selectedWallet === wallet} - muted={isMuted(selectedNetwork!)} - > - {wallet.title} - - ) : ( - } - iconRight={} - muted={isMuted(selectedNetwork!)} - > - {wallet.title} - - ) - })} - - - - )} + setStep(step === 2 ? 0 : 2)} + > + + {shownWallets.map((wallet) => { + return wallet.installed ? ( + } + iconRight={ + selectedWallet && isConnectError && selectedWallet === wallet ? ( + + ) : undefined + } + onClick={() => { + showWallets(selectedNetwork, wallet) + connect(wallet) + }} + loading={isConnecting && wallet === pendingWallet} + active={selectedWallet === wallet} + muted={isMuted(selectedNetwork!)} + > + {wallet.title} + + ) : ( + } + iconRight={} + muted={isMuted(selectedNetwork!)} + > + {wallet.title} + + ) + })} + + {view === 'accounts' && ( - <> - - } - rightElement={ - selectedWallet && - 'extensionName' in selectedWallet && - ((selectedWallet.extensionName === 'subwallet-js' && isSubWallet()) || - (selectedWallet.extensionName === 'talisman' && isTalismanWallet())) && ( - - ) - } - > - {connectedType === 'substrate' ? ( - - ) : null} - - + setStep(step === 3 ? 0 : 3)} + title="Step 3: Choose account" + tooltip={scopedNetworks && } + done={!!selectedAddress} + > + {connectedType === 'substrate' ? ( + + ) : null} + )} - + Need help connecting a wallet?{' '} void; showAdvancedAccounts?: boolean }) { + const theme = useTheme() const { substrate: { combinedAccounts, selectAccount, selectedCombinedAccount, selectedAddress }, } = useWallet() @@ -330,37 +258,39 @@ function SubstrateAccounts({ onClose, showAdvancedAccounts }: { onClose: () => v return ( <> - + {combinedAccounts .filter((acc) => showAdvancedAccounts || (!acc.proxies && !acc.multisig)) .map((acc, index) => { const actingAddress = acc.proxies?.at(-1)?.delegator || acc.multisig?.address || acc.signingAccount.address return ( - - } - label={} - onClick={() => { - onClose() - selectAccount( - acc.signingAccount.address, - acc.proxies?.map((p) => p.delegator), - acc.multisig?.address - ) - }} - selected={ - acc === selectedCombinedAccount || - (!selectedCombinedAccount && - selectedAddress === acc.signingAccount.address && - !acc.multisig && - !acc.proxies) - } - proxyRights={acc.proxies?.[0].types - .map((type) => (PROXY_TYPE_LABELS as any)[type] ?? type) - .join(' / ')} - multisig={acc.multisig} - /> + + + } + label={} + onClick={() => { + onClose() + selectAccount( + acc.signingAccount.address, + acc.proxies?.map((p) => p.delegator), + acc.multisig?.address + ) + }} + selected={ + acc === selectedCombinedAccount || + (!selectedCombinedAccount && + selectedAddress === acc.signingAccount.address && + !acc.multisig && + !acc.proxies) + } + proxyRights={acc.proxies?.[0].types + .map((type) => (PROXY_TYPE_LABELS as any)[type] ?? type) + .join(' / ')} + multisig={acc.multisig} + /> + ) })} diff --git a/centrifuge-react/src/components/WalletProvider/utils.ts b/centrifuge-react/src/components/WalletProvider/utils.ts index 7dd17ce59f..e35cf9c9ca 100644 --- a/centrifuge-react/src/components/WalletProvider/utils.ts +++ b/centrifuge-react/src/components/WalletProvider/utils.ts @@ -1,11 +1,11 @@ -import centrifugeLogo from '@centrifuge/fabric/assets/logos/centrifuge.svg' +import { IconCentrifuge } from '@centrifuge/fabric' import { Wallet } from '@subwallet/wallet-connect/types' import * as React from 'react' import { CentrifugeContext, useCentrifugeUtils } from '../CentrifugeProvider/CentrifugeProvider' +import { useWallet } from './WalletProvider' import { EvmChains, getChainInfo } from './evm/chains' import { EvmConnectorMeta } from './evm/connectors' import { Network } from './types' -import { useWallet } from './WalletProvider' export function getNetworkName( network: Network, @@ -37,7 +37,7 @@ export function useGetNetworkIcon() { substrate: { evmChainId }, } = useWallet() return (network: Network) => - network === 'centrifuge' || network === evmChainId ? centrifugeLogo : (evm.chains as any)[network]?.iconUrl ?? '' + network === 'centrifuge' || network === evmChainId ? IconCentrifuge : (evm.chains as any)[network]?.iconUrl ?? '' } export function useNetworkIcon(network: Network) { diff --git a/fabric/src/components/Button/WalletButton.tsx b/fabric/src/components/Button/WalletButton.tsx index e47ce45b0b..e03c97aa67 100644 --- a/fabric/src/components/Button/WalletButton.tsx +++ b/fabric/src/components/Button/WalletButton.tsx @@ -18,7 +18,6 @@ export type WalletButtonProps = Omit< alias?: string balance?: string icon?: IconTheme | React.ReactElement - title: string } const StyledButton = styled.button` diff --git a/fabric/src/components/Dialog/index.tsx b/fabric/src/components/Dialog/index.tsx index d90f24b316..734cf807fd 100644 --- a/fabric/src/components/Dialog/index.tsx +++ b/fabric/src/components/Dialog/index.tsx @@ -70,11 +70,21 @@ function DialogInner({ children, isOpen, onClose, width = 'dialog', icon: IconCo {IconComp && (isComponent(IconComp) ? : IconComp)} - {typeof title === 'string' ? {title} : title} + {typeof title === 'string' ? ( + + {title} + + ) : ( + title + )}