Skip to content

Commit 6eb501b

Browse files
authored
Merge pull request #143 from TTMordred/main
Update file in Staking branches
2 parents d6bbe43 + 54ede11 commit 6eb501b

23 files changed

Lines changed: 2989 additions & 479 deletions

File tree

app/NFT/collection/[collectionId]/page.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ export default function CollectionDetailsPage() {
225225
// Add network as a filter attribute
226226
attributeMap['Network'] = [
227227
networkId === '0x1' ? 'Ethereum' :
228-
networkId === '0xaa36a7' ? 'Sepolia' :
229228
networkId === '0x38' ? 'BNB Chain' :
230229
'BNB Testnet'
231230
];
@@ -339,7 +338,6 @@ export default function CollectionDetailsPage() {
339338
const getExplorerLink = (address: string) => {
340339
const chainConfig = {
341340
'0x1': 'https://etherscan.io',
342-
'0xaa36a7': 'https://sepolia.etherscan.io',
343341
'0x38': 'https://bscscan.com',
344342
'0x61': 'https://testnet.bscscan.com',
345343
};
@@ -352,7 +350,6 @@ export default function CollectionDetailsPage() {
352350
const getNetworkName = () => {
353351
const networks = {
354352
'0x1': 'Ethereum',
355-
'0xaa36a7': 'Sepolia',
356353
'0x38': 'BNB Chain',
357354
'0x61': 'BNB Testnet',
358355
};

app/NFT/collection/page.tsx

Lines changed: 94 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,24 @@ export default function NFTCollectionPage() {
202202
method: 'eth_chainId',
203203
});
204204
setChainId(chainId);
205+
// Load collections immediately after setting chainId
206+
loadCollections(chainId);
207+
// Initial trending data - load for default period
208+
loadTrendingCollections('24h');
205209
} catch (error) {
206210
console.error('Error checking network:', error);
211+
// If there's an error, still load with default chainId
212+
loadCollections(chainId);
213+
loadTrendingCollections('24h');
207214
}
215+
} else {
216+
// If no window.ethereum, load with default chainId
217+
loadCollections(chainId);
218+
loadTrendingCollections('24h');
208219
}
209220
};
210221

211222
checkNetwork();
212-
loadCollections(chainId);
213-
214-
// Initial trending data
215-
loadTrendingCollections('24h');
216223
}, []);
217224

218225
// Load user NFTs when account or chain changes
@@ -304,6 +311,29 @@ export default function NFTCollectionPage() {
304311
// Load trending collections
305312
const loadTrendingCollections = useCallback(async (period: string) => {
306313
try {
314+
// Create placeholder data with empty array if collections not loaded yet
315+
if (collections.length === 0) {
316+
// Set mock empty data with period to display the section even when data is loading
317+
setTrendingData({
318+
period,
319+
data: [
320+
{
321+
id: 'loading-1',
322+
name: 'Loading...',
323+
imageUrl: '/images/placeholder-nft.png',
324+
chain: chainId,
325+
floorPrice: '0.00',
326+
priceChange: 0,
327+
volume: '0.00',
328+
volumeChange: 0,
329+
},
330+
// Add more placeholder items as needed
331+
]
332+
});
333+
// Return early - real data will be loaded once collections are available
334+
return;
335+
}
336+
307337
// In real app this would fetch real data
308338
const mockTrendingData = {
309339
period,
@@ -323,7 +353,14 @@ export default function NFTCollectionPage() {
323353
} catch (error) {
324354
console.error('Error loading trending data:', error);
325355
}
326-
}, [collections]);
356+
}, [collections, chainId]);
357+
358+
useEffect(() => {
359+
// When collections are loaded, update the trending data
360+
if (collections.length > 0) {
361+
loadTrendingCollections(trendingPeriod);
362+
}
363+
}, [collections, loadTrendingCollections, trendingPeriod]);
327364

328365
const handleNetworkChange = (networkId: string) => {
329366
setChainId(networkId);
@@ -516,52 +553,63 @@ export default function NFTCollectionPage() {
516553
</tr>
517554
</thead>
518555
<tbody>
519-
{trendingData.data.map((item, i) => (
520-
<motion.tr
521-
key={item.id}
522-
whileHover={{ backgroundColor: "rgba(255,255,255,0.03)" }}
523-
className="cursor-pointer border-b border-gray-800/50"
524-
onClick={() => handleCardClick(item.id)}
525-
initial={{ opacity: 0, y: 10 }}
526-
animate={{ opacity: 1, y: 0 }}
527-
transition={{ delay: 0.3 + i * 0.05 }}
528-
>
529-
<td className="p-2 text-gray-400">{i + 1}</td>
530-
<td className="p-2">
531-
<div className="flex items-center gap-3">
532-
<div className="relative h-10 w-10 rounded-lg overflow-hidden">
533-
<Image
534-
src={item.imageUrl}
535-
alt={item.name}
536-
fill
537-
className="object-cover"
538-
/>
539-
</div>
540-
<div>
541-
<div className="font-medium flex items-center gap-1">
542-
{item.name}
543-
{(i === 0 || i === 2) && <Verified className="h-3.5 w-3.5 text-blue-400" />}
556+
{trendingData.data.length > 0 ? (
557+
trendingData.data.map((item, i) => (
558+
<motion.tr
559+
key={item.id}
560+
whileHover={{ backgroundColor: "rgba(255,255,255,0.03)" }}
561+
className="cursor-pointer border-b border-gray-800/50"
562+
onClick={() => handleCardClick(item.id)}
563+
initial={{ opacity: 0, y: 10 }}
564+
animate={{ opacity: 1, y: 0 }}
565+
transition={{ delay: 0.3 + i * 0.05 }}
566+
>
567+
<td className="p-2 text-gray-400">{i + 1}</td>
568+
<td className="p-2">
569+
<div className="flex items-center gap-3">
570+
<div className="relative h-10 w-10 rounded-lg overflow-hidden">
571+
<Image
572+
src={item.imageUrl}
573+
alt={item.name}
574+
fill
575+
className="object-cover"
576+
/>
544577
</div>
545-
<div className="text-xs text-gray-400">
546-
{getNetworkName(item.chain)}
578+
<div>
579+
<div className="font-medium flex items-center gap-1">
580+
{item.name}
581+
{(i === 0 || i === 2) && <Verified className="h-3.5 w-3.5 text-blue-400" />}
582+
</div>
583+
<div className="text-xs text-gray-400">
584+
{getNetworkName(item.chain)}
585+
</div>
547586
</div>
548587
</div>
588+
</td>
589+
<td className="p-2 text-right font-medium">
590+
{item.floorPrice} {item.chain === '0x1' || item.chain === '0xaa36a7' ? 'ETH' : 'BNB'}
591+
</td>
592+
<td className={`p-2 text-right ${item.priceChange >= 0 ? 'text-green-500' : 'text-red-500'}`}>
593+
{item.priceChange >= 0 ? '+' : ''}{item.priceChange.toFixed(2)}%
594+
</td>
595+
<td className="p-2 text-right font-medium">
596+
{item.volume} {item.chain === '0x1' || item.chain === '0xaa36a7' ? 'ETH' : 'BNB'}
597+
</td>
598+
<td className={`p-2 text-right ${item.volumeChange >= 0 ? 'text-green-500' : 'text-red-500'}`}>
599+
{item.volumeChange >= 0 ? '+' : ''}{item.volumeChange.toFixed(2)}%
600+
</td>
601+
</motion.tr>
602+
))
603+
) : (
604+
<tr className="border-b border-gray-800/50">
605+
<td colSpan={6} className="p-4 text-center text-gray-400">
606+
<div className="flex flex-col items-center gap-2">
607+
<div className="h-5 w-5 border-2 border-t-transparent animate-spin rounded-full" />
608+
<span>Loading trending collections...</span>
549609
</div>
550610
</td>
551-
<td className="p-2 text-right font-medium">
552-
{item.floorPrice} {item.chain === '0x1' || item.chain === '0xaa36a7' ? 'ETH' : 'BNB'}
553-
</td>
554-
<td className={`p-2 text-right ${item.priceChange >= 0 ? 'text-green-500' : 'text-red-500'}`}>
555-
{item.priceChange >= 0 ? '+' : ''}{item.priceChange.toFixed(2)}%
556-
</td>
557-
<td className="p-2 text-right font-medium">
558-
{item.volume} {item.chain === '0x1' || item.chain === '0xaa36a7' ? 'ETH' : 'BNB'}
559-
</td>
560-
<td className={`p-2 text-right ${item.volumeChange >= 0 ? 'text-green-500' : 'text-red-500'}`}>
561-
{item.volumeChange >= 0 ? '+' : ''}{item.volumeChange.toFixed(2)}%
562-
</td>
563-
</motion.tr>
564-
))}
611+
</tr>
612+
)}
565613
</tbody>
566614
</table>
567615
</div>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { NextResponse } from "next/server";
2+
3+
const ALCHEMY_API_KEY = process.env.ALCHEMY_API_KEY;
4+
const ALCHEMY_API_URL = `https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`;
5+
6+
interface Transaction {
7+
blockHash: string;
8+
blockNumber: string;
9+
from: string;
10+
gas: string;
11+
gasPrice: string;
12+
hash: string;
13+
input: string;
14+
nonce: string;
15+
to: string;
16+
transactionIndex: string;
17+
value: string;
18+
type: string;
19+
timestamp: number;
20+
}
21+
22+
export async function GET(request: Request) {
23+
const { searchParams } = new URL(request.url);
24+
const blockNumber = searchParams.get("blockNumber");
25+
26+
if (!blockNumber) {
27+
return NextResponse.json(
28+
{ error: "Block number is required" },
29+
{ status: 400 }
30+
);
31+
}
32+
33+
try {
34+
// First, get block data to get timestamp
35+
const blockResponse = await fetch(ALCHEMY_API_URL, {
36+
method: 'POST',
37+
headers: { 'Content-Type': 'application/json' },
38+
body: JSON.stringify({
39+
jsonrpc: '2.0',
40+
id: 1,
41+
method: 'eth_getBlockByNumber',
42+
params: [
43+
`0x${Number(blockNumber).toString(16)}`,
44+
false
45+
]
46+
})
47+
});
48+
49+
const blockData = await blockResponse.json();
50+
51+
if (!blockData.result) {
52+
return NextResponse.json(
53+
{ error: "Block not found" },
54+
{ status: 404 }
55+
);
56+
}
57+
58+
const timestamp = parseInt(blockData.result.timestamp, 16);
59+
60+
// Get all transactions from the block
61+
const txnsResponse = await fetch(ALCHEMY_API_URL, {
62+
method: 'POST',
63+
headers: { 'Content-Type': 'application/json' },
64+
body: JSON.stringify({
65+
jsonrpc: '2.0',
66+
id: 1,
67+
method: 'eth_getBlockByNumber',
68+
params: [
69+
`0x${Number(blockNumber).toString(16)}`,
70+
true
71+
]
72+
})
73+
});
74+
75+
const txnsData = await txnsResponse.json();
76+
77+
if (!txnsData.result || !txnsData.result.transactions) {
78+
return NextResponse.json(
79+
{ error: "Failed to fetch transactions" },
80+
{ status: 500 }
81+
);
82+
}
83+
84+
const transactions: Transaction[] = txnsData.result.transactions.map((tx: any) => ({
85+
blockHash: tx.blockHash,
86+
blockNumber: parseInt(tx.blockNumber, 16).toString(),
87+
from: tx.from,
88+
gas: parseInt(tx.gas, 16).toString(),
89+
gasPrice: parseInt(tx.gasPrice, 16).toString(),
90+
hash: tx.hash,
91+
input: tx.input,
92+
nonce: parseInt(tx.nonce, 16).toString(),
93+
to: tx.to || '0x0', // Contract creation if no 'to' address
94+
transactionIndex: parseInt(tx.transactionIndex, 16).toString(),
95+
value: (parseInt(tx.value, 16) / 1e18).toString(), // Convert from Wei to ETH
96+
type: parseInt(tx.type, 16).toString(),
97+
timestamp: timestamp
98+
}));
99+
100+
return NextResponse.json({
101+
blockNumber,
102+
timestamp,
103+
transactions,
104+
total: transactions.length
105+
});
106+
107+
} catch (error) {
108+
console.error("Error fetching block transactions:", error);
109+
return NextResponse.json(
110+
{ error: "Failed to fetch block transactions" },
111+
{ status: 500 }
112+
);
113+
}
114+
}

0 commit comments

Comments
 (0)