11import { Suspense } from 'react' ;
22
3- import {
4- getCategories ,
5- getCoinDetails ,
6- getCoinOHLC ,
7- getTrendingCoins ,
8- } from '@/lib/coingecko.actions' ;
9- import { cn , formatPercentage , formatPrice } from '@/lib/utils' ;
10- import Image from 'next/image' ;
11- import Link from 'next/link' ;
123import {
134 Table ,
145 TableBody ,
@@ -18,9 +9,10 @@ import {
189 TableRow ,
1910} from '@/components/ui/table' ;
2011
21- import { TrendingDown , TrendingUp } from 'lucide-react' ;
2212import { Skeleton } from '@/components/ui/skeleton' ;
23- import CandlestickChart from '@/components/CandlestickChart' ;
13+ import { CoinOverviewSection } from '@/components/CoinOverviewSection' ;
14+ import { CategoriesSection } from '@/components/CategoriesSection' ;
15+ import { TrendingCoinsSection } from '@/components/TrendingCoinsSection' ;
2416
2517const Home = ( ) => {
2618 return (
@@ -30,8 +22,8 @@ const Home = () => {
3022 < CoinOverviewSection />
3123 </ Suspense >
3224
33- < Suspense fallback = { < TopMoversFallback /> } >
34- < TopMoversSection />
25+ < Suspense fallback = { < TrendingCoinsFallback /> } >
26+ < TrendingCoinsSection />
3527 </ Suspense >
3628 </ section >
3729
@@ -46,180 +38,6 @@ const Home = () => {
4638
4739export default Home ;
4840
49- const CoinOverviewSection = async ( ) => {
50- const [ coinData , coinOHLCData ] = await Promise . all ( [
51- getCoinDetails ( 'bitcoin' ) ,
52- getCoinOHLC ( 'bitcoin' , 1 , 'usd' , 'hourly' , 'full' ) ,
53- ] ) ;
54-
55- return (
56- < div className = 'chart-section-container' >
57- < CandlestickChart data = { coinOHLCData } coinId = 'bitcoin' >
58- < div className = 'chart-section-header' >
59- < Image
60- src = { coinData . image . large }
61- alt = { coinData . name }
62- width = { 56 }
63- height = { 56 }
64- className = 'chart-section-image'
65- />
66- < div className = 'chart-section-info' >
67- < p className = 'chart-section-coin-name' >
68- { coinData . name } / { coinData . symbol . toUpperCase ( ) }
69- </ p >
70- < h1 className = 'chart-section-price' >
71- { formatPrice ( coinData . market_data . current_price . usd ) }
72- </ h1 >
73- </ div >
74- </ div >
75- </ CandlestickChart >
76- </ div >
77- ) ;
78- } ;
79-
80- const TopMoversSection = async ( ) => {
81- const trendingCoins = ( await getTrendingCoins ( ) ) as TrendingCoin [ ] ;
82-
83- return (
84- < div className = 'top-movers-container' >
85- < h4 className = 'section-title px-5' > Trending Coins</ h4 >
86- < div className = 'table-scrollbar-container custom-scrollbar' >
87- < Table >
88- < TableHeader className = 'table-header-cell' >
89- < TableRow className = 'hover:bg-transparent' >
90- < TableHead className = 'table-head-left' > Name</ TableHead >
91- < TableHead className = 'table-header-cell table-cell' >
92- 24h Change
93- </ TableHead >
94- < TableHead className = 'table-head-right' > Price</ TableHead >
95- </ TableRow >
96- </ TableHeader >
97- < TableBody >
98- { trendingCoins . slice ( 0 , 6 ) . map ( ( coin : TrendingCoin , index ) => {
99- const item = coin . item ;
100- const isTrendingUp =
101- item . data . price_change_percentage_24h . usd > 0 ;
102-
103- return (
104- < TableRow key = { index } className = 'table-row-hover' >
105- < TableCell className = 'font-bold' >
106- < Link href = { `/coins/${ item . id } ` } className = 'coin-link' >
107- < Image
108- src = { item . large }
109- alt = { item . name }
110- width = { 36 }
111- height = { 36 }
112- className = 'coin-image'
113- />
114- < div >
115- < p className = 'text-sm md:text-base' > { item . name } </ p >
116- </ div >
117- </ Link >
118- </ TableCell >
119- < TableCell className = 'table-cell-change' >
120- < div
121- className = { cn (
122- 'price-change-indicator' ,
123- isTrendingUp ? 'text-green-500' : 'text-red-500'
124- ) }
125- >
126- < p >
127- { formatPercentage (
128- item . data . price_change_percentage_24h . usd
129- ) }
130- </ p >
131- { isTrendingUp ? (
132- < TrendingUp width = { 16 } height = { 16 } />
133- ) : (
134- < TrendingDown width = { 16 } height = { 16 } />
135- ) }
136- </ div >
137- </ TableCell >
138- < TableCell className = 'table-cell-price' >
139- { formatPrice ( item . data . price ) }
140- </ TableCell >
141- </ TableRow >
142- ) ;
143- } ) }
144- </ TableBody >
145- </ Table >
146- </ div >
147- </ div >
148- ) ;
149- } ;
150-
151- const CategoriesSection = async ( ) => {
152- const categories = ( await getCategories ( ) ) as Category [ ] ;
153-
154- return (
155- < div className = 'custom-scrollbar pt-8 mt-5 w-full bg-dark-500 rounded-xl overflow-hidden' >
156- < h4 className = 'section-title pl-5' > Top Categories</ h4 >
157- < Table >
158- < TableHeader className = 'text-purple-100' >
159- < TableRow className = 'hover:bg-transparent' >
160- < TableHead className = 'exchange-header-left' > Category</ TableHead >
161- < TableHead className = 'text-purple-100' > Top Gainers</ TableHead >
162- < TableHead className = 'text-purple-100 pl-7' > 24h Change</ TableHead >
163- < TableHead className = 'text-purple-100' > Market Cap</ TableHead >
164- < TableHead className = 'text-purple-100' > 24h Volume</ TableHead >
165- </ TableRow >
166- </ TableHeader >
167- < TableBody >
168- { categories . map ( ( category : Category , index : number ) => {
169- const isTrendingUp = category . market_cap_change_24h > 0 ;
170- return (
171- < TableRow
172- key = { index }
173- className = 'md:text-base rounded-lg hover:!bg-dark-400/30'
174- >
175- < TableCell className = 'pl-5 font-bold' >
176- { category . name }
177- </ TableCell >
178- < TableCell className = 'flex gap-1 mr-5' >
179- { category . top_3_coins . map ( ( coin : string ) => (
180- < Image
181- key = { coin }
182- src = { coin }
183- alt = 'Coin image'
184- width = { 28 }
185- height = { 28 }
186- className = 'rounded-full py-2'
187- />
188- ) ) }
189- </ TableCell >
190- < TableCell className = 'font-medium' >
191- < div
192- className = { cn (
193- 'flex flex-1 gap-1 items-end pl-5 text-base font-medium' ,
194- {
195- 'text-green-500' : category . market_cap_change_24h > 0 ,
196- 'text-red-500' : category . market_cap_change_24h < 0 ,
197- }
198- ) }
199- >
200- < p > { formatPercentage ( category . market_cap_change_24h ) } </ p >
201- { isTrendingUp ? (
202- < TrendingUp width = { 16 } height = { 16 } />
203- ) : (
204- < TrendingDown width = { 16 } height = { 16 } />
205- ) }
206- </ div >
207- </ TableCell >
208- < TableCell className = 'font-medium' >
209- { formatPrice ( category . market_cap ) }
210- </ TableCell >
211- < TableCell className = 'font-medium' >
212- { formatPrice ( category . volume_24h ) }
213- </ TableCell >
214- </ TableRow >
215- ) ;
216- } ) }
217- </ TableBody >
218- </ Table >
219- </ div >
220- ) ;
221- } ;
222-
22341const ChartSectionFallback = ( ) => (
22442 < div className = 'chart-section-container' >
22543 < div className = 'w-full h-full min-h-[420px] rounded-2xl bg-dark-500/60 p-6' >
@@ -235,9 +53,9 @@ const ChartSectionFallback = () => (
23553 </ div >
23654) ;
23755
238- const TopMoversFallback = ( ) => (
56+ const TrendingCoinsFallback = ( ) => (
23957 < div className = 'top-movers-container' >
240- < h4 className = 'section-title px-5' > Top Movers </ h4 >
58+ < h4 className = 'section-title px-5' > Trending Coins </ h4 >
24159 < div className = 'table-scrollbar-container custom-scrollbar' >
24260 < Table >
24361 < TableHeader className = 'table-header-cell' >
0 commit comments