Skip to content

Commit de21763

Browse files
committed
fix
1 parent 68118ea commit de21763

File tree

8 files changed

+173
-122
lines changed

8 files changed

+173
-122
lines changed

app/coins/[id]/page.tsx

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
2323
const coinOHLCData = await getCoinOHLC(id, 30, 'usd', 'hourly', 'full');
2424
const pool = await fetchPools(id);
2525

26-
console.log('coinOHLCData', coinOHLCData);
26+
console.log('pool Data:', pool);
2727

2828
const coin = {
2929
id: coinData.id,
@@ -40,7 +40,7 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
4040
coinData.market_data.price_change_percentage_30d_in_currency.usd,
4141
marketCap: coinData.market_data.market_cap.usd,
4242
marketCapRank: coinData.market_cap_rank,
43-
description: coinData.description.en, //
43+
description: coinData.description.en,
4444
totalVolume: coinData.market_data.total_volume.usd,
4545
website: coinData.links.homepage[0],
4646
explorer: coinData.links.blockchain_site[0],
@@ -56,12 +56,62 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
5656
coinId={id}
5757
pool={pool}
5858
coin={coin}
59-
/>
59+
>
60+
{/* Exchange Listings */}
61+
<div className='w-full mt-8 space-y-4'>
62+
<h4 className='text-2xl'>Exchange Listings</h4>
63+
<div className='custom-scrollbar bg-dark-500 rounded-xl overflow-hidden'>
64+
<Table>
65+
<TableHeader className='text-purple-100'>
66+
<TableRow className='hover:bg-transparent'>
67+
<TableHead className='pl-5 py-5 text-purple-100'>
68+
Exchange
69+
</TableHead>
70+
<TableHead className='text-purple-100'>Pair</TableHead>
71+
<TableHead className='text-purple-100'>Price</TableHead>
72+
<TableHead className='pr-5 text-purple-100 text-end'>
73+
Last Traded
74+
</TableHead>
75+
</TableRow>
76+
</TableHeader>
77+
<TableBody>
78+
{coin.tickers
79+
.slice(0, 7)
80+
.map((ticker: Ticker, index: number) => (
81+
<TableRow
82+
key={index}
83+
className='overflow-hidden rounded-lg'
84+
>
85+
<TableCell className=' text-green-500 font-bold'>
86+
<Link
87+
href={ticker.trade_url}
88+
target='_blank'
89+
className='py-4 pl-3 block max-w-[110px] truncate'
90+
>
91+
{ticker.market.name}
92+
</Link>
93+
</TableCell>
94+
<TableCell className='font-medium truncate max-w-[100%] py-4 pr-5'>
95+
{ticker.base} / {ticker.target}
96+
</TableCell>
97+
<TableCell className='font-medium'>
98+
{formatPrice(ticker.converted_last.usd)}
99+
</TableCell>
100+
<TableCell className='pr-5 text-end'>
101+
{timeAgo(ticker.timestamp)}
102+
</TableCell>
103+
</TableRow>
104+
))}
105+
</TableBody>
106+
</Table>
107+
</div>
108+
</div>
109+
</LiveDataWrapper>
60110
</section>
61111

62112
<section className='size-full max-lg:mt-8 lg:col-span-1'>
63113
{/* Converter */}
64-
<div className='w-full space-y-4'>
114+
<div className='w-full space-y-5'>
65115
<h4 className='text-2xl font-semibold'>
66116
{coin.symbol.toUpperCase()} Converter
67117
</h4>
@@ -134,55 +184,9 @@ const CoinDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
134184
</div>
135185
</div>
136186

137-
{/* Recent Trades */}
138-
<div className='w-full mt-8 space-y-4'>
139-
<h4 className='text-2xl'>Exchange Listings</h4>
140-
<div className='custom-scrollbar bg-dark-500 rounded-xl overflow-hidden'>
141-
<Table>
142-
<TableHeader className='text-purple-100'>
143-
<TableRow className='hover:bg-transparent'>
144-
<TableHead className='pl-5 py-5 text-purple-100'>
145-
Exchange
146-
</TableHead>
147-
<TableHead className='text-purple-100'>Pair</TableHead>
148-
<TableHead className='text-purple-100'>Price</TableHead>
149-
<TableHead className='pr-5 text-purple-100 text-end'>
150-
Last Traded
151-
</TableHead>
152-
</TableRow>
153-
</TableHeader>
154-
<TableBody>
155-
{coin.tickers
156-
.slice(0, 7)
157-
.map((ticker: Ticker, index: number) => (
158-
<TableRow
159-
key={index}
160-
className='overflow-hidden rounded-lg'
161-
>
162-
<TableCell className=' text-green-500 font-bold'>
163-
<Link
164-
href={ticker.trade_url}
165-
target='_blank'
166-
className='py-4 pl-3 block max-w-[110px] truncate'
167-
>
168-
{ticker.market.name}
169-
</Link>
170-
</TableCell>
171-
<TableCell className='font-medium truncate max-w-[100%] py-4 pr-5'>
172-
{ticker.base} / {ticker.target}
173-
</TableCell>
174-
<TableCell className='font-medium'>
175-
{formatPrice(ticker.converted_last.usd)}
176-
</TableCell>
177-
<TableCell className='pr-5 text-end'>
178-
{timeAgo(ticker.timestamp)}
179-
</TableCell>
180-
</TableRow>
181-
))}
182-
</TableBody>
183-
</Table>
184-
</div>
185-
</div>
187+
<p className='mt-8 text-sm font-sans text-purple-50 leading-[30px]'>
188+
{coin.description}
189+
</p>
186190
</section>
187191
</main>
188192
);

components/CandlestickChart.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,11 @@ export default function CandlestickChart({
4040
// Memoize converted data to avoid recalculating on every render
4141
const chartData = useMemo(() => convertOHLCData(activeData), [activeData]);
4242

43-
console.log('CandlestickChart chartData:', chartData);
44-
// Fetch OHLC data
4543
const fetchOHLCData = async (selectedPeriod: Period) => {
4644
setLoading(true);
4745
try {
4846
const config = PERIOD_CONFIG[selectedPeriod];
4947

50-
// Dynamically import the server action
51-
5248
const newData = await getCoinOHLC(
5349
coinId,
5450
config.days,

components/Converter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const Converter = ({ symbol, icon, priceList }: ConverterProps) => {
2020
const convertedPrice = (parseFloat(amount) || 0) * (priceList[currency] || 0);
2121

2222
return (
23-
<div className='space-y-2 bg-dark-500 p-5 rounded-lg '>
23+
<div className='space-y-2 bg-dark-500 px-5 py-7 rounded-lg '>
2424
<div className='bg-dark-400 h-12 w-full rounded-md flex items-center justify-between py-4 pr-4'>
2525
<Input
2626
type='number'

components/LiveDataWrapper.tsx

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useEffect, useRef, useState, useCallback } from 'react';
1313
import CoinHeader from './CoinHeader';
1414
import { Separator } from './ui/separator';
1515
import CandlestickChart from './CandlestickChart';
16-
import { timeAgo } from '@/lib/utils';
16+
import { formatPrice, formatTime, timeAgo } from '@/lib/utils';
1717

1818
const WS_BASE = `${process.env.NEXT_PUBLIC_COINGECKO_WEBSOCKET_URL}?x_cg_pro_api_key=${process.env.NEXT_PUBLIC_COINGECKO_API_KEY}`;
1919

@@ -22,22 +22,19 @@ export default function LiveDataWrapper({
2222
pool,
2323
coin,
2424
coinOHLCData,
25+
children,
2526
}: LiveDataProps) {
2627
const wsRef = useRef<WebSocket | null>(null);
2728
const subscribed = useRef<Set<string>>(new Set());
2829

2930
const [price, setPrice] = useState<ExtendedPriceData | null>(null);
30-
const [trades, setTrades] = useState<TradeData[] | null>(null);
31+
const [trades, setTrades] = useState<TradeData[]>([]);
3132
const [ohlcv, setOhlcv] = useState<OHLCData[]>(coinOHLCData);
3233
const [isWsReady, setIsWsReady] = useState(false);
3334

3435
// Track where historical data ends and live data begins
3536
const historicalDataLength = useRef(coinOHLCData.length);
3637

37-
console.log('price', price);
38-
console.log('trades', trades);
39-
console.log('ohlcv', ohlcv);
40-
4138
const handleMessage = useCallback((event: MessageEvent) => {
4239
const ws = wsRef.current;
4340
const msg: WebSocketMessage = JSON.parse(event.data);
@@ -66,15 +63,19 @@ export default function LiveDataWrapper({
6663
}
6764

6865
if (msg.c === 'G2') {
69-
setTrades([
70-
{
71-
price: msg.pu,
72-
value: msg.vo,
73-
timestamp: msg.t,
74-
type: msg.ty,
75-
amount: msg.to,
76-
},
77-
]);
66+
const newTrade: TradeData = {
67+
price: msg.pu,
68+
value: msg.vo,
69+
timestamp: (msg.t ?? 0) * 1000, // Convert to milliseconds
70+
type: msg.ty,
71+
amount: msg.to,
72+
};
73+
74+
setTrades((prev) => {
75+
// Prepend new trade to beginning (most recent first)
76+
const allTrades = [newTrade, ...prev];
77+
return allTrades.slice(0, 10);
78+
});
7879
}
7980

8081
if (msg.ch === 'G3') {
@@ -161,8 +162,8 @@ export default function LiveDataWrapper({
161162
let active = true;
162163
(async () => {
163164
setPrice(null);
164-
setTrades(null);
165-
// Reset to historical data only (clear live data)
165+
// Reset to empty (clear live data)
166+
setTrades([]);
166167
setOhlcv(coinOHLCData);
167168
historicalDataLength.current = coinOHLCData.length;
168169

@@ -216,39 +217,59 @@ export default function LiveDataWrapper({
216217
<Separator className='my-8 bg-purple-600' />
217218

218219
{/* Recent Trades */}
219-
<div className='w-full mt-8 space-y-4'>
220+
<div className='w-full my-8 space-y-4'>
220221
<h4 className='text-2xl'>Recent Trades</h4>
221-
<Table className='bg-dark-500 rounded-xl'>
222-
<TableHeader className='text-purple-100'>
223-
<TableRow className='hover:bg-transparent'>
224-
<TableHead className='pl-5 py-5 text-purple-100'>
225-
Amount
226-
</TableHead>
227-
<TableHead className='text-purple-100'>Price</TableHead>
228-
<TableHead className='pr-8 text-purple-100'>Value</TableHead>
229-
<TableHead className='pr-8 text-purple-100'>Buy/Sell</TableHead>
230-
<TableHead className='pr-8 text-purple-100'>Time</TableHead>
231-
</TableRow>
232-
</TableHeader>
233-
<TableBody>
234-
{trades?.map((trade, index) => (
235-
<TableRow key={index}>
236-
<TableCell className='pl-5 py-4 font-medium'>
237-
{trade.amount}
238-
</TableCell>
239-
<TableCell className='font-medium'>{trade.price}</TableCell>
240-
<TableCell className='font-medium'>{trade.value}</TableCell>
241-
<TableCell className='font-medium'>
242-
{trade.type === 'b' ? 'Buy' : 'Sell'}
243-
</TableCell>
244-
<TableCell className='pr-5'>
245-
{trade.timestamp && timeAgo(trade.timestamp)}
246-
</TableCell>
247-
</TableRow>
248-
))}
249-
</TableBody>
250-
</Table>
222+
<div className='custom-scrollbar bg-dark-500 rounded-xl overflow-hidden'>
223+
{trades.length > 0 ? (
224+
<Table className='bg-dark-500'>
225+
<TableHeader className='text-purple-100'>
226+
<TableRow className='hover:bg-transparent'>
227+
<TableHead className='pl-5 text-purple-100'>Price</TableHead>
228+
<TableHead className='py-5 text-purple-100'>Amount</TableHead>
229+
<TableHead className='pr-8 text-purple-100'>Value</TableHead>
230+
<TableHead className='pr-8 text-purple-100'>
231+
Buy/Sell
232+
</TableHead>
233+
<TableHead className='pr-8 text-purple-100'>Time</TableHead>
234+
</TableRow>
235+
</TableHeader>
236+
<TableBody>
237+
{trades?.map((trade, index) => (
238+
<TableRow key={index}>
239+
<TableCell className='pl-5 py-5 font-medium'>
240+
{trade.price ? formatPrice(trade.price) : '-'}
241+
</TableCell>
242+
<TableCell className='py-4 font-medium'>
243+
{trade.amount?.toFixed(4) ?? '-'}
244+
</TableCell>
245+
<TableCell className='font-medium'>
246+
{trade.value ? formatPrice(trade.value) : '-'}
247+
</TableCell>
248+
<TableCell className='font-medium'>
249+
<span
250+
className={
251+
trade.type === 'b' ? 'text-green-500' : 'text-red-500'
252+
}
253+
>
254+
{trade.type === 'b' ? 'Buy' : 'Sell'}
255+
</span>
256+
</TableCell>
257+
<TableCell className='pr-5'>
258+
{trade.timestamp ? timeAgo(trade.timestamp) : '-'}
259+
</TableCell>
260+
</TableRow>
261+
))}
262+
</TableBody>
263+
</Table>
264+
) : (
265+
<div className='text-center p-10 text-purple-100/50'>
266+
No recent trades
267+
</div>
268+
)}
269+
</div>
251270
</div>
271+
272+
{children}
252273
</section>
253274
);
254275
}

components/SearchModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export const SearchModal = ({
194194
className='size-9 rounded-full'
195195
/>
196196
<div className='flex flex-col'>
197-
<p className='font-bold'>{coin.name}</p>
197+
<p className='font-bold text-white'>{coin.name}</p>
198198
<p className='text-sm text-purple-100 uppercase'>
199199
{coin.symbol}
200200
</p>

0 commit comments

Comments
 (0)