MP-3564: added navigation dropdown and Governance NavLink (#639)
This commit is contained in:
parent
9c1d4dfbee
commit
74f4206668
@ -28,6 +28,7 @@
|
||||
"@sentry/nextjs": "^7.77.0",
|
||||
"@splinetool/react-spline": "^2.2.6",
|
||||
"@splinetool/runtime": "^0.9.482",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tanstack/react-table": "^8.10.6",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"bignumber.js": "^9.1.2",
|
||||
|
@ -10,14 +10,17 @@ import Settings from 'components/Settings'
|
||||
import Wallet from 'components/Wallet'
|
||||
import useAccountId from 'hooks/useAccountId'
|
||||
import useStore from 'store'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
import { ENABLE_HLS } from 'utils/constants'
|
||||
import { getGovernanceUrl } from 'utils/helpers'
|
||||
|
||||
export const menuTree: { pages: Page[]; label: string }[] = [
|
||||
export const menuTree = (walletId: WalletID): MenuTreeEntry[] => [
|
||||
{ pages: ['trade'], label: 'Trade' },
|
||||
{ pages: ['lend', 'farm'], label: 'Earn' },
|
||||
{ pages: ['borrow'], label: 'Borrow' },
|
||||
...(ENABLE_HLS ? [{ pages: ['hls-staking'] as Page[], label: 'High Leverage' }] : []),
|
||||
{ pages: ['portfolio'], label: 'Portfolio' },
|
||||
{ pages: ['governance'], label: 'Governance', externalUrl: getGovernanceUrl(walletId) },
|
||||
]
|
||||
|
||||
export default function DesktopHeader() {
|
||||
@ -37,9 +40,8 @@ export default function DesktopHeader() {
|
||||
return (
|
||||
<header
|
||||
className={classNames(
|
||||
'fixed left-0 top-0 z-50 hidden w-full',
|
||||
'fixed left-0 top-0 z-50 w-full',
|
||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:h-full before:w-full before:rounded-sm before:backdrop-blur-sticky',
|
||||
'lg:block',
|
||||
)}
|
||||
>
|
||||
<div
|
||||
|
@ -1,18 +1,28 @@
|
||||
import { useShuttle } from '@delphi-labs/shuttle-react'
|
||||
import classNames from 'classnames'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import Button from 'components/Button'
|
||||
import { menuTree } from 'components/Header/DesktopHeader'
|
||||
import { Logo } from 'components/Icons'
|
||||
import { ChevronDown, Logo } from 'components/Icons'
|
||||
import { NavLink } from 'components/Navigation/NavLink'
|
||||
import useAccountId from 'hooks/useAccountId'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
import useStore from 'store'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
import { getRoute } from 'utils/route'
|
||||
|
||||
export default function DesktopNavigation() {
|
||||
const [showMenu, setShowMenu] = useToggle()
|
||||
const { recentWallet } = useShuttle()
|
||||
const walletId = (recentWallet?.providerId as WalletID) ?? WalletID.Keplr
|
||||
const address = useStore((s) => s.address)
|
||||
const accountId = useAccountId()
|
||||
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
|
||||
const menu = useMemo(() => menuTree(walletId), [walletId])
|
||||
|
||||
function getIsActive(pages: string[]) {
|
||||
const segments = location.pathname.split('/')
|
||||
return pages.some((page) => segments.includes(page))
|
||||
@ -30,16 +40,62 @@ export default function DesktopNavigation() {
|
||||
</span>
|
||||
</NavLink>
|
||||
{!focusComponent && (
|
||||
<div className='flex gap-8 px-6'>
|
||||
{menuTree.map((item, index) => (
|
||||
<div className='flex gap-8 px-6 @container/navigation relative flex-1'>
|
||||
{menu.map((item, index) => (
|
||||
<NavLink
|
||||
key={index}
|
||||
href={getRoute(item.pages[0], address, accountId)}
|
||||
href={
|
||||
item.externalUrl ? item.externalUrl : getRoute(item.pages[0], address, accountId)
|
||||
}
|
||||
isActive={getIsActive(item.pages)}
|
||||
className={`@nav-${index}/navigation:inline-block hidden whitespace-nowrap`}
|
||||
target={item.externalUrl ? '_blank' : undefined}
|
||||
>
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
<div className={`@nav-${menu.length - 1}/navigation:hidden flex items-center relative`}>
|
||||
<Button
|
||||
leftIcon={<ChevronDown />}
|
||||
color='quaternary'
|
||||
variant='transparent'
|
||||
onClick={() => setShowMenu(!showMenu)}
|
||||
text='More'
|
||||
className='!text-base !p-0 !min-h-0'
|
||||
/>
|
||||
<div
|
||||
className={classNames(
|
||||
showMenu ? 'flex' : 'hidden',
|
||||
'absolute left-0 top-[calc(100%+4px)]',
|
||||
)}
|
||||
>
|
||||
<ul
|
||||
className={classNames(
|
||||
'py-4 list-none flex flex-wrap gap-2 bg-white/10 backdrop-blur-lg',
|
||||
'relative isolate max-w-full overflow-hidden rounded-sm',
|
||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:rounded-sm before:p-[1px] before:border-glas',
|
||||
)}
|
||||
>
|
||||
{menu.map((item, index) => (
|
||||
<li className={`@nav-${index}/navigation:hidden block w-full m-0`} key={index}>
|
||||
<NavLink
|
||||
href={
|
||||
item.externalUrl
|
||||
? item.externalUrl
|
||||
: getRoute(item.pages[0], address, accountId)
|
||||
}
|
||||
onClick={() => setShowMenu(false)}
|
||||
isActive={getIsActive(item.pages)}
|
||||
className='w-full px-4 whitespace-nowrap'
|
||||
target={item.externalUrl ? '_blank' : undefined}
|
||||
>
|
||||
{item.label}
|
||||
</NavLink>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -6,16 +6,22 @@ interface Props {
|
||||
href: string
|
||||
children: string | ReactNode
|
||||
isActive?: boolean
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
target?: string
|
||||
}
|
||||
|
||||
export const NavLink = (props: Props) => {
|
||||
return (
|
||||
<Link
|
||||
to={props.href}
|
||||
onClick={props.onClick ? props.onClick : undefined}
|
||||
className={classNames(
|
||||
'text-sm font-semibold hover:text-white active:text-white',
|
||||
props.className,
|
||||
'font-semibold hover:text-white active:text-white',
|
||||
props.isActive ? 'pointer-events-none text-white' : 'text-white/60',
|
||||
)}
|
||||
target={props.target}
|
||||
>
|
||||
{props.children}
|
||||
</Link>
|
||||
|
@ -3,6 +3,9 @@ export enum DocURL {
|
||||
BORROW_LENDING_URL = 'https://docs.marsprotocol.io/docs/learn/mars-v2/borrow',
|
||||
CHANGE_LOG_URL = 'https://docs.marsprotocol.io/docs/overview/changelog',
|
||||
COOKIE_POLICY_URL = 'https://docs.marsprotocol.io/docs/overview/legal/cookie-policy',
|
||||
COUNCIL_LEAP = 'https://cosmos.leapwallet.io/chains/mars/governance',
|
||||
COUNCIL_STATION = 'https://station.terra.money/gov#PROPOSAL_STATUS_VOTING_PERIOD',
|
||||
COUNCIL_KEPLR = 'https://wallet.keplr.app/chains/mars-hub?tab=governance',
|
||||
DOCS_URL = 'https://docs.marsprotocol.io/',
|
||||
FARM_INTRO_URL = 'https://docs.marsprotocol.io/docs/learn/tutorials/farming/farming-intro',
|
||||
MANAGE_ACCOUNT_URL = 'https://docs.marsprotocol.io/docs/learn/tutorials/credit-accounts/credit-accounts-intro',
|
||||
|
5
src/types/interfaces/components/Navigation.d.ts
vendored
Normal file
5
src/types/interfaces/components/Navigation.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
interface MenuTreeEntry {
|
||||
pages: Page[]
|
||||
label: string
|
||||
externalUrl?: string
|
||||
}
|
1
src/types/interfaces/route.d.ts
vendored
1
src/types/interfaces/route.d.ts
vendored
@ -7,3 +7,4 @@ type Page =
|
||||
| 'portfolio/{accountId}'
|
||||
| 'hls-farm'
|
||||
| 'hls-staking'
|
||||
| 'governance'
|
||||
|
@ -3,6 +3,8 @@ import throttle from 'lodash.throttle'
|
||||
|
||||
import { BN_ZERO } from 'constants/math'
|
||||
import { BNCoin } from 'types/classes/BNCoin'
|
||||
import { DocURL } from 'types/enums/docURL'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
import { getCoinValue } from 'utils/formatters'
|
||||
|
||||
BigNumber.config({ EXPONENTIAL_AT: 1e9 })
|
||||
@ -60,3 +62,14 @@ export function getValueFromBNCoins(coins: BNCoin[], prices: BNCoin[]): BigNumbe
|
||||
export function getLeverageFromLTV(ltv: number) {
|
||||
return +(1 / (1 - ltv)).toPrecision(2)
|
||||
}
|
||||
|
||||
export function getGovernanceUrl(walletId: WalletID) {
|
||||
switch (walletId) {
|
||||
case WalletID.Station:
|
||||
return DocURL.COUNCIL_STATION
|
||||
case WalletID.Leap:
|
||||
return DocURL.COUNCIL_LEAP
|
||||
default:
|
||||
return DocURL.COUNCIL_KEPLR
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,18 @@ module.exports = {
|
||||
'fill-martian-red',
|
||||
'fill-grey-light',
|
||||
'w-2',
|
||||
'@nav-0/navigation:inline-block',
|
||||
'@nav-1/navigation:inline-block',
|
||||
'@nav-2/navigation:inline-block',
|
||||
'@nav-3/navigation:inline-block',
|
||||
'@nav-4/navigation:inline-block',
|
||||
'@nav-5/navigation:inline-block',
|
||||
'@nav-0/navigation:hidden',
|
||||
'@nav-1/navigation:hidden',
|
||||
'@nav-2/navigation:hidden',
|
||||
'@nav-3/navigation:hidden',
|
||||
'@nav-4/navigation:hidden',
|
||||
'@nav-5/navigation:hidden',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
@ -122,6 +134,14 @@ module.exports = {
|
||||
white: '#FFF',
|
||||
pink: '#de587f',
|
||||
},
|
||||
containers: {
|
||||
'nav-0': '100px',
|
||||
'nav-1': '160px',
|
||||
'nav-2': '250px',
|
||||
'nav-3': '400px',
|
||||
'nav-4': '500px',
|
||||
'nav-5': '600px',
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'sans-serif'],
|
||||
},
|
||||
@ -278,6 +298,7 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
require('tailwind-scrollbar-hide'),
|
||||
require('@tailwindcss/container-queries'),
|
||||
plugin(function ({ addBase, addUtilities, theme }) {
|
||||
addBase({
|
||||
h1: { fontSize: '61px', lineHeight: '80px', fontWeight: theme('fontWeight.light') },
|
||||
|
@ -3252,6 +3252,11 @@
|
||||
dependencies:
|
||||
tslib "^2.4.0"
|
||||
|
||||
"@tailwindcss/container-queries@^0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz#9a759ce2cb8736a4c6a0cb93aeb740573a731974"
|
||||
integrity sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==
|
||||
|
||||
"@tanstack/react-table@^8.10.6":
|
||||
version "8.10.6"
|
||||
resolved "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.10.6.tgz"
|
||||
|
Loading…
Reference in New Issue
Block a user