Skip to content
This repository was archived by the owner on Dec 23, 2025. It is now read-only.

Commit 7796f8d

Browse files
committed
feat: add realtime update
1 parent 7924b68 commit 7796f8d

12 files changed

Lines changed: 97 additions & 584 deletions

File tree

.env.development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
NEXT_PUBLIC_APP_URL=http://localhost:3000

.env.production

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
NEXT_PUBLIC_APP_URL=${VERCEL_URL}

src/app/_components/crypto-bubbles.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ if (typeof Highcharts === 'object') {
1111
HC_more(Highcharts)
1212
}
1313

14-
import { Crypto } from '../types'
14+
import { CryptoData } from '../../lib/types'
1515

1616
export type CryptoBubblesProps = {
17-
cryptos: Crypto[]
17+
cryptos: CryptoData[]
1818
className?: string
1919
}
2020

src/app/_components/crypto-table/columns.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
'use client'
22

3-
import { Crypto } from '@/app/types'
3+
import { CryptoData } from '@/lib/types'
44
import { ColumnDef } from '@tanstack/react-table'
55
import Image from 'next/image'
66
import numeral from 'numeral'
77

8-
export const columns: ColumnDef<Crypto>[] = [
8+
export const columns: ColumnDef<CryptoData>[] = [
99
{
1010
header: '',
11-
// accessorFn: (row) => ({ rank: row.rank, image: row.image }),
1211
accessorKey: 'rank',
1312
cell: ({ row }) => (
14-
<div className="flex items-center gap-2">
15-
<div className="min-w-4 text-right">
13+
<div className="flex items-center gap-2 pr-2">
14+
<div className="min-w-6 shrink-0 text-right">
1615
{numeral(row.getValue('rank')).format('0,0')}
1716
</div>
1817
<Image
1918
src={row.original.image}
2019
width={32}
2120
height={32}
2221
alt={row.original.symbol}
22+
className="shrink-0"
2323
/>
2424
</div>
2525
),
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use client'
2+
3+
import { REFRESH_INTERVAL } from '@/lib/constants'
4+
import { CryptoData } from '@/lib/types'
5+
import { getCryptoData } from '@/services/cryptos'
6+
import { FC, useEffect, useState } from 'react'
7+
import { CryptoBubbles } from './crypto-bubbles'
8+
import { CryptoDataTable } from './crypto-table/crypto-table'
9+
import { columns } from './crypto-table/columns'
10+
11+
export type RealtimeCryptoWrapperProps = {
12+
initialCryptos: CryptoData[]
13+
top: number
14+
}
15+
16+
export const RealtimeCryptoWrapper: FC<RealtimeCryptoWrapperProps> = ({
17+
initialCryptos,
18+
top,
19+
}) => {
20+
const [cryptos, setCryptos] = useState<CryptoData[]>(initialCryptos)
21+
22+
useEffect(() => {
23+
const interval = setInterval(async () => {
24+
getCryptoData(top).then(setCryptos)
25+
}, REFRESH_INTERVAL)
26+
27+
return () => clearInterval(interval)
28+
}, [top])
29+
30+
return (
31+
<>
32+
<CryptoBubbles
33+
cryptos={cryptos}
34+
className="h-[calc(100dvh-56px)] bg-slate-900"
35+
/>
36+
<div className="container py-6">
37+
<CryptoDataTable columns={columns} data={cryptos} />
38+
</div>
39+
</>
40+
)
41+
}

src/app/api/cryptos/route.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { CRYPTO_DATA_URL } from '@/lib/constants'
2+
import { CryptoData } from '@/lib/types'
3+
import { getCryptoData } from '@/services/cryptos'
4+
import { orderBy } from 'lodash-es'
5+
6+
export const dynamic = 'force-dynamic'
7+
8+
export async function GET(request: Request) {
9+
const top = parseInt(new URL(request.url).searchParams.get('top') || '100')
10+
11+
const response = await fetch(CRYPTO_DATA_URL)
12+
const data: CryptoData[] = await response.json()
13+
14+
const cryptos = orderBy(data, 'rank', 'asc').slice(
15+
Math.max(0, top - 100),
16+
top,
17+
)
18+
19+
return Response.json(cryptos)
20+
}

0 commit comments

Comments
 (0)