Skip to content

Implement AI prediction history card, news UI, and API connections#44

Merged
Ed-hacker merged 34 commits intoreleasefrom
main
Mar 6, 2026
Merged

Implement AI prediction history card, news UI, and API connections#44
Ed-hacker merged 34 commits intoreleasefrom
main

Conversation

@Ed-hacker
Copy link
Contributor

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.

Juyoung03 and others added 30 commits February 8, 2026 16:21
[FEAT] AI 예측 히스토리 카드 구현
[MOD] 코인 상세 정보 api 연결
[MOD] 리팩터링 및 에러 처리 코드 추가
[FEAT] 코인별 뉴스 카드 ui 구현
[FEAT] 코인 리스트 클릭 시 상세 페이지 이동 기능 구현
[FEAT] ai 예측 히스토리 api 연결 및 데이터 가공
@Ed-hacker Ed-hacker requested a review from Copilot March 6, 2026 01:38
@Ed-hacker Ed-hacker merged commit dde5867 into release Mar 6, 2026
4 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 CoinDetailPage to 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 MainPage with news analysis feed and coin list table, SearchResultPage with 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)
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
fetch(`https://api.bithumb.com/public/candlestick/BTC_KRW/1h`, options)
fetch(`https://api.bithumb.com/public/candlestick/${ticker}_KRW/1h`, options)

Copilot uses AI. Check for mistakes.
Comment on lines 71 to +74
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)
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

const [coinInfo, setCoinInfo] = useState({
name: "",
ticker1: "",
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 29 to 30
const formatPrice = Number(value) / 100000000;
return `${formatPrice.toLocaleString(undefined, {maximumFractionDigits: 1})}억`;
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
}

useEffect (() => {
const options = {method: 'GET', headers: {accept: 'application/json'}};
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +19
return `${time.getFullYear()}년 ${time.getMonth() + 1}월 ${time.getDate()}일
${time.getHours()}:${time.getMinutes()}`
}


Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
return `${time.getFullYear()}${time.getMonth() + 1}${time.getDate()}
${time.getHours()}:${time.getMinutes()}`
}
return `${time.getFullYear()}${time.getMonth() + 1}${time.getDate()}${time.getHours()}:${time.getMinutes()}`
}

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +10
POSITIVE : "positive"
}
const contentType = {
NEGATIVE : "악재",
POSITIVE : "호재"
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
POSITIVE : "positive"
}
const contentType = {
NEGATIVE : "악재",
POSITIVE : "호재"
POSITIVE : "positive",
NEUTRAL : "neutral",
}
const contentType = {
NEGATIVE : "악재",
POSITIVE : "호재",
NEUTRAL : "중립",

Copilot uses AI. Check for mistakes.

export const getCandleInfo = async (ticker, unit=1, count=200) => {
try {
const res = await instance.get(`/api/v1/market/candles/${ticker}?unit=${unit}&count=${count}`);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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 },
});

Copilot uses AI. Check for mistakes.
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"iconify-icon": "^3.0.2",
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
export const getPredictionNews = async (ticker, predictionId) => {
try {
const res = await instance.get(`/api/v1/crypto/${ticker}/predictions/${predictionId}/news`);
console.log(res);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
console.log(res);
//console.log(res);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants