Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

boost token ux #27

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 100 additions & 100 deletions components/HeroTokenButton.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
import Image from 'next/image'
import { formatTokenSymbol } from 'utils/tokens'
import useBankRates from 'hooks/useBankRates'
import useLeverageMax from 'hooks/useLeverageMax'
import mangoStore from '@store/mangoStore'
import SheenLoader from './shared/SheenLoader'
import { SOL_YIELD } from './Stake'
import Tooltip from './shared/Tooltip'
import Link from 'next/link'
import { StakeableToken } from 'hooks/useStakeableTokens'
import {
ArrowTopRightOnSquareIcon,
InformationCircleIcon,
} from '@heroicons/react/20/solid'

export const HERO_TOKEN_BUTTON_CLASSES =
'inner-shadow-bottom default-transition relative w-full rounded-xl border border-th-bkg-3 bg-th-bkg-1 px-6 py-4 text-th-fgd-1 focus:outline-none focus-visible:border-th-fgd-4 md:hover:bg-th-bkg-2 md:hover:focus-visible:border-th-fgd-4'

export const HERO_TOKEN_IMAGE_WRAPPER_CLASSES =
'inner-shadow-bottom-sm mb-2 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 shrink-0'

const HeroTokenButton = ({
onClick,
tokenName,
tokenInfo,
}: {
tokenName: string
tokenInfo: StakeableToken
onClick: () => void
}) => {
const leverage = useLeverageMax(tokenName)
const { symbol, name } = tokenInfo.token ?? {}
const { estNetApy } = tokenInfo ?? {}
const groupLoaded = mangoStore((s) => s.groupLoaded)

const { stakeBankDepositRate, financialMetrics } = useBankRates(
tokenName,
leverage,
)

const { financialMetrics: estimatedNetAPYFor1xLev } = useBankRates(
tokenName,
1,
)

const APY_Daily_Compound =
Math.pow(1 + Number(stakeBankDepositRate) / 365, 365) - 1
const UiRate =
tokenName === 'USDC'
? APY_Daily_Compound * 100
: Math.max(estimatedNetAPYFor1xLev.APY, financialMetrics.APY)

const renderRateEmoji = (token: string, rate: number) => {
if (token.toLowerCase().includes('sol')) {
if (rate >= 20) {
Expand All @@ -53,97 +45,105 @@ const HeroTokenButton = ({
}
}

const emoji = renderRateEmoji(tokenName, UiRate)
const emoji = renderRateEmoji(symbol, estNetApy)

return (
<button
className={`inner-shadow-bottom default-transition relative w-full rounded-xl border border-th-bkg-3 bg-th-bkg-1 p-6 text-th-fgd-1 focus:outline-none focus-visible:border-th-fgd-4 md:hover:bg-th-bkg-2 md:hover:focus-visible:border-th-fgd-4`}
onClick={onClick}
>
<button className={HERO_TOKEN_BUTTON_CLASSES} onClick={onClick}>
<div>
<div className="flex flex-col items-center">
<div
className={`inner-shadow-bottom-sm mb-2 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`}
>
<div className="flex items-center space-x-2.5">
<div className={HERO_TOKEN_IMAGE_WRAPPER_CLASSES}>
<Image
src={`/icons/${tokenName.toLowerCase()}.svg`}
src={`/icons/${symbol.toLowerCase()}.svg`}
width={32}
height={32}
alt="Select a token"
/>
</div>
<div className="flex flex-col items-center">
<p className={`text-th-fgd-1`}>{formatTokenSymbol(tokenName)}</p>
<span className={`text-2xl font-bold`}>
{!groupLoaded ? (
<SheenLoader>
<div className={`h-6 w-10 bg-th-bkg-2`} />
</SheenLoader>
) : !UiRate || isNaN(UiRate) ? (
<span className="text-base font-normal text-th-fgd-4">
Rate Unavailable
<div className="flex w-full justify-between">
<div className="text-left">
<div className="flex items-center">
<span className="mr-1.5 text-xl font-bold">
{formatTokenSymbol(symbol)}
</span>
) : (
`${UiRate.toFixed(2)}%`
)}
</span>
{groupLoaded ? (
<div className="mt-1 flex items-center">
{SOL_YIELD.includes(tokenName) ? (
<>
<Image
className="mr-1.5"
src={`/icons/sol.svg`}
width={16}
height={16}
alt="SOL Logo"
/>
<span className="text-sm text-th-fgd-4">Earn SOL</span>
</>
) : (
<>
<Image
className="mr-1.5"
src={`/icons/usdc.svg`}
width={16}
height={16}
alt="USDC Logo"
/>
<span className="text-sm text-th-fgd-4">Earn USDC</span>
</>
)}
<Tooltip
content={
<>
<p>
{tokenInfo?.token?.description
? tokenInfo.token.description
: name}
</p>
<div className="flex">
{tokenInfo?.token?.links?.website ? (
<a
className="mr-2 mt-2 flex items-center"
href={tokenInfo.token.links.website}
target="_blank"
rel="noopener noreferrer"
>
<span className="mr-0.5">Website</span>
<ArrowTopRightOnSquareIcon className="h-3 w-3" />
</a>
) : null}
{tokenInfo?.token?.links?.twitter ? (
<a
className="mt-2 flex items-center"
href={tokenInfo.token.links.twitter}
target="_blank"
rel="noopener noreferrer"
>
<span className="mr-0.5">Twitter</span>
<ArrowTopRightOnSquareIcon className="h-3 w-3" />
</a>
) : null}
</div>
</>
}
>
<InformationCircleIcon className="mb-0.5 h-4 w-4 cursor-help text-th-bkg-4" />
</Tooltip>
</div>
) : null}
<p className={`text-xs text-th-fgd-4`}>{name}</p>
</div>
<div className="text-right">
<p className={`text-xs text-th-fgd-4`}>Max APY</p>
<div className="flex items-center">
{emoji ? (
<Tooltip
content={
<>
<p className="mb-2">
The max APY is favorable right now. Rates can change
very quickly. Make sure you understand the risks
before boosting.
</p>
<Link href="/risks" shallow>
Risks
</Link>
</>
}
>
<span className="mr-2 text-lg">{emoji}</span>
</Tooltip>
) : null}
<span className={`text-xl font-bold`}>
{!groupLoaded ? (
<SheenLoader>
<div className={`h-6 w-10 bg-th-bkg-2`} />
</SheenLoader>
) : !estNetApy || isNaN(estNetApy) ? (
<span className="text-base font-normal text-th-fgd-4">
Rate Unavailable
</span>
) : (
`${estNetApy.toFixed(2)}%`
)}
</span>
</div>
</div>
</div>
</div>
</div>
{emoji ? (
<div
className="absolute left-0 top-0 h-0 w-0 rounded-tl-xl"
style={{
borderTopWidth: '100px',
borderRightWidth: '100px',
borderTopColor: 'var(--bkg-2)',
borderRightColor: 'transparent',
}}
>
<Tooltip
content={
<>
<p className="mb-2">
The max APY is favorable right now. Rates can change very
quickly. Make sure you understand the risks before boosting.
</p>
<Link href="/risks" shallow>
Risks
</Link>
</>
}
>
<span className="absolute bottom-12 left-4 text-2xl">{emoji}</span>
</Tooltip>
</div>
) : null}
</button>
)
}
Expand Down
2 changes: 1 addition & 1 deletion components/NavTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const NavTabs = <T extends Values>({
<>
{values.map(([value, count], i) => (
<button
className={`mx-auto flex w-full items-center justify-center border-y-2 border-r border-th-fgd-1 py-3.5 font-bold first:rounded-l-lg first:border-l-2 last:rounded-r-lg last:border-r-2 ${
className={`mx-auto flex h-14 w-full items-center justify-center border-y-2 border-r border-th-fgd-1 font-bold first:rounded-l-xl first:border-l-2 last:rounded-r-xl last:border-r-2 ${
activeValue === value
? 'inner-shadow-top-sm bg-th-active text-th-fgd-1'
: 'inner-shadow-bottom-sm default-transition bg-th-bkg-1 text-th-fgd-1 md:hover:bg-th-bkg-2'
Expand Down
Loading
Loading