Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces multi-sport support, specifically adding Basketball functionality alongside Soccer. Key changes include updating API types and queries to support sport-specific data, refactoring routing to include sport categories in URLs, and implementing a new basketball scoreboard. Review feedback identified critical routing issues where relative paths could lead to 404 errors and suggested improvements for the basketball scoreboard, such as robust team-to-score matching and dynamic handling of multiple overtime periods.
I am having trouble creating individual review comments. Click here to see my feedback.
apps/spectator/src/app/games/basketball/_components/score-board.tsx (21-23)
현재 구현은 scores 배열의 첫 번째 요소가 홈 팀, 두 번째 요소가 어웨이 팀이라고 가정하고 있습니다. 하지만 API 응답에서 팀의 순서가 항상 일정하다는 보장이 없으므로, gameTeamId를 사용하여 각 팀의 점수를 정확하게 매칭하는 것이 안전합니다.
const home = scores.find(s => s.gameTeamId === homeTeam.gameTeamId);
const away = scores.find(s => s.gameTeamId === awayTeam.gameTeamId);
acc.home[index] = home?.score ?? null;
acc.away[index] = away?.score ?? null;
apps/spectator/src/app/(home)/_components/tab.tsx (117-127)
routes.game 함수가 반환하는 경로 문자열에는 시작 슬래시(/)가 포함되어 있지 않습니다. 이를 Link의 href나 router.push에 그대로 사용하면 현재 페이지 경로를 기준으로 하는 상대 경로로 동작하여, 홈 페이지가 아닌 곳에서 클릭 시 404 오류가 발생할 수 있습니다. 모든 이동 경로 앞에 /를 추가하여 절대 경로를 보장해야 합니다.
<Link href={`/${link}`} className="column flex-1 gap-2">
<GameCard.Team index={1} />
<GameCard.Team index={2} />
</Link>
<div role="separator" className="w-px bg-gray-100" />
<GameCard.Actions
onBroadcastClick={() => router.push(`/${link}`)}
onCheerClick={() => router.push(`/${link}?cheer=1`)}
/>
apps/spectator/src/app/leagues/[id]/_components/game-list.tsx (55-56)
link 변수를 사용하여 페이지를 이동할 때 절대 경로를 보장하기 위해 앞에 슬래시(/)를 추가해야 합니다. 현재 onBroadcastClick에는 슬래시가 누락되어 있고, onCheerClick에는 포함되어 있어 일관성이 부족하며 잠재적인 라우팅 오류의 원인이 됩니다.
onBroadcastClick={() => router.push(`/${link}`)}
onCheerClick={() => router.push(`/${link}?cheer=1`)}
apps/spectator/src/app/teams/[id]/_components/team-info.tsx (39-53)
routes.game에서 생성된 경로는 절대 경로가 아니므로, Link와 router.push에서 사용할 때 앞에 /를 추가해야 합니다. 현재 팀 상세 페이지(/teams/[id])에서 이 링크를 클릭하면 상대 경로로 인식되어 잘못된 주소로 이동하게 됩니다.
<Link href={`/${link}`} className="column flex-1 gap-2">
<GameCard.Team index={1} />
<GameCard.Team index={2} />
</Link>
<div role="separator" className="w-px bg-gray-100" />
<GameCard.Actions
onStatsClick={state === 'FINISHED' ? () => router.push(`/${link}`) : undefined}
onBroadcastClick={
state !== 'FINISHED' ? () => router.push(`/${link}`) : undefined
}
onCheerClick={
state !== 'FINISHED' ? () => router.push(`/${link}?cheer=1`) : undefined
}
/>
apps/spectator/src/app/games/basketball/_components/score-board.tsx (18)
쿼터 라벨 생성 로직이 최대 5개(4쿼터 + 연장 1회)로 고정되어 있습니다. 농구 경기는 2차 이상의 연장전이 발생할 수 있으므로, quarterScores 배열의 길이에 따라 라벨을 동적으로 생성하도록 개선하는 것이 좋습니다.
const labels = quarterScores.map((_, index) => {
if (index < 4) return `${index + 1}Q`;
return index === 4 ? 'OT' : `OT${index - 3}`;
});
✅ 작업 내용
📝 참고 자료
♾️ 기타