Conversation
Deploying mateball-client with
|
| Latest commit: |
8849960
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://937009a3.mateball-client.pages.dev |
| Branch Preview URL: | https://fix--409-home.mateball-client.pages.dev |
개요홈 페이지를 재구조화하여 매칭 목록 탭 기능을 제거하고 경기 카드 기반의 새로운 변경 사항
예상 코드 리뷰 난이도🎯 3 (보통) | ⏱️ ~20분 관련 가능성 있는 PR
검수자
축하 시
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
|
MATEBALL-STORYBOOK |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/pages/home/components/calendar-section.tsx (1)
5-21: 🛠️ Refactor suggestion | 🟠 MajorProps interface에 정의된
activeType과onTabChange가 사용되지 않습니다.
CalendarSectionProps에activeType과onTabChange가 정의되어 있지만, 컴포넌트에서 destructure하거나 사용하지 않습니다. 사용하지 않는 props와 관련 import를 제거하세요.♻️ 미사용 props 제거
import WeekCalendar from '@components/calendar/week-calendar'; -import type { TabType } from '@components/tab/tab/constants/tab-type'; import CalendarButton from '@pages/home/components/calendar-button'; interface CalendarSectionProps { - activeType: TabType; - onTabChange: (type: TabType) => void; selectedDate: Date; onDateChange: (date: Date) => void; baseWeekDate: Date; onOpenBottomSheet: () => void; entryDate: Date; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/home/components/calendar-section.tsx` around lines 5 - 21, The CalendarSectionProps interface declares activeType and onTabChange but the CalendarSection component never destructures or uses them; remove the unused props by deleting activeType and onTabChange from the CalendarSectionProps definition and update any call sites if necessary, and also remove any related unused imports or references tied to those symbols (CalendarSectionProps, activeType, onTabChange, and the CalendarSection component signature) so the prop type and component props stay in sync.src/shared/components/calendar/week-calendar.tsx (1)
26-37:⚠️ Potential issue | 🟠 Major비활성화된 날짜에서 클릭 이벤트가 차단되지 않습니다.
calendarDayVariants의disabledvariant는 시각적 스타일(cursor-not-allowed text-gray-500)만 적용하고pointer-events-none이나<button disabled>속성을 포함하지 않습니다. 따라서 사용자가 과거 날짜를 클릭하면 여전히onChange(day)가 호출되어entryDate이전 날짜를 선택할 수 있습니다.🐛 클릭 차단 로직 추가 제안
const handleClick = (day: Date) => { + if (isBefore(startOfDay(day), startOfDay(entryDate))) { + return; + } onChange(day); };또는 버튼에
disabled속성을 추가하세요:<button key={day.toISOString()} type="button" + disabled={isDisabled} onClick={() => handleClick(day)}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/shared/components/calendar/week-calendar.tsx` around lines 26 - 37, The button allows clicks even when `isDisabled` is true; prevent selection by short-circuiting clicks and/or disabling the button: update the click handling so `handleClick(day)` first checks `isDisabled` and returns early if true, and/or add the `disabled` attribute to the rendered <button> and include `pointer-events-none` in `calendarDayVariants` when `disabled` is true; ensure the existing `onChange(day)` call is only invoked when not disabled so past dates cannot be selected.
🧹 Nitpick comments (3)
src/pages/home/components/top-section.tsx (1)
2-3: TODO 추적: 유저 수 API 연결 필요하드코딩된
MOCK_USERS = 124값이 TODO 주석과 함께 남아 있습니다. API 연결 작업이 추후 진행될 예정인지 확인 부탁드립니다.이 작업을 추적하기 위해 별도 이슈를 생성해 드릴까요?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/home/components/top-section.tsx` around lines 2 - 3, The hardcoded MOCK_USERS = 124 in top-section.tsx should be replaced with a real data source: either accept a usersCount prop on the TopSection component (prop name usersCount) and use that instead of MOCK_USERS, or implement a small data fetch inside TopSection (call the users count API, handle loading/error states, and set state via useEffect) and remove the mock constant; if you can't implement the API now, create a tracked issue and replace the constant with a clearly named TODO constant (e.g., USERS_COUNT_PLACEHOLDER) and add a comment linking the issue ID so the future work is discoverable.src/pages/home/home.tsx (1)
66-74: 사용되지 않는 props가CalendarSection에 전달되고 있습니다.
activeType과onTabChange가CalendarSection에 전달되지만,CalendarSection컴포넌트에서 destructure하거나 사용하지 않습니다. props interface에서 제거하거나, 필요 없다면 여기서 전달을 중단하세요.♻️ 미사용 props 제거 제안
<CalendarSection - activeType={activeType} - onTabChange={changeTab} selectedDate={selectedDate} onDateChange={setSelectedDate} baseWeekDate={baseWeekDate} onOpenBottomSheet={() => setIsCalendarBottomSheetOpen(true)} entryDate={entryDate} />그리고 Line 22에서도 사용하지 않는다면:
-const { activeType, changeTab } = useTabState(); +const { activeType } = useTabState();
activeType은 Line 87GameMatchBottomSheet에서 여전히 사용되므로 유지합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/home/home.tsx` around lines 66 - 74, CalendarSection is receiving props activeType and onTabChange (passed as activeType and changeTab) that CalendarSection does not destructure or use; either remove these props from the JSX usage (the CalendarSection element) or add them to CalendarSection's props interface and use them inside CalendarSection; specifically, update the CalendarSection call in home.tsx to stop passing activeType and onTabChange (changeTab) if they are unused, or update the CalendarSection component to accept and handle activeType and onTabChange (e.g., destructure them in its props signature and implement the tab logic) — note activeType is still used by GameMatchBottomSheet elsewhere so keep it in the parent state if needed.src/pages/home/utils/game-card-renderers.tsx (1)
35-37: TODO: 버튼에onClick핸들러가 없어 기능하지 않습니다."메이트 만나기" 버튼에 네비게이션이 연결되지 않아 사용자가 클릭해도 아무 동작이 없습니다. TODO 주석이 있으니 추후 구현 예정인 것으로 보이지만, 이 PR에서 해결하거나 이슈로 추적하는 것을 권장합니다.
이 기능 구현을 위해 새 이슈를 생성해 드릴까요?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/home/utils/game-card-renderers.tsx` around lines 35 - 37, The "메이트 만나기" Button in game-card-renderers.tsx is missing an onClick handler so it does nothing; add an onClick prop to the Button (the element with label "메이트 만나기") that invokes navigation or a provided callback: either call the router's navigate (e.g., via useNavigate in the containing component) to the appropriate route or forward a handler passed from the parent (e.g., onMeetMate) so the click triggers navigation; if you don't implement navigation here, open a tracking issue and replace the TODO comment with a clear TODO+issue reference.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/home/components/calendar-button.tsx`:
- Line 11: In the CalendarButton component's className string (the JSX element
with className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem]
rounded-[8px]p-[0.8rem]"), there's a missing space between "rounded-[8px]" and
"p-[0.8rem]"; fix it by inserting a space so both Tailwind utilities apply
(i.e., change the className to include "rounded-[8px] p-[0.8rem]").
In `@src/pages/home/utils/game-card-renderers.tsx`:
- Around line 21-31: The code unsafely casts game.awayTeam and game.homeTeam to
ChipColor (using Chip with bgColor/textColor set to game.awayTeam as ChipColor),
which can break styles if the API returns unexpected team names; update the
renderer to validate the team strings against the allowed chipVariantOptions (or
reuse the validation logic from ChipList) and provide a safe fallback (e.g., a
default ChipColor or an "unknown" variant) before passing values to Chip
(referencing Chip, ChipColor, chipVariantOptions, ChipList, game.awayTeam,
game.homeTeam); ensure the validation/fallback is applied for both away and home
team values so class-variance-authority always receives a valid variant.
In `@src/shared/components/ui/empty-view.tsx`:
- Line 16: The h3 in the EmptyView component uses text-gray-100 which matches
the page background and is invisible; update the h3 className in the EmptyView
(the element rendering <h3 className="head_20_sb text-gray-100">{text}</h3>) to
a darker gray (e.g., text-gray-500 or text-gray-700) so the main title is
readable (keep the existing typography class head_20_sb and only replace
text-gray-100).
---
Outside diff comments:
In `@src/pages/home/components/calendar-section.tsx`:
- Around line 5-21: The CalendarSectionProps interface declares activeType and
onTabChange but the CalendarSection component never destructures or uses them;
remove the unused props by deleting activeType and onTabChange from the
CalendarSectionProps definition and update any call sites if necessary, and also
remove any related unused imports or references tied to those symbols
(CalendarSectionProps, activeType, onTabChange, and the CalendarSection
component signature) so the prop type and component props stay in sync.
In `@src/shared/components/calendar/week-calendar.tsx`:
- Around line 26-37: The button allows clicks even when `isDisabled` is true;
prevent selection by short-circuiting clicks and/or disabling the button: update
the click handling so `handleClick(day)` first checks `isDisabled` and returns
early if true, and/or add the `disabled` attribute to the rendered <button> and
include `pointer-events-none` in `calendarDayVariants` when `disabled` is true;
ensure the existing `onChange(day)` call is only invoked when not disabled so
past dates cannot be selected.
---
Nitpick comments:
In `@src/pages/home/components/top-section.tsx`:
- Around line 2-3: The hardcoded MOCK_USERS = 124 in top-section.tsx should be
replaced with a real data source: either accept a usersCount prop on the
TopSection component (prop name usersCount) and use that instead of MOCK_USERS,
or implement a small data fetch inside TopSection (call the users count API,
handle loading/error states, and set state via useEffect) and remove the mock
constant; if you can't implement the API now, create a tracked issue and replace
the constant with a clearly named TODO constant (e.g., USERS_COUNT_PLACEHOLDER)
and add a comment linking the issue ID so the future work is discoverable.
In `@src/pages/home/home.tsx`:
- Around line 66-74: CalendarSection is receiving props activeType and
onTabChange (passed as activeType and changeTab) that CalendarSection does not
destructure or use; either remove these props from the JSX usage (the
CalendarSection element) or add them to CalendarSection's props interface and
use them inside CalendarSection; specifically, update the CalendarSection call
in home.tsx to stop passing activeType and onTabChange (changeTab) if they are
unused, or update the CalendarSection component to accept and handle activeType
and onTabChange (e.g., destructure them in its props signature and implement the
tab logic) — note activeType is still used by GameMatchBottomSheet elsewhere so
keep it in the parent state if needed.
In `@src/pages/home/utils/game-card-renderers.tsx`:
- Around line 35-37: The "메이트 만나기" Button in game-card-renderers.tsx is missing
an onClick handler so it does nothing; add an onClick prop to the Button (the
element with label "메이트 만나기") that invokes navigation or a provided callback:
either call the router's navigate (e.g., via useNavigate in the containing
component) to the appropriate route or forward a handler passed from the parent
(e.g., onMeetMate) so the click triggers navigation; if you don't implement
navigation here, open a tracking issue and replace the TODO comment with a clear
TODO+issue reference.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b3905291-610b-4710-b70d-abe96f9abf0c
⛔ Files ignored due to path filters (1)
src/shared/assets/svgs/empty-2.svgis excluded by!**/*.svg
📒 Files selected for processing (14)
src/pages/home/components/calendar-button.tsxsrc/pages/home/components/calendar-section.tsxsrc/pages/home/components/game-list-section.tsxsrc/pages/home/components/match-list-section.tsxsrc/pages/home/components/top-section.tsxsrc/pages/home/home.tsxsrc/pages/home/utils/game-card-renderers.tsxsrc/shared/apis/game/game-queries.tssrc/shared/components/calendar/constants/CALENDAR.tssrc/shared/components/calendar/month-calendar.tsxsrc/shared/components/calendar/week-calendar.tsxsrc/shared/components/ui/empty-view.tsxsrc/shared/styles/theme.csssrc/stories/foundations/tokens/colors.ts
💤 Files with no reviewable changes (1)
- src/pages/home/components/match-list-section.tsx
| <button | ||
| type="button" | ||
| className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem] rounded-[8px] bg-gray-900 p-[0.8rem]" | ||
| className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem] rounded-[8px]p-[0.8rem]" |
There was a problem hiding this comment.
Tailwind 클래스명 오타: 공백 누락
rounded-[8px]p-[0.8rem]에서 클래스 사이에 공백이 누락되었습니다. 이로 인해 rounded-[8px]과 p-[0.8rem] 모두 적용되지 않습니다.
🐛 수정 제안
<button
type="button"
- className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem] rounded-[8px]p-[0.8rem]"
+ className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem] rounded-[8px] p-[0.8rem]"
onClick={onOpenBottomSheet}
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem] rounded-[8px]p-[0.8rem]" | |
| <button | |
| type="button" | |
| className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem] rounded-[8px] p-[0.8rem]" | |
| onClick={onOpenBottomSheet} | |
| > |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/pages/home/components/calendar-button.tsx` at line 11, In the
CalendarButton component's className string (the JSX element with
className="h-[3.2rem] flex-row-center cursor-pointer gap-[0.8rem]
rounded-[8px]p-[0.8rem]"), there's a missing space between "rounded-[8px]" and
"p-[0.8rem]"; fix it by inserting a space so both Tailwind utilities apply
(i.e., change the className to include "rounded-[8px] p-[0.8rem]").
| <Chip | ||
| label={game.awayTeam} | ||
| bgColor={game.awayTeam as ChipColor} | ||
| textColor={game.awayTeam as ChipColor} | ||
| /> | ||
| <p className="body_16_m text-gray-white">vs</p> | ||
| <Chip | ||
| label={game.homeTeam} | ||
| bgColor={game.homeTeam as ChipColor} | ||
| textColor={game.homeTeam as ChipColor} | ||
| /> |
There was a problem hiding this comment.
ChipColor로의 unsafe cast - API에서 예상치 못한 팀명이 오면 스타일이 깨집니다.
game.awayTeam as ChipColor와 game.homeTeam as ChipColor는 API 응답값이 chipVariantOptions에 정의된 유효한 팀명(두산, LG, 롯데, NC, KIA, 한화, KT, 삼성, SSG, 키움)과 일치한다고 가정합니다. 유효하지 않은 값이 들어오면 class-variance-authority가 스타일을 적용하지 못해 깨진 UI가 렌더링됩니다.
ChipList 컴포넌트(src/shared/components/chip/chip-list.tsx)처럼 유효성 검사를 추가하거나, fallback 처리를 권장합니다.
🛡️ 유효성 검사 또는 fallback 추가 제안
+import { chipVariantOptions } from '@components/chip/styles/chip-variants';
+
+const getChipColor = (team: string): ChipColor => {
+ return Object.keys(chipVariantOptions.bgColor).includes(team)
+ ? (team as ChipColor)
+ : 'default';
+};
+
export const renderGameCard = (game: GameCardItem) => (
// ...
<Chip
label={game.awayTeam}
- bgColor={game.awayTeam as ChipColor}
- textColor={game.awayTeam as ChipColor}
+ bgColor={getChipColor(game.awayTeam)}
+ textColor={getChipColor(game.awayTeam)}
/>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/pages/home/utils/game-card-renderers.tsx` around lines 21 - 31, The code
unsafely casts game.awayTeam and game.homeTeam to ChipColor (using Chip with
bgColor/textColor set to game.awayTeam as ChipColor), which can break styles if
the API returns unexpected team names; update the renderer to validate the team
strings against the allowed chipVariantOptions (or reuse the validation logic
from ChipList) and provide a safe fallback (e.g., a default ChipColor or an
"unknown" variant) before passing values to Chip (referencing Chip, ChipColor,
chipVariantOptions, ChipList, game.awayTeam, game.homeTeam); ensure the
validation/fallback is applied for both away and home team values so
class-variance-authority always receives a valid variant.
| <Icon name={iconName} size={8.4} /> | ||
| <div className="flex-col-center gap-[0.8rem] text-center"> | ||
| <h3 className="head_20_sb">{text}</h3> | ||
| <h3 className="head_20_sb text-gray-100">{text}</h3> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: EmptyView 컴포넌트의 사용처와 배경색 확인
# EmptyView를 사용하는 파일 검색
rg -n -A 5 -B 2 'EmptyView' --type=tsx --type=tsRepository: MATEBALL/MATEBALL-CLIENT
Length of output: 95
🏁 Script executed:
#!/bin/bash
# 올바른 방식으로 EmptyView 사용처 검색
rg 'EmptyView' -A 5 -B 2Repository: MATEBALL/MATEBALL-CLIENT
Length of output: 3977
🏁 Script executed:
#!/bin/bash
# empty-view.tsx 파일 내용 확인
cat -n src/shared/components/ui/empty-view.tsxRepository: MATEBALL/MATEBALL-CLIENT
Length of output: 856
🏁 Script executed:
#!/bin/bash
# 테마 파일에서 text-gray-100 색상값 확인
find . -type f -name "*.css" -o -name "*.ts" -o -name "*.js" | xargs grep -l "gray-100\|f6f7f9" 2>/dev/null | head -20Repository: MATEBALL/MATEBALL-CLIENT
Length of output: 204
🏁 Script executed:
#!/bin/bash
# tailwind 설정 파일 확인
find . -type f -name "tailwind.config.*" | xargs catRepository: MATEBALL/MATEBALL-CLIENT
Length of output: 50
🏁 Script executed:
#!/bin/bash
# theme.css 파일 내용 확인
cat -n src/shared/styles/theme.css | head -100Repository: MATEBALL/MATEBALL-CLIENT
Length of output: 3365
🏁 Script executed:
#!/bin/bash
# colors.ts 파일 내용 확인
cat -n src/stories/foundations/tokens/colors.tsRepository: MATEBALL/MATEBALL-CLIENT
Length of output: 2615
🏁 Script executed:
#!/bin/bash
# button-variants.ts에서 텍스트 색상 사용 패턴 확인
cat -n src/shared/components/button/button/styles/button-variants.ts | grep -A 2 -B 2 "text-gray"Repository: MATEBALL/MATEBALL-CLIENT
Length of output: 460
h3 텍스트 색상이 배경과 동일하여 가시성 문제 발생
text-gray-100 (#f6f7f9)은 페이지 배경 색상과 정확히 동일합니다. EmptyView가 사용되는 모든 페이지에서 주 제목 텍스트가 완전히 보이지 않습니다.
부제목(p)은 올바르게 text-gray-500 (#acadae)을 사용하여 가독성이 있으므로, h3도 동일하게 text-gray-500 이상의 어두운 색상(text-gray-700, text-gray-800 등)으로 변경해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/shared/components/ui/empty-view.tsx` at line 16, The h3 in the EmptyView
component uses text-gray-100 which matches the page background and is invisible;
update the h3 className in the EmptyView (the element rendering <h3
className="head_20_sb text-gray-100">{text}</h3>) to a darker gray (e.g.,
text-gray-500 or text-gray-700) so the main title is readable (keep the existing
typography class head_20_sb and only replace text-gray-100).
#️⃣ Related Issue
Closes #409
☀️ New-insight
𝟭. "오늘 기준"과 "진입 시점 기준"을 명확하게 하기 위해
new Date()대신 진입 시점의 기준값을 상태로 관리하는 것이 더 안정적이다.𝟮. 리액트쿼리에서 쿼리키가 변경될 때 발생하는 미세한 깜빡임을
placeholderData: keepPreviousData를 통해 쉽게 개선할 수 있다.💎 PR Point
𝟭. 홈 화면 변경
𝟮. 캘린더 선택 로직 개선
𝟯. React Query 깜빡임 개선
placeholderData: keepPreviousData를 통해 이전 데이터를 유지하여 UI 깜빡임 감소📸 Screenshot
Summary by CodeRabbit
릴리스 노트