Skip to content

Commit b264b3c

Browse files
Merge pull request #61 from anmolsah/feature/add-pagination-crypto
Added pagination for top coins in Crypto.jsx (#41)
2 parents 165122f + 68c35eb commit b264b3c

2 files changed

Lines changed: 77 additions & 14 deletions

File tree

src/pages/Crypto.jsx

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,46 +18,77 @@
1818
* - [ ] Dark mode adaptive coloring for charts
1919
* - [ ] Extract to service + custom hook (useCryptoMarkets)
2020
*/
21-
import { useEffect, useState } from 'react';
22-
import Loading from '../components/Loading.jsx';
23-
import ErrorMessage from '../components/ErrorMessage.jsx';
24-
import Card from '../components/Card.jsx';
21+
import { useEffect, useState } from "react";
22+
import Loading from "../components/Loading.jsx";
23+
import ErrorMessage from "../components/ErrorMessage.jsx";
24+
import Card from "../components/Card.jsx";
2525

2626
export default function Crypto() {
2727
const [coins, setCoins] = useState([]);
28-
const [query, setQuery] = useState('');
28+
const [query, setQuery] = useState("");
2929
const [loading, setLoading] = useState(false);
3030
const [error, setError] = useState(null);
31+
const [page, setPage] = useState(1);
3132

32-
useEffect(() => { fetchCoins(); }, []);
33+
useEffect(() => {
34+
fetchCoins();
35+
}, [page]);
3336

3437
async function fetchCoins() {
3538
try {
36-
setLoading(true); setError(null);
37-
const res = await fetch('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=50&page=1&sparkline=false');
38-
if (!res.ok) throw new Error('Failed to fetch');
39+
setLoading(true);
40+
setError(null);
41+
const res = await fetch(
42+
`https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=50&page=${page}&sparkline=false`
43+
);
44+
if (!res.ok) throw new Error("Failed to fetch");
3945
const json = await res.json();
4046
setCoins(json);
41-
} catch (e) { setError(e); } finally { setLoading(false); }
47+
} catch (e) {
48+
setError(e);
49+
} finally {
50+
setLoading(false);
51+
}
4252
}
4353

44-
const filtered = coins.filter(c => c.name.toLowerCase().includes(query.toLowerCase()));
54+
const filtered = coins.filter((c) =>
55+
c.name.toLowerCase().includes(query.toLowerCase())
56+
);
4557

4658
return (
4759
<div>
4860
<h2>Cryptocurrency Tracker</h2>
49-
<input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search coin" />
61+
<input
62+
value={query}
63+
onChange={(e) => setQuery(e.target.value)}
64+
placeholder="Search coin"
65+
/>
66+
5067
{loading && <Loading />}
5168
<ErrorMessage error={error} />
5269
<div className="grid">
53-
{filtered.map(c => (
54-
<Card key={c.id} title={c.name} footer={<span>${c.current_price}</span>}>
70+
{filtered.map((c) => (
71+
<Card
72+
key={c.id}
73+
title={c.name}
74+
footer={<span>${c.current_price}</span>}
75+
>
5576
<p>Market Cap: ${c.market_cap.toLocaleString()}</p>
5677
<p>24h: {c.price_change_percentage_24h?.toFixed(2)}%</p>
5778
{/* TODO: Add mini sparkline chart */}
5879
</Card>
5980
))}
6081
</div>
82+
83+
<div className="pagination">
84+
<button onClick={() => setPage((p) => p - 1)} disabled={page === 1}>
85+
Previous
86+
</button>
87+
88+
<span>Page {page}</span>
89+
90+
<button onClick={() => setPage((p) => p + 1)}>Next</button>
91+
</div>
6192
</div>
6293
);
6394
}

src/styles.css

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,3 +412,35 @@ blockquote {
412412
@media (max-width: 640px) {
413413
.weather-inner { padding: 1rem; }
414414
}
415+
416+
417+
/**Pagination **/
418+
419+
.pagination {
420+
width: 100%;
421+
display: flex;
422+
justify-content: center;
423+
align-items: center;
424+
margin-top: 20px;
425+
gap: 15px;
426+
}
427+
428+
.pagination button {
429+
padding: 8px 16px;
430+
border-radius: 5px;
431+
border: none;
432+
background-color: #007bff;
433+
color: white;
434+
font-weight: bold;
435+
cursor: pointer;
436+
transition: background-color 0.2s;
437+
}
438+
439+
.pagination button:hover {
440+
background-color: #0056b3;
441+
}
442+
443+
.pagination button:disabled {
444+
background-color: #ccc;
445+
cursor: not-allowed;
446+
}

0 commit comments

Comments
 (0)