1- import { Badge } from '@/components/ui/badge' ;
2- import { Separator } from '@/components/ui/separator' ;
3- import { getCoinDetails , getCoinOHLC } from '@/lib/ coingecko.actions' ;
4- import { cn , formatPercentage , formatPrice , timeAgo } from '@/lib/utils' ;
5- import { ArrowUpRight , TrendingDown , TrendingUp } from 'lucide-react ' ;
6-
7- import Image from 'next/image ' ;
1+ import {
2+ getCoinDetails ,
3+ getCoinOHLC ,
4+ fetchPools ,
5+ } from '@/lib/ coingecko.actions ' ;
6+ import { formatPrice , timeAgo } from '@/lib/utils' ;
7+ import { ArrowUpRight } from 'lucide-react ' ;
88import Link from 'next/link' ;
99import {
1010 Table ,
@@ -15,13 +15,15 @@ import {
1515 TableRow ,
1616} from '@/components/ui/table' ;
1717import { Converter } from '@/components/Converter' ;
18- import CandlestickChart from '@/components/CandlestickChart' ;
19- import LiveCoinHeader from '@/components/LiveCoinHeader' ;
18+ import LiveDataWrapper from '@/components/LiveDataWrapper' ;
2019
2120const CoinDetails = async ( { params } : { params : Promise < { id : string } > } ) => {
2221 const { id } = await params ;
2322 const coinData = await getCoinDetails ( id ) ;
2423 const coinOHLCData = await getCoinOHLC ( id , 30 , 'usd' , 'hourly' , 'full' ) ;
24+ const pool = await fetchPools ( id ) ;
25+
26+ console . log ( 'coinOHLCData' , coinOHLCData ) ;
2527
2628 const coin = {
2729 id : coinData . id ,
@@ -46,200 +48,15 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
4648 tickers : coinData . tickers ,
4749 } ;
4850
49- const isTrendingUp = coin . priceChangePercentage24h > 0 ;
50-
5151 return (
5252 < main className = 'py-12 container size-full grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 items-center gap-6 xl:gap-10 justify-center' >
5353 < section className = 'size-full xl:col-span-2' >
54- { /* Coin Details */ }
55- < div className = 'space-y-5 w-full' >
56- < h3 className = 'text-3xl font-medium' > { coin . name } </ h3 >
57- < div className = 'flex gap-3 items-center' >
58- < Image
59- src = { coin . image }
60- alt = { coin . name }
61- width = { 77 }
62- height = { 77 }
63- className = 'size-[45px] sm:size-[50px] xl:size-[77px]'
64- />
65- < div className = 'flex gap-4' >
66- < h1 className = 'text-3xl sm:text-5xl xl:text-6xl font-semibold' >
67- { formatPrice ( coin . price ) }
68- </ h1 >
69- < Badge
70- className = { cn (
71- 'font-medium mt-2 h-fit py-1 flex items-center gap-1' ,
72- isTrendingUp
73- ? 'bg-green-500/20 text-green-600'
74- : 'bg-red-500/20 text-red-500'
75- ) }
76- >
77- { formatPercentage ( coin . priceChangePercentage24h ) }
78- { isTrendingUp ? < TrendingUp /> : < TrendingDown /> }
79- (24h)
80- </ Badge >
81- </ div >
82- </ div >
83- < div className = 'grid grid-cols-3 mt-8 gap-4 sm:gap-6 w-fit' >
84- { /* Today */ }
85- < div className = 'text-base border-r border-purple-600 flex flex-col gap-2' >
86- < p className = 'text-purple-100 max-sm:text-sm' > Today</ p >
87- < div
88- className = { cn (
89- 'flex flex-1 gap-1 items-end text-sm font-medium' ,
90- {
91- 'text-green-500' : coin . priceChangePercentage24h > 0 ,
92- 'text-red-500' : coin . priceChangePercentage24h < 0 ,
93- }
94- ) }
95- >
96- < p > { formatPercentage ( coin . priceChangePercentage24h ) } </ p >
97- { isTrendingUp ? (
98- < TrendingUp width = { 16 } height = { 16 } />
99- ) : (
100- < TrendingDown width = { 16 } height = { 16 } />
101- ) }
102- </ div >
103- </ div >
104- { /* 30 Days */ }
105- < div className = 'text-base border-r border-purple-600 flex flex-col gap-2' >
106- < p className = 'text-purple-100 max-sm:text-sm' > 30 Days</ p >
107- < div
108- className = { cn (
109- 'flex gap-1 flex-1 items-end text-sm font-medium' ,
110- {
111- 'text-green-500' : coin . priceChangePercentage30d > 0 ,
112- 'text-red-500' : coin . priceChangePercentage30d < 0 ,
113- }
114- ) }
115- >
116- < p > { formatPercentage ( coin . priceChangePercentage30d ) } </ p >
117- { isTrendingUp ? (
118- < TrendingUp width = { 16 } height = { 16 } />
119- ) : (
120- < TrendingDown width = { 16 } height = { 16 } />
121- ) }
122- </ div >
123- </ div >
124- { /* Rank */ }
125- < div className = 'text-base flex flex-col gap-2' >
126- < p className = 'text-purple-100 max-sm:text-sm' >
127- Price Change (24h)
128- </ p >
129- < p
130- className = { cn ( 'flex gap-1 items-center text-sm font-medium' , {
131- 'text-green-500' : coin . priceChange24h > 0 ,
132- 'text-red-500' : coin . priceChange24h < 0 ,
133- } ) }
134- >
135- { formatPrice ( coin . priceChange24h ) }
136- </ p >
137- </ div >
138- </ div >
139- </ div >
140-
141- < Separator className = 'my-8 bg-purple-600' />
142-
143- { /* Trend Overview */ }
144- < div className = 'w-full' >
145- < h4 className = 'text-2xl mb-4' > Trend Overview</ h4 >
146- < CandlestickChart data = { coinOHLCData } coinId = { id } />
147- </ div >
148-
149- < Separator className = 'my-8 bg-purple-600' />
150-
151- { /* Coin Details */ }
152- < div className = 'w-full grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2 xl:grid-cols-3 gap-3 sm:gap-5' >
153- < div className = 'text-base bg-dark-500 p-4 rounded-lg flex flex-col gap-1' >
154- < p className = 'text-purple-100' > Market Cap</ p >
155- < p className = 'text-base font-medium' >
156- { formatPrice ( coin . marketCap ) }
157- </ p >
158- </ div >
159- < div className = 'text-base bg-dark-500 p-4 rounded-lg flex flex-col gap-1' >
160- < p className = 'text-purple-100 ' > Total Volume</ p >
161- < p className = 'text-base font-medium' >
162- { formatPrice ( coin . totalVolume ) }
163- </ p >
164- </ div >
165- < div className = 'text-base bg-dark-500 p-4 rounded-lg flex flex-col gap-1' >
166- < p className = 'text-purple-100 ' > Market Cap Rank</ p >
167- < p className = 'text-base font-bold' > { coin . marketCapRank } </ p >
168- </ div >
169-
170- < div className = 'text-base bg-dark-500 p-4 rounded-lg flex flex-col gap-1' >
171- < p className = 'text-purple-100 ' > Website</ p >
172- { coin . website ? (
173- < div className = 'flex items-center text-green-500 gap-1' >
174- < Link href = { coin . website } target = '_blank' >
175- Website
176- </ Link >
177- < ArrowUpRight size = { 16 } />
178- </ div >
179- ) : (
180- '-'
181- ) }
182- </ div >
183- < div className = 'text-base bg-dark-500 p-4 rounded-lg flex flex-col gap-1' >
184- < p className = 'text-purple-100 ' > Explorer</ p >
185- { coin . explorer ? (
186- < div className = 'flex items-center text-green-500 gap-1' >
187- < Link href = { coin . explorer } target = '_blank' >
188- Explorer
189- </ Link >
190- < ArrowUpRight size = { 16 } />
191- </ div >
192- ) : (
193- '-'
194- ) }
195- </ div >
196- < div className = 'text-base bg-dark-500 p-4 rounded-lg flex flex-col gap-1' >
197- < p className = 'text-purple-100 ' > Community Link</ p >
198- { coin . communityLink ? (
199- < div className = 'flex items-center text-green-500 gap-1' >
200- < Link href = { coin . communityLink } target = '_blank' >
201- Community
202- </ Link >
203- < ArrowUpRight size = { 16 } />
204- </ div >
205- ) : (
206- '-'
207- ) }
208- </ div >
209- </ div >
210-
211- { /* Order Book */ }
212- { /* <div className='w-full mt-8 space-y-4'>
213- <h4 className='text-2xl'>Order Book</h4>
214- <Table className='bg-dark-500 rounded-xl'>
215- <TableHeader className='text-purple-100'>
216- <TableRow className='hover:bg-transparent'>
217- <TableHead className='pl-5 py-5 text-purple-100'>
218- Price (BTC)
219- </TableHead>
220- <TableHead className='text-purple-100'>Amount (BTC)</TableHead>
221- <TableHead className='pr-8 text-purple-100'>
222- Amount (ETH)
223- </TableHead>
224- </TableRow>
225- </TableHeader>
226- <TableBody>
227- {orderBook.map((order, index) => (
228- <TableRow key={index}>
229- <TableCell className='pl-5 py-4 font-medium'>
230- {order.price}
231- </TableCell>
232- <TableCell className='pl-5 font-medium'>
233- {order.amountBTC}
234- </TableCell>
235- <TableCell className='pr-5 font-medium'>
236- {order.amountETH}
237- </TableCell>
238- </TableRow>
239- ))}
240- </TableBody>
241- </Table>
242- </div> */ }
54+ < LiveDataWrapper
55+ coinOHLCData = { coinOHLCData }
56+ coinId = { id }
57+ pool = { pool }
58+ coin = { coin }
59+ />
24360 </ section >
24461
24562 < section className = 'size-full max-lg:mt-8 lg:col-span-1' >
@@ -255,6 +72,68 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
25572 />
25673 </ div >
25774
75+ { /* Coin Details */ }
76+ < div className = 'w-full mt-8 space-y-4' >
77+ < h4 className = 'text-2xl' > Coin Details</ h4 >
78+ < div className = 'rounded-lg grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2 gap-3 sm:gap-5' >
79+ < div className = 'text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3' >
80+ < p className = 'text-purple-100' > Market Cap</ p >
81+ < p className = 'text-base font-medium' >
82+ { formatPrice ( coin . marketCap ) }
83+ </ p >
84+ </ div >
85+ < div className = 'text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3' >
86+ < p className = 'text-purple-100 ' > Market Cap Rank</ p >
87+ < p className = 'text-base font-bold' > # { coin . marketCapRank } </ p >
88+ </ div >
89+ < div className = 'text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3' >
90+ < p className = 'text-purple-100 ' > Total Volume</ p >
91+ < p className = 'text-base font-medium' >
92+ { formatPrice ( coin . totalVolume ) }
93+ </ p >
94+ </ div >
95+ < div className = 'text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3' >
96+ < p className = 'text-purple-100 ' > Website</ p >
97+ { coin . website ? (
98+ < div className = 'flex items-center text-green-500 gap-1' >
99+ < Link href = { coin . website } target = '_blank' >
100+ Website
101+ </ Link >
102+ < ArrowUpRight size = { 16 } />
103+ </ div >
104+ ) : (
105+ '-'
106+ ) }
107+ </ div >
108+ < div className = 'text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3' >
109+ < p className = 'text-purple-100 ' > Explorer</ p >
110+ { coin . explorer ? (
111+ < div className = 'flex items-center text-green-500 gap-1' >
112+ < Link href = { coin . explorer } target = '_blank' >
113+ Explorer
114+ </ Link >
115+ < ArrowUpRight size = { 16 } />
116+ </ div >
117+ ) : (
118+ '-'
119+ ) }
120+ </ div >
121+ < div className = 'text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3' >
122+ < p className = 'text-purple-100 ' > Community Link</ p >
123+ { coin . communityLink ? (
124+ < div className = 'flex items-center text-green-500 gap-1' >
125+ < Link href = { coin . communityLink } target = '_blank' >
126+ Community
127+ </ Link >
128+ < ArrowUpRight size = { 16 } />
129+ </ div >
130+ ) : (
131+ '-'
132+ ) }
133+ </ div >
134+ </ div >
135+ </ div >
136+
258137 { /* Recent Trades */ }
259138 < div className = 'w-full mt-8 space-y-4' >
260139 < h4 className = 'text-2xl' > Exchange Listings</ h4 >
@@ -304,39 +183,6 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
304183 </ Table >
305184 </ div >
306185 </ div >
307-
308- { /* Recent Trades */ }
309- { /* <div className='w-full mt-8 space-y-4'>
310- <h4 className='text-2xl'>Recent Trades</h4>
311- <Table className='bg-dark-500 rounded-xl'>
312- <TableHeader className='text-purple-100'>
313- <TableRow className='hover:bg-transparent'>
314- <TableHead className='pl-5 py-5 text-purple-100'>
315- Time
316- </TableHead>
317- <TableHead className='text-purple-100'>Price (BTC)</TableHead>
318- <TableHead className='pr-8 text-purple-100'>
319- Amount (ETH)
320- </TableHead>
321- </TableRow>
322- </TableHeader>
323- <TableBody>
324- {orderBook.map((order, index) => (
325- <TableRow key={index}>
326- <TableCell className='pl-5 py-4 font-medium'>
327- {order.price}
328- </TableCell>
329- <TableCell className='pl-5 font-medium'>
330- {order.amountBTC}
331- </TableCell>
332- <TableCell className='pr-5 font-medium'>
333- {order.amountETH}
334- </TableCell>
335- </TableRow>
336- ))}
337- </TableBody>
338- </Table>
339- </div> */ }
340186 </ section >
341187 </ main >
342188 ) ;
0 commit comments