Skip to content

Commit b77f4ee

Browse files
committed
refactor: coin details page and datatable
1 parent dc5fa21 commit b77f4ee

File tree

7 files changed

+120
-63
lines changed

7 files changed

+120
-63
lines changed

app/coins/[id]/page.tsx

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import Link from 'next/link';
2+
import { ArrowUpRight } from 'lucide-react';
3+
14
import {
25
getCoinDetails,
36
getCoinOHLC,
@@ -9,8 +12,6 @@ import LiveDataWrapper from '@/components/LiveDataWrapper';
912
import { TopGainersLosers } from '@/components/coin-details/TopGainersLosers';
1013
import { DataTable } from '@/components/DataTable';
1114
import { formatPrice, timeAgo } from '@/lib/utils';
12-
import Link from 'next/link';
13-
import { ArrowUpRight } from 'lucide-react';
1415

1516
const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
1617
const { id } = await params;
@@ -58,72 +59,83 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
5859
const exchangeColumns = [
5960
{
6061
header: 'Exchange',
61-
cellClassName: 'text-green-500 font-bold',
62+
cellClassName: 'exchange-name',
6263
cell: (ticker: Ticker) => (
63-
<Link href={ticker.trade_url} target='_blank' className='exchange-link'>
64+
<>
6465
{ticker.market.name}
65-
</Link>
66+
67+
<Link
68+
href={ticker.trade_url}
69+
target='_blank'
70+
aria-label='View coin'
71+
/>
72+
</>
6673
),
6774
},
6875
{
6976
header: 'Pair',
7077
cell: (ticker: Ticker) => (
71-
<div className='exchange-pair'>
72-
<p className='truncate max-w-[100px] h-full'>{ticker.base}</p>/
73-
<p className='truncate max-w-[100px] h-full ml-2'>{ticker.target}</p>
78+
<div className='pair'>
79+
<p>{ticker.base}</p>
80+
<p>{ticker.target}</p>
7481
</div>
7582
),
7683
},
7784
{
7885
header: 'Price',
79-
cellClassName: 'font-medium',
86+
cellClassName: 'price-cell',
8087
cell: (ticker: Ticker) => formatPrice(ticker.converted_last.usd),
8188
},
8289
{
8390
header: 'Last Traded',
8491
headClassName: 'text-end',
85-
cellClassName: 'exchange-timestamp',
92+
cellClassName: 'time-cell',
8693
cell: (ticker: Ticker) => timeAgo(ticker.timestamp),
8794
},
8895
];
8996

9097
return (
91-
<main className='coin-details-main'>
92-
<section className='size-full xl:col-span-2'>
98+
<main id='coin-details-page'>
99+
<section className='primary'>
93100
<LiveDataWrapper
94101
coinId={id}
95102
poolId={pool.id}
96103
coin={coinData}
97104
coinOHLCData={coinOHLCData}
98105
>
99-
<div className='w-full mt-8 space-y-4'>
100-
<h4 className='section-title'>Exchange Listings</h4>
101-
<div className='custom-scrollbar mt-5 exchange-container'>
102-
<DataTable
103-
columns={exchangeColumns}
104-
data={coinData.tickers.slice(0, 7)}
105-
rowKey={(_, index) => index}
106-
/>
107-
</div>
106+
<div className='exchange-section'>
107+
<h4>Exchange Listings</h4>
108+
109+
<DataTable
110+
tableClassName='exchange-table'
111+
columns={exchangeColumns}
112+
data={coinData.tickers.slice(0, 7)}
113+
rowKey={(_, index) => index}
114+
headerCellClassName='py-4! bg-dark-400 text-purple-100'
115+
bodyCellClassName='py-2!'
116+
bodyRowClassName='relative'
117+
/>
108118
</div>
109119
</LiveDataWrapper>
110120
</section>
111121

112-
<section className='size-full max-lg:mt-8 lg:col-span-1'>
122+
<section className='secondary'>
113123
<Converter
114124
symbol={coinData.symbol}
115125
icon={coinData.image.small}
116126
priceList={coinData.market_data.current_price}
117127
/>
118128

119-
<div className='w-full mt-8 space-y-4'>
120-
<h4 className='section-title pb-3'>Coin Details</h4>
121-
<div className='coin-details-grid'>
129+
<div className='details'>
130+
<h4>Coin Details</h4>
131+
132+
<ul className='details-grid'>
122133
{coinDetails.map(({ label, value, link, linkText }, index) => (
123-
<div key={index} className='detail-card'>
124-
<p className='text-purple-100'>{label}</p>
134+
<li key={index}>
135+
<p className='label'>{label}</p>
136+
125137
{link ? (
126-
<div className='detail-link'>
138+
<div className='link'>
127139
<Link href={link} target='_blank'>
128140
{linkText || label}
129141
</Link>
@@ -132,9 +144,9 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
132144
) : (
133145
<p className='text-base font-medium'>{value}</p>
134146
)}
135-
</div>
147+
</li>
136148
))}
137-
</div>
149+
</ul>
138150
</div>
139151

140152
<TopGainersLosers />

app/coins/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ const Coins = async ({
9191
data={coinsData}
9292
rowKey={(coin) => coin.id}
9393
headerCellClassName='py-4! bg-dark-400 text-purple-100'
94-
bodyCellClassName='py-4! '
94+
bodyCellClassName='py-4!'
95+
bodyRowClassName='relative'
9596
/>
9697

9798
<CoinsPagination

app/globals.css

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -420,48 +420,88 @@
420420
}
421421

422422
.table-cell-price {
423-
@apply font-bold pr-5 text-sm max-w-[100%] truncate;
423+
@apply font-bold pr-5 text-sm max-w-full truncate;
424424
}
425425

426426
/* Coin Details Page Utilities */
427-
.coin-details-main {
427+
#coin-details-page {
428428
@apply py-12 px-4 sm:px-6 mx-auto max-w-[1440px] size-full grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 items-center gap-6 xl:gap-10 justify-center;
429-
}
430429

431-
.exchange-container {
432-
@apply bg-dark-500 rounded-xl overflow-hidden;
433-
}
430+
.primary {
431+
@apply size-full xl:col-span-2;
432+
}
434433

435-
.exchange-header-left {
436-
@apply pl-5 py-5 text-purple-100;
437-
}
434+
.secondary {
435+
@apply size-full max-lg:mt-8 lg:col-span-1;
436+
}
438437

439-
.exchange-header-right {
440-
@apply pr-5 text-purple-100 text-end;
441-
}
438+
.exchange-section {
439+
@apply w-full mt-8 space-y-4;
442440

443-
.exchange-link {
444-
@apply py-4 pl-3 block w-full max-w-[230px] truncate whitespace-pre-wrap;
445-
}
441+
h4 {
442+
@apply text-xl md:text-2xl font-semibold mb-2;
443+
}
444+
}
446445

447-
.exchange-pair {
448-
@apply font-medium h-full flex py-4 pr-5;
449-
}
446+
.exchange-table {
447+
@apply bg-dark-500 rounded-xl overflow-hidden mt-5;
450448

451-
.exchange-timestamp {
452-
@apply pr-5 text-end;
453-
}
449+
.exchange-name {
450+
@apply text-green-500 font-bold;
454451

455-
.coin-details-grid {
456-
@apply rounded-lg grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2 gap-3 sm:gap-5;
452+
a {
453+
@apply absolute inset-0 z-10;
454+
}
455+
}
456+
457+
.pair {
458+
@apply font-medium h-full flex py-4 pr-5 space-x-2;
459+
460+
p {
461+
@apply truncate max-w-[100px] h-full;
462+
}
463+
}
464+
465+
.price-cell {
466+
@apply font-medium;
467+
}
468+
469+
.time-cell {
470+
@apply pr-5 text-end;
471+
}
472+
}
473+
474+
.details {
475+
@apply w-full mt-8 space-y-4;
476+
477+
h4 {
478+
@apply text-xl md:text-2xl font-semibold mb-2 pb-3;
479+
}
480+
481+
.details-grid {
482+
@apply rounded-lg grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2 gap-3 sm:gap-5;
483+
484+
li {
485+
@apply text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3;
486+
487+
.label {
488+
@apply text-purple-100;
489+
}
490+
491+
.link {
492+
@apply flex items-center text-green-500 gap-1;
493+
}
494+
}
495+
}
496+
}
457497
}
458498

459-
.detail-card {
460-
@apply text-base bg-dark-500 px-5 py-6 rounded-lg flex flex-col gap-3;
499+
.exchange-header-left {
500+
@apply pl-5 py-5 text-purple-100;
461501
}
462502

463-
.detail-link {
464-
@apply flex items-center text-green-500 gap-1;
503+
.exchange-header-right {
504+
@apply pr-5 text-purple-100 text-end;
465505
}
466506

467507
.coin-description {

components/DataTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const DataTable = <T,>({
4343
<TableRow
4444
key={rowKey(row, rowIndex)}
4545
className={cn(
46-
'overflow-hidden rounded-lg hover:bg-dark-400/30!',
46+
'overflow-hidden rounded-lg border-b border-purple-100/5 hover:bg-dark-400/30!',
4747
bodyRowClassName
4848
)}
4949
>

components/LiveDataWrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ export default function LiveDataWrapper({
9393
columns={tradeColumns}
9494
data={trades ?? []}
9595
rowKey={(_, index) => index}
96-
headerCellClassName='py-5! text-purple-100!'
97-
bodyCellClassName='py-5!'
96+
headerCellClassName='py-4! bg-dark-400 text-purple-100'
97+
bodyCellClassName='py-4!'
9898
/>
9999
</div>
100100

components/home/Categories.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ export const Categories = async () => {
6666
<div id='categories' className='custom-scrollbar'>
6767
<h4>Top Categories</h4>
6868
<DataTable
69+
tableClassName='mt-3'
6970
columns={columns}
7071
data={categories}
7172
rowKey={(_, index) => index}
73+
headerCellClassName='py-3! bg-dark-400 text-purple-100'
74+
bodyCellClassName='py-2!'
7275
/>
7376
</div>
7477
);

components/home/TrendingCoins.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ export const TrendingCoins = async () => {
6262
<h4>Trending Coins</h4>
6363

6464
<DataTable
65-
tableClassName='trending-coins-table'
65+
tableClassName='trending-coins-table mt-3'
6666
columns={columns}
6767
data={trendingCoins.slice(0, 6)}
6868
rowKey={(_, index) => index}
69-
bodyRowClassName='body-row'
69+
headerCellClassName='py-3! bg-dark-400 text-purple-100'
70+
bodyCellClassName='py-2!'
7071
/>
7172
</div>
7273
);

0 commit comments

Comments
 (0)