v2.2.4 (#810)
* feat: handle URLs with or without trailing slash (#803) * feat: handle URLs with or without trailing slash * tidy: cleanup slashes * Fix docker build (#805) * fix: fixed the docker build * tidy: cleanup * env: remove env contents (#808) * Portfolio fix (#809) * fix: fixed the portfolio account detail page layout * fix: fixed portfolio cards * tidy: refactor * align buttons, perps row clickable (#807) * align buttons, perps row clickable * fix comments * update to v2.2.4 * fix borrowbutton logic, add vault deposit manage btn, fix icon size vault modal --------- Co-authored-by: Linkie Link <linkielink.dev@gmail.com> --------- Co-authored-by: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com>
This commit is contained in:
parent
f7f8136b38
commit
c08ee627fc
13
.env
13
.env
@ -1,13 +0,0 @@
|
|||||||
# DO NOT EDIT THIS FILE WHEN USING DOCKER
|
|
||||||
# These values are used to replace the values in the built app,
|
|
||||||
# you should pass environment variables as defined in README.md
|
|
||||||
|
|
||||||
# CONFIG #
|
|
||||||
NEXT_PUBLIC_NETWORK=mainnet
|
|
||||||
|
|
||||||
# OSMOSIS-1 #
|
|
||||||
NEXT_PUBLIC_OSMOSIS_RPC=APP_NEXT_OSMOSIS_RPC
|
|
||||||
NEXT_PUBLIC_OSMOSIS_REST=APP_NEXT_OSMOSIS_REST
|
|
||||||
|
|
||||||
# WALLET CONNECT #
|
|
||||||
NEXT_PUBLIC_WALLET_CONNECT_ID=APP_NEXT_WALLET_CONNECT_ID
|
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mars-v2-frontend",
|
"name": "mars-v2-frontend",
|
||||||
"version": "2.2.3",
|
"version": "2.2.4",
|
||||||
"homepage": "./",
|
"homepage": "./",
|
||||||
"private": false,
|
"private": false,
|
||||||
"license": "SEE LICENSE IN LICENSE FILE",
|
"license": "SEE LICENSE IN LICENSE FILE",
|
||||||
|
@ -18,6 +18,7 @@ import chains from 'configs/chains'
|
|||||||
import { BN_ZERO } from 'constants/math'
|
import { BN_ZERO } from 'constants/math'
|
||||||
import useBaseAsset from 'hooks/assets/useBasetAsset'
|
import useBaseAsset from 'hooks/assets/useBasetAsset'
|
||||||
import useMarketEnabledAssets from 'hooks/assets/useMarketEnabledAssets'
|
import useMarketEnabledAssets from 'hooks/assets/useMarketEnabledAssets'
|
||||||
|
import useChainConfig from 'hooks/useChainConfig'
|
||||||
import useCurrentWallet from 'hooks/useCurrentWallet'
|
import useCurrentWallet from 'hooks/useCurrentWallet'
|
||||||
import useICNSDomain from 'hooks/useICNSDomain'
|
import useICNSDomain from 'hooks/useICNSDomain'
|
||||||
import useToggle from 'hooks/useToggle'
|
import useToggle from 'hooks/useToggle'
|
||||||
@ -27,7 +28,6 @@ import { NETWORK } from 'types/enums/network'
|
|||||||
import { ChainInfoID } from 'types/enums/wallet'
|
import { ChainInfoID } from 'types/enums/wallet'
|
||||||
import { truncate } from 'utils/formatters'
|
import { truncate } from 'utils/formatters'
|
||||||
import { getPage, getRoute } from 'utils/route'
|
import { getPage, getRoute } from 'utils/route'
|
||||||
import useChainConfig from 'hooks/useChainConfig'
|
|
||||||
|
|
||||||
export default function WalletConnectedButton() {
|
export default function WalletConnectedButton() {
|
||||||
// ---------------
|
// ---------------
|
||||||
@ -90,7 +90,7 @@ export default function WalletConnectedButton() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate(getRoute(getPage(pathname), searchParams))
|
navigate(getRoute(getPage(pathname), new URLSearchParams()))
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -63,16 +63,22 @@ export default function HealthBar({
|
|||||||
health={isUpdated ? updatedHealth : health}
|
health={isUpdated ? updatedHealth : health}
|
||||||
healthFactor={isUpdated ? updatedHealthFactor : healthFactor}
|
healthFactor={isUpdated ? updatedHealthFactor : healthFactor}
|
||||||
>
|
>
|
||||||
<>
|
<div className={classNames('flex w-full', showIcon && 'gap-2')}>
|
||||||
{showIcon && (
|
{showIcon && (
|
||||||
<HealthIcon
|
<HealthIcon
|
||||||
health={health}
|
health={health}
|
||||||
isLoading={healthFactor === 0}
|
isLoading={healthFactor === 0}
|
||||||
className={classNames('mr-2', iconClassName)}
|
className={iconClassName}
|
||||||
colorClass='text-white'
|
colorClass='text-white'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className={classNames('flex w-full', 'rounded-full overflow-hidden', className)}>
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'flex w-full flex-shrink',
|
||||||
|
'rounded-full overflow-hidden',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
version='1.1'
|
version='1.1'
|
||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
@ -153,7 +159,7 @@ export default function HealthBar({
|
|||||||
)}
|
)}
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</div>
|
||||||
</HealthTooltip>
|
</HealthTooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { ExclamationMarkCircled, Heart } from 'components/common/Icons'
|
|||||||
interface Props {
|
interface Props {
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
health: number
|
health: number
|
||||||
className: string
|
className?: string
|
||||||
colorClass?: string
|
colorClass?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,9 +14,9 @@ export default function HealthIcon(props: Props) {
|
|||||||
const color = colorClass ?? 'text-white'
|
const color = colorClass ?? 'text-white'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='w-5'>
|
||||||
{!isLoading && health === 0 ? (
|
{!isLoading && health === 0 ? (
|
||||||
<ExclamationMarkCircled className={classNames('w-5 text-loss animate-pulse', className)} />
|
<ExclamationMarkCircled className={classNames(' text-loss animate-pulse', className)} />
|
||||||
) : (
|
) : (
|
||||||
<Heart
|
<Heart
|
||||||
className={classNames(
|
className={classNames(
|
||||||
@ -26,6 +26,6 @@ export default function HealthIcon(props: Props) {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
import { useCallback } from 'react'
|
|
||||||
|
|
||||||
import Button from 'components/common/Button'
|
|
||||||
import ActionButton from 'components/common/Button/ActionButton'
|
|
||||||
import { HandCoins, Plus } from 'components/common/Icons'
|
|
||||||
import useMarketEnabledAssets from 'hooks/assets/useMarketEnabledAssets'
|
|
||||||
import useStore from 'store'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
data: BorrowMarketTableData
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function BorrowActionButtons(props: Props) {
|
|
||||||
const { asset, accountDebt } = props.data
|
|
||||||
const marketAssets = useMarketEnabledAssets()
|
|
||||||
const currentAsset = marketAssets.find((a) => a.denom === asset.denom)
|
|
||||||
|
|
||||||
const borrowHandler = useCallback(() => {
|
|
||||||
if (!currentAsset) return null
|
|
||||||
useStore.setState({ borrowModal: { asset: currentAsset, marketData: props.data } })
|
|
||||||
}, [currentAsset, props.data])
|
|
||||||
|
|
||||||
const repayHandler = useCallback(() => {
|
|
||||||
if (!currentAsset) return null
|
|
||||||
useStore.setState({
|
|
||||||
borrowModal: { asset: currentAsset, marketData: props.data, isRepay: true },
|
|
||||||
})
|
|
||||||
}, [currentAsset, props.data])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='flex flex-row space-x-2'>
|
|
||||||
<ActionButton
|
|
||||||
leftIcon={<Plus className='w-3' />}
|
|
||||||
onClick={borrowHandler}
|
|
||||||
color='secondary'
|
|
||||||
text={accountDebt ? 'Borrow more' : 'Borrow'}
|
|
||||||
className='text-center min-w-40'
|
|
||||||
/>
|
|
||||||
{accountDebt && (
|
|
||||||
<Button color='tertiary' leftIcon={<HandCoins />} text='Repay' onClick={repayHandler} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -2,12 +2,10 @@ import { Row } from '@tanstack/react-table'
|
|||||||
import { Table as TanstackTable } from '@tanstack/table-core/build/lib/types'
|
import { Table as TanstackTable } from '@tanstack/table-core/build/lib/types'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
import BorrowActionButtons from 'components/borrow/BorrowActionButtons'
|
|
||||||
import { NAME_META } from 'components/borrow/Table/Columns/Name'
|
import { NAME_META } from 'components/borrow/Table/Columns/Name'
|
||||||
import useAvailableColumns from 'components/borrow/Table/Columns/useAvailableColumns'
|
import useAvailableColumns from 'components/borrow/Table/Columns/useAvailableColumns'
|
||||||
import MarketDetails from 'components/common/MarketDetails'
|
import MarketDetails from 'components/common/MarketDetails'
|
||||||
import Table from 'components/common/Table'
|
import Table from 'components/common/Table'
|
||||||
import ActionButtonRow from 'components/common/Table/ActionButtonRow'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: BorrowMarketTableData[]
|
data: BorrowMarketTableData[]
|
||||||
@ -20,14 +18,7 @@ export default function AvailableBorrowingsTable(props: Props) {
|
|||||||
const renderExpanded = useCallback(
|
const renderExpanded = useCallback(
|
||||||
(row: Row<BorrowMarketTableData>, _: TanstackTable<BorrowMarketTableData>) => {
|
(row: Row<BorrowMarketTableData>, _: TanstackTable<BorrowMarketTableData>) => {
|
||||||
const currentRow = row as Row<BorrowMarketTableData>
|
const currentRow = row as Row<BorrowMarketTableData>
|
||||||
return (
|
return <MarketDetails row={currentRow} type='borrow' />
|
||||||
<>
|
|
||||||
<ActionButtonRow row={currentRow}>
|
|
||||||
<BorrowActionButtons data={row.original} />
|
|
||||||
</ActionButtonRow>
|
|
||||||
<MarketDetails row={currentRow} type='borrow' />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
61
src/components/borrow/Table/Columns/BorrowButton.tsx
Normal file
61
src/components/borrow/Table/Columns/BorrowButton.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
|
import ActionButton from 'components/common/Button/ActionButton'
|
||||||
|
import { Plus } from 'components/common/Icons'
|
||||||
|
import Text from 'components/common/Text'
|
||||||
|
import { Tooltip } from 'components/common/Tooltip'
|
||||||
|
import ConditionalWrapper from 'hocs/ConditionalWrapper'
|
||||||
|
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
|
||||||
|
import useStore from 'store'
|
||||||
|
|
||||||
|
export const BORROW_BUTTON_META = {
|
||||||
|
accessorKey: 'borrow',
|
||||||
|
enableSorting: false,
|
||||||
|
header: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
data: LendingMarketTableData
|
||||||
|
}
|
||||||
|
export default function BorrowButton(props: Props) {
|
||||||
|
const account = useCurrentAccount()
|
||||||
|
const address = useStore((s) => s.address)
|
||||||
|
const hasNoDeposits = !account?.deposits?.length && !account?.lends?.length && !!address
|
||||||
|
|
||||||
|
const borrowHandler = useCallback(() => {
|
||||||
|
if (!props.data.asset) return null
|
||||||
|
useStore.setState({ borrowModal: { asset: props.data.asset, marketData: props.data } })
|
||||||
|
}, [props.data])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex justify-end'>
|
||||||
|
<ConditionalWrapper
|
||||||
|
condition={hasNoDeposits}
|
||||||
|
wrapper={(children) => (
|
||||||
|
<Tooltip
|
||||||
|
type='warning'
|
||||||
|
content={
|
||||||
|
<Text size='sm'>{`You don’t have any collateral.
|
||||||
|
Please first deposit into your Credit Account before borrowing.`}</Text>
|
||||||
|
}
|
||||||
|
contentClassName='max-w-[200px]'
|
||||||
|
className='ml-auto'
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ActionButton
|
||||||
|
leftIcon={<Plus />}
|
||||||
|
disabled={hasNoDeposits}
|
||||||
|
color='tertiary'
|
||||||
|
onClick={(e) => {
|
||||||
|
borrowHandler()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
text='Borrow'
|
||||||
|
/>
|
||||||
|
</ConditionalWrapper>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -4,7 +4,6 @@ import Loading from 'components/common/Loading'
|
|||||||
export const BORROW_RATE_META = {
|
export const BORROW_RATE_META = {
|
||||||
accessorKey: 'apy.borrow',
|
accessorKey: 'apy.borrow',
|
||||||
header: 'Borrow Rate APY',
|
header: 'Borrow Rate APY',
|
||||||
meta: { className: 'w-40' },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
21
src/components/borrow/Table/Columns/Chevron.tsx
Normal file
21
src/components/borrow/Table/Columns/Chevron.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { ChevronDown, ChevronUp } from 'components/common/Icons'
|
||||||
|
|
||||||
|
export const CHEVRON_META = {
|
||||||
|
id: 'chevron',
|
||||||
|
enableSorting: false,
|
||||||
|
header: '',
|
||||||
|
meta: {
|
||||||
|
className: 'w-5',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
isExpanded: boolean
|
||||||
|
}
|
||||||
|
export default function Chevron(props: Props) {
|
||||||
|
return (
|
||||||
|
<div className='flex items-center justify-end'>
|
||||||
|
<div className='w-4'>{props.isExpanded ? <ChevronUp /> : <ChevronDown />}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -10,7 +10,6 @@ export const LIQUIDITY_META = {
|
|||||||
accessorKey: 'liquidity',
|
accessorKey: 'liquidity',
|
||||||
header: 'Liquidity Available',
|
header: 'Liquidity Available',
|
||||||
id: 'liquidity',
|
id: 'liquidity',
|
||||||
meta: { className: 'w-40' },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const liquiditySortingFn = (
|
export const liquiditySortingFn = (
|
||||||
|
@ -1,20 +1,55 @@
|
|||||||
import { ChevronDown, ChevronUp } from 'components/common/Icons'
|
import { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
|
import DropDownButton from 'components/common/Button/DropDownButton'
|
||||||
|
import { HandCoins, Plus } from 'components/common/Icons'
|
||||||
|
import useStore from 'store'
|
||||||
|
|
||||||
export const MANAGE_META = {
|
export const MANAGE_META = {
|
||||||
accessorKey: 'manage',
|
accessorKey: 'manage',
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
header: 'Manage',
|
header: '',
|
||||||
meta: { className: 'w-30' },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isExpanded: boolean
|
data: BorrowMarketTableData
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Manage(props: Props) {
|
export default function Manage(props: Props) {
|
||||||
|
const address = useStore((s) => s.address)
|
||||||
|
|
||||||
|
const borrowHandler = useCallback(() => {
|
||||||
|
if (!props.data.asset) return null
|
||||||
|
useStore.setState({ borrowModal: { asset: props.data.asset, marketData: props.data } })
|
||||||
|
}, [props.data])
|
||||||
|
|
||||||
|
const repayHandler = useCallback(() => {
|
||||||
|
if (!props.data.asset) return null
|
||||||
|
useStore.setState({
|
||||||
|
borrowModal: { asset: props.data.asset, marketData: props.data, isRepay: true },
|
||||||
|
})
|
||||||
|
}, [props.data])
|
||||||
|
|
||||||
|
const ITEMS: DropDownItem[] = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
icon: <Plus />,
|
||||||
|
text: 'Borrow more',
|
||||||
|
onClick: borrowHandler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <HandCoins />,
|
||||||
|
text: 'Repay',
|
||||||
|
onClick: repayHandler,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[borrowHandler, repayHandler],
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!address) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center justify-end'>
|
<div className='flex justify-end z-10'>
|
||||||
<div className='w-4'>{props.isExpanded ? <ChevronUp /> : <ChevronDown />}</div>
|
<DropDownButton items={ITEMS} text='Manage' color='tertiary' />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { ColumnDef } from '@tanstack/react-table'
|
import { ColumnDef } from '@tanstack/react-table'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
|
import BorrowButton, { BORROW_BUTTON_META } from 'components/borrow/Table/Columns/BorrowButton'
|
||||||
import BorrowRate, { BORROW_RATE_META } from 'components/borrow/Table/Columns/BorrowRate'
|
import BorrowRate, { BORROW_RATE_META } from 'components/borrow/Table/Columns/BorrowRate'
|
||||||
|
import Chevron, { CHEVRON_META } from 'components/borrow/Table/Columns/Chevron'
|
||||||
import Liquidity, {
|
import Liquidity, {
|
||||||
LIQUIDITY_META,
|
LIQUIDITY_META,
|
||||||
liquiditySortingFn,
|
liquiditySortingFn,
|
||||||
} from 'components/borrow/Table/Columns/Liquidity'
|
} from 'components/borrow/Table/Columns/Liquidity'
|
||||||
import Manage, { MANAGE_META } from 'components/borrow/Table/Columns/Manage'
|
|
||||||
import Name, { NAME_META } from 'components/borrow/Table/Columns/Name'
|
import Name, { NAME_META } from 'components/borrow/Table/Columns/Name'
|
||||||
|
|
||||||
export default function useAvailableColumns() {
|
export default function useAvailableColumns() {
|
||||||
@ -26,8 +27,12 @@ export default function useAvailableColumns() {
|
|||||||
sortingFn: liquiditySortingFn,
|
sortingFn: liquiditySortingFn,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...MANAGE_META,
|
...BORROW_BUTTON_META,
|
||||||
cell: ({ row }) => <Manage isExpanded={row.getIsExpanded()} />,
|
cell: ({ row }) => <BorrowButton data={row.original} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...CHEVRON_META,
|
||||||
|
cell: ({ row }) => <Chevron isExpanded={row.getIsExpanded()} />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -2,6 +2,7 @@ import { ColumnDef } from '@tanstack/react-table'
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
import BorrowRate, { BORROW_RATE_META } from 'components/borrow/Table/Columns/BorrowRate'
|
import BorrowRate, { BORROW_RATE_META } from 'components/borrow/Table/Columns/BorrowRate'
|
||||||
|
import Chevron, { CHEVRON_META } from 'components/borrow/Table/Columns/Chevron'
|
||||||
import Debt, { DEBT_META, debtSortingFn } from 'components/borrow/Table/Columns/Debt'
|
import Debt, { DEBT_META, debtSortingFn } from 'components/borrow/Table/Columns/Debt'
|
||||||
import Liquidity, {
|
import Liquidity, {
|
||||||
LIQUIDITY_META,
|
LIQUIDITY_META,
|
||||||
@ -33,7 +34,11 @@ export default function useDepositedColumns() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
...MANAGE_META,
|
...MANAGE_META,
|
||||||
cell: ({ row }) => <Manage isExpanded={row.getIsExpanded()} />,
|
cell: ({ row }) => <Manage data={row.original} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...CHEVRON_META,
|
||||||
|
cell: ({ row }) => <Chevron isExpanded={row.getIsExpanded()} />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import { Row } from '@tanstack/react-table'
|
import { Row } from '@tanstack/react-table'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
import BorrowActionButtons from 'components/borrow/BorrowActionButtons'
|
|
||||||
import { NAME_META } from 'components/borrow/Table/Columns/Name'
|
import { NAME_META } from 'components/borrow/Table/Columns/Name'
|
||||||
import useDepositedColumns from 'components/borrow/Table/Columns/useDepositedColumns'
|
import useDepositedColumns from 'components/borrow/Table/Columns/useDepositedColumns'
|
||||||
import MarketDetails from 'components/common/MarketDetails'
|
import MarketDetails from 'components/common/MarketDetails'
|
||||||
import Table from 'components/common/Table'
|
import Table from 'components/common/Table'
|
||||||
import ActionButtonRow from 'components/common/Table/ActionButtonRow'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: BorrowMarketTableData[]
|
data: BorrowMarketTableData[]
|
||||||
@ -17,15 +15,7 @@ export default function DepositedBorrowingsTable(props: Props) {
|
|||||||
const columns = useDepositedColumns()
|
const columns = useDepositedColumns()
|
||||||
|
|
||||||
const renderExpanded = useCallback((row: Row<BorrowMarketTableData>) => {
|
const renderExpanded = useCallback((row: Row<BorrowMarketTableData>) => {
|
||||||
const currentRow = row as Row<BorrowMarketTableData>
|
return <MarketDetails row={row} type='borrow' />
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ActionButtonRow row={currentRow}>
|
|
||||||
<BorrowActionButtons data={row.original} />
|
|
||||||
</ActionButtonRow>
|
|
||||||
<MarketDetails row={row} type='borrow' />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
if (!props.data.length) return null
|
if (!props.data.length) return null
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import Button from 'components/common/Button/index'
|
import Button from 'components/common/Button/index'
|
||||||
import { ChevronDown } from 'components/common/Icons'
|
import { ChevronDown } from 'components/common/Icons'
|
||||||
import Text from 'components/common/Text'
|
import Text from 'components/common/Text'
|
||||||
import { Tooltip } from 'components/common/Tooltip'
|
import { Tooltip } from 'components/common/Tooltip'
|
||||||
|
import ConditionalWrapper from 'hocs/ConditionalWrapper'
|
||||||
import useToggle from 'hooks/useToggle'
|
import useToggle from 'hooks/useToggle'
|
||||||
|
|
||||||
interface Props extends ButtonProps {
|
interface Props extends ButtonProps {
|
||||||
items: DropDownItem[]
|
items: DropDownItem[]
|
||||||
text: string
|
text: string
|
||||||
|
showProgressIndicator?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DropDownButton(props: Props) {
|
export default function DropDownButton(props: Props) {
|
||||||
@ -16,16 +20,20 @@ export default function DropDownButton(props: Props) {
|
|||||||
content={<DropDown closeMenu={() => toggleIsOpen(false)} {...props} />}
|
content={<DropDown closeMenu={() => toggleIsOpen(false)} {...props} />}
|
||||||
type='info'
|
type='info'
|
||||||
placement='bottom'
|
placement='bottom'
|
||||||
contentClassName='!bg-white/10 backdrop-blur-xl !p-0'
|
contentClassName='!bg-white/10 backdrop-blur-xl !p-0 w-full min-w-[140px]'
|
||||||
interactive
|
interactive
|
||||||
hideArrow
|
hideArrow
|
||||||
visible={isOpen}
|
visible={isOpen}
|
||||||
onClickOutside={() => toggleIsOpen(false)}
|
onClickOutside={() => toggleIsOpen(false)}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => toggleIsOpen()}
|
onClick={(e) => {
|
||||||
|
toggleIsOpen()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
rightIcon={<ChevronDown />}
|
rightIcon={<ChevronDown />}
|
||||||
iconClassName='w-3 h-3'
|
iconClassName='w-3 h-3'
|
||||||
|
showProgressIndicator={props.showProgressIndicator}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -39,7 +47,7 @@ interface DropDownProps {
|
|||||||
|
|
||||||
function DropDown(props: DropDownProps) {
|
function DropDown(props: DropDownProps) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='w-full'>
|
||||||
{props.items.map((item) => (
|
{props.items.map((item) => (
|
||||||
<DropDownItem key={item.text} item={item} closeMenu={props.closeMenu} />
|
<DropDownItem key={item.text} item={item} closeMenu={props.closeMenu} />
|
||||||
))}
|
))}
|
||||||
@ -54,15 +62,38 @@ interface DropDownItemProps {
|
|||||||
|
|
||||||
function DropDownItem(props: DropDownItemProps) {
|
function DropDownItem(props: DropDownItemProps) {
|
||||||
return (
|
return (
|
||||||
<button
|
<ConditionalWrapper
|
||||||
onClick={() => {
|
condition={!!props.item.disabled}
|
||||||
props.item.onClick()
|
wrapper={(children) => {
|
||||||
props.closeMenu()
|
if (!props.item.disabledTooltip) return children
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
type='warning'
|
||||||
|
content={<Text size='sm'>{props.item.disabledTooltip}</Text>}
|
||||||
|
contentClassName='max-w-[200px]'
|
||||||
|
className='ml-auto'
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
}}
|
}}
|
||||||
className=' px-4 py-3 flex gap-2 items-center hover:bg-white/5 w-full [&:not(:last-child)]:border-b border-white/10'
|
|
||||||
>
|
>
|
||||||
<div className='flex justify-center w-5 h-5'>{props.item.icon}</div>
|
<button
|
||||||
<Text size='sm'>{props.item.text}</Text>
|
onClick={(e) => {
|
||||||
</button>
|
e.preventDefault()
|
||||||
|
props.item.onClick()
|
||||||
|
props.closeMenu()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
className={classNames(
|
||||||
|
'z-1 px-4 py-3 flex gap-2 items-center w-full [&:not(:last-child)]:border-b border-white/10',
|
||||||
|
props.item.disabled ? 'bg-black/20 text-white/40 cursor-events-none' : 'hover:bg-white/5',
|
||||||
|
)}
|
||||||
|
disabled={props.item.disabled}
|
||||||
|
>
|
||||||
|
<div className='flex justify-center w-4 h-4'>{props.item.icon}</div>
|
||||||
|
<Text size='sm'>{props.item.text}</Text>
|
||||||
|
</button>
|
||||||
|
</ConditionalWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,11 @@ export default function DepositCapMessage(props: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames('flex items-start', props.className)}>
|
<div className={classNames('flex items-start', props.className)}>
|
||||||
{props.showIcon && <InfoCircle width={26} className='mr-5' />}
|
{props.showIcon && (
|
||||||
|
<div className='w-6 mr-5'>
|
||||||
|
<InfoCircle />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className='flex flex-col gap-2'>
|
<div className='flex flex-col gap-2'>
|
||||||
<Text size='sm'>Deposit Cap Reached!</Text>
|
<Text size='sm'>Deposit Cap Reached!</Text>
|
||||||
<Text size='xs' className='text-white/40'>{`Unfortunately you're not able to ${
|
<Text size='xs' className='text-white/40'>{`Unfortunately you're not able to ${
|
||||||
|
@ -10,6 +10,7 @@ interface Props<T> {
|
|||||||
className?: string
|
className?: string
|
||||||
isSelectable?: boolean
|
isSelectable?: boolean
|
||||||
type?: TableType
|
type?: TableType
|
||||||
|
onClick?: (id: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBorderColor(
|
function getBorderColor(
|
||||||
@ -36,7 +37,7 @@ export default function Row<T>(props: Props<T>) {
|
|||||||
key={`${row.id}-row`}
|
key={`${row.id}-row`}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'group/row transition-bg',
|
'group/row transition-bg',
|
||||||
(renderExpanded || isSelectable) && 'hover:cursor-pointer',
|
(renderExpanded || isSelectable || props.onClick) && 'hover:cursor-pointer',
|
||||||
canExpand && row.getIsExpanded() ? 'is-expanded bg-black/20' : 'hover:bg-white/5',
|
canExpand && row.getIsExpanded() ? 'is-expanded bg-black/20' : 'hover:bg-white/5',
|
||||||
)}
|
)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@ -49,6 +50,10 @@ export default function Row<T>(props: Props<T>) {
|
|||||||
table.resetExpanded()
|
table.resetExpanded()
|
||||||
!isExpanded && row.toggleExpanded()
|
!isExpanded && row.toggleExpanded()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.onClick) {
|
||||||
|
props.onClick((row.original as any).asset.denom)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => {
|
{row.getVisibleCells().map((cell) => {
|
||||||
@ -61,7 +66,7 @@ export default function Row<T>(props: Props<T>) {
|
|||||||
spacingClassName ?? 'px-3 py-4',
|
spacingClassName ?? 'px-3 py-4',
|
||||||
type && type !== 'strategies' && isSymbolOrName && 'border-l',
|
type && type !== 'strategies' && isSymbolOrName && 'border-l',
|
||||||
type && type !== 'strategies' && getBorderColor(type, cell.row.original as any),
|
type && type !== 'strategies' && getBorderColor(type, cell.row.original as any),
|
||||||
cell.column.columnDef.meta?.className,
|
cell.column.columnDef.meta?.className ?? 'w-min',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||||
|
@ -31,6 +31,7 @@ interface Props<T> {
|
|||||||
hideCard?: boolean
|
hideCard?: boolean
|
||||||
setRowSelection?: OnChangeFn<RowSelectionState>
|
setRowSelection?: OnChangeFn<RowSelectionState>
|
||||||
selectedRows?: RowSelectionState
|
selectedRows?: RowSelectionState
|
||||||
|
onClickRow?: (id: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Table<T>(props: Props<T>) {
|
export default function Table<T>(props: Props<T>) {
|
||||||
@ -75,6 +76,7 @@ export default function Table<T>(props: Props<T>) {
|
|||||||
props.spacingClassName ?? 'px-4 py-3',
|
props.spacingClassName ?? 'px-4 py-3',
|
||||||
header.column.getCanSort() && 'hover:cursor-pointer',
|
header.column.getCanSort() && 'hover:cursor-pointer',
|
||||||
header.id === 'symbol' || header.id === 'name' ? 'text-left' : 'text-right',
|
header.id === 'symbol' || header.id === 'name' ? 'text-left' : 'text-right',
|
||||||
|
'w-min',
|
||||||
header.column.columnDef.meta?.className,
|
header.column.columnDef.meta?.className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -122,6 +124,7 @@ export default function Table<T>(props: Props<T>) {
|
|||||||
spacingClassName={props.spacingClassName}
|
spacingClassName={props.spacingClassName}
|
||||||
isSelectable={!!props.setRowSelection}
|
isSelectable={!!props.setRowSelection}
|
||||||
type={props.type}
|
type={props.type}
|
||||||
|
onClick={props.onClickRow}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -16,9 +16,9 @@ export default function TooltipContent(props: Props) {
|
|||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex max-w-[320px] flex-1 gap-2 rounded-lg p-3 text-sm shadow-tooltip backdrop-blur-[100px]',
|
'flex max-w-[320px] flex-1 gap-2 rounded-base p-3 text-sm shadow-tooltip backdrop-blur-[100px]',
|
||||||
'relative isolate max-w-full overflow-hidden',
|
'relative isolate max-w-full overflow-hidden',
|
||||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:rounded-lg before:p-[1px] before:border-glas',
|
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:rounded-base before:p-[1px] before:border-glas',
|
||||||
props.type === 'info' && 'bg-white/10',
|
props.type === 'info' && 'bg-white/10',
|
||||||
props.type === 'warning' && 'bg-warning',
|
props.type === 'warning' && 'bg-warning',
|
||||||
props.type === 'error' && 'bg-error',
|
props.type === 'error' && 'bg-error',
|
||||||
|
@ -48,7 +48,7 @@ export const Tooltip = (props: Props) => {
|
|||||||
visible={props.visible}
|
visible={props.visible}
|
||||||
>
|
>
|
||||||
{props.children ? (
|
{props.children ? (
|
||||||
<span
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
props.underline &&
|
props.underline &&
|
||||||
'border-b hover:cursor-help border-dashed border-white/20 pb-1 hover:border-transparent',
|
'border-b hover:cursor-help border-dashed border-white/20 pb-1 hover:border-transparent',
|
||||||
@ -57,7 +57,7 @@ export const Tooltip = (props: Props) => {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</span>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
className={classNames(
|
className={classNames(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import ActionButton from 'components/common/Button/ActionButton'
|
import ActionButton from 'components/common/Button/ActionButton'
|
||||||
|
import { Plus } from 'components/common/Icons'
|
||||||
import Loading from 'components/common/Loading'
|
import Loading from 'components/common/Loading'
|
||||||
import useStore from 'store'
|
import useStore from 'store'
|
||||||
|
|
||||||
@ -9,6 +10,8 @@ interface Props {
|
|||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DEPOSIT_META = { accessorKey: 'deposit', enableSorting: false, header: '' }
|
||||||
|
|
||||||
export const Deposit = (props: Props) => {
|
export const Deposit = (props: Props) => {
|
||||||
const { vault } = props
|
const { vault } = props
|
||||||
|
|
||||||
@ -26,7 +29,12 @@ export const Deposit = (props: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center justify-end'>
|
<div className='flex items-center justify-end'>
|
||||||
<ActionButton onClick={enterVaultHandler} color='tertiary' text='Deposit' />
|
<ActionButton
|
||||||
|
onClick={enterVaultHandler}
|
||||||
|
color='tertiary'
|
||||||
|
text='Deposit'
|
||||||
|
leftIcon={<Plus />}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import classNames from 'classnames'
|
|
||||||
import React from 'react'
|
|
||||||
|
|
||||||
import { ChevronDown } from 'components/common/Icons'
|
|
||||||
import Loading from 'components/common/Loading'
|
|
||||||
|
|
||||||
export const DETAILS_META = { accessorKey: 'details', enableSorting: false, header: 'Deposit' }
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
isLoading: boolean
|
|
||||||
isExpanded: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Details(props: Props) {
|
|
||||||
if (props.isLoading) return <Loading />
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='flex items-center justify-end'>
|
|
||||||
<div className={classNames('w-4', props.isExpanded && 'rotate-180')}>
|
|
||||||
<ChevronDown />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
116
src/components/earn/farm/Table/Columns/Manage.tsx
Normal file
116
src/components/earn/farm/Table/Columns/Manage.tsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import moment from 'moment/moment'
|
||||||
|
import React, { useCallback, useMemo, useState } from 'react'
|
||||||
|
|
||||||
|
import { AccountArrowDown, LockLocked, LockUnlocked, Plus } from 'components/common/Icons'
|
||||||
|
import Loading from 'components/common/Loading'
|
||||||
|
import { VaultStatus } from 'types/enums/vault'
|
||||||
|
|
||||||
|
import { DEFAULT_SETTINGS } from '../../../../../constants/defaultSettings'
|
||||||
|
import { LocalStorageKeys } from '../../../../../constants/localStorageKeys'
|
||||||
|
import useLocalStorage from '../../../../../hooks/localStorage/useLocalStorage'
|
||||||
|
import useAccountId from '../../../../../hooks/useAccountId'
|
||||||
|
import useStore from '../../../../../store'
|
||||||
|
import DropDownButton from '../../../../common/Button/DropDownButton'
|
||||||
|
|
||||||
|
export const MANAGE_META = { accessorKey: 'details', enableSorting: false, header: '' }
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
vault: DepositedVault
|
||||||
|
isLoading: boolean
|
||||||
|
isExpanded: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Manage(props: Props) {
|
||||||
|
const accountId = useAccountId()
|
||||||
|
const address = useStore((s) => s.address)
|
||||||
|
const withdrawFromVaults = useStore((s) => s.withdrawFromVaults)
|
||||||
|
const [slippage] = useLocalStorage<number>(LocalStorageKeys.SLIPPAGE, DEFAULT_SETTINGS.slippage)
|
||||||
|
const [isConfirming, setIsConfirming] = useState(false)
|
||||||
|
|
||||||
|
const depositMoreHandler = useCallback(() => {
|
||||||
|
useStore.setState({
|
||||||
|
vaultModal: {
|
||||||
|
vault: props.vault,
|
||||||
|
isDeposited: true,
|
||||||
|
selectedBorrowDenoms: [props.vault.denoms.secondary],
|
||||||
|
isCreate: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [props.vault])
|
||||||
|
|
||||||
|
const unlockHandler = useCallback(
|
||||||
|
() => useStore.setState({ unlockModal: { vault: props.vault } }),
|
||||||
|
[props.vault],
|
||||||
|
)
|
||||||
|
|
||||||
|
const withdrawHandler = useCallback(async () => {
|
||||||
|
if (!accountId) return
|
||||||
|
setIsConfirming(true)
|
||||||
|
await withdrawFromVaults({
|
||||||
|
accountId: accountId,
|
||||||
|
vaults: [props.vault],
|
||||||
|
slippage,
|
||||||
|
})
|
||||||
|
}, [accountId, props.vault, slippage, withdrawFromVaults])
|
||||||
|
|
||||||
|
const ITEMS: DropDownItem[] = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
icon: <Plus />,
|
||||||
|
text: 'Deposit more',
|
||||||
|
onClick: depositMoreHandler,
|
||||||
|
},
|
||||||
|
...(props.vault.status === VaultStatus.ACTIVE
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
icon: <LockUnlocked />,
|
||||||
|
text: 'Unlock to withdraw',
|
||||||
|
onClick: unlockHandler,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
...(props.vault.status === VaultStatus.UNLOCKING
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
icon: <LockLocked />,
|
||||||
|
text: `Withdraw in ${moment(props.vault?.unlocksAt).fromNow(true)}`,
|
||||||
|
onClick: () => {},
|
||||||
|
disabled: true,
|
||||||
|
disabledTooltip: '',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
...(props.vault.status === VaultStatus.UNLOCKED
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
icon: <AccountArrowDown />,
|
||||||
|
text: 'Withdraw funds',
|
||||||
|
onClick: withdrawHandler,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
depositMoreHandler,
|
||||||
|
props.vault.status,
|
||||||
|
props.vault?.unlocksAt,
|
||||||
|
unlockHandler,
|
||||||
|
withdrawHandler,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
if (props.isLoading) return <Loading />
|
||||||
|
|
||||||
|
if (!address) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex justify-end z-10'>
|
||||||
|
<DropDownButton
|
||||||
|
items={ITEMS}
|
||||||
|
text='Manage'
|
||||||
|
color='tertiary'
|
||||||
|
showProgressIndicator={isConfirming}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -2,7 +2,6 @@ import { ColumnDef } from '@tanstack/react-table'
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
import Apy, { APY_META } from 'components/earn/farm/Table/Columns/Apy'
|
import Apy, { APY_META } from 'components/earn/farm/Table/Columns/Apy'
|
||||||
import { Deposit } from 'components/earn/farm/Table/Columns/Deposit'
|
|
||||||
import DepositCap, {
|
import DepositCap, {
|
||||||
DEPOSIT_CAP_META,
|
DEPOSIT_CAP_META,
|
||||||
depositCapSortingFn,
|
depositCapSortingFn,
|
||||||
@ -10,7 +9,8 @@ import DepositCap, {
|
|||||||
import MaxLTV, { LTV_MAX_META } from 'components/earn/farm/Table/Columns/MaxLTV'
|
import MaxLTV, { LTV_MAX_META } from 'components/earn/farm/Table/Columns/MaxLTV'
|
||||||
import Name, { NAME_META } from 'components/earn/farm/Table/Columns/Name'
|
import Name, { NAME_META } from 'components/earn/farm/Table/Columns/Name'
|
||||||
import TVL, { TVL_META } from 'components/earn/farm/Table/Columns/TVL'
|
import TVL, { TVL_META } from 'components/earn/farm/Table/Columns/TVL'
|
||||||
import { DETAILS_META } from 'components/earn/farm/Table/Columns/Details'
|
|
||||||
|
import { Deposit, DEPOSIT_META } from './Deposit'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
@ -41,7 +41,7 @@ export default function useAvailableColumns(props: Props) {
|
|||||||
cell: ({ row }) => <MaxLTV vault={row.original as Vault} isLoading={props.isLoading} />,
|
cell: ({ row }) => <MaxLTV vault={row.original as Vault} isLoading={props.isLoading} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...DETAILS_META,
|
...DEPOSIT_META,
|
||||||
cell: ({ row }) => <Deposit vault={row.original as Vault} isLoading={props.isLoading} />,
|
cell: ({ row }) => <Deposit vault={row.original as Vault} isLoading={props.isLoading} />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -6,7 +6,7 @@ import DepositCap, {
|
|||||||
DEPOSIT_CAP_META,
|
DEPOSIT_CAP_META,
|
||||||
depositCapSortingFn,
|
depositCapSortingFn,
|
||||||
} from 'components/earn/farm/Table/Columns/DepositCap'
|
} from 'components/earn/farm/Table/Columns/DepositCap'
|
||||||
import Details, { DETAILS_META } from 'components/earn/farm/Table/Columns/Details'
|
import Manage, { MANAGE_META } from 'components/earn/farm/Table/Columns/Manage'
|
||||||
import MaxLTV, { LTV_MAX_META } from 'components/earn/farm/Table/Columns/MaxLTV'
|
import MaxLTV, { LTV_MAX_META } from 'components/earn/farm/Table/Columns/MaxLTV'
|
||||||
import Name, { NAME_META } from 'components/earn/farm/Table/Columns/Name'
|
import Name, { NAME_META } from 'components/earn/farm/Table/Columns/Name'
|
||||||
import PositionValue, {
|
import PositionValue, {
|
||||||
@ -55,8 +55,14 @@ export default function useDepositedColumns(props: Props) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...DETAILS_META,
|
...MANAGE_META,
|
||||||
cell: ({ row }) => <Details isLoading={props.isLoading} isExpanded={row.getIsExpanded()} />,
|
cell: ({ row }) => (
|
||||||
|
<Manage
|
||||||
|
vault={row.original}
|
||||||
|
isLoading={props.isLoading}
|
||||||
|
isExpanded={row.getIsExpanded()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}, [props.isLoading])
|
}, [props.isLoading])
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import { Row } from '@tanstack/react-table'
|
import React from 'react'
|
||||||
import { Table as TanStackTable } from '@tanstack/table-core/build/lib/types'
|
|
||||||
import React, { useCallback } from 'react'
|
|
||||||
|
|
||||||
import useDepositedColumns from 'components/earn/farm/Table/Columns/useDepositedColumns'
|
|
||||||
import VaultExpanded from 'components/earn/farm/VaultExpanded'
|
|
||||||
import Table from 'components/common/Table'
|
import Table from 'components/common/Table'
|
||||||
|
import useDepositedColumns from 'components/earn/farm/Table/Columns/useDepositedColumns'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: DepositedVault[]
|
data: DepositedVault[]
|
||||||
@ -14,20 +11,12 @@ type Props = {
|
|||||||
export default function DepositedVaultsTable(props: Props) {
|
export default function DepositedVaultsTable(props: Props) {
|
||||||
const columns = useDepositedColumns({ isLoading: props.isLoading })
|
const columns = useDepositedColumns({ isLoading: props.isLoading })
|
||||||
|
|
||||||
const renderExpanded = useCallback(
|
|
||||||
(row: Row<DepositedVault>, table: TanStackTable<DepositedVault>) => (
|
|
||||||
<VaultExpanded row={row} resetExpanded={table.resetExpanded} />
|
|
||||||
),
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
title='Deposited Vaults'
|
title='Deposited Vaults'
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={props.data}
|
data={props.data}
|
||||||
initialSorting={[{ id: 'name', desc: true }]}
|
initialSorting={[{ id: 'name', desc: true }]}
|
||||||
renderExpanded={renderExpanded}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
import { useCallback } from 'react'
|
|
||||||
|
|
||||||
import { ACCOUNT_MENU_BUTTON_ID } from 'components/account/AccountMenuContent'
|
|
||||||
import Button from 'components/common/Button'
|
|
||||||
import ActionButton from 'components/common/Button/ActionButton'
|
|
||||||
import { ArrowDownLine, ArrowUpLine, Enter, ExclamationMarkCircled } from 'components/common/Icons'
|
|
||||||
import Text from 'components/common/Text'
|
|
||||||
import { Tooltip } from 'components/common/Tooltip'
|
|
||||||
import ConditionalWrapper from 'hocs/ConditionalWrapper'
|
|
||||||
import useAccountId from 'hooks/useAccountId'
|
|
||||||
import useAlertDialog from 'hooks/useAlertDialog'
|
|
||||||
import useAutoLend from 'hooks/useAutoLend'
|
|
||||||
import useCurrentAccountDeposits from 'hooks/useCurrentAccountDeposits'
|
|
||||||
import useLendAndReclaimModal from 'hooks/useLendAndReclaimModal'
|
|
||||||
import useStore from 'store'
|
|
||||||
import { byDenom } from 'utils/array'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
data: LendingMarketTableData
|
|
||||||
}
|
|
||||||
|
|
||||||
const buttonClassnames = 'm-0 flex w-40'
|
|
||||||
const iconClassnames = 'ml-0 mr-1 w-4 h-4'
|
|
||||||
|
|
||||||
export default function LendingActionButtons(props: Props) {
|
|
||||||
const { asset, accountLentValue: accountLendValue } = props.data
|
|
||||||
const accountDeposits = useCurrentAccountDeposits()
|
|
||||||
const { openLend, openReclaim } = useLendAndReclaimModal()
|
|
||||||
const { open: showAlertDialog } = useAlertDialog()
|
|
||||||
const { isAutoLendEnabledForCurrentAccount } = useAutoLend()
|
|
||||||
const assetDepositAmount = accountDeposits.find(byDenom(asset.denom))?.amount
|
|
||||||
const address = useStore((s) => s.address)
|
|
||||||
const accountId = useAccountId()
|
|
||||||
const hasNoDeposit = !!(!assetDepositAmount && address && accountId)
|
|
||||||
|
|
||||||
const handleUnlend = useCallback(() => {
|
|
||||||
if (isAutoLendEnabledForCurrentAccount) {
|
|
||||||
showAlertDialog({
|
|
||||||
icon: <ExclamationMarkCircled width={18} />,
|
|
||||||
title: 'Disable Automatically Lend Assets',
|
|
||||||
content:
|
|
||||||
"Your auto-lend feature is currently enabled. To unlend your funds, please confirm if you'd like to disable this feature in order to continue.",
|
|
||||||
positiveButton: {
|
|
||||||
onClick: () => document.getElementById(ACCOUNT_MENU_BUTTON_ID)?.click(),
|
|
||||||
text: 'Continue to Account Settings',
|
|
||||||
icon: <Enter />,
|
|
||||||
},
|
|
||||||
negativeButton: {
|
|
||||||
text: 'Cancel',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
openReclaim(props.data)
|
|
||||||
}, [isAutoLendEnabledForCurrentAccount, openReclaim, props.data, showAlertDialog])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='flex flex-row space-x-2'>
|
|
||||||
{accountLendValue && accountLendValue.isGreaterThan(0) && (
|
|
||||||
<Button
|
|
||||||
leftIcon={<ArrowDownLine />}
|
|
||||||
iconClassName={iconClassnames}
|
|
||||||
color='secondary'
|
|
||||||
onClick={handleUnlend}
|
|
||||||
className={buttonClassnames}
|
|
||||||
>
|
|
||||||
Unlend
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<ConditionalWrapper
|
|
||||||
condition={hasNoDeposit}
|
|
||||||
wrapper={(children) => (
|
|
||||||
<Tooltip
|
|
||||||
type='warning'
|
|
||||||
content={
|
|
||||||
<Text size='sm'>{`You don’t have any ${asset.symbol}. Please first deposit ${asset.symbol} into your Credit Account before lending.`}</Text>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<ActionButton
|
|
||||||
leftIcon={<ArrowUpLine />}
|
|
||||||
iconClassName={iconClassnames}
|
|
||||||
disabled={hasNoDeposit}
|
|
||||||
color='secondary'
|
|
||||||
onClick={() => openLend(props.data)}
|
|
||||||
className={buttonClassnames}
|
|
||||||
text='Lend'
|
|
||||||
/>
|
|
||||||
</ConditionalWrapper>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,12 +1,10 @@
|
|||||||
import { Row } from '@tanstack/react-table'
|
import { Row } from '@tanstack/react-table'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
import LendingActionButtons from 'components/earn/lend/LendingActionButtons'
|
|
||||||
import { NAME_META } from 'components/earn/lend/Table/Columns/Name'
|
|
||||||
import useAvailableColumns from 'components/earn/lend/Table/Columns/useAvailableColumns'
|
|
||||||
import MarketDetails from 'components/common/MarketDetails'
|
import MarketDetails from 'components/common/MarketDetails'
|
||||||
import Table from 'components/common/Table'
|
import Table from 'components/common/Table'
|
||||||
import ActionButtonRow from 'components/common/Table/ActionButtonRow'
|
import { NAME_META } from 'components/earn/lend/Table/Columns/Name'
|
||||||
|
import useAvailableColumns from 'components/earn/lend/Table/Columns/useAvailableColumns'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: LendingMarketTableData[]
|
data: LendingMarketTableData[]
|
||||||
@ -19,9 +17,6 @@ export default function AvailableLendsTable(props: Props) {
|
|||||||
const renderExpanded = useCallback(
|
const renderExpanded = useCallback(
|
||||||
(row: Row<LendingMarketTableData>) => (
|
(row: Row<LendingMarketTableData>) => (
|
||||||
<>
|
<>
|
||||||
<ActionButtonRow row={row}>
|
|
||||||
<LendingActionButtons data={row.original} />
|
|
||||||
</ActionButtonRow>
|
|
||||||
<MarketDetails row={row} type='lend' />
|
<MarketDetails row={row} type='lend' />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
21
src/components/earn/lend/Table/Columns/Chevron.tsx
Normal file
21
src/components/earn/lend/Table/Columns/Chevron.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { ChevronDown, ChevronUp } from 'components/common/Icons'
|
||||||
|
|
||||||
|
export const CHEVRON_META = {
|
||||||
|
id: 'chevron',
|
||||||
|
enableSorting: false,
|
||||||
|
header: '',
|
||||||
|
meta: {
|
||||||
|
className: 'w-5',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
isExpanded: boolean
|
||||||
|
}
|
||||||
|
export default function Chevron(props: Props) {
|
||||||
|
return (
|
||||||
|
<div className='flex items-center justify-end'>
|
||||||
|
<div className='w-4'>{props.isExpanded ? <ChevronUp /> : <ChevronDown />}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -10,7 +10,6 @@ export const DEPOSIT_CAP_META = {
|
|||||||
accessorKey: 'marketDepositCap',
|
accessorKey: 'marketDepositCap',
|
||||||
header: 'Deposit Cap',
|
header: 'Deposit Cap',
|
||||||
id: 'marketDepositCap',
|
id: 'marketDepositCap',
|
||||||
meta: { className: 'w-40' },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const marketDepositCapSortingFn = (
|
export const marketDepositCapSortingFn = (
|
||||||
|
60
src/components/earn/lend/Table/Columns/LendButton.tsx
Normal file
60
src/components/earn/lend/Table/Columns/LendButton.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import ActionButton from 'components/common/Button/ActionButton'
|
||||||
|
import { ArrowUpLine } from 'components/common/Icons'
|
||||||
|
import Text from 'components/common/Text'
|
||||||
|
import { Tooltip } from 'components/common/Tooltip'
|
||||||
|
import ConditionalWrapper from 'hocs/ConditionalWrapper'
|
||||||
|
import useAccountId from 'hooks/useAccountId'
|
||||||
|
import useCurrentAccountDeposits from 'hooks/useCurrentAccountDeposits'
|
||||||
|
import useLendAndReclaimModal from 'hooks/useLendAndReclaimModal'
|
||||||
|
import useStore from 'store'
|
||||||
|
import { byDenom } from 'utils/array'
|
||||||
|
|
||||||
|
export const LEND_BUTTON_META = {
|
||||||
|
accessorKey: 'lend',
|
||||||
|
enableSorting: false,
|
||||||
|
header: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
data: LendingMarketTableData
|
||||||
|
}
|
||||||
|
export default function LendButton(props: Props) {
|
||||||
|
const { openLend } = useLendAndReclaimModal()
|
||||||
|
const accountDeposits = useCurrentAccountDeposits()
|
||||||
|
const assetDepositAmount = accountDeposits.find(byDenom(props.data.asset.denom))?.amount
|
||||||
|
const address = useStore((s) => s.address)
|
||||||
|
const accountId = useAccountId()
|
||||||
|
const hasNoDeposit = !!(!assetDepositAmount && address && accountId)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex justify-end'>
|
||||||
|
<ConditionalWrapper
|
||||||
|
condition={hasNoDeposit}
|
||||||
|
wrapper={(children) => (
|
||||||
|
<Tooltip
|
||||||
|
type='warning'
|
||||||
|
content={
|
||||||
|
<Text size='sm'>{`You don’t have any ${props.data.asset.symbol}.
|
||||||
|
Please first deposit ${props.data.asset.symbol} into your Credit Account before lending.`}</Text>
|
||||||
|
}
|
||||||
|
contentClassName='max-w-[200px]'
|
||||||
|
className='ml-auto'
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ActionButton
|
||||||
|
leftIcon={<ArrowUpLine />}
|
||||||
|
disabled={hasNoDeposit}
|
||||||
|
color='tertiary'
|
||||||
|
onClick={(e) => {
|
||||||
|
openLend(props.data)
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
text='Lend'
|
||||||
|
/>
|
||||||
|
</ConditionalWrapper>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,21 +1,82 @@
|
|||||||
import { ChevronDown, ChevronUp } from 'components/common/Icons'
|
import { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
|
import { ACCOUNT_MENU_BUTTON_ID } from 'components/account/AccountMenuContent'
|
||||||
|
import DropDownButton from 'components/common/Button/DropDownButton'
|
||||||
|
import { ArrowDownLine, ArrowUpLine, Enter, ExclamationMarkCircled } from 'components/common/Icons'
|
||||||
|
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
|
||||||
|
import useAlertDialog from 'hooks/useAlertDialog'
|
||||||
|
import useAutoLend from 'hooks/useAutoLend'
|
||||||
|
import useLendAndReclaimModal from 'hooks/useLendAndReclaimModal'
|
||||||
|
import useStore from 'store'
|
||||||
|
|
||||||
export const MANAGE_META = {
|
export const MANAGE_META = {
|
||||||
accessorKey: 'manage',
|
accessorKey: 'manage',
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
header: 'Manage',
|
header: '',
|
||||||
meta: {
|
|
||||||
className: 'w-30',
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isExpanded: boolean
|
data: LendingMarketTableData
|
||||||
}
|
}
|
||||||
export default function Manage(props: Props) {
|
export default function Manage(props: Props) {
|
||||||
|
const { openLend, openReclaim } = useLendAndReclaimModal()
|
||||||
|
const { isAutoLendEnabledForCurrentAccount } = useAutoLend()
|
||||||
|
const { open: showAlertDialog } = useAlertDialog()
|
||||||
|
const address = useStore((s) => s.address)
|
||||||
|
const account = useCurrentAccount()
|
||||||
|
|
||||||
|
const hasAssetInDeposits = useMemo(
|
||||||
|
() => !!account?.deposits?.find((deposit) => deposit.denom === props.data.asset.denom),
|
||||||
|
[account?.deposits, props.data.asset.denom],
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleUnlend = useCallback(() => {
|
||||||
|
if (isAutoLendEnabledForCurrentAccount) {
|
||||||
|
showAlertDialog({
|
||||||
|
icon: <ExclamationMarkCircled width={18} />,
|
||||||
|
title: 'Disable Automatically Lend Assets',
|
||||||
|
content:
|
||||||
|
"Your auto-lend feature is currently enabled. To unlend your funds, please confirm if you'd like to disable this feature in order to continue.",
|
||||||
|
positiveButton: {
|
||||||
|
onClick: () => document.getElementById(ACCOUNT_MENU_BUTTON_ID)?.click(),
|
||||||
|
text: 'Continue to Account Settings',
|
||||||
|
icon: <Enter />,
|
||||||
|
},
|
||||||
|
negativeButton: {
|
||||||
|
text: 'Cancel',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
openReclaim(props.data)
|
||||||
|
}, [isAutoLendEnabledForCurrentAccount, openReclaim, props.data, showAlertDialog])
|
||||||
|
|
||||||
|
const ITEMS: DropDownItem[] = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
icon: <ArrowUpLine />,
|
||||||
|
text: 'Lend more',
|
||||||
|
onClick: () => openLend(props.data),
|
||||||
|
disabled: !hasAssetInDeposits,
|
||||||
|
disabledTooltip: `You don’t have any ${props.data.asset.symbol}.
|
||||||
|
Please first deposit ${props.data.asset.symbol} into your Credit Account before lending.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <ArrowDownLine />,
|
||||||
|
text: 'Unlend',
|
||||||
|
onClick: handleUnlend,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[handleUnlend, hasAssetInDeposits, openLend, props.data],
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!address) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center justify-end'>
|
<div className='flex justify-end z-10'>
|
||||||
<div className='w-4'>{props.isExpanded ? <ChevronUp /> : <ChevronDown />}</div>
|
<DropDownButton items={ITEMS} text='Manage' color='tertiary' />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ import { ColumnDef } from '@tanstack/react-table'
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
import Apy, { APY_META } from 'components/earn/lend/Table/Columns/Apy'
|
import Apy, { APY_META } from 'components/earn/lend/Table/Columns/Apy'
|
||||||
|
import Chevron, { CHEVRON_META } from 'components/earn/lend/Table/Columns/Chevron'
|
||||||
import DepositCap, {
|
import DepositCap, {
|
||||||
DEPOSIT_CAP_META,
|
DEPOSIT_CAP_META,
|
||||||
marketDepositCapSortingFn,
|
marketDepositCapSortingFn,
|
||||||
} from 'components/earn/lend/Table/Columns/DepositCap'
|
} from 'components/earn/lend/Table/Columns/DepositCap'
|
||||||
import Manage, { MANAGE_META } from 'components/earn/lend/Table/Columns/Manage'
|
import LendButton, { LEND_BUTTON_META } from 'components/earn/lend/Table/Columns/LendButton'
|
||||||
import Name, { NAME_META } from 'components/earn/lend/Table/Columns/Name'
|
import Name, { NAME_META } from 'components/earn/lend/Table/Columns/Name'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -36,8 +37,12 @@ export default function useAvailableColumns(props: Props) {
|
|||||||
sortingFn: marketDepositCapSortingFn,
|
sortingFn: marketDepositCapSortingFn,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...MANAGE_META,
|
...LEND_BUTTON_META,
|
||||||
cell: ({ row }) => <Manage isExpanded={row.getIsExpanded()} />,
|
cell: ({ row }) => <LendButton data={row.original} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...CHEVRON_META,
|
||||||
|
cell: ({ row }) => <Chevron isExpanded={row.getIsExpanded()} />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}, [props.isLoading])
|
}, [props.isLoading])
|
||||||
|
@ -2,6 +2,7 @@ import { ColumnDef } from '@tanstack/react-table'
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
import Apy, { APY_META } from 'components/earn/lend/Table/Columns/Apy'
|
import Apy, { APY_META } from 'components/earn/lend/Table/Columns/Apy'
|
||||||
|
import Chevron, { CHEVRON_META } from 'components/earn/lend/Table/Columns/Chevron'
|
||||||
import DepositCap, {
|
import DepositCap, {
|
||||||
DEPOSIT_CAP_META,
|
DEPOSIT_CAP_META,
|
||||||
marketDepositCapSortingFn,
|
marketDepositCapSortingFn,
|
||||||
@ -48,7 +49,11 @@ export default function useDepositedColumns(props: Props) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
...MANAGE_META,
|
...MANAGE_META,
|
||||||
cell: ({ row }) => <Manage isExpanded={row.getIsExpanded()} />,
|
cell: ({ row }) => <Manage data={row.original} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...CHEVRON_META,
|
||||||
|
cell: ({ row }) => <Chevron isExpanded={row.getIsExpanded()} />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}, [props.isLoading])
|
}, [props.isLoading])
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import { Row } from '@tanstack/react-table'
|
import { Row } from '@tanstack/react-table'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
import LendingActionButtons from 'components/earn/lend/LendingActionButtons'
|
|
||||||
import { NAME_META } from 'components/earn/lend/Table/Columns/Name'
|
|
||||||
import useDepositedColumns from 'components/earn/lend/Table/Columns/useDepositedColumns'
|
|
||||||
import MarketDetails from 'components/common/MarketDetails'
|
import MarketDetails from 'components/common/MarketDetails'
|
||||||
import Table from 'components/common/Table'
|
import Table from 'components/common/Table'
|
||||||
import ActionButtonRow from 'components/common/Table/ActionButtonRow'
|
import { NAME_META } from 'components/earn/lend/Table/Columns/Name'
|
||||||
|
import useDepositedColumns from 'components/earn/lend/Table/Columns/useDepositedColumns'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: LendingMarketTableData[]
|
data: LendingMarketTableData[]
|
||||||
@ -17,14 +15,7 @@ export default function DepositedLendsTable(props: Props) {
|
|||||||
const columns = useDepositedColumns({ isLoading: props.isLoading })
|
const columns = useDepositedColumns({ isLoading: props.isLoading })
|
||||||
|
|
||||||
const renderExpanded = useCallback(
|
const renderExpanded = useCallback(
|
||||||
(row: Row<LendingMarketTableData>) => (
|
(row: Row<LendingMarketTableData>) => <MarketDetails row={row} type='lend' />,
|
||||||
<>
|
|
||||||
<ActionButtonRow row={row}>
|
|
||||||
<LendingActionButtons data={row.original} />
|
|
||||||
</ActionButtonRow>
|
|
||||||
<MarketDetails row={row} type='lend' />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,10 +1,32 @@
|
|||||||
|
import { useCallback } from 'react'
|
||||||
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
|
import Table from 'components/common/Table'
|
||||||
import usePerpsBalancesColumns from 'components/perps/BalancesTable/Columns/usePerpsBalancesColumns'
|
import usePerpsBalancesColumns from 'components/perps/BalancesTable/Columns/usePerpsBalancesColumns'
|
||||||
import usePerpsBalancesData from 'components/perps/BalancesTable/usePerpsBalancesData'
|
import usePerpsBalancesData from 'components/perps/BalancesTable/usePerpsBalancesData'
|
||||||
import Table from 'components/common/Table'
|
import { SearchParams } from 'types/enums/searchParams'
|
||||||
|
import { getSearchParamsObject } from 'utils/route'
|
||||||
|
|
||||||
export default function PerpsBalancesTable() {
|
export default function PerpsBalancesTable() {
|
||||||
const data = usePerpsBalancesData()
|
const data = usePerpsBalancesData()
|
||||||
const columns = usePerpsBalancesColumns()
|
const columns = usePerpsBalancesColumns()
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams()
|
||||||
|
|
||||||
return <Table title='Perp Positions' columns={columns} data={data} initialSorting={[]} />
|
const onClickRow = useCallback((denom: string) => {
|
||||||
|
const params = getSearchParamsObject(searchParams)
|
||||||
|
setSearchParams({
|
||||||
|
...params,
|
||||||
|
[SearchParams.PERPS_MARKET]: denom,
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
title='Perp Positions'
|
||||||
|
columns={columns}
|
||||||
|
data={data}
|
||||||
|
initialSorting={[]}
|
||||||
|
onClickRow={onClickRow}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ export default function PortfolioAccountPageHeader(props: Props) {
|
|||||||
<NavLink to={getRoute('portfolio', searchParams, address, selectedAccountId)}>
|
<NavLink to={getRoute('portfolio', searchParams, address, selectedAccountId)}>
|
||||||
<Text className='text-white/40'>Portfolio</Text>
|
<Text className='text-white/40'>Portfolio</Text>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<ArrowRight className='h-3 text-white/60 ' />
|
<div className='h-3'>
|
||||||
|
<ArrowRight className='h-3 text-white/60 ' />
|
||||||
|
</div>
|
||||||
<Text tag='span'>Credit Account {props.accountId}</Text>
|
<Text tag='span'>Credit Account {props.accountId}</Text>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -2,9 +2,9 @@ import React from 'react'
|
|||||||
|
|
||||||
import HealthBar from 'components/account/Health/HealthBar'
|
import HealthBar from 'components/account/Health/HealthBar'
|
||||||
import Card from 'components/common/Card'
|
import Card from 'components/common/Card'
|
||||||
import HLSTag from 'components/hls/HLSTag'
|
|
||||||
import Text from 'components/common/Text'
|
import Text from 'components/common/Text'
|
||||||
import TitleAndSubCell from 'components/common/TitleAndSubCell'
|
import TitleAndSubCell from 'components/common/TitleAndSubCell'
|
||||||
|
import HLSTag from 'components/hls/HLSTag'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
stats: { title: React.ReactNode; sub: string }[]
|
stats: { title: React.ReactNode; sub: string }[]
|
||||||
@ -33,7 +33,7 @@ export default function Skeleton(props: Props) {
|
|||||||
<TitleAndSubCell key={`${accountId}-${sub}`} title={title} sub={sub} />
|
<TitleAndSubCell key={`${accountId}-${sub}`} title={title} sub={sub} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className='flex gap-1 mt-6'>
|
<div className='flex mt-6'>
|
||||||
<HealthBar health={health} healthFactor={healthFactor} showIcon />
|
<HealthBar health={health} healthFactor={healthFactor} showIcon />
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -3,10 +3,10 @@ import React from 'react'
|
|||||||
import HealthBar from 'components/account/Health/HealthBar'
|
import HealthBar from 'components/account/Health/HealthBar'
|
||||||
import HealthIcon from 'components/account/Health/HealthIcon'
|
import HealthIcon from 'components/account/Health/HealthIcon'
|
||||||
import Card from 'components/common/Card'
|
import Card from 'components/common/Card'
|
||||||
import HLSTag from 'components/hls/HLSTag'
|
|
||||||
import Loading from 'components/common/Loading'
|
import Loading from 'components/common/Loading'
|
||||||
import Text from 'components/common/Text'
|
import Text from 'components/common/Text'
|
||||||
import TitleAndSubCell from 'components/common/TitleAndSubCell'
|
import TitleAndSubCell from 'components/common/TitleAndSubCell'
|
||||||
|
import HLSTag from 'components/hls/HLSTag'
|
||||||
import useAccount from 'hooks/accounts/useAccount'
|
import useAccount from 'hooks/accounts/useAccount'
|
||||||
import { DEFAULT_PORTFOLIO_STATS } from 'utils/constants'
|
import { DEFAULT_PORTFOLIO_STATS } from 'utils/constants'
|
||||||
|
|
||||||
@ -31,9 +31,11 @@ export default function SummarySkeleton(props: Props) {
|
|||||||
{account?.kind === 'high_levered_strategy' && <HLSTag />}
|
{account?.kind === 'high_levered_strategy' && <HLSTag />}
|
||||||
</div>
|
</div>
|
||||||
{health !== undefined && healthFactor !== undefined && (
|
{health !== undefined && healthFactor !== undefined && (
|
||||||
<div className='flex gap-1 max-w-[300px] flex-grow'>
|
<div className='flex items-center justify-end flex-grow gap-2'>
|
||||||
<HealthIcon isLoading={healthFactor === 0} health={health} className='w-5' />
|
<HealthIcon isLoading={healthFactor === 0} health={health} />
|
||||||
<HealthBar health={health} healthFactor={healthFactor} className='h-full' />
|
<div className='w-[260px]'>
|
||||||
|
<HealthBar health={health} healthFactor={healthFactor} className='h-3' />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,4 +2,6 @@ interface DropDownItem {
|
|||||||
icon: import('react').ReactNode
|
icon: import('react').ReactNode
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
text: string
|
text: string
|
||||||
|
disabled?: boolean
|
||||||
|
disabledTooltip?: string
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
export const getUrl = (baseUrl: string, path: string): string => {
|
export const getUrl = (baseUrl: string, path: string): string => {
|
||||||
|
const isPlaceholder = baseUrl.split('APP_').length > 1
|
||||||
|
|
||||||
|
if (isPlaceholder) return baseUrl + '/' + path
|
||||||
|
|
||||||
const url = new URL(baseUrl)
|
const url = new URL(baseUrl)
|
||||||
|
|
||||||
if (process.env.NEXT_PUBLIC_API_KEY)
|
if (process.env.NEXT_PUBLIC_API_KEY)
|
||||||
|
Loading…
Reference in New Issue
Block a user