Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces basketball-specific game pages and a new ScoreBoard component to display scores by quarter. It refactors the routing system to include the sport type in game URLs (e.g., /games/basketball/:id) and adds the necessary API hooks and types for fetching quarter-level data. The review feedback focuses on improving the ScoreBoard component by using dynamic labels from the API, mapping scores more safely using team IDs, and consolidating the layout into a single table for better accessibility. Additionally, it is recommended to use absolute paths for routing consistency across the application.
|
|
||
| const [homeTeam, awayTeam] = gameInfo.gameTeams; | ||
|
|
||
| const labels = quarterScores.length === 5 ? [...BASE_LABELS, 'OT'] : BASE_LABELS; |
There was a problem hiding this comment.
| const scores = quarterScores.reduce( | ||
| (acc, { scores }, index) => { | ||
| const [home, away] = scores; | ||
| acc.home[index] = home.score; | ||
| acc.away[index] = away.score; | ||
|
|
||
| return acc; | ||
| }, | ||
| { home: Array(labels.length).fill(null), away: Array(labels.length).fill(null) }, | ||
| ); |
There was a problem hiding this comment.
배열 구조 분해 할당([home, away] = scores)은 API에서 반환하는 팀의 순서에 의존하므로 위험할 수 있습니다. homeTeam과 awayTeam의 gameTeamId를 사용하여 명확하게 매칭하는 것이 좋습니다.
const homeScores = quarterScores.map(q => q.scores.find(s => s.gameTeamId === homeTeam.gameTeamId)?.score ?? '-');
const awayScores = quarterScores.map(q => q.scores.find(s => s.gameTeamId === awayTeam.gameTeamId)?.score ?? '-');
| <div className="mb-4 flex justify-center px-4 text-sm"> | ||
| <div className="grid w-1/5 shrink-0 grid-rows-[auto_auto_auto]"> | ||
| <div className="font-semibold text-greyscale-500">팀명</div> | ||
| <div className="pt-2">{homeTeam.gameTeamName}</div> | ||
| <div>{awayTeam.gameTeamName}</div> | ||
| </div> | ||
|
|
||
| <table className="w-3/5 border-collapse text-center"> | ||
| <thead> | ||
| <tr className="text-greyscale-500"> | ||
| {labels.map((label) => ( | ||
| <th className="font-semibold" key={label}> | ||
| {label} | ||
| </th> | ||
| ))} | ||
| <th className="text-blue-600">총점</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| <tr> | ||
| {labels.map((label, index) => ( | ||
| <td className="pt-2" key={`home-${label}`}> | ||
| {scores.home[index] ?? '-'} | ||
| </td> | ||
| ))} | ||
| <td className="pt-2 text-blue-600">{homeTeam.score}</td> | ||
| </tr> | ||
| <tr> | ||
| {labels.map((label, index) => ( | ||
| <td key={`away-${label}`}>{scores.away[index] ?? '-'}</td> | ||
| ))} | ||
| <td className="text-blue-600">{awayTeam.score}</td> | ||
| </tr> | ||
| </tbody> | ||
| <caption className="sr-only">스코어보드 경기현황</caption> | ||
| </table> | ||
| </div> |
| onBroadcastClick={() => router.push(link)} | ||
| onCheerClick={() => router.push(`/${link}?cheer=1`)} |
✅ 작업 내용
UI
URL
📝 참고 자료
♾️ 기타