import PropTypes from "prop-types";
import { Link } from "react-router-dom";
function HomeCoinInfo({ rank, id, name, symbol, first_data_at }) {
return (
<div>
<h2>
<Link to={`/DetailCoin/${id}`}>{id}</Link>
</h2>
<ul>
<li>rank : {rank}</li>
<li>name : {name}</li>
<li>symbol : {symbol}</li>
<li>first_data_at : {first_data_at}</li>
</ul>
</div>
);
}
HomeCoinInfo.propTypes = {
rank: PropTypes.string.isRequired,
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
symbol: PropTypes.string.isRequired,
first_data_at: PropTypes.string.isRequired,
};
export default HomeCoinInfo;
/* .container {
height: 100%;
display: flex;
justify-content: center;
} */
.coinsMainText {
text-align: center; /* 텍스트 중앙 정렬 */
}
.coins {
display: grid;
grid-template-columns: repeat(4, minmax(400px, 1fr));
grid-gap: 100px;
padding: 150px;
width: 50%;
padding-top: 20px;
}
.coins > div {
border: 1px solid #ccc; /* 각 코인 항목에 경계선 추가 */
padding: 20px; /* 경계선과 내용 사이에 여백 추가 */
border-radius: 8px; /* 경계선의 모서리를 둥글게 만듦 */
background-color: #fff; /* 배경색을 흰색으로 설정 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 약간의 그림자 추가 */
}
@media screen and (max-width: 1090px) {
.coins {
grid-template-columns: 1fr;
width: 100%;
}
}
.eachCoin:hover {
background-color: green;
transform: scale(1.1); /* 5%만큼 크기를 증가시킴 */
}
import React, { useState, useEffect } from "react";
import styles from "./HomeCoin.module.css";
import HomeCoinInfo from "../components/HomeCoinInfo";
function HomeCoin() {
const [coin, setCoin] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchCoinData() {
try {
const response = await fetch("https://api.coinpaprika.com/v1/tickers");
const coins = await response.json();
setCoin(coins); // >>> 모두 다 불러옴
} catch (error) {
setError(error);
console.error("Error fetching coin data:", error);
}
}
fetchCoinData();
}, []);
if (error) {
return <div>Error fetching coin data: {error.message}</div>;
}
if (!coin) {
return <div>Loading...</div>;
}
return (
<div className="HomeCoin-js-container">
<div className={styles.coinsMainText}>
<h1>IrishNoah Bit-Coin Information</h1>
</div>
<div className={styles.coins}>
{coin.map((data) => (
<div className={styles.eachCoin}>
<div>
<HomeCoinInfo
rank={data.rank}
id={data.id}
name={data.name}
symbol={data.symbol}
first_data_at={data.first_data_at}
/>
</div>
</div>
))}
</div>
</div>
);
}
export default HomeCoin;
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
function DetailCoin() {
const { id } = useParams(); // URL에서 id 파라미터를 추출합니다.
const [coin, setCoin] = useState(null);
useEffect(() => {
fetch(`https://api.coinpaprika.com/v1/tickers/${id}`) // 코인 정보를 가져오는 API (예시 URL)
.then((response) => response.json())
.then((data) => {
setCoin(data);
console.log(data);
})
.catch((error) => console.error("Error fetching coin data:", error));
}, [id]); // id가 변경될 때마다 이 effect를 다시 실행합니다.
if (!coin) {
return <p>Loading...</p>;
}
const quotes = coin.quotes.USD;
return (
<div>
<h1>
{coin.name} ({coin.id})
</h1>
<ul>
<li>Rank: {coin.rank}</li>
<li>symbol: {coin.symbol}</li>
<li>total_supply: {coin.total_supply}</li>
<li>first_data_at: {coin.first_data_at}</li>
<li>last_updated: {coin.last_updated}</li>
{Object.keys(quotes).map((key) => (
<li key={key}>
{key}: {quotes[key]}
</li>
))}
</ul>
</div>
);
}
export default DetailCoin;
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import DetailCoin from "./routes/DetailCoin";
import HomeCoin from "./routes/HomeCoin";
function App() {
return (
<Router>
<Switch>
<Route path="/hello">
<h1>Hello</h1>
</Route>
<Route path="/DetailCoin/:id">
<DetailCoin />
</Route>
<Route path="/">
<HomeCoin />
</Route>
</Switch>
</Router>
);
}
export default App;
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./styles.css";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
⇒ 화면 1

⇒ 화면 2
