Conversation
[FEAT] AI 예측 히스토리 카드 구현
[MOD] 코인 상세 정보 api 연결
[MOD] 코인 차트 api 연결
[MOD] 리팩터링 및 에러 처리 코드 추가
[FEAT] newsCard UI 구현
[ADD] 코인 로고 추가
[UI] 메인 페이지 구현
Feature/1 coin
Feature/4 newslist
[FEAT] 코인별 뉴스 카드 ui 구현
[MOD] roundButton 수정
[FEAT] 코인 별 뉴스 api 연결
[FEAT] 코인 리스트 클릭 시 상세 페이지 이동 기능 구현
[FEAT] ai 예측 히스토리 api 연결 및 데이터 가공
[MOD] cointable null 처리
[FEAT] 뉴스 검색 기능 구현
There was a problem hiding this comment.
Pull request overview
This PR adds several new features to the CoinSight cryptocurrency tracking application: it introduces API integration modules for news, coin data, and market tickers; refactors the CoinDetail page to use dynamic routing with :ticker params; adds new UI components for AI prediction history cards, daily news, and search functionality; and connects these components to backend APIs with proper loading/error state handling.
Changes:
- Added new API modules (
News/search,News/analysis,Market/tickers,CoinDetail/coinNews,CoinDetail/aihistory,CoinDetail/chart) and updated existing ones to integrate with the backend - Refactored
CoinDetailPageto support dynamic coin tickers via URL params, added AI prediction history (History/HistoryCard), daily news (DailyNews/DailyNewsCard), and migrated chart data fetching to the backend API - Added
MainPagewith news analysis feed and coin list table,SearchResultPagewith news search, and shared components (SearchBar,RoundButton,NewsCard,CoinListTable)
Reviewed changes
Copilot reviewed 26 out of 28 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
src/App.jsx |
Added dynamic :ticker route for CoinDetail and new /search route |
src/pages/CoinDetailPage.jsx |
Refactored to use useParams for dynamic ticker, integrated backend API for coin info |
src/pages/MainPage.jsx |
Added news analysis feed, search bar, and coin list table |
src/pages/SearchResultPage.jsx |
New page for news search results |
src/components/common/SearchBar.jsx |
New shared search bar with navigation |
src/components/common/RoundButton.jsx |
New reusable sentiment/status badge button |
src/components/common/Navbar.jsx |
Minor formatting and min-width addition |
src/components/MainPage/NewsCard.jsx |
New news card with sentiment display and time-ago formatting |
src/components/MainPage/CoinListTable.jsx |
New coin price table with domestic/overseas tabs |
src/components/MainPage/NewsSearchBar.jsx |
New news-specific search bar (unused) |
src/components/MainPage/CoinSearchBar.jsx |
New coin-specific search bar (unused) |
src/components/CoinDetail/History.jsx |
Refactored to fetch AI prediction history from backend API |
src/components/CoinDetail/HistoryCard.jsx |
New card for displaying individual AI predictions |
src/components/CoinDetail/PredictionNewsCard.jsx |
New card for articles used in predictions |
src/components/CoinDetail/DailyNews.jsx |
New daily news section for coin detail |
src/components/CoinDetail/DailyNewsCard.jsx |
New card for daily news items |
src/components/CoinDetail/CoinChart.jsx |
Migrated chart data fetching to backend API (partial) |
src/apis/News/search.js |
New API for news search |
src/apis/News/analysis.js |
New API for news analysis list |
src/apis/Market/tickers.js |
New API for market tickers |
src/apis/CoinDetail/coinNews.js |
New API for coin-specific news |
src/apis/CoinDetail/coinInfo.js |
Updated to return res.data instead of res |
src/apis/CoinDetail/chart.js |
New API for candle chart data |
src/apis/CoinDetail/aihistory.js |
New API for AI predictions and prediction news |
src/assets/pixelarticons--coin.svg |
New fallback coin logo SVG |
package.json / package-lock.json |
Added iconify-icon dependency |
.env.example |
Deleted |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| } | ||
| } | ||
|
|
||
| fetch(`https://api.bithumb.com/public/candlestick/BTC_KRW/1h`, options) |
There was a problem hiding this comment.
The Bithumb candlestick API URL is hardcoded to BTC_KRW, but the page now supports dynamic tickers via useParams(). For any coin other than BTC, this will always fetch BTC data, producing incorrect fluctuation rate and price information. The URL should use the dynamic ticker value (e.g., constructing ${ticker}_KRW).
| fetch(`https://api.bithumb.com/public/candlestick/BTC_KRW/1h`, options) | |
| fetch(`https://api.bithumb.com/public/candlestick/${ticker}_KRW/1h`, options) |
| const onClickDay = () => { | ||
| const options = {method: 'GET', headers: {accept: 'application/json'}}; | ||
|
|
||
| fetch(`https://api.bithumb.com/v1/candles/days?market=${coinName}&count=200`, options) | ||
| fetch(`https://api.bithumb.com/v1/candles/days?market=${ticker}&count=200`, options) |
There was a problem hiding this comment.
The onClickDay function still calls the Bithumb API directly with ticker as the market parameter, but the ticker prop now contains just the symbol (e.g., BTC), whereas the Bithumb API expects the full market format (e.g., KRW-BTC). This means the 1-day chart will fail for all coins. The other time intervals (1min, 1hr, 4hr) were correctly migrated to use the backend API via fetchCandleData. The onClickDay should also be migrated to use the backend API for consistency and correctness.
|
|
||
| const [coinInfo, setCoinInfo] = useState({ | ||
| name: "", | ||
| ticker1: "", |
There was a problem hiding this comment.
The property name ticker1 is unclear and ambiguous. It stores the ticker from the API response to differentiate it from the ticker URL param, but the name doesn't convey this purpose. Consider a more descriptive name like apiTicker or displayTicker, or simply reuse the ticker param since they should represent the same value.
| const formatPrice = Number(value) / 100000000; | ||
| return `${formatPrice.toLocaleString(undefined, {maximumFractionDigits: 1})}억`; |
There was a problem hiding this comment.
Inside formatPrice, the local variable formatPrice shadows the outer function name formatPrice. While this works because JavaScript resolves the inner scope variable, it's confusing and could lead to subtle bugs if the function were ever intended to be called recursively or referenced internally. Consider renaming the local variable to something like priceInEok.
| } | ||
|
|
||
| useEffect (() => { | ||
| const options = {method: 'GET', headers: {accept: 'application/json'}}; |
There was a problem hiding this comment.
The options variable declared on line 34 is only used by the hardcoded Bithumb fetch call on line 58. Now that fetchCoinInfo uses the backend API via getCoinInfo, this options variable is only needed for the remaining direct fetch. Once the Bithumb fetch is also migrated to the backend API, this variable should be removed.
| return `${time.getFullYear()}년 ${time.getMonth() + 1}월 ${time.getDate()}일 | ||
| ${time.getHours()}:${time.getMinutes()}` | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
The formatTime function produces a multi-line string due to the template literal spanning two lines. The output will contain unintended whitespace/newline characters between the date and time portions. The template literal should be on a single line or the whitespace should be trimmed.
| return `${time.getFullYear()}년 ${time.getMonth() + 1}월 ${time.getDate()}일 | |
| ${time.getHours()}:${time.getMinutes()}` | |
| } | |
| return `${time.getFullYear()}년 ${time.getMonth() + 1}월 ${time.getDate()}일 ${time.getHours()}:${time.getMinutes()}` | |
| } |
| POSITIVE : "positive" | ||
| } | ||
| const contentType = { | ||
| NEGATIVE : "악재", | ||
| POSITIVE : "호재" |
There was a problem hiding this comment.
Same as DailyNewsCard, labelType and contentType only handle NEGATIVE and POSITIVE but not NEUTRAL. If the API returns a NEUTRAL sentiment, both mappings will return undefined, causing RoundButton to render with undefined status and content.
| POSITIVE : "positive" | |
| } | |
| const contentType = { | |
| NEGATIVE : "악재", | |
| POSITIVE : "호재" | |
| POSITIVE : "positive", | |
| NEUTRAL : "neutral", | |
| } | |
| const contentType = { | |
| NEGATIVE : "악재", | |
| POSITIVE : "호재", | |
| NEUTRAL : "중립", |
|
|
||
| export const getCandleInfo = async (ticker, unit=1, count=200) => { | ||
| try { | ||
| const res = await instance.get(`/api/v1/market/candles/${ticker}?unit=${unit}&count=${count}`); |
There was a problem hiding this comment.
Query parameters are manually concatenated into the URL string rather than using params as done consistently in all other API functions in this PR (e.g., search.js, analysis.js, tickers.js, coinNews.js). This is inconsistent and could lead to encoding issues. Use params: { unit, count } as the second argument to instance.get for consistency with the rest of the codebase.
| const res = await instance.get(`/api/v1/market/candles/${ticker}?unit=${unit}&count=${count}`); | |
| const res = await instance.get(`/api/v1/market/candles/${ticker}`, { | |
| params: { unit, count }, | |
| }); |
| "eslint-plugin-react-hooks": "^7.0.1", | ||
| "eslint-plugin-react-refresh": "^0.4.24", | ||
| "globals": "^16.5.0", | ||
| "iconify-icon": "^3.0.2", |
There was a problem hiding this comment.
The iconify-icon package is added under devDependencies, but it is used at runtime in multiple components (RoundButton, SearchBar, CoinListTable, HistoryCard, etc.) as a web component. Since it is needed in the production bundle, it should be in dependencies instead of devDependencies. While Vite will still bundle it during development, this is semantically incorrect and could cause issues in certain build/deployment pipelines that strip devDependencies.
| export const getPredictionNews = async (ticker, predictionId) => { | ||
| try { | ||
| const res = await instance.get(`/api/v1/crypto/${ticker}/predictions/${predictionId}/news`); | ||
| console.log(res); |
There was a problem hiding this comment.
console.log(res) is left in production code. Other API functions in this PR correctly comment out or omit their console.log calls. This debug logging should be removed.
| console.log(res); | |
| //console.log(res); |
This pull request introduces several new API integrations and refactors key components in the Coin Detail feature to improve data fetching, error handling, and user experience. The changes include adding new API modules for coins and news, updating routing to support dynamic coin tickers, and refactoring components to utilize the new APIs and display loading/error states. Additionally, a new package is added for icon support.