Conversation
요약Walkthrough배팅 컴포넌트에 인터랙티브한 상태 관리와 버튼 핸들러를 추가하고, 베팅 이력에 클라이언트 측 페이지네이션 기능을 도입했습니다. 새로운 Pagination 컴포넌트를 추가하고 테스트 데이터를 확장했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Betting Component
participant State
User->>Betting Component: Up/Down 버튼 클릭
Betting Component->>State: isBetting 상태 업데이트
State->>Betting Component: 활성 스타일 + 체크 표시
Betting Component->>User: UI 반영
User->>Betting Component: 취소(X) 클릭
Betting Component->>State: isBetting = 'none'
State->>Betting Component: 상태 초기화
Betting Component->>User: 버튼 상태 복구
sequenceDiagram
participant User
participant BettingHistory
participant Pagination Component
User->>BettingHistory: 페이지 이력 타입 변경
BettingHistory->>BettingHistory: currentPage = 0 (초기화)
BettingHistory->>Pagination Component: currentPage, totalPages 전달
User->>Pagination Component: 다음/이전 버튼 클릭
Pagination Component->>BettingHistory: onPageChange(newPage)
BettingHistory->>BettingHistory: currentData 계산 및 업데이트
BettingHistory->>User: 페이지 데이터 렌더링
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
frontend/src/utils/dailyBettingHistory.js (1)
35-794: 테스트 데이터 다양성을 개선하세요.페이지네이션 테스트를 위해 동일한 3개의 레코드(2025-08-24, 2025-08-23, 2025-08-22)를 반복하고 있습니다. 이는 페이지네이션 기능 테스트에는 충분하지만, 더 현실적인 테스트를 위해 다음을 고려하세요:
- 다양한 날짜 범위 사용
- 여러 종목 심볼 추가 (AAPL 외에 GOOGL, MSFT 등)
- 다양한 가격 변동 및 백분율
- 무작위 참가자 수 및 포인트
더 다양한 테스트 데이터를 생성하는 헬퍼 함수를 작성할 수 있습니다:
// 테스트 데이터 생성 헬퍼 추가 const generateTestData = (count) => { const symbols = ['AAPL', 'GOOGL', 'MSFT', 'TSLA']; const results = ['UP', 'DOWN']; const data = []; for (let i = 0; i < count; i++) { const date = new Date(2025, 7, 24 - i); const dateStr = date.toISOString().split('T')[0]; data.push({ date: dateStr, symbol: symbols[i % symbols.length], closePrice: 70 + Math.random() * 30, nextClosePrice: 70 + Math.random() * 30, changePercent: -30 + Math.random() * 60, points: 200 + Math.floor(Math.random() * 200), participants: 100 + Math.floor(Math.random() * 300), result: results[i % 2], isCorrect: Math.random() > 0.5, }); } return data; };frontend/src/components/stockgame/BettingHistory.module.css (1)
130-133: 하드코딩된 여백 값을 개선하세요.
margin-left: 230px는 고정값으로 다양한 화면 크기나 레이아웃 변경에 취약합니다. 더 유연한 중앙 정렬을 위해 다음을 고려하세요:.paginationContainer { display: flex; - margin-left: 230px; + justify-content: center; + width: 100%; }또는 페이지네이션을 베팅 카드와 정렬해야 하는 경우:
.paginationContainer { display: flex; - margin-left: 230px; + justify-content: flex-start; + padding-left: 0; + /* 부모 요소의 패딩/여백과 일치시키기 */ }frontend/src/utils/weeklyBettingHistory.js (1)
35-133: 테스트 데이터 다양성을 개선하세요.dailyBettingHistory.js와 동일한 문제가 있습니다. 동일한 3개 레코드를 4번 반복하는 대신, 더 다양하고 현실적인 주간 베팅 이력 데이터를 생성하세요. 다른 주차, 종목, 가격 변동을 사용하여 페이지네이션과 UI 렌더링을 더 효과적으로 테스트할 수 있습니다.
frontend/src/components/stockgame/BettingHistory.jsx (1)
15-16: 페이지네이션 상태 관리가 올바릅니다.
currentPage상태와itemsPerPage상수를 사용한 페이지네이션 설정이 적절합니다.향후 유연성을 위해
itemsPerPage를 props로 받는 것을 고려하세요:-const BettingHistory = ({ type }) => { +const BettingHistory = ({ type, itemsPerPage = 5 }) => { const formatDate = (dateStr) => { const [year, month, day] = dateStr.split('-'); return `${year}년 ${month}월 ${day}일`; }; const [currentPage, setCurrentPage] = useState(1); - const itemsPerPage = 5;frontend/src/components/stockgame/Betting.jsx (2)
11-31: 네이티브 다이얼로그 대신 커스텀 모달을 사용하세요.
confirm()과alert()는 작동하지만 사용자 경험을 저해하고 브랜드 일관성이 없습니다.커스텀 모달 컴포넌트를 사용하는 것을 권장합니다:
// 예시: 커스텀 모달 라이브러리 또는 자체 구현 const onClickUpBet = () => { if (isBetting !== 'none') { showToast('이미 베팅하셨습니다.', 'warning'); return; } showConfirmModal({ title: '상승 베팅', message: '상승에 베팅하시겠습니까?', onConfirm: () => { setIsBetting('up'); // API 호출 추가 } }); };추가로 핸들러 로직에 중복이 있습니다. 리팩토링을 고려하세요:
const handleBet = (betType, message) => { if (isBetting !== 'none') { alert('이미 베팅하셨습니다.'); return; } if (confirm(message)) { setIsBetting(betType); // TODO: API 호출 추가 } }; const onClickUpBet = () => handleBet('up', '상승에 베팅하시겠습니까?'); const onClickDownBet = () => handleBet('down', '하락에 베팅하시겠습니까?');
57-63: 아이콘 문자 대신 실제 아이콘을 사용하세요.체크 표시로 텍스트 'v'를 사용하고 있습니다. 더 나은 시각적 표현과 접근성을 위해 실제 체크 아이콘을 사용하세요.
// 체크 아이콘을 import import checkIcon from '../../assets/check_icon.svg'; // JSX에서: {isBetting === 'up' && ( <div className={styles.upBetCheck}> <img src={checkIcon} alt="체크" /> </div> )}또는 SVG 아이콘 라이브러리 사용:
import { Check } from 'react-icons/fa'; // 또는 다른 아이콘 라이브러리 {isBetting === 'up' && ( <div className={styles.upBetCheck}> <Check size={10} /> </div> )}Also applies to: 73-81
frontend/src/components/stockgame/Pagination.jsx (1)
25-76: 접근성 속성을 추가하세요.페이지네이션 컴포넌트에 스크린 리더 사용자를 위한 접근성 속성이 누락되었습니다.
다음과 같이 접근성을 개선하세요:
- <div className={styles.pagination}> + <nav className={styles.pagination} role="navigation" aria-label="페이지네이션"> <button className={styles.arrow} onClick={() => handleClick(currentPage - 1)} disabled={currentPage === 1} + aria-label="이전 페이지" > < 이전 </button> ... {pages.map((page) => ( <button key={page} className={`${styles.page} ${ page === currentPage ? styles.active : '' }`} onClick={() => handleClick(page)} + aria-label={`${page}페이지`} + aria-current={page === currentPage ? 'page' : undefined} > {page} </button> ))} ... <button className={styles.arrow} onClick={() => handleClick(currentPage + 1)} disabled={currentPage === totalPages} + aria-label="다음 페이지" > 다음 > </button> - </div> + </nav>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
frontend/src/components/stockgame/Betting.jsx(3 hunks)frontend/src/components/stockgame/Betting.module.css(3 hunks)frontend/src/components/stockgame/BettingHistory.jsx(2 hunks)frontend/src/components/stockgame/BettingHistory.module.css(1 hunks)frontend/src/components/stockgame/Pagination.jsx(1 hunks)frontend/src/components/stockgame/Pagination.module.css(1 hunks)frontend/src/pages/StockGame.module.css(1 hunks)frontend/src/utils/dailyBettingHistory.js(1 hunks)frontend/src/utils/weeklyBettingHistory.js(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
frontend/src/components/stockgame/Pagination.jsx (1)
frontend/src/components/stockgame/BettingHistory.jsx (2)
totalPages(26-26)currentPage(15-15)
frontend/src/components/stockgame/Betting.jsx (1)
frontend/src/utils/bettingInfo.js (4)
mockDailyBet(1-9)mockDailyBet(1-9)mockWeeklyBet(11-19)mockWeeklyBet(11-19)
frontend/src/components/stockgame/BettingHistory.jsx (3)
frontend/src/utils/weeklyBettingHistory.js (2)
weeklyBettingHistory(1-134)weeklyBettingHistory(1-134)frontend/src/utils/dailyBettingHistory.js (2)
dailyBettingHistory(1-794)dailyBettingHistory(1-794)frontend/src/components/stockgame/Pagination.jsx (1)
Pagination(3-77)
🔇 Additional comments (14)
frontend/src/pages/StockGame.module.css (1)
51-51: 간격 조정이 새로운 UI 요소를 수용합니다.
gap을 10px에서 30px으로 증가시킨 것은 Betting.jsx에 추가된 취소 버튼과 활성 상태 표시기를 위한 공간을 확보하는 데 적합합니다.frontend/src/components/stockgame/BettingHistory.jsx (3)
19-21: 타입 변경 시 페이지 초기화가 올바르게 구현되었습니다.
typeprop이 변경될 때currentPage를 1로 리셋하는 것은 주간/일간 베팅 전환 시 사용자 경험을 위한 올바른 접근입니다.
26-36: 페이지네이션 계산 로직이 정확합니다.
totalPages계산,currentData슬라이싱,handlePageChange핸들러가 모두 올바르게 구현되었습니다.
83-89: Pagination 컴포넌트 통합이 적절합니다.Pagination 컴포넌트에 필요한 모든 props(
currentPage,totalPages,onPageChange)를 올바르게 전달하고 있습니다.frontend/src/components/stockgame/Betting.module.css (4)
12-12: 상대 위치 지정이 올바르게 추가되었습니다.
position: relative를 추가하여 내부의 절대 위치 요소(취소 버튼)를 위한 컨테이너 역할을 하도록 합니다.
82-101: 상승 베팅 활성 상태 스타일이 잘 구현되었습니다.
position: relative,.upActive보더,.upBetCheck체크 표시의 조합이 활성 베팅 상태를 명확하게 시각화합니다.
115-134: 하락 베팅 활성 상태 스타일이 잘 구현되었습니다.상승 베팅과 일관된 패턴으로 하락 베팅의 활성 상태를 표시합니다. 색상 구분(#ff6348)이 명확합니다.
136-145: 취소 버튼 위치와 스타일이 적절합니다.절대 위치(
bottom: 15px,right: 30px)를 사용하여 카드 하단 우측에 취소 옵션을 배치한 것이 UI/UX 관점에서 적절합니다.frontend/src/components/stockgame/Pagination.module.css (1)
1-35: 페이지네이션 스타일이 깔끔하고 접근성이 좋습니다.새로운 Pagination.module.css가 잘 구성되어 있습니다:
- Flexbox 레이아웃으로 중앙 정렬
- 버튼에 적절한 패딩과 border-radius
- 비활성화 상태에
cursor: not-allowed사용- 활성 페이지를 위한 명확한 시각적 구분
- 부드러운 전환 효과
frontend/src/components/stockgame/Betting.jsx (3)
8-8: 베팅 상태 관리가 적절히 초기화되었습니다.
isBetting상태를'none'으로 초기화하여 세 가지 상태('none', 'up', 'down')를 관리하는 것이 적절합니다.
11-31: API 통합을 위한 준비를 확인하세요.현재 구현은 로컬 상태만 업데이트합니다. 실제 베팅을 서버에 저장하는 API 호출이 필요합니다. TODO 주석을 추가하거나 다음 단계로 API 통합을 계획하고 있는지 확인하세요.
API 엔드포인트가 준비되어 있나요? 다음과 같은 호출이 필요합니다:
const onClickUpBet = async () => { if (isBetting !== 'none') { alert('이미 베팅하셨습니다.'); return; } if (confirm('상승에 베팅하시겠습니까?')) { try { await api.placeBet({ type: 'up', period, date: mockBettingInfo.date }); setIsBetting('up'); } catch (error) { alert('베팅에 실패했습니다.'); } } };
84-88: 취소 기능이 잘 구현되었습니다.
isBetting !== 'none'일 때만 취소 버튼을 조건부 렌더링하는 것이 적절합니다. 사용자에게 명확한 시각적 피드백을 제공합니다.frontend/src/components/stockgame/Pagination.jsx (2)
3-7: 페이지 검증 로직이 정확합니다.유효하지 않은 페이지 번호에 대한 방어 로직이 올바르게 구현되어 있습니다.
9-21: 슬라이딩 윈도우 계산 로직이 올바릅니다.최대 5개의 페이지를 표시하는 윈도우가 현재 페이지를 중심으로 정확하게 계산되며, 시작과 끝 경계에서의 엣지 케이스도 적절히 처리됩니다.
| <button className={styles.page} onClick={() => handleClick(1)}> | ||
| 1 | ||
| </button> | ||
| {totalPages > 10 && <span className={styles.ellipsis}>...</span>} |
There was a problem hiding this comment.
말줄임표 표시 조건을 의미적으로 개선하세요.
현재 totalPages > 10 조건은 페이지 간 실제 간격이 아닌 전체 페이지 수만 확인합니다. 말줄임표는 표시되는 페이지 사이에 숨겨진 페이지가 있을 때만 나타나야 합니다.
다음 diff를 적용하여 조건을 개선하세요:
- {totalPages > 10 && <span className={styles.ellipsis}>...</span>}
+ {pages[0] > 2 && <span className={styles.ellipsis}>...</span>}그리고:
- {totalPages > 10 && <span className={styles.ellipsis}>...</span>}
+ {pages[pages.length - 1] < totalPages - 1 && <span className={styles.ellipsis}>...</span>}Also applies to: 58-58
🤖 Prompt for AI Agents
In frontend/src/components/stockgame/Pagination.jsx around lines 40 and 58, the
ellipsis display currently uses the semantic-less check `totalPages > 10`;
change it to show ellipses only when there are hidden pages outside the
displayed range: use the component's computed startPage and endPage (or the
equivalent variables that determine the visible page window) and render a
leading ellipsis only when startPage > 1 and a trailing ellipsis only when
endPage < totalPages so ellipses appear only when pages are actually hidden.
1) 작업한 이슈번호
SISC1-77
2) 변경 요약 (What & Why)
3) 스크린샷/동영상 (UI 변경 시)
상승 베팅 시
페이지네이션


4) 상세 변경사항 (전부 다)
5) 참고사항
사이드바 수정하면서 CSS가 틀어진 거 같은데, 현재 올라와있는 사이드바 pr 적용하면 베팅 카드 피그마와 동일하게 디자인되어 있습니다.
사이드바 pr 머지 후, 다시 스타일 수정할 예정입니다.
Summary by CodeRabbit
새로운 기능