more elements
This commit is contained in:
parent
5bde98b388
commit
37bf6ba578
|
@ -24,12 +24,17 @@ const Layout = ({ children }: { children: ReactNode }) => {
|
||||||
<main
|
<main
|
||||||
className={`${themeData.fonts.body.variable} ${themeData.fonts.display.variable} ${themeData.fonts.mono.variable} font-sans bg-[#889FD3] bg-[url('/images/rays.svg')] bg-cover bg-fixed bg-center`}
|
className={`${themeData.fonts.body.variable} ${themeData.fonts.display.variable} ${themeData.fonts.mono.variable} font-sans bg-[#889FD3] bg-[url('/images/rays.svg')] bg-cover bg-fixed bg-center`}
|
||||||
>
|
>
|
||||||
<div className={`min-h-screen`}>
|
<div className={`relative min-h-screen`}>
|
||||||
|
<div className="from-th-primary-3 to-th-primary-2 border-th-primary-4 absolute bottom-0 h-44 w-full border-b-[20px] bg-gradient-to-b" />
|
||||||
|
<div className="relative z-10">
|
||||||
<TopBar />
|
<TopBar />
|
||||||
|
<div className="mx-auto max-w-3xl px-6 pb-12 md:pb-20 lg:px-12">
|
||||||
{children}
|
{children}
|
||||||
|
</div>
|
||||||
<DeployRefreshManager />
|
<DeployRefreshManager />
|
||||||
<TermsOfUse />
|
<TermsOfUse />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
type Values = string | number
|
||||||
|
|
||||||
|
interface NavTabsProps<T extends Values> {
|
||||||
|
activeValue: string
|
||||||
|
onChange: (x: T) => void
|
||||||
|
values: T[]
|
||||||
|
names?: Array<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavTabs = <T extends Values>({
|
||||||
|
activeValue,
|
||||||
|
values,
|
||||||
|
names,
|
||||||
|
onChange,
|
||||||
|
}: NavTabsProps<T>) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{values.map((value, i) => (
|
||||||
|
<button
|
||||||
|
className={`mx-auto w-full border-y-2 border-r border-th-fgd-1 pb-2.5 pt-3.5 font-display first:rounded-l-lg first:border-l-2 last:rounded-r-lg last:border-r-2 ${
|
||||||
|
activeValue === value
|
||||||
|
? 'text-shadow inner-shadow-top-sm bg-th-primary-2 text-th-active'
|
||||||
|
: 'inner-shadow-bottom-sm default-transition bg-th-bkg-1 text-th-fgd-1 md:hover:bg-th-bkg-2'
|
||||||
|
}`}
|
||||||
|
key={`${value}` + i}
|
||||||
|
onClick={() => onChange(value)}
|
||||||
|
>
|
||||||
|
{names ? names[i] : value}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NavTabs
|
|
@ -36,22 +36,23 @@ const Positions = ({
|
||||||
}, [group])
|
}, [group])
|
||||||
|
|
||||||
const positions = useMemo(() => {
|
const positions = useMemo(() => {
|
||||||
if (!banks.length || !stakeAccounts?.length) return []
|
|
||||||
const positions = []
|
const positions = []
|
||||||
|
if (banks.length) {
|
||||||
for (const bank of banks) {
|
for (const bank of banks) {
|
||||||
if (!bank) continue
|
if (!bank) continue
|
||||||
const acct = stakeAccounts.find((acc) => acc.getTokenBalanceUi(bank) > 0)
|
const acct = stakeAccounts?.find(
|
||||||
|
(acc) => acc.getTokenBalanceUi(bank) > 0,
|
||||||
|
)
|
||||||
const balance = acct ? acct.getTokenBalanceUi(bank) : 0
|
const balance = acct ? acct.getTokenBalanceUi(bank) : 0
|
||||||
positions.push({ balance, bank })
|
positions.push({ balance, bank })
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const sortedPositions = positions.sort((a, b) => b.balance - a.balance)
|
const sortedPositions = positions.sort((a, b) => b.balance - a.balance)
|
||||||
return showInactivePositions
|
return showInactivePositions
|
||||||
? sortedPositions
|
? sortedPositions
|
||||||
: sortedPositions.filter((pos) => pos.balance > 0)
|
: sortedPositions.filter((pos) => pos.balance > 0)
|
||||||
}, [banks, showInactivePositions, stakeAccounts])
|
}, [banks, showInactivePositions, stakeAccounts])
|
||||||
|
|
||||||
console.log('positions', positions)
|
|
||||||
|
|
||||||
const numberOfPositions = useMemo(() => {
|
const numberOfPositions = useMemo(() => {
|
||||||
if (!positions.length) return 0
|
if (!positions.length) return 0
|
||||||
return positions.filter((pos) => pos.balance > 0).length
|
return positions.filter((pos) => pos.balance > 0).length
|
||||||
|
@ -64,11 +65,11 @@ const Positions = ({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return positions.length ? (
|
return (
|
||||||
<div className="space-y-3">
|
<>
|
||||||
<div className="mb-4 flex items-center justify-between">
|
<div className="mb-2 flex items-center justify-between rounded-lg border-2 border-th-fgd-1 bg-th-bkg-1 px-6 py-3.5">
|
||||||
<p>{`You have ${numberOfPositions} active position${
|
<p className="font-medium">{`You have ${numberOfPositions} active position${
|
||||||
numberOfPositions > 1 ? 's' : ''
|
numberOfPositions !== 1 ? 's' : ''
|
||||||
}`}</p>
|
}`}</p>
|
||||||
<Switch
|
<Switch
|
||||||
checked={showInactivePositions}
|
checked={showInactivePositions}
|
||||||
|
@ -77,19 +78,26 @@ const Positions = ({
|
||||||
Show Inactive
|
Show Inactive
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
<div className="grid grid-cols-1 gap-2">
|
||||||
{positions.map((position, i) => {
|
{positions.length ? (
|
||||||
|
positions.map((position, i) => {
|
||||||
const { balance, bank } = position
|
const { balance, bank } = position
|
||||||
return bank ? (
|
return bank ? (
|
||||||
<div
|
<div
|
||||||
className="rounded-2xl border border-th-fgd-1 p-6"
|
className="rounded-2xl border-2 border-th-fgd-1 bg-th-bkg-1 p-6"
|
||||||
key={i + balance}
|
key={i + balance}
|
||||||
>
|
>
|
||||||
<div className="mb-6 flex flex-col border-b border-th-bkg-4 pb-6 md:flex-row md:items-center md:justify-between">
|
<div className="mb-4 flex flex-col border-b border-th-bkg-3 pb-4 md:flex-row md:items-center md:justify-between">
|
||||||
<div className="mb-4 flex items-center space-x-3 md:mb-0">
|
<div className="mb-4 flex items-center space-x-3 md:mb-0">
|
||||||
<TokenLogo bank={bank} size={40} />
|
<div
|
||||||
|
className={`inner-shadow-bottom-sm flex h-14 w-14 items-center justify-center rounded-full border border-th-bkg-2 bg-gradient-to-b from-th-bkg-1 to-th-bkg-2`}
|
||||||
|
>
|
||||||
|
<TokenLogo bank={bank} size={32} />
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3>{formatTokenSymbol(bank.name)}</h3>
|
<h3 className="-mb-1 text-2xl">
|
||||||
|
{formatTokenSymbol(bank.name)}
|
||||||
|
</h3>
|
||||||
<span
|
<span
|
||||||
className={`text-sm ${
|
className={`text-sm ${
|
||||||
balance ? 'text-th-fgd-1' : 'text-th-fgd-4'
|
balance ? 'text-th-fgd-1' : 'text-th-fgd-4'
|
||||||
|
@ -99,49 +107,48 @@ const Positions = ({
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button onClick={() => handleAddOrManagePosition(bank.name)}>
|
||||||
onClick={() => handleAddOrManagePosition(bank.name)}
|
<span className="mt-1 text-base tracking-wider">
|
||||||
secondary
|
|
||||||
>
|
|
||||||
{balance ? 'Manage' : 'Add Position'}
|
{balance ? 'Manage' : 'Add Position'}
|
||||||
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="mb-1">Position Size</p>
|
<p className="mb-1 text-th-fgd-4">Position Size</p>
|
||||||
<span className="text-xl font-bold">
|
<span className="text-xl font-bold">
|
||||||
<FormatNumericValue value={balance} decimals={6} />{' '}
|
<FormatNumericValue value={balance} decimals={6} />{' '}
|
||||||
{formatTokenSymbol(bank.name)}
|
{formatTokenSymbol(bank.name)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="mb-1">Est. APY</p>
|
<p className="mb-1 text-th-fgd-4">Est. APY</p>
|
||||||
<span className="text-xl font-bold">
|
<span className="text-xl font-bold">
|
||||||
{loadingRates ? (
|
{loadingRates ? (
|
||||||
<SheenLoader className="mt-1">
|
<SheenLoader className="mt-1">
|
||||||
<div className="h-6 w-16 bg-th-bkg-2" />
|
<div className="h-6 w-16 bg-th-bkg-2" />
|
||||||
</SheenLoader>
|
</SheenLoader>
|
||||||
) : stakeRates?.[bank.name.toLowerCase()] ? (
|
) : stakeRates?.[bank.name.toLowerCase()] ? (
|
||||||
`${(stakeRates?.[bank.name.toLowerCase()] * 100).toFixed(
|
`${(
|
||||||
2,
|
stakeRates?.[bank.name.toLowerCase()] * 100
|
||||||
)}%`
|
).toFixed(2)}%`
|
||||||
) : null}
|
) : null}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="mb-1">Leverage</p>
|
<p className="mb-1 text-th-fgd-4">Leverage</p>
|
||||||
<span className="text-xl font-bold">
|
<span className="text-xl font-bold">
|
||||||
{balance ? '3x' : '0x'}
|
{balance ? '3x' : '0x'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="mb-1">Earned</p>
|
<p className="mb-1 text-th-fgd-4">Earned</p>
|
||||||
<span className="text-xl font-bold">
|
<span className="text-xl font-bold">
|
||||||
{balance ? '3.321 SOL' : '0 SOL'}
|
{balance ? '3.321 SOL' : '0 SOL'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="mb-1">Liquidation Price</p>
|
<p className="mb-1 text-th-fgd-4">Liquidation Price</p>
|
||||||
<span className="whitespace-nowrap text-xl font-bold">
|
<span className="whitespace-nowrap text-xl font-bold">
|
||||||
{balance ? '1.234' : '0'}{' '}
|
{balance ? '1.234' : '0'}{' '}
|
||||||
{`${formatTokenSymbol(bank.name)}/SOL`}
|
{`${formatTokenSymbol(bank.name)}/SOL`}
|
||||||
|
@ -150,10 +157,15 @@ const Positions = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null
|
) : null
|
||||||
})}
|
})
|
||||||
|
) : (
|
||||||
|
<div className="flex justify-center rounded-2xl border-2 border-th-fgd-1 bg-th-bkg-1 p-6">
|
||||||
|
<span>Nothing to see here...</span>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Positions
|
export default Positions
|
||||||
|
|
|
@ -41,6 +41,7 @@ import { MangoAccount } from '@blockworks-foundation/mango-v4'
|
||||||
import { AnchorProvider } from '@project-serum/anchor'
|
import { AnchorProvider } from '@project-serum/anchor'
|
||||||
import useBankRates from 'hooks/useBankRates'
|
import useBankRates from 'hooks/useBankRates'
|
||||||
import { Disclosure } from '@headlessui/react'
|
import { Disclosure } from '@headlessui/react'
|
||||||
|
import SheenLoader from './shared/SheenLoader'
|
||||||
|
|
||||||
const set = mangoStore.getState().set
|
const set = mangoStore.getState().set
|
||||||
|
|
||||||
|
@ -99,6 +100,7 @@ function StakeForm({ token: selectedToken }: StakeFormProps) {
|
||||||
// const banks = useBanksWithBalances('walletBalance')
|
// const banks = useBanksWithBalances('walletBalance')
|
||||||
const { usedTokens, totalTokens } = useMangoAccountAccounts()
|
const { usedTokens, totalTokens } = useMangoAccountAccounts()
|
||||||
const { group } = useMangoGroup()
|
const { group } = useMangoGroup()
|
||||||
|
const groupLoaded = mangoStore((s) => s.groupLoaded)
|
||||||
const {
|
const {
|
||||||
stakeBankDepositRate,
|
stakeBankDepositRate,
|
||||||
borrowBankBorrowRate,
|
borrowBankBorrowRate,
|
||||||
|
@ -320,14 +322,19 @@ function StakeForm({ token: selectedToken }: StakeFormProps) {
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Disclosure.Button
|
<Disclosure.Button
|
||||||
className={`w-full rounded-xl border-2 border-th-bkg-3 px-4 py-2 text-left focus:outline-none ${
|
className={`w-full rounded-xl border-2 border-th-bkg-3 px-4 py-3 text-left focus:outline-none ${
|
||||||
open ? 'rounded-b-none border-b-0' : ''
|
open ? 'rounded-b-none border-b-0' : ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="font-medium">Est. Net APY</p>
|
<p className="font-medium">Est. Net APY</p>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="mt-1 font-display text-2xl text-th-success">
|
<span className="font-mono text-lg text-th-success">
|
||||||
|
{estimatedNetAPY >= 0
|
||||||
|
? '+'
|
||||||
|
: estimatedNetAPY === 0
|
||||||
|
? ''
|
||||||
|
: '-'}
|
||||||
<FormatNumericValue
|
<FormatNumericValue
|
||||||
value={estimatedNetAPY}
|
value={estimatedNetAPY}
|
||||||
decimals={2}
|
decimals={2}
|
||||||
|
@ -342,12 +349,13 @@ function StakeForm({ token: selectedToken }: StakeFormProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Disclosure.Button>
|
</Disclosure.Button>
|
||||||
<Disclosure.Panel className="space-y-2 rounded-xl rounded-t-none border-2 border-t-0 border-th-bkg-3 px-4 pb-4">
|
<Disclosure.Panel className="space-y-2 rounded-xl rounded-t-none border-2 border-t-0 border-th-bkg-3 px-4 pb-3">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<p className="text-th-fgd-4">
|
<p className="text-th-fgd-4">
|
||||||
{formatTokenSymbol(selectedToken)} Leveraged APY
|
{formatTokenSymbol(selectedToken)} Leveraged APY
|
||||||
</p>
|
</p>
|
||||||
<span className="font-mono text-th-success">
|
<span className="font-mono text-th-success">
|
||||||
|
{leveragedAPY > 0.01 ? '+' : ''}
|
||||||
<FormatNumericValue
|
<FormatNumericValue
|
||||||
value={leveragedAPY}
|
value={leveragedAPY}
|
||||||
decimals={2}
|
decimals={2}
|
||||||
|
@ -366,6 +374,7 @@ function StakeForm({ token: selectedToken }: StakeFormProps) {
|
||||||
: 'text-th-bkg-4'
|
: 'text-th-bkg-4'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
{stakeBankDepositRate > 0.01 ? '+' : ''}
|
||||||
<FormatNumericValue
|
<FormatNumericValue
|
||||||
value={stakeBankDepositRate}
|
value={stakeBankDepositRate}
|
||||||
decimals={2}
|
decimals={2}
|
||||||
|
@ -384,6 +393,7 @@ function StakeForm({ token: selectedToken }: StakeFormProps) {
|
||||||
: 'text-th-bkg-4'
|
: 'text-th-bkg-4'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
-
|
||||||
<FormatNumericValue
|
<FormatNumericValue
|
||||||
value={borrowBankBorrowRate}
|
value={borrowBankBorrowRate}
|
||||||
decimals={2}
|
decimals={2}
|
||||||
|
@ -417,6 +427,12 @@ function StakeForm({ token: selectedToken }: StakeFormProps) {
|
||||||
)}
|
)}
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
</div>
|
</div>
|
||||||
|
) : !groupLoaded ? (
|
||||||
|
<div className="pt-8">
|
||||||
|
<SheenLoader className="flex flex-1 rounded-xl">
|
||||||
|
<div className="h-[56px] w-full bg-th-bkg-2" />
|
||||||
|
</SheenLoader>
|
||||||
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
{connected ? (
|
{connected ? (
|
||||||
|
|
|
@ -7,6 +7,8 @@ import ConnectWalletButton from './wallet/ConnectWalletButton'
|
||||||
import useOnlineStatus from 'hooks/useOnlineStatus'
|
import useOnlineStatus from 'hooks/useOnlineStatus'
|
||||||
import mangoStore from '@store/mangoStore'
|
import mangoStore from '@store/mangoStore'
|
||||||
import ThemeToggle from './ThemeToggle'
|
import ThemeToggle from './ThemeToggle'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
const TopBar = () => {
|
const TopBar = () => {
|
||||||
const { connected } = useWallet()
|
const { connected } = useWallet()
|
||||||
|
@ -14,6 +16,8 @@ const TopBar = () => {
|
||||||
|
|
||||||
const [copied, setCopied] = useState('')
|
const [copied, setCopied] = useState('')
|
||||||
const isOnline = useOnlineStatus()
|
const isOnline = useOnlineStatus()
|
||||||
|
const router = useRouter()
|
||||||
|
const { pathname } = router
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => setCopied(''), 2000)
|
setTimeout(() => setCopied(''), 2000)
|
||||||
|
@ -22,13 +26,15 @@ const TopBar = () => {
|
||||||
return (
|
return (
|
||||||
<div className="mb-8 flex h-20 items-center justify-between pr-4">
|
<div className="mb-8 flex h-20 items-center justify-between pr-4">
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
|
<Link href="/" shallow={true}>
|
||||||
<img
|
<img
|
||||||
className="relative top-6 h-auto w-[200px] flex-shrink-0"
|
className="relative top-6 h-auto w-[200px] flex-shrink-0 cursor-pointer"
|
||||||
src={themeData.logoPath}
|
src={themeData.logoPath}
|
||||||
alt="logo"
|
alt="logo"
|
||||||
/>
|
/>
|
||||||
|
</Link>
|
||||||
{!isOnline ? (
|
{!isOnline ? (
|
||||||
<div className="bg-th-down absolute left-1/2 top-3 z-10 flex h-10 w-max -translate-x-1/2 items-center rounded-full px-4 py-2 md:top-8">
|
<div className="absolute left-1/2 top-3 z-10 flex h-10 w-max -translate-x-1/2 items-center rounded-full bg-th-down px-4 py-2 md:top-8">
|
||||||
<ExclamationTriangleIcon className="h-5 w-5 flex-shrink-0 text-th-fgd-1" />
|
<ExclamationTriangleIcon className="h-5 w-5 flex-shrink-0 text-th-fgd-1" />
|
||||||
<p className="ml-2 text-th-fgd-1">
|
<p className="ml-2 text-th-fgd-1">
|
||||||
Your connection appears to be offline
|
Your connection appears to be offline
|
||||||
|
@ -36,6 +42,10 @@ const TopBar = () => {
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-4">
|
||||||
|
<div className="flex space-x-6 pr-4">
|
||||||
|
<NavLink active={pathname === '/'} path="/" text="Boost!" />
|
||||||
|
<NavLink active={pathname === '/faqs'} path="/faqs" text="FAQs" />
|
||||||
|
</div>
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
{connected ? <ConnectedMenu /> : <ConnectWalletButton />}
|
{connected ? <ConnectedMenu /> : <ConnectWalletButton />}
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,3 +55,25 @@ const TopBar = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TopBar
|
export default TopBar
|
||||||
|
|
||||||
|
const NavLink = ({
|
||||||
|
active,
|
||||||
|
path,
|
||||||
|
text,
|
||||||
|
}: {
|
||||||
|
active: boolean
|
||||||
|
path: string
|
||||||
|
text: string
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Link href={path} shallow={true}>
|
||||||
|
<span
|
||||||
|
className={`default-transition border-b-4 border-th-active font-display text-xl md:hover:text-th-active ${
|
||||||
|
active ? 'text-th-active' : 'text-th-bkg-1'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -298,14 +298,14 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<Disclosure.Button
|
<Disclosure.Button
|
||||||
className={`w-full rounded-xl border-2 border-th-bkg-3 px-4 py-2 text-left focus:outline-none ${
|
className={`w-full rounded-xl border-2 border-th-bkg-3 px-4 py-3 text-left focus:outline-none ${
|
||||||
open ? 'rounded-b-none border-b-0' : ''
|
open ? 'rounded-b-none border-b-0' : ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="font-medium">Staked Amount</p>
|
<p className="font-medium">Staked Amount</p>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="mt-1 font-display text-2xl text-th-fgd-1">
|
<span className="font-mono text-lg text-th-fgd-1">
|
||||||
<FormatNumericValue
|
<FormatNumericValue
|
||||||
value={tokenMax.maxAmount}
|
value={tokenMax.maxAmount}
|
||||||
decimals={stakeBank.mintDecimals}
|
decimals={stakeBank.mintDecimals}
|
||||||
|
@ -319,7 +319,7 @@ function UnstakeForm({ token: selectedToken }: UnstakeFormProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Disclosure.Button>
|
</Disclosure.Button>
|
||||||
<Disclosure.Panel className="space-y-2 rounded-xl rounded-t-none border-2 border-t-0 border-th-bkg-3 px-4 pb-4">
|
<Disclosure.Panel className="space-y-2 rounded-xl rounded-t-none border-2 border-t-0 border-th-bkg-3 px-4 pb-3">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<p className="text-th-fgd-4">Staked Amount</p>
|
<p className="text-th-fgd-4">Staked Amount</p>
|
||||||
<span className="font-mono text-th-fgd-1">
|
<span className="font-mono text-th-fgd-1">
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { Disclosure } from '@headlessui/react'
|
||||||
|
import { ChevronDownIcon } from '@heroicons/react/20/solid'
|
||||||
|
|
||||||
|
const FAQS = [
|
||||||
|
{ question: 'FAQ 1', answer: 'Answer' },
|
||||||
|
{ question: 'FAQ 2', answer: 'Answer' },
|
||||||
|
{ question: 'FAQ 3', answer: 'Answer' },
|
||||||
|
{ question: 'FAQ 4', answer: 'Answer' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const FaqsPage = () => {
|
||||||
|
return (
|
||||||
|
<div className="rounded-2xl border-2 border-th-fgd-1 bg-th-bkg-1 p-6">
|
||||||
|
<h1>FAQs</h1>
|
||||||
|
<p className="mb-4">Need more info? Reach out to us on ...</p>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{FAQS.map((faq) => {
|
||||||
|
const { question, answer } = faq
|
||||||
|
return (
|
||||||
|
<Disclosure key={question}>
|
||||||
|
{({ open }) => (
|
||||||
|
<div>
|
||||||
|
<Disclosure.Button
|
||||||
|
className={`w-full rounded-xl border-2 border-th-bkg-3 px-4 py-3 text-left focus:outline-none ${
|
||||||
|
open ? 'rounded-b-none border-b-0' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<p className="font-medium">{question}</p>
|
||||||
|
<ChevronDownIcon
|
||||||
|
className={`${
|
||||||
|
open ? 'rotate-180' : 'rotate-360'
|
||||||
|
} h-6 w-6 flex-shrink-0 text-th-fgd-1`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Disclosure.Button>
|
||||||
|
<Disclosure.Panel className="space-y-2 rounded-xl rounded-t-none border-2 border-t-0 border-th-bkg-3 px-4 pb-3">
|
||||||
|
<p>{answer}</p>
|
||||||
|
</Disclosure.Panel>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Disclosure>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FaqsPage
|
|
@ -30,7 +30,7 @@ const Switch: FunctionComponent<SwitchProps> = ({
|
||||||
checked ? 'bg-th-success' : 'bg-th-bkg-4'
|
checked ? 'bg-th-success' : 'bg-th-bkg-4'
|
||||||
} relative inline-flex ${
|
} relative inline-flex ${
|
||||||
small ? 'h-4 w-8' : 'h-5 w-10'
|
small ? 'h-4 w-8' : 'h-5 w-10'
|
||||||
} flex-shrink-0 cursor-pointer rounded-full
|
} inner-shadow-top-sm flex-shrink-0 cursor-pointer rounded-full
|
||||||
border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-th-fgd-4 ${
|
border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-th-fgd-4 ${
|
||||||
disabled ? 'opacity-60' : ''
|
disabled ? 'opacity-60' : ''
|
||||||
}`}
|
}`}
|
||||||
|
@ -50,8 +50,8 @@ const Switch: FunctionComponent<SwitchProps> = ({
|
||||||
: 'translate-x-0'
|
: 'translate-x-0'
|
||||||
} pointer-events-none inline-block ${
|
} pointer-events-none inline-block ${
|
||||||
small ? 'h-3 w-3' : 'h-4 w-4'
|
small ? 'h-3 w-3' : 'h-4 w-4'
|
||||||
} rounded-full
|
} inner-shadow-bottom-sm
|
||||||
bg-white shadow ring-0 transition duration-200 ease-in-out`}
|
rounded-full bg-white ring-0 transition duration-200 ease-in-out`}
|
||||||
></span>
|
></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import FaqsPage from '@components/faqs/FaqsPage'
|
||||||
|
import type { NextPage } from 'next'
|
||||||
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
|
|
||||||
|
export async function getStaticProps({ locale }: { locale: string }) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
...(await serverSideTranslations(locale, ['common'])),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Faqs: NextPage = () => {
|
||||||
|
return <FaqsPage />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Faqs
|
|
@ -1,3 +1,4 @@
|
||||||
|
import NavTabs from '@components/NavTabs'
|
||||||
import Positions from '@components/Positions'
|
import Positions from '@components/Positions'
|
||||||
import Stake from '@components/Stake'
|
import Stake from '@components/Stake'
|
||||||
import Stats from '@components/Stats'
|
import Stats from '@components/Stats'
|
||||||
|
@ -19,7 +20,7 @@ export async function getStaticProps({ locale }: { locale: string }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Index: NextPage = () => {
|
const Index: NextPage = () => {
|
||||||
const [activeTab, setActiveTab] = useState('Boost')
|
const [activeTab, setActiveTab] = useState('Boost!')
|
||||||
const selectedToken = mangoStore((s) => s.selectedToken)
|
const selectedToken = mangoStore((s) => s.selectedToken)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -41,51 +42,16 @@ const Index: NextPage = () => {
|
||||||
}, [selectedToken])
|
}, [selectedToken])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto max-w-3xl px-6 pb-12 md:pb-20 lg:px-12">
|
<>
|
||||||
<div className="mb-6 grid grid-cols-4 rounded-lg border-2 border-th-fgd-1 bg-white text-lg">
|
<div className="mb-6 grid grid-cols-4">
|
||||||
<button
|
<NavTabs
|
||||||
className={`col-span-1 mx-auto w-full rounded-l-[5px] border-r border-th-fgd-1 pb-2 pt-3 font-display ${
|
activeValue={activeTab}
|
||||||
activeTab === 'Boost'
|
values={['Boost!', 'Positions', 'History', 'Stats']}
|
||||||
? 'text-shadow inner-shadow-top-sm bg-th-primary-2 text-th-active'
|
onChange={setActiveTab}
|
||||||
: 'inner-shadow-bottom-sm default-transition bg-th-bkg-1 text-th-fgd-1 md:hover:bg-th-bkg-2'
|
/>
|
||||||
}`}
|
|
||||||
onClick={() => setActiveTab('Boost')}
|
|
||||||
>
|
|
||||||
Boost!
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`col-span-1 mx-auto w-full border-r border-th-fgd-1 pb-2 pt-3 font-display ${
|
|
||||||
activeTab === 'Positions'
|
|
||||||
? 'text-shadow inner-shadow-top-sm bg-th-primary-2 text-th-active'
|
|
||||||
: 'inner-shadow-bottom-sm default-transition bg-th-bkg-1 text-th-fgd-1 md:hover:bg-th-bkg-2'
|
|
||||||
}`}
|
|
||||||
onClick={() => setActiveTab('Positions')}
|
|
||||||
>
|
|
||||||
Positions
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`col-span-1 mx-auto w-full border-r border-th-fgd-1 pb-2 pt-3 font-display ${
|
|
||||||
activeTab === 'History'
|
|
||||||
? 'text-shadow inner-shadow-top-sm bg-th-primary-2 text-th-active'
|
|
||||||
: 'inner-shadow-bottom-sm default-transition bg-th-bkg-1 text-th-fgd-1 md:hover:bg-th-bkg-2'
|
|
||||||
}`}
|
|
||||||
onClick={() => setActiveTab('History')}
|
|
||||||
>
|
|
||||||
History
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`col-span-1 mx-auto w-full rounded-r-[5px] pb-2 pt-3 font-display ${
|
|
||||||
activeTab === 'Stats'
|
|
||||||
? 'text-shadow inner-shadow-top-sm bg-th-primary-2 text-th-active'
|
|
||||||
: 'inner-shadow-bottom-sm default-transition bg-th-bkg-1 text-th-fgd-1 md:hover:bg-th-bkg-2'
|
|
||||||
}`}
|
|
||||||
onClick={() => setActiveTab('Stats')}
|
|
||||||
>
|
|
||||||
Stats
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<TabContent activeTab={activeTab} setActiveTab={setActiveTab} />
|
<TabContent activeTab={activeTab} setActiveTab={setActiveTab} />
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +65,7 @@ const TabContent = ({
|
||||||
setActiveTab: (tab: string) => void
|
setActiveTab: (tab: string) => void
|
||||||
}) => {
|
}) => {
|
||||||
switch (activeTab) {
|
switch (activeTab) {
|
||||||
case 'Boost':
|
case 'Boost!':
|
||||||
return <Stake />
|
return <Stake />
|
||||||
case 'Positions':
|
case 'Positions':
|
||||||
return <Positions setActiveTab={setActiveTab} />
|
return <Positions setActiveTab={setActiveTab} />
|
||||||
|
|
|
@ -98,6 +98,7 @@ th {
|
||||||
--primary-1: theme('colors.light-theme.primary-1');
|
--primary-1: theme('colors.light-theme.primary-1');
|
||||||
--primary-2: theme('colors.light-theme.primary-2');
|
--primary-2: theme('colors.light-theme.primary-2');
|
||||||
--primary-3: theme('colors.light-theme.primary-3');
|
--primary-3: theme('colors.light-theme.primary-3');
|
||||||
|
--primary-4: theme('colors.light-theme.primary-4');
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme='Dark'] {
|
[data-theme='Dark'] {
|
||||||
|
@ -124,6 +125,7 @@ th {
|
||||||
--primary-1: theme('colors.dark-theme.primary-1');
|
--primary-1: theme('colors.dark-theme.primary-1');
|
||||||
--primary-2: theme('colors.dark-theme.primary-2');
|
--primary-2: theme('colors.dark-theme.primary-2');
|
||||||
--primary-3: theme('colors.dark-theme.primary-3');
|
--primary-3: theme('colors.dark-theme.primary-3');
|
||||||
|
--primary-4: theme('colors.dark-theme.primary-4');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base */
|
/* Base */
|
||||||
|
@ -158,7 +160,7 @@ h1,
|
||||||
h2,
|
h2,
|
||||||
h3,
|
h3,
|
||||||
h4 {
|
h4 {
|
||||||
@apply font-bold text-th-fgd-1;
|
@apply font-display text-th-fgd-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
@ -290,7 +292,7 @@ table p {
|
||||||
}
|
}
|
||||||
|
|
||||||
#range-slider-gradient .range-slider__thumb[data-upper] {
|
#range-slider-gradient .range-slider__thumb[data-upper] {
|
||||||
@apply h-7 w-4 rounded-full border border-th-primary-3 bg-th-primary-1 shadow-[inset_0_-3px_0px_rgba(0,0,0,0.15)];
|
@apply border-th-primary-3 bg-th-primary-1 h-7 w-4 rounded-full border shadow-[inset_0_-3px_0px_rgba(0,0,0,0.15)];
|
||||||
}
|
}
|
||||||
|
|
||||||
#range-slider-gradient .range-slider__range {
|
#range-slider-gradient .range-slider__range {
|
||||||
|
@ -382,7 +384,7 @@ table p {
|
||||||
}
|
}
|
||||||
|
|
||||||
.raised-button-primary {
|
.raised-button-primary {
|
||||||
@apply relative bg-th-primary-1 transition-none;
|
@apply bg-th-primary-1 relative transition-none;
|
||||||
box-shadow: 0 4px var(--primary-3);
|
box-shadow: 0 4px var(--primary-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ module.exports = {
|
||||||
'primary-1': '#99ADD9',
|
'primary-1': '#99ADD9',
|
||||||
'primary-2': '#889FD3',
|
'primary-2': '#889FD3',
|
||||||
'primary-3': '#728DC8',
|
'primary-3': '#728DC8',
|
||||||
|
'primary-4': '#627DB8',
|
||||||
},
|
},
|
||||||
'dark-theme': {
|
'dark-theme': {
|
||||||
active: {
|
active: {
|
||||||
|
@ -74,6 +75,7 @@ module.exports = {
|
||||||
'primary-1': '#99ADD9',
|
'primary-1': '#99ADD9',
|
||||||
'primary-2': '#889FD3',
|
'primary-2': '#889FD3',
|
||||||
'primary-3': '#728DC8',
|
'primary-3': '#728DC8',
|
||||||
|
'primary-4': '#627DB8',
|
||||||
},
|
},
|
||||||
'th-bkg-1': 'var(--bkg-1)',
|
'th-bkg-1': 'var(--bkg-1)',
|
||||||
'th-bkg-2': 'var(--bkg-2)',
|
'th-bkg-2': 'var(--bkg-2)',
|
||||||
|
@ -98,6 +100,7 @@ module.exports = {
|
||||||
'th-primary-1': 'var(--primary-1)',
|
'th-primary-1': 'var(--primary-1)',
|
||||||
'th-primary-2': 'var(--primary-2)',
|
'th-primary-2': 'var(--primary-2)',
|
||||||
'th-primary-3': 'var(--primary-3)',
|
'th-primary-3': 'var(--primary-3)',
|
||||||
|
'th-primary-4': 'var(--primary-4)',
|
||||||
},
|
},
|
||||||
cursor: {
|
cursor: {
|
||||||
help: 'help',
|
help: 'help',
|
||||||
|
|
|
@ -4051,12 +4051,7 @@ copy-to-clipboard@^3.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
toggle-selection "^1.0.6"
|
toggle-selection "^1.0.6"
|
||||||
|
|
||||||
core-js@^3:
|
core-js@^3, core-js@^3.22.4:
|
||||||
version "3.29.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.29.0.tgz#0273e142b67761058bcde5615c503c7406b572d6"
|
|
||||||
integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==
|
|
||||||
|
|
||||||
core-js@^3.22.4:
|
|
||||||
version "3.32.2"
|
version "3.32.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.2.tgz#172fb5949ef468f93b4be7841af6ab1f21992db7"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.32.2.tgz#172fb5949ef468f93b4be7841af6ab1f21992db7"
|
||||||
integrity sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==
|
integrity sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==
|
||||||
|
|
Loading…
Reference in New Issue