Skip to content

Commit b7eb308

Browse files
committed
clean up
1 parent cadd2a1 commit b7eb308

File tree

7 files changed

+276
-248
lines changed

7 files changed

+276
-248
lines changed

app/coins/[id]/page.tsx

Lines changed: 12 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,19 @@ import {
22
getCoinDetails,
33
getCoinOHLC,
44
fetchPools,
5-
getTopGainersLosers,
65
} from '@/lib/coingecko.actions';
7-
import { formatPrice, timeAgo } from '@/lib/utils';
8-
import Link from 'next/link';
9-
import CoinDetailCard from '@/components/CoinDetailCard';
10-
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
11-
import {
12-
Table,
13-
TableBody,
14-
TableCell,
15-
TableHead,
16-
TableHeader,
17-
TableRow,
18-
} from '@/components/ui/table';
196
import { Converter } from '@/components/Converter';
207
import LiveDataWrapper from '@/components/LiveDataWrapper';
21-
import CoinCard from '@/components/CoinCard';
8+
import { ExchangeListings } from '@/components/ExchangeListings';
9+
import { CoinDetailsSection } from '@/components/CoinDetailsSection';
10+
import { TopGainersLosers } from '@/components/TopGainersLosers';
2211

2312
const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
2413
const { id } = await params;
2514
const coinData = await getCoinDetails(id);
26-
const topGainersLosers = await getTopGainersLosers();
2715
const pool = await fetchPools(id);
2816
const coinOHLCData = await getCoinOHLC(id, 1, 'usd', 'hourly', 'full');
2917

30-
const coinDetails = [
31-
{
32-
label: 'Market Cap',
33-
value: formatPrice(coinData.market_data.market_cap.usd),
34-
},
35-
{
36-
label: 'Market Cap Rank',
37-
value: `# ${coinData.market_cap_rank}`,
38-
},
39-
{
40-
label: 'Total Volume',
41-
value: formatPrice(coinData.market_data.total_volume.usd),
42-
},
43-
{
44-
label: 'Website',
45-
value: '-',
46-
link: coinData.links.homepage[0],
47-
linkText: 'Website',
48-
},
49-
{
50-
label: 'Explorer',
51-
value: '-',
52-
link: coinData.links.blockchain_site[0],
53-
linkText: 'Explorer',
54-
},
55-
{
56-
label: 'Community Link',
57-
value: '-',
58-
link: coinData.links.subreddit_url,
59-
linkText: 'Community',
60-
},
61-
];
62-
6318
return (
6419
<main className='coin-details-main'>
6520
<section className='size-full xl:col-span-2'>
@@ -69,147 +24,24 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
6924
coin={coinData}
7025
coinOHLCData={coinOHLCData}
7126
>
72-
{/* Exchange Listings - pass it as a child of a client component
73-
// so it will be render server side */}
74-
<div className='w-full mt-8 space-y-4'>
75-
<h4 className='section-title'>Exchange Listings</h4>
76-
<div className='custom-scrollbar mt-5 exchange-container'>
77-
<Table>
78-
<TableHeader className='text-purple-100'>
79-
<TableRow className='hover:bg-transparent'>
80-
<TableHead className='exchange-header-left'>
81-
Exchange
82-
</TableHead>
83-
<TableHead className='text-purple-100'>Pair</TableHead>
84-
<TableHead className='text-purple-100'>Price</TableHead>
85-
<TableHead className='exchange-header-right'>
86-
Last Traded
87-
</TableHead>
88-
</TableRow>
89-
</TableHeader>
90-
<TableBody>
91-
{coinData.tickers
92-
.slice(0, 7)
93-
.map((ticker: Ticker, index: number) => (
94-
<TableRow
95-
key={index}
96-
className='overflow-hidden rounded-lg hover:!bg-dark-400/30'
97-
>
98-
<TableCell className=' text-green-500 font-bold'>
99-
<Link
100-
href={ticker.trade_url}
101-
target='_blank'
102-
className='exchange-link'
103-
>
104-
{ticker.market.name}
105-
</Link>
106-
</TableCell>
107-
<TableCell>
108-
<div className='exchange-pair'>
109-
<p className='truncate max-w-[100px] h-full'>
110-
{ticker.base}
111-
</p>
112-
/
113-
<p className='truncate max-w-[100px] h-full ml-2'>
114-
{ticker.target}
115-
</p>
116-
</div>
117-
</TableCell>
118-
<TableCell className='font-medium'>
119-
{formatPrice(ticker.converted_last.usd)}
120-
</TableCell>
121-
<TableCell className='exchange-timestamp'>
122-
{timeAgo(ticker.timestamp)}
123-
</TableCell>
124-
</TableRow>
125-
))}
126-
</TableBody>
127-
</Table>
128-
</div>
129-
</div>
27+
{/* Exchange Listings - pass it as a child of a client componentso it will be render server side */}
28+
<ExchangeListings coinData={coinData} />
13029
</LiveDataWrapper>
13130
</section>
13231

13332
<section className='size-full max-lg:mt-8 lg:col-span-1'>
13433
{/* Converter */}
135-
<div className='w-full space-y-5'>
136-
<h4 className='converter-title'>
137-
{coinData.symbol.toUpperCase()} Converter
138-
</h4>
139-
<Converter
140-
symbol={coinData.symbol}
141-
icon={coinData.image.small}
142-
priceList={coinData.market_data.current_price}
143-
/>
144-
</div>
34+
<Converter
35+
symbol={coinData.symbol}
36+
icon={coinData.image.small}
37+
priceList={coinData.market_data.current_price}
38+
/>
14539

14640
{/* Coin Details */}
147-
<div className='w-full mt-8 space-y-4'>
148-
<h4 className='section-title pb-3'>Coin Details</h4>
149-
<div className='coin-details-grid'>
150-
{coinDetails.map((detail, index) => (
151-
<CoinDetailCard
152-
key={index}
153-
label={detail.label}
154-
value={detail.value}
155-
link={detail.link}
156-
linkText={detail.linkText}
157-
/>
158-
))}
159-
</div>
160-
</div>
41+
<CoinDetailsSection coinData={coinData} />
16142

16243
{/* Top Gainers / Losers */}
163-
<Tabs defaultValue='top-gainers' className='mt-8 w-full'>
164-
<TabsList className='size-full p-1 bg-transparent border-b border-dark-500 rounded-none '>
165-
<TabsTrigger
166-
value='top-gainers'
167-
className='data-[state=active]:!border-none data-[state=active]:!bg-transparent flex justify-start !mb-0 py-2 text-lg font-semibold md:text-2xl'
168-
>
169-
Top Gainers
170-
</TabsTrigger>
171-
<TabsTrigger
172-
value='top-losers'
173-
className='data-[state=active]:!border-none data-[state=active]:!bg-transparent flex justify-start !mb-0 py-2 text-lg font-semibold md:text-2xl'
174-
>
175-
Top Losers
176-
</TabsTrigger>
177-
</TabsList>
178-
<TabsContent value='top-gainers' className='top-list'>
179-
{topGainersLosers.top_gainers.map(
180-
(coin: TopGainersLosersResponse) => (
181-
<CoinCard
182-
key={coin.id}
183-
id={coin.id}
184-
name={coin.name}
185-
symbol={coin.symbol}
186-
image={coin.image}
187-
price={coin.usd}
188-
priceChangePercentage24h={coin.usd_24h_change}
189-
volume24={coin.usd_24h_vol}
190-
rank={coin.market_cap_rank}
191-
/>
192-
)
193-
)}
194-
</TabsContent>
195-
<TabsContent value='top-losers' className='top-list'>
196-
{topGainersLosers.top_losers.map(
197-
(coin: TopGainersLosersResponse) => (
198-
<CoinCard
199-
key={coin.id}
200-
id={coin.id}
201-
name={coin.name}
202-
symbol={coin.symbol}
203-
image={coin.image}
204-
price={coin.usd}
205-
priceChangePercentage24h={coin.usd_24h_change}
206-
volume24={coin.usd_24h_vol}
207-
rank={coin.market_cap_rank}
208-
/>
209-
)
210-
)}
211-
</TabsContent>
212-
</Tabs>
44+
<TopGainersLosers />
21345
</section>
21446
</main>
21547
);

app/globals.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@
221221
@apply w-full flex flex-col justify-center h-full py-4 bg-dark-500 rounded-xl;
222222
}
223223

224+
.categories-container {
225+
@apply pt-8 mt-5 w-full bg-dark-500 rounded-xl overflow-hidden;
226+
}
227+
224228
.main-container {
225229
@apply py-6 md:py-12 mx-auto px-4 sm:px-6 max-w-[1440px] w-full space-y-6 md:space-y-6;
226230
}
@@ -525,7 +529,7 @@
525529

526530
/* ChartSection Component Utilities */
527531
.chart-section-container {
528-
@apply w-full h-full xl:col-span-2 px-2 py-3 bg-dark-500 rounded-xl;
532+
@apply w-full h-full xl:col-span-2 px-2 bg-dark-500 rounded-xl;
529533
}
530534

531535
.chart-section-header {
@@ -547,6 +551,10 @@
547551
.chart-section-price {
548552
@apply text-xl md:text-2xl font-semibold;
549553
}
554+
555+
.skeleton {
556+
@apply bg-dark-400/60;
557+
}
550558
}
551559

552560
/* Custom Scrollbar Styles */

app/page.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ const CoinOverviewFallback = () => (
4242
<div className='chart-section-container'>
4343
<div className='w-full h-full min-h-[420px] rounded-2xl bg-dark-500/60 p-6'>
4444
<div className='flex items-center gap-4 mb-6'>
45-
<Skeleton className='h-14 w-14 rounded-full bg-dark-400/60' />
45+
<Skeleton className='h-14 w-14 rounded-full skeleton' />
4646
<div className='flex flex-col gap-2 flex-1'>
47-
<Skeleton className='h-4 w-1/3 bg-dark-400/60' />
48-
<Skeleton className='h-8 w-1/2 bg-dark-400/60' />
47+
<Skeleton className='h-4 w-1/3 skeleton' />
48+
<Skeleton className='h-8 w-1/2 skeleton' />
4949
</div>
5050
</div>
51-
<Skeleton className='h-[280px] w-full rounded-xl bg-dark-400/60' />
51+
<Skeleton className='h-[280px] w-full rounded-xl skeleton' />
5252
</div>
5353
</div>
5454
);
@@ -72,15 +72,15 @@ const TrendingCoinsFallback = () => (
7272
<TableRow key={index} className='table-row-hover'>
7373
<TableCell className='font-bold'>
7474
<div className='flex items-center gap-3'>
75-
<Skeleton className='h-9 w-9 rounded-full bg-dark-400/60' />
76-
<Skeleton className='h-4 w-24 bg-dark-400/60' />
75+
<Skeleton className='h-9 w-9 rounded-full skeleton' />
76+
<Skeleton className='h-4 w-24 skeleton' />
7777
</div>
7878
</TableCell>
7979
<TableCell className='table-cell-change'>
80-
<Skeleton className='h-4 w-16 bg-dark-400/60' />
80+
<Skeleton className='h-4 w-16 skeleton' />
8181
</TableCell>
8282
<TableCell className='table-cell-price'>
83-
<Skeleton className='h-4 w-20 bg-dark-400/60' />
83+
<Skeleton className='h-4 w-20 skeleton' />
8484
</TableCell>
8585
</TableRow>
8686
))}
@@ -91,7 +91,7 @@ const TrendingCoinsFallback = () => (
9191
);
9292

9393
const CategoriesFallback = () => (
94-
<div className='custom-scrollbar pt-8 mt-5 w-full bg-dark-500 rounded-xl overflow-hidden'>
94+
<div className='custom-scrollbar categories-container'>
9595
<h4 className='section-title pl-5'>Top Categories</h4>
9696
<Table>
9797
<TableHeader className='text-purple-100'>
@@ -110,24 +110,24 @@ const CategoriesFallback = () => (
110110
className='md:text-base rounded-lg hover:!bg-dark-400/30'
111111
>
112112
<TableCell className='pl-5 font-bold'>
113-
<Skeleton className='h-4 w-32 bg-dark-400/60' />
113+
<Skeleton className='h-4 w-32 skeleton' />
114114
</TableCell>
115115
<TableCell className='flex gap-1 mr-5'>
116116
{Array.from({ length: 3 }).map((__, coinIndex) => (
117117
<Skeleton
118118
key={coinIndex}
119-
className='h-7 w-7 rounded-full bg-dark-400/60'
119+
className='h-7 w-7 rounded-full skeleton'
120120
/>
121121
))}
122122
</TableCell>
123123
<TableCell className='font-medium'>
124-
<Skeleton className='h-4 w-16 bg-dark-400/60' />
124+
<Skeleton className='h-4 w-16 skeleton' />
125125
</TableCell>
126126
<TableCell className='font-medium'>
127-
<Skeleton className='h-4 w-20 bg-dark-400/60' />
127+
<Skeleton className='h-4 w-20 skeleton' />
128128
</TableCell>
129129
<TableCell className='font-medium'>
130-
<Skeleton className='h-4 w-24 bg-dark-400/60' />
130+
<Skeleton className='h-4 w-24 skeleton' />
131131
</TableCell>
132132
</TableRow>
133133
))}

components/CoinDetailsSection.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import CoinDetailCard from './CoinDetailCard';
2+
import { formatPrice } from '@/lib/utils';
3+
4+
export const CoinDetailsSection = ({
5+
coinData,
6+
}: {
7+
coinData: CoinDetailsData;
8+
}) => {
9+
const coinDetails = [
10+
{
11+
label: 'Market Cap',
12+
value: formatPrice(coinData.market_data.market_cap.usd),
13+
},
14+
{
15+
label: 'Market Cap Rank',
16+
value: `# ${coinData.market_cap_rank}`,
17+
},
18+
{
19+
label: 'Total Volume',
20+
value: formatPrice(coinData.market_data.total_volume.usd),
21+
},
22+
{
23+
label: 'Website',
24+
value: '-',
25+
link: coinData.links.homepage[0],
26+
linkText: 'Website',
27+
},
28+
{
29+
label: 'Explorer',
30+
value: '-',
31+
link: coinData.links.blockchain_site[0],
32+
linkText: 'Explorer',
33+
},
34+
{
35+
label: 'Community Link',
36+
value: '-',
37+
link: coinData.links.subreddit_url,
38+
linkText: 'Community',
39+
},
40+
];
41+
42+
return (
43+
<div className='w-full mt-8 space-y-4'>
44+
<h4 className='section-title pb-3'>Coin Details</h4>
45+
<div className='coin-details-grid'>
46+
{coinDetails.map((detail, index) => (
47+
<CoinDetailCard
48+
key={index}
49+
label={detail.label}
50+
value={detail.value}
51+
link={detail.link}
52+
linkText={detail.linkText}
53+
/>
54+
))}
55+
</div>
56+
</div>
57+
);
58+
};

0 commit comments

Comments
 (0)