Skip to content

fix: SP2 마이 페이지 및 매칭 조건 수정 페이지 수정#408

Open
bongtta wants to merge 14 commits intodevelopfrom
fix/#399/mypage
Open

fix: SP2 마이 페이지 및 매칭 조건 수정 페이지 수정#408
bongtta wants to merge 14 commits intodevelopfrom
fix/#399/mypage

Conversation

@bongtta
Copy link
Contributor

@bongtta bongtta commented Mar 23, 2026

#️⃣ Related Issue

Closes #399

☀️ New-insight

  • 숫자 입력 처리 시 number state보다 string state로 관리한 뒤 변환하는 것이 UX 및 validation 처리에 더 유리하다

💎 PR Point

  • 기존 Card 컴포넌트를 확장하지 않고, ProfileCard를 별도 컴포넌트로 분리
  • 매칭 조건 수정 페이지에서 성별 섹션 삭제, 평균 직관 수 섹션 추가
  • 매칭 수, 평균 직관 수 api 연결 완료
  • 매칭 조건 수정(평균 직관 수) api 연결 완료
  • 프로필 이미지 api는 머지 후 회원가입 페이지와 한번에 연결 예정

📸 Screenshot

스크린샷 2026-03-24 오전 1 32 03 스크린샷 2026-03-24 오전 1 32 28 스크린샷 2026-03-24 오전 1 39 58

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 프로필 카드에 매칭 횟수 및 평균 시즌 통계 표시 추가
    • 프로필 편집 페이지에 프로필 이미지 섹션 추가
  • Refactor

    • 매칭 조건에서 성별 선호도를 평균 직관 수로 변경
    • 매칭 조건 API 엔드포인트 및 요청 구조 업데이트
  • Style

    • 새로운 버튼 크기 및 색상 토큰 추가
    • UI 레이아웃 및 스타일 개선

@bongtta bongtta self-assigned this Mar 23, 2026
@bongtta bongtta requested a review from heesunee as a code owner March 23, 2026 16:45
@bongtta bongtta linked an issue Mar 23, 2026 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

Walkthrough

마이페이지 프로필 편집 기능을 개선하여 선호 성별 필드를 제거하고 평균 직관 수 필드를 추가하며, 프로필 이미지 영역을 추가합니다. 이에 따라 API 엔드포인트를 v3로 업그레이드하고 관련 타입, 상태 관리, UI 컴포넌트를 업데이트합니다.

Changes

Cohort / File(s) Summary
프로필 편집 페이지
src/pages/edit-profile/edit-profile.tsx
성별 선호도 상태 제거, avgSeason 입력 필드 추가, 프로필 이미지 섹션 UI 추가(TODO 주석 포함), 레이아웃 간격 조정.
프로필 카드 컴포넌트
src/pages/profile/components/profile-card.tsx
새로운 ProfileCard 컴포넌트 추가: 사용자 프로필 정보(닉네임, 이미지, 팀, 스타일)와 통계(매칭 수, 평균 직관 횟수) 표시, 프로필 수정 버튼으로 라우팅.
프로필 페이지
src/pages/profile/profile.tsx
Card + Button 조합을 ProfileCard 컴포넌트로 대체, 목 데이터로 매칭 수 및 평균 직관 횟수 전달, 레이아웃 갭 증가(1.6rem3.2rem).
API 타입 및 뮤테이션
src/shared/apis/user/user-mutations.ts, src/shared/types/user-types.ts, src/shared/constants/api.ts
genderPreference 필드를 avgSeason으로 변경, getMatchConditionResponsepostMatchConditionRequest 인터페이스 업데이트, API 엔드포인트 /v2/users/match-condition/v3/users/match-condition.
UI 컴포넌트 스타일
src/shared/components/button/button/styles/button-variants.ts, src/shared/components/chip/styles/chip-state-variants.ts
버튼에 새로운 S 사이즈 variant 추가(w-full px-[1.6rem] py-[0.6rem]), Chip 컴포넌트 outline 상태 스타일 최적화.
테마 및 유틸리티
src/shared/styles/theme.css, src/shared/styles/custom-utilities.css, src/stories/foundations/tokens/colors.ts
새로운 그레이스케일 색상 변수 --color-gray-950 (#333333) 추가, 새로운 유틸리티 클래스 .flex-row-evenly 추가.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • heesunee
  • Dubabbi

🐰 성별은 떠나고, 직관은 남는다네요,
프로필 이미지 반짝반짝, 평균 횟수 업업!
v3로 업그레이드된 API 통로,
마이페이지는 이제 더 멋있어요! ⚾✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 마이 페이지와 매칭 조건 수정 페이지의 수정 작업을 명확하게 설명하며, 변경사항의 핵심을 잘 반영합니다.
Linked Issues check ✅ Passed 모든 요구사항이 충족되었습니다: 프로필 이미지 영역 추가, 선호 성별 영역 삭제, 평균 직관 횟수 영역 추가가 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 #399 이슈의 범위 내에 있습니다. 색상 토큰, 유틸리티, 버튼 변형 등의 추가 변경사항들은 UI 구현을 지원하는 필수 스타일링 변경입니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/#399/mypage

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

MATEBALL-STORYBOOK
⚾ Storybook 배포가 완료되었습니다!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/shared/types/user-types.ts (1)

56-59: ⚠️ Potential issue | 🟡 Minor

매칭 조건 API 주석 버전/메서드를 현재 스펙으로 갱신해 주세요.

현재 주석이 /v2, post로 남아 있어 실제 구현(/v3, PATCH)과 불일치합니다.

📝 제안 수정안
 /**
  * 매칭 조건 조회
  * get
- * /v2/users/match-condition
+ * /v3/users/match-condition
  */
 export interface getMatchConditionResponse {
   team: string;
   teamAllowed: string | null;
   style: string;
   avgSeason: number;
 }

 /**
  * 매칭 조건 수정
- * post
- * /v2/users/match-condition
+ * patch
+ * /v3/users/match-condition
  */
 export interface postMatchConditionRequest {

Also applies to: 68-71

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/types/user-types.ts` around lines 56 - 59, Update the outdated API
comment blocks that describe "매칭 조건" to match the actual implementation: change
the path version from /v2 to /v3 and update the HTTP method from POST/GET
(whichever is currently written) to PATCH; locate the comment blocks labeled "매칭
조건 조회" (and the other occurrence around the second comment at lines 68-71) in
src/shared/types/user-types.ts and replace the incorrect version/method text so
the comments reflect the real endpoint (/v3/users/match-condition) and method
(PATCH), keeping any other descriptive text intact.
🧹 Nitpick comments (1)
src/pages/profile/components/profile-card.tsx (1)

18-19: onEditProfile prop이 선언되었지만 사용되지 않습니다.

ProfileCardPropsonEditProfile이 정의되어 있지만 (Line 15), 컴포넌트에서 destructure되지 않고 대신 내부적으로 useNavigate를 직접 사용합니다. 이는 컴포넌트의 재사용성을 제한합니다.

♻️ 권장 수정: prop을 통한 네비게이션 처리
-const ProfileCard = ({ nickname, imgUrl, team, style, matchCnt, avgSeason }: ProfileCardProps) => {
-  const navigate = useNavigate();
+const ProfileCard = ({ nickname, imgUrl, team, style, matchCnt, avgSeason, onEditProfile }: ProfileCardProps) => {
-            onClick={() => navigate(ROUTES.PROFILE_EDIT)}
+            onClick={onEditProfile}

이렇게 하면 useNavigateROUTES import도 제거할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/profile/components/profile-card.tsx` around lines 18 - 19, The
ProfileCard component currently ignores the onEditProfile prop defined in
ProfileCardProps and uses useNavigate/navigate internally; fix this by
destructuring onEditProfile from the ProfileCard props (alongside nickname,
imgUrl, team, style, matchCnt, avgSeason) and call onEditProfile from the
component's edit handler instead of calling navigate/ROUTES directly; remove the
useNavigate import and any ROUTES usage/imports, and ensure callers of
ProfileCard pass a handler when navigation/edit behavior is required.
🤖 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/profile/components/profile-card.tsx`:
- Around line 51-58: matchCnt와 avgSeason이 optional이라 값이 없을 때 "undefined"가 렌더링될 수
있으므로 ProfileCard 컴포넌트에서 matchCnt와 avgSeason에 기본값을 제공하도록 수정하세요; 예를 들어 props 구조분해할
때 또는 렌더링 위치(해당 <p> 요소들에서)에서 matchCnt와 avgSeason을 nullish 병합 연산자(또는 삼항)로 대체값을 넣어
안전하게 표시하도록 변경하고, 필요하면 컴포넌트의 기본 props 선언(defaultProps 또는 파라미터 기본값)을 추가해
undefined를 방지하세요 (참조 심볼: matchCnt, avgSeason, ProfileCard / profile-card.tsx).
- Around line 33-34: The code unsafely casts `team` and `style` to `ChipColor`
when rendering <Chip>, which can cause runtime styling errors if the API returns
unexpected values; create a type-safe mapper function (e.g.,
normalizeToChipColor or mapToChipVariant) that accepts the raw `team`/`style`
strings, checks them against the valid keys in `chipVariants` (or the
`ChipColor` union from src/shared/components/card/match-card/types/card.ts), and
returns a safe `ChipColor` fallback when no match is found, then use that mapper
when passing bgColor and textColor to the `Chip` component instead of `team as
ChipColor` and `style as ChipColor`.

In `@src/pages/profile/profile.tsx`:
- Around line 26-34: The passed onEditProfile prop is unused by ProfileCard;
update ProfileCard to accept and use this callback instead of internally calling
useNavigate: add onEditProfile to the component props/interface (e.g., in the
ProfileCardProps type), destructure onEditProfile in the ProfileCard function,
replace the internal navigate-based edit handler (the code that currently calls
navigate(...) inside ProfileCard) with a call to onEditProfile(), and remove the
internal useNavigate usage for that action; ensure the prop remains optional or
provide a safe no-op fallback if needed.

In `@src/shared/components/chip/styles/chip-state-variants.ts`:
- Line 11: The outline variant string (the value for the outline key in
chip-state-variants.ts currently "bg-gray-white text-main-900 outline-[1px]
outline-main-900") only sets outline-width and color but omits outline-style, so
add an outline-style utility such as outline-solid (or the shorthand outline) to
that class list so the border actually renders (update the outline value to
include outline-solid alongside outline-[1px] and outline-main-900).

---

Outside diff comments:
In `@src/shared/types/user-types.ts`:
- Around line 56-59: Update the outdated API comment blocks that describe "매칭
조건" to match the actual implementation: change the path version from /v2 to /v3
and update the HTTP method from POST/GET (whichever is currently written) to
PATCH; locate the comment blocks labeled "매칭 조건 조회" (and the other occurrence
around the second comment at lines 68-71) in src/shared/types/user-types.ts and
replace the incorrect version/method text so the comments reflect the real
endpoint (/v3/users/match-condition) and method (PATCH), keeping any other
descriptive text intact.

---

Nitpick comments:
In `@src/pages/profile/components/profile-card.tsx`:
- Around line 18-19: The ProfileCard component currently ignores the
onEditProfile prop defined in ProfileCardProps and uses useNavigate/navigate
internally; fix this by destructuring onEditProfile from the ProfileCard props
(alongside nickname, imgUrl, team, style, matchCnt, avgSeason) and call
onEditProfile from the component's edit handler instead of calling
navigate/ROUTES directly; remove the useNavigate import and any ROUTES
usage/imports, and ensure callers of ProfileCard pass a handler when
navigation/edit behavior is required.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 509fdf8a-bf66-4941-a351-77e80bf3b23f

📥 Commits

Reviewing files that changed from the base of the PR and between 18cce7d and a78de0a.

📒 Files selected for processing (11)
  • src/pages/edit-profile/edit-profile.tsx
  • src/pages/profile/components/profile-card.tsx
  • src/pages/profile/profile.tsx
  • src/shared/apis/user/user-mutations.ts
  • src/shared/components/button/button/styles/button-variants.ts
  • src/shared/components/chip/styles/chip-state-variants.ts
  • src/shared/constants/api.ts
  • src/shared/styles/custom-utilities.css
  • src/shared/styles/theme.css
  • src/shared/types/user-types.ts
  • src/stories/foundations/tokens/colors.ts

Comment on lines +33 to +34
<Chip label={team} bgColor={team as ChipColor} textColor={team as ChipColor} />
<Chip label={style} bgColor={style as ChipColor} textColor={style as ChipColor} />
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

as ChipColor 타입 캐스팅이 런타임 오류를 야기할 수 있습니다.

teamstyle 값을 ChipColor로 강제 캐스팅하고 있지만, API에서 반환되는 값이 chipVariants에 정의된 유효한 색상 키와 일치하지 않을 수 있습니다. 이 경우 스타일이 적용되지 않거나 예기치 않은 렌더링이 발생할 수 있습니다.

관련 코드 참조: src/shared/components/card/match-card/types/card.tsChipColor 타입 정의

♻️ 권장 수정: 타입 안전한 매핑 함수 사용
+// 유효한 ChipColor 매핑 (card.ts의 chipVariants 기반)
+const teamToChipColor: Record<string, ChipColor> = {
+  KIA: 'KIA',
+  삼성: '삼성',
+  // ... 다른 팀들 추가
+};
+
+const styleToChipColor: Record<string, ChipColor> = {
+  열정응원러: '열정응원러',
+  경기집중러: '경기집중러',
+  직관먹방러: '직관먹방러',
+};

-<Chip label={team} bgColor={team as ChipColor} textColor={team as ChipColor} />
-<Chip label={style} bgColor={style as ChipColor} textColor={style as ChipColor} />
+<Chip label={team} bgColor={teamToChipColor[team]} textColor={teamToChipColor[team]} />
+<Chip label={style} bgColor={styleToChipColor[style]} textColor={styleToChipColor[style]} />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/profile/components/profile-card.tsx` around lines 33 - 34, The code
unsafely casts `team` and `style` to `ChipColor` when rendering <Chip>, which
can cause runtime styling errors if the API returns unexpected values; create a
type-safe mapper function (e.g., normalizeToChipColor or mapToChipVariant) that
accepts the raw `team`/`style` strings, checks them against the valid keys in
`chipVariants` (or the `ChipColor` union from
src/shared/components/card/match-card/types/card.ts), and returns a safe
`ChipColor` fallback when no match is found, then use that mapper when passing
bgColor and textColor to the `Chip` component instead of `team as ChipColor` and
`style as ChipColor`.

Comment on lines +51 to +58
<p className="head_20_sb text-gray-white">{matchCnt}</p>
</div>
<div className="h-[3.3rem]">
<Divider direction="vertical" thickness={0.1} color="bg-gray-600" />
</div>
<div className="flex-col-between gap-[0.2rem]">
<p className="cap_14_sb text-gray-400">시즌 평균 직관</p>
<p className="head_20_sb text-gray-white">{avgSeason}</p>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

optional props matchCnt, avgSeasonundefined로 렌더링될 수 있습니다.

matchCntavgSeason은 optional로 선언되어 있지만, 값이 없을 때 fallback 처리 없이 직접 렌더링됩니다. 이 경우 UI에 "undefined" 텍스트가 표시될 수 있습니다.

🛡️ 권장 수정: 기본값 제공
-<p className="head_20_sb text-gray-white">{matchCnt}</p>
+<p className="head_20_sb text-gray-white">{matchCnt ?? 0}</p>
-<p className="head_20_sb text-gray-white">{avgSeason}</p>
+<p className="head_20_sb text-gray-white">{avgSeason ?? 0}</p>
📝 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.

Suggested change
<p className="head_20_sb text-gray-white">{matchCnt}</p>
</div>
<div className="h-[3.3rem]">
<Divider direction="vertical" thickness={0.1} color="bg-gray-600" />
</div>
<div className="flex-col-between gap-[0.2rem]">
<p className="cap_14_sb text-gray-400">시즌 평균 직관</p>
<p className="head_20_sb text-gray-white">{avgSeason}</p>
<p className="head_20_sb text-gray-white">{matchCnt ?? 0}</p>
</div>
<div className="h-[3.3rem]">
<Divider direction="vertical" thickness={0.1} color="bg-gray-600" />
</div>
<div className="flex-col-between gap-[0.2rem]">
<p className="cap_14_sb text-gray-400">시즌 평균 직관</p>
<p className="head_20_sb text-gray-white">{avgSeason ?? 0}</p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/profile/components/profile-card.tsx` around lines 51 - 58,
matchCnt와 avgSeason이 optional이라 값이 없을 때 "undefined"가 렌더링될 수 있으므로 ProfileCard
컴포넌트에서 matchCnt와 avgSeason에 기본값을 제공하도록 수정하세요; 예를 들어 props 구조분해할 때 또는 렌더링 위치(해당
<p> 요소들에서)에서 matchCnt와 avgSeason을 nullish 병합 연산자(또는 삼항)로 대체값을 넣어 안전하게 표시하도록
변경하고, 필요하면 컴포넌트의 기본 props 선언(defaultProps 또는 파라미터 기본값)을 추가해 undefined를 방지하세요 (참조
심볼: matchCnt, avgSeason, ProfileCard / profile-card.tsx).

Comment on lines +26 to 34
<ProfileCard
nickname={data.nickname ?? ''}
imgUrl={[data.imgUrl ?? '']}
imgUrl={data.imgUrl ?? ''}
team={data.team ?? ''}
style={data.style ?? ''}
age={data.age ?? ''}
gender={data.gender ?? ''}
introduction={data.introduction ?? ''}
chips={[(data.team ?? '') as ChipColor, (data.style ?? '') as ChipColor]}
/>
<Button
size="L"
label="프로필 · 매칭 조건 수정"
onClick={() => navigate(ROUTES.PROFILE_EDIT)}
matchCnt={MOCK_MATCH_COUNT}
avgSeason={MOCK_AVERAGE_SEASON_COUNT}
onEditProfile={() => navigate(ROUTES.PROFILE_EDIT)}
/>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

onEditProfile prop이 ProfileCard에서 사용되지 않습니다.

onEditProfile 콜백을 ProfileCard에 전달하고 있지만, ProfileCard 컴포넌트 내부에서는 이 prop을 destructure하지 않고 자체적으로 useNavigate를 사용해 네비게이션을 처리하고 있습니다 (profile-card.tsx Line 18, 43 참조).

두 가지 방법 중 하나를 선택하세요:

  1. ProfileCard에서 onEditProfile prop을 사용하도록 수정
  2. 여기서 onEditProfile prop 전달을 제거
♻️ 권장 수정 방안 (옵션 1: ProfileCard에서 prop 사용)

profile-card.tsx 수정:

-const ProfileCard = ({ nickname, imgUrl, team, style, matchCnt, avgSeason }: ProfileCardProps) => {
-  const navigate = useNavigate();
+const ProfileCard = ({ nickname, imgUrl, team, style, matchCnt, avgSeason, onEditProfile }: ProfileCardProps) => {
-            onClick={() => navigate(ROUTES.PROFILE_EDIT)}
+            onClick={onEditProfile}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/profile/profile.tsx` around lines 26 - 34, The passed onEditProfile
prop is unused by ProfileCard; update ProfileCard to accept and use this
callback instead of internally calling useNavigate: add onEditProfile to the
component props/interface (e.g., in the ProfileCardProps type), destructure
onEditProfile in the ProfileCard function, replace the internal navigate-based
edit handler (the code that currently calls navigate(...) inside ProfileCard)
with a call to onEditProfile(), and remove the internal useNavigate usage for
that action; ensure the prop remains optional or provide a safe no-op fallback
if needed.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 23, 2026

Deploying mateball-client with  Cloudflare Pages  Cloudflare Pages

Latest commit: 97a61f5
Status: ✅  Deploy successful!
Preview URL: https://3e4fa6dd.mateball-client.pages.dev
Branch Preview URL: https://fix--399-mypage.mateball-client.pages.dev

View logs

@MATEBALL MATEBALL deleted a comment from coderabbitai bot Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: 마이페이지를 수정합니다.

1 participant