Skip to content

Commit

Permalink
setup contentful for token pages
Browse files Browse the repository at this point in the history
  • Loading branch information
saml33 committed Nov 29, 2023
1 parent 9872908 commit 0122122
Show file tree
Hide file tree
Showing 23 changed files with 497 additions and 88 deletions.
Empty file.
29 changes: 29 additions & 0 deletions app/(pages)/explore/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { fetchTokenPages } from '../../../contentful/tokenPage'
import Explore from '../../components/explore/Explore'
import SectionWrapper from '../../components/shared/SectionWrapper'
// import { fetchMarketData } from '../../utils/mango'
import { draftMode } from 'next/headers'

async function ExplorePage() {
// const marketData = await fetchMarketData()
const tokens = await fetchTokenPages({
preview: draftMode().isEnabled,
})

return (
<SectionWrapper>
<h1 className="text-5xl mb-10">Explore</h1>
<ul>
{tokens && tokens?.length ? (
<Explore tokens={tokens} />
) : (
<div className="p-6 rounded-xl border border-th-bkg-3">
<p className="text-center">Nothing to see here...</p>
</div>
)}
</ul>
</SectionWrapper>
)
}

export default ExplorePage
4 changes: 2 additions & 2 deletions app/(pages)/learn/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Metadata } from 'next'
import { draftMode } from 'next/headers'
import { notFound } from 'next/navigation'
import Link from 'next/link'
import { fetchBlogPost, fetchBlogPosts } from '../../../contentful/blogPost'
import RichText from '../../../contentful/RichText'
import { fetchBlogPost, fetchBlogPosts } from '../../../../contentful/blogPost'
import RichText from '../../../../contentful/RichText'

interface BlogPostPageParams {
slug: string
Expand Down
2 changes: 1 addition & 1 deletion app/(pages)/learn/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { draftMode } from 'next/headers'
import Link from 'next/link'
import { fetchBlogPosts } from '../../contentful/blogPost'
import SectionWrapper from '../../components/shared/SectionWrapper'
import { fetchBlogPosts } from '../../../contentful/blogPost'

async function BlogPage() {
// Fetch blog posts using the content preview
Expand Down
43 changes: 43 additions & 0 deletions app/components/explore/Explore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use client'

import { TokenPageWithData } from '../../../contentful/tokenPage'
import { Table, Td, Th, TrBody, TrHead } from '../shared/TableElements'

const Explore = ({ tokens }: { tokens: TokenPageWithData[] }) => {
return (
<Table>
<thead>
<TrHead>
<Th className="text-left">Token</Th>
<Th className="text-left">Price</Th>
<Th className="text-left">Change</Th>
</TrHead>
</thead>
<tbody>
{tokens.map((token) => {
const { tokenName, slug, symbol, birdeyeData } = token
const price = birdeyeData?.price || '–'
const change24Hour = birdeyeData?.priceChange24hPercent
? `${birdeyeData.priceChange24hPercent.toFixed(2)}%`
: '–'
return (
<TrBody key={slug}>
<Td>
<p>{tokenName}</p>
<p>{symbol}</p>
</Td>
<Td>
<p>{price}</p>
</Td>
<Td>
<p>{change24Hour}</p>
</Td>
</TrBody>
)
})}
</tbody>
</Table>
)
}

export default Explore
73 changes: 20 additions & 53 deletions app/components/home/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ import IconWithText from '../shared/IconWithText'
import SectionWrapper from '../shared/SectionWrapper'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
import { useLayoutEffect, useMemo, useRef } from 'react'
import { MotionPathPlugin } from 'gsap/dist/MotionPathPlugin'
import ColorBlur from '../shared/ColorBlur'
import Ottersec from '../icons/Ottersec'
import TabsText from '../shared/TabsText'
import MarketCard from './MarketCard'
// import TabsText from '../shared/TabsText'
// import MarketCard from './MarketCard'
import { formatNumericValue, numberCompacter } from '../../utils'
import HeroStat from './HeroStat'
import useMarketsData from '../../hooks/useMarketData'
import { useQuery } from '@tanstack/react-query'
import { MANGO_DATA_API_URL } from '../../utils/constants'
import Loading from '../shared/Loading'
// import Loading from '../shared/Loading'

gsap.registerPlugin(MotionPathPlugin)
gsap.registerPlugin(ScrollTrigger)
Expand Down Expand Up @@ -60,7 +60,7 @@ const fetchAppData = async () => {
}

const HomePage = () => {
const [activeMarketTab, setActiveMarketTab] = useState('Spot')
// const [activeMarketTab, setActiveMarketTab] = useState('Spot')
const { data: marketData, isLoading: loadingMarketData } = useMarketsData()

const { data: appData, isLoading: loadingAppData } = useQuery({
Expand All @@ -74,49 +74,15 @@ const HomePage = () => {
const coreFeatures = useRef<HTMLDivElement>(null)
const build = useRef<HTMLDivElement>(null)

const tabsWithCount: [string, number][] = useMemo(() => {
const perpMarketsNumber =
(marketData?.perpData && Object.keys(marketData?.perpData)?.length) || 0
const spotMarketsNumber =
(marketData?.spotData && Object.keys(marketData?.spotData)?.length) || 0
const tabs: [string, number][] = [
['Spot', spotMarketsNumber],
['Perp', perpMarketsNumber],
]
return tabs
}, [marketData])

const formattedSpotData = useMemo(() => {
if (!marketData?.spotData || !Object.keys(marketData?.spotData)?.length)
return []
const data = Object.entries(marketData.spotData)
.sort((a, b) => {
const aVolume = a[1][0]?.quote_volume_24h || 0
const bVolume = b[1][0]?.quote_volume_24h || 0
return bVolume - aVolume
})
.map(([key, value]) => {
const data = value[0]
return { name: key, data }
})
return data
}, [marketData])

const formattedPerpData = useMemo(() => {
if (!marketData?.perpData || !Object.keys(marketData?.perpData)?.length)
return []
const data = Object.entries(marketData.perpData)
.sort((a, b) => {
const aVolume = a[1][0]?.quote_volume_24h || 0
const bVolume = b[1][0]?.quote_volume_24h || 0
return bVolume - aVolume
})
.map(([key, value]) => {
const data = value[0]
return { name: key, data }
})
return data
}, [marketData])
// const tabsWithCount: [string, number][] = useMemo(() => {
// const perpMarketsNumber = marketData?.perp?.length || 0
// const spotMarketsNumber = marketData?.spot?.length || 0
// const tabs: [string, number][] = [
// ['Spot', spotMarketsNumber],
// ['Perp', perpMarketsNumber],
// ]
// return tabs
// }, [marketData])

const formattedAppStatsData = useMemo(() => {
if (!appData || !Object.keys(appData).length)
Expand Down Expand Up @@ -258,6 +224,9 @@ const HomePage = () => {
return () => ctx.revert() // <- Cleanup!
}, [])

const numberOfMarkets =
(marketData?.spot.length || 0) + (marketData?.perp.length || 0)

return (
<>
<SectionWrapper className="overflow-hidden h-[760px] lg:h-auto">
Expand Down Expand Up @@ -302,9 +271,7 @@ const HomePage = () => {
<div className="grid grid-cols-4 gap-6">
<HeroStat
title="Markets"
value={(
formattedSpotData.length + formattedPerpData.length
).toString()}
value={numberOfMarkets.toString()}
loading={loadingMarketData}
/>
<HeroStat
Expand Down Expand Up @@ -385,7 +352,7 @@ const HomePage = () => {
/>
</div>
</SectionWrapper>
<SectionWrapper className="border-t border-th-bkg-3">
{/* <SectionWrapper className="border-t border-th-bkg-3">
<div className="w-full h-full">
<h2 className="mb-4 text-center">Markets</h2>
<p className="mb-10 intro-p text-center max-w-lg mx-auto">
Expand Down Expand Up @@ -418,7 +385,7 @@ const HomePage = () => {
)}
</div>
</div>
</SectionWrapper>
</SectionWrapper> */}
<div className="bg-[url('/images/new/stage-slice.png')] bg-repeat-x bg-contain">
<SectionWrapper className="relative overflow-hidden">
<ColorBlur
Expand Down
31 changes: 19 additions & 12 deletions app/components/navigation/DesktopNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,10 @@ import Link from 'next/link'
import { usePathname } from 'next/navigation'

const DesktopNavigation = () => {
const pathname = usePathname()
return (
<div className="hidden lg:flex lg:items-center space-x-8">
<Link href="/learn" shallow>
<span
className={`font-display ${
pathname === '/blog'
? 'text-th-active md:hover:text-th-active'
: 'text-th-fgd-2 md:hover:text-th-fgd-1'
} default-transition text-base`}
>
Learn
</span>
</Link>
<NavigationLink path="/explore" text="Explore" />
<NavigationLink path="/learn" text="Learn" />
<NavigationItem title="Developers">
<NavigationItemPanel>
<NavigationItemLink
Expand Down Expand Up @@ -187,3 +177,20 @@ const NavigationItem = ({
const NavigationItemPanel = ({ children }: { children: ReactNode }) => {
return <div className="bg-th-bkg-2 py-4 rounded-lg">{children}</div>
}

const NavigationLink = ({ path, text }: { path: string; text: string }) => {
const pathname = usePathname()
return (
<Link href={path} shallow>
<span
className={`font-display ${
pathname === path
? 'text-th-active md:hover:text-th-active'
: 'text-th-fgd-2 md:hover:text-th-fgd-1'
} default-transition text-base`}
>
{text}
</span>
</Link>
)
}
120 changes: 120 additions & 0 deletions app/components/shared/TableElements.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { MouseEventHandler, ReactNode, forwardRef } from 'react'
import { LinkButton } from './Button'
import { ArrowSmallDownIcon } from '@heroicons/react/20/solid'
import { SortConfig } from '../../hooks/useSortableData'

export const Table = ({
children,
className,
}: {
children: ReactNode
className?: string
}) => <table className={`m-0 min-w-full p-0 ${className}`}>{children}</table>

export const TrHead = ({
children,
className,
}: {
children: ReactNode
className?: string
}) => <tr className={`border-b border-th-bkg-3 ${className}`}>{children}</tr>

export const Th = ({
children,
className,
id,
xBorder = false,
}: {
children?: ReactNode
className?: string
id?: string
xBorder?: boolean
}) => (
<th
className={`whitespace-nowrap px-2 py-3 text-xs font-normal text-th-fgd-3 first:pl-6 last:pr-6 xl:px-4 ${
xBorder ? 'border-x border-th-bkg-3' : ''
} ${className}`}
id={id}
scope="col"
>
{children}
</th>
)

interface TrBodyProps {
children: ReactNode
className?: string
onClick?: () => void
onMouseEnter?: (x: any) => void
onMouseLeave?: MouseEventHandler
}

export const TrBody = forwardRef<HTMLTableRowElement, TrBodyProps>(
(props, ref) => {
const { children, className, onClick, onMouseEnter, onMouseLeave } = props
return (
<tr
className={`border-y border-th-bkg-3 ${className}`}
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
ref={ref}
>
{children}
</tr>
)
},
)

TrBody.displayName = 'TrBody'

export const Td = ({
children,
className,
xBorder = false,
}: {
children: ReactNode
className?: string
xBorder?: boolean
}) => (
<td
className={`px-2 py-3 first:pl-6 last:pr-6 xl:px-4 ${
xBorder ? 'border-x border-th-bkg-3' : ''
} ${className}`}
>
{children}
</td>
)

export const SortableColumnHeader = ({
sort,
sortConfig,
sortKey,
title,
titleClass,
}: {
sort: (key: string) => void
sortConfig: SortConfig | null
sortKey: string
title: string
titleClass?: string
}) => {
return (
<LinkButton
className="flex items-center font-normal"
onClick={() => sort(sortKey)}
>
<span className={`text-th-fgd-3 ${titleClass}`}>{title}</span>
<ArrowSmallDownIcon
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
sortConfig?.key === sortKey
? sortConfig?.direction === 'ascending'
? 'rotate-180'
: 'rotate-360'
: null
}`}
/>
</LinkButton>
)
}
Loading

0 comments on commit 0122122

Please sign in to comment.