Skip to content

Commit

Permalink
more token page
Browse files Browse the repository at this point in the history
  • Loading branch information
saml33 committed Dec 1, 2023
1 parent 0be2262 commit 1af4975
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 62 deletions.
22 changes: 22 additions & 0 deletions app/(pages)/explore/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ArrowLeftIcon } from '@heroicons/react/20/solid'
import Link from 'next/link'

export default function TokenPageLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<Link
className="text-th-fgd-4 flex items-center space-x-1"
href="/explore"
shallow
>
<ArrowLeftIcon className="h-5 w-5" />
<span>View all tokens</span>
</Link>
<div className="mt-8">{children}</div>
</>
)
}
69 changes: 51 additions & 18 deletions app/(pages)/explore/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@ import {
fetchTokenPages,
} from '../../../../contentful/tokenPage'
import { makeApiRequest } from '../../../utils/birdeye'
import { DAILY_SECONDS } from '../../../utils/constants'
import TokenPriceChart from '../../../components/explore/TokenPriceChart'
import TokenMarketStats from '../../../components/explore/TokenMarketStats'
import { CUSTOM_TOKEN_ICONS, DAILY_SECONDS } from '../../../utils/constants'
import TokenPriceChart from '../../../components/explore/token-page/TokenPriceChart'
import TokenMarketStats from '../../../components/explore/token-page/TokenMarketStats'
import TokenAbout from '../../../components/explore/token-page/TokenAbout'
import { fetchMangoTokensData } from '../../../utils/mango'
import { MangoTokenData } from '../../../types/mango'
import Image from 'next/image'
import TokenMangoStats from '../../../components/explore/token-page/TokenMangoStats'
import ButtonLink from '../../../components/shared/ButtonLink'

const SECTION_WRAPPER_CLASSES = 'border-t border-th-bkg-3 pt-6 mt-20'

interface TokenPageParams {
slug: string
Expand Down Expand Up @@ -56,10 +64,17 @@ async function TokenPage({ params }: TokenPageProps) {
return notFound()
}

const { birdeyeData, description, mint, symbol, tokenName } = tokenPageData

const mangoTokensData = await fetchMangoTokensData()
const mangoTokenData: MangoTokenData | undefined = mangoTokensData.find(
(mangoToken) => mangoToken?.mint === mint,
)

// get price history for token price chart
const queryEnd = Math.floor(Date.now() / 1000)
const queryStart = queryEnd - 30 * DAILY_SECONDS
const birdeyeQuery = `defi/history_price?address=${tokenPageData.mint}&address_type=token&type=30m&time_from=${queryStart}&time_to=${queryEnd}`
const birdeyeQuery = `defi/history_price?address=${mint}&address_type=token&type=30m&time_from=${queryStart}&time_to=${queryEnd}`
const birdeyePricesResponse = await makeApiRequest(birdeyeQuery)
const birdeyePrices = birdeyePricesResponse?.data?.items?.length
? birdeyePricesResponse.data.items
Expand All @@ -68,25 +83,43 @@ async function TokenPage({ params }: TokenPageProps) {
data.unixTime = data.unixTime * 1000
}

// const hasCustomIcon = CUSTOM_TOKEN_ICONS[tokenPageData.symbol.toLowerCase()]
// const logoPath = hasCustomIcon
// ? `/icons/tokens/${mangoSymbol.toLowerCase()}.svg`
// : birdeyeData?.logoURI
const hasCustomIcon = Object.keys(CUSTOM_TOKEN_ICONS).find(
(icon) => icon === mangoTokenData?.symbol.toLowerCase(),
)
const logoPath = hasCustomIcon
? `/icons/tokens/${mangoTokenData?.symbol.toLowerCase()}.svg`
: birdeyeData?.logoURI

return (
<div>
<div className="mb-4 pb-4 border-b border-th-bkg-3 flex items-center">
<h1 className="text-4xl">
{tokenPageData.tokenName}{' '}
<span className="text-xl font-body font-normal text-th-fgd-4">
{tokenPageData.symbol}
</span>
</h1>
<div className="mb-6 pb-6 border-b border-th-bkg-3 flex items-center justify-between">
<div className="flex items-center space-x-2.5">
<Image src={logoPath} alt="Logo" height={40} width={40} />
<h1 className="text-4xl">
{tokenName}{' '}
<span className="text-xl font-body font-normal text-th-fgd-4">
{symbol}
</span>
</h1>
</div>
<div className="flex space-x-3">
<ButtonLink path="#" linkText="Swap" secondary />
<ButtonLink path="#" linkText="Trade" secondary />
</div>
</div>
<TokenPriceChart chartData={birdeyePrices} />
<h2 className="mb-4 text-2xl">Mango stats</h2>
<TokenMarketStats tokenData={tokenPageData} />
<h2 className="mb-4 text-2xl">{`About ${tokenPageData.tokenName}`}</h2>
<div className={SECTION_WRAPPER_CLASSES}>
<h2 className="mb-4 text-2xl">Mango stats</h2>
<TokenMangoStats mangoData={mangoTokenData} />
</div>
<div className={SECTION_WRAPPER_CLASSES}>
<h2 className="mb-4 text-2xl">Market stats</h2>
<TokenMarketStats tokenData={tokenPageData} />
</div>
<div className={SECTION_WRAPPER_CLASSES}>
<h2 className="mb-4 text-2xl">{`About ${tokenName}`}</h2>
<TokenAbout content={description} />
</div>
</div>
)
}
Expand Down
4 changes: 3 additions & 1 deletion app/(pages)/explore/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ export default function PageLayout({
}: {
children: React.ReactNode
}) {
return <div className="px-20 py-12">{children}</div>
return (
<div className="px-20 pb-12 pt-8 max-w-[1280px] mx-auto">{children}</div>
)
}
4 changes: 2 additions & 2 deletions app/(pages)/explore/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { fetchTokenPages } from '../../../contentful/tokenPage'
import Explore from '../../components/explore/Explore'
import { draftMode } from 'next/headers'
import { fetchMangoTokenData } from '../../utils/mango'
import { fetchMangoTokensData } from '../../utils/mango'

async function ExplorePage() {
const tokens = await fetchTokenPages({
preview: draftMode().isEnabled,
})
const mangoTokensData = await fetchMangoTokenData()
const mangoTokensData = await fetchMangoTokensData()
return (
<>
<h1 className="text-5xl mb-10">Explore</h1>
Expand Down
34 changes: 0 additions & 34 deletions app/components/explore/TokenMarketStats.tsx

This file was deleted.

31 changes: 31 additions & 0 deletions app/components/explore/token-page/KeyValuePairDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ReactNode } from 'react'
import Tooltip from '../../shared/Tooltip'

const KeyValuePairDisplay = ({
label,
value,
tooltipContent,
}: {
label: string
value: number | string | ReactNode
tooltipContent?: string
}) => {
return (
<div>
<div className="w-max">
<Tooltip content={tooltipContent}>
<p
className={`mb-1 leading-tight ${
tooltipContent ? 'tooltip-underline' : ''
}`}
>
{label}
</p>
</Tooltip>
</div>
<span className="text-3xl font-display text-th-fgd-1">{value}</span>
</div>
)
}

export default KeyValuePairDisplay
12 changes: 12 additions & 0 deletions app/components/explore/token-page/TokenAbout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Document as RichTextDocument } from '@contentful/rich-text-types'
import RichText from '../../../../contentful/RichText'

const TokenAbout = ({ content }: { content: RichTextDocument | null }) => {
return (
<div className="max-w-4xl">
<RichText document={content} />
</div>
)
}

export default TokenAbout
34 changes: 34 additions & 0 deletions app/components/explore/token-page/TokenMangoStats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client'

import { MangoTokenData } from '../../../types/mango'
import { numberCompacter } from '../../../utils/numbers'
import KeyValuePairDisplay from './KeyValuePairDisplay'

const TokenMangoStats = ({
mangoData,
}: {
mangoData: MangoTokenData | undefined
}) => {
if (!mangoData) return null
return (
<div className="grid grid-cols-3 grid-flow-row gap-6">
<KeyValuePairDisplay
label="Deposit rate"
value={<span className="text-th-up">5.42%</span>}
/>
<KeyValuePairDisplay
label="Borrow rate"
value={<span className="text-th-down">7.33%</span>}
/>
<KeyValuePairDisplay
label="Available"
value={numberCompacter.format(234956688)}
/>
<KeyValuePairDisplay label="Asset weight" value="0.00x" />
<KeyValuePairDisplay label="Liability weight" value="1.80x" />
<KeyValuePairDisplay label="Max leverage" value="5x" />
</div>
)
}

export default TokenMangoStats
31 changes: 31 additions & 0 deletions app/components/explore/token-page/TokenMarketStats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

import { TokenPageWithData } from '../../../../contentful/tokenPage'
import { numberCompacter } from '../../../utils/numbers'
import KeyValuePairDisplay from './KeyValuePairDisplay'

const TokenMarketStats = ({ tokenData }: { tokenData: TokenPageWithData }) => {
if (!tokenData?.birdeyeData) return null
const { birdeyeData } = tokenData
return (
<div className="grid grid-cols-3 grid-flow-row gap-6">
<KeyValuePairDisplay
label="FDMC"
value={
birdeyeData?.mc ? `$${numberCompacter.format(birdeyeData.mc)}` : '–'
}
tooltipContent="Fully diluted market cap"
/>
<KeyValuePairDisplay
label="Supply"
value={
birdeyeData?.supply
? `$${numberCompacter.format(birdeyeData.supply)}`
: '–'
}
/>
</div>
)
}

export default TokenMarketStats
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client'

import { useState } from 'react'
import { BirdeyePriceHistoryData } from '../../types/birdeye'
import { formatYAxis } from '../../utils/numbers'
import DetailedAreaOrBarChart from '../shared/DetailedAreaOrBarChart'
import { BirdeyePriceHistoryData } from '../../../types/birdeye'
import { formatYAxis } from '../../../utils/numbers'
import DetailedAreaOrBarChart from '../../shared/DetailedAreaOrBarChart'

const TokenPriceChart = ({
chartData,
Expand Down
6 changes: 5 additions & 1 deletion app/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ p {
}

a {
@apply tracking-wider text-base lg:text-lg default-transition;
@apply tracking-wider text-th-active md:hover:text-th-fgd-1 text-base xl:text-lg default-transition;
}

.font-mono {
Expand All @@ -210,6 +210,10 @@ table p {
@apply text-th-fgd-1;
}

.tooltip-underline {
@apply default-transition w-max border-b border-dashed border-current hover:cursor-help hover:border-transparent;
}

/* Scrollbars */

.hide-scroll::-webkit-scrollbar {
Expand Down
2 changes: 1 addition & 1 deletion app/utils/mango.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FormattedMarketData, MarketData } from '../types/mango'
import { MANGO_DATA_API_URL } from './constants'

export const fetchMangoTokenData = async () => {
export const fetchMangoTokensData = async () => {
try {
const response = await fetch(
`${MANGO_DATA_API_URL}/stats/token-price-history`,
Expand Down
25 changes: 24 additions & 1 deletion contentful/RichText.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BLOCKS, MARKS } from '@contentful/rich-text-types'
import { Document as RichTextDocument } from '@contentful/rich-text-types'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'

Expand All @@ -10,7 +11,29 @@ function RichText({ document }: RichTextProps) {
return null
}

return <>{documentToReactComponents(document)}</>
return <>{documentToReactComponents(document, options)}</>
}

export default RichText

const Bold = ({ children }) => <p className="font-bold">{children}</p>

const Text = ({ children }) => <p className="mb-2">{children}</p>

const H3 = ({ children }) => <h3 className="mb-2 text-lg">{children}</h3>

const Spacer = () => (
<hr style={{ borderColor: 'transparent', marginBottom: '12px' }} />
)

const options = {
renderMark: {
[MARKS.BOLD]: (text) => <Bold>{text}</Bold>,
},
renderNode: {
[BLOCKS.PARAGRAPH]: (node, children) => <Text>{children}</Text>,
[BLOCKS.HEADING_3]: (node, children) => <H3>{children}</H3>,
[BLOCKS.HR]: () => <Spacer />,
},
// renderText: (text) => text.replace('!', '?'),
}
2 changes: 1 addition & 1 deletion tsconfig.tsbuildinfo

Large diffs are not rendered by default.

0 comments on commit 1af4975

Please sign in to comment.