Skip to content

Conversation

@kyeongb-bin
Copy link
Collaborator

[FEAT] 마이페이지 매칭 현황 화면 구현

🎯 Issue


📝 변경 내용

마이페이지 내 매칭 현황 화면을 구현하고, 관련 컴포넌트들을 재사용 가능하도록 리팩토링했습니다.

주요 구현 내용

  1. 매칭 현황 페이지 구현

    • 받은 요청/보낸 요청 탭 구조
    • 프로젝트 섹션 (ProjectCard)
    • 넥트 팀원 섹션 (ProfileCard, RoleTagChip)
    • 유의사항 섹션 (MatchingNotice)
  2. 매칭 현황 컴포넌트 구현

    • ProfileCard: 프로필 이미지, 닉네임, 파트, 소개, 메시지 버튼
    • MatchingTimerCard: 타이머 및 액션 버튼 (거절/수락/취소)
    • ProjectCard: 프로젝트 정보 카드
    • MatchingNotice: 매칭 유의사항 안내
  3. 매칭 액션 모달 구현

    • 매칭 거절/수락/취소 확인 모달
    • 매칭 액션 성공 모달 (거절/수락/취소)
  4. 공용 컴포넌트 개선

    • CTAModal 공용 컴포넌트로 이동 및 단일 버튼 모드 추가
    • SegmentTabButton 공용 컴포넌트 생성 및 탭 버튼 통합

✅ 변경 사항

  • 새로운 기능 추가
  • 버그 수정
  • UI/UX 개선
  • 리팩토링
  • 문서 업데이트

📷 스크린샷

스크린샷 2026-02-04 00 17 53

📋 체크리스트

  • 브라우저에서 정상 동작 확인
  • 기존 기능에 영향 없음 확인

@kyeongb-bin kyeongb-bin self-assigned this Feb 3, 2026
@kyeongb-bin kyeongb-bin added ✨ Feature 기능 추가 🐶 갱빈 갱빈/김경빈 labels Feb 3, 2026
@netlify
Copy link

netlify bot commented Feb 3, 2026

Deploy Preview for umc-nect ready!

Name Link
🔨 Latest commit 2e17992
🔍 Latest deploy log https://app.netlify.com/projects/umc-nect/deploys/698a328eb5020200087de18b
😎 Deploy Preview https://deploy-preview-64--umc-nect.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@gemini-code-assist
Copy link

Summary of Changes

Hello @kyeongb-bin, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 마이페이지에 사용자가 받은 매칭 요청과 보낸 매칭 요청을 모두 확인할 수 있는 "매칭 현황" 화면을 새로 추가합니다. 또한, 매칭 관련 기능을 위한 재사용 가능한 UI 컴포넌트들을 생성하고 기존 공용 모달 컴포넌트를 개선하는 중요한 리팩토링 작업을 포함합니다.

Highlights

  • 새로운 기능: 마이페이지 매칭 현황 화면 구현: 사용자가 받은 매칭 요청과 보낸 매칭 요청을 한눈에 확인할 수 있는 '매칭 현황' 페이지가 마이페이지에 추가되었습니다.
  • 매칭 관련 컴포넌트 재사용성 개선: 매칭 현황 화면을 구성하는 ProfileCard, MatchingTimerCard, ProjectCard, MatchingNotice 등의 컴포넌트들이 재사용 가능하도록 구현되었습니다.
  • 공용 컴포넌트 CTAModal 개선 및 통합: 기존 CTAModal이 공용 컴포넌트로 이동되었으며, 단일 버튼 모드가 추가되어 유연성이 향상되었습니다. 이로 인해 ConfirmModal.tsx는 제거되었습니다.
  • 공용 SegmentTabButton 컴포넌트 추가: 탭 버튼을 통합 관리하기 위한 SegmentTabButton 공용 컴포넌트가 새로 생성되었으며, 기존 Tabbar.tsx를 대체합니다.
  • 새로운 매칭 현황 페이지 라우팅 추가: src/App.tsx/mypage/matching 경로가 추가되어 새로운 매칭 현황 페이지에 접근할 수 있게 되었습니다.
Changelog
  • src/App.tsx
    • MatchingStatus 컴포넌트 임포트 추가
    • 마이페이지 하위에 /mypage/matching 경로를 추가하여 MatchingStatus 컴포넌트를 렌더링하도록 설정
  • src/assets/icons/mypage/chat.svg
    • ProfileCard에서 사용될 채팅 아이콘 SVG 파일 추가
  • src/components/common/CTAModal.tsx
    • 새로운 공용 CTAModal 컴포넌트 추가
    • 단일 버튼 모드 및 메시지 하이라이팅 기능 지원
  • src/components/common/ConfirmModal.tsx
    • 더 이상 사용되지 않는 ConfirmModal 컴포넌트 제거
  • src/components/layout/Layout.tsx
    • CTAModal 컴포넌트의 임포트 경로를 src/components/common/CTAModal로 업데이트
  • src/components/mypage/CTAModal.tsx
    • 기존 마이페이지 전용 CTAModal 컴포넌트 제거 (공용 컴포넌트로 대체)
  • src/components/mypage/SegmentTabButton.tsx
    • 탭 텍스트와 카운트를 표시하고 활성화 상태를 관리하는 공용 SegmentTabButton 컴포넌트 추가
  • src/components/mypage/idea-analysis/IdeaAnalysis.tsx
    • CTAModal 컴포넌트의 임포트 경로를 src/components/common/CTAModal로 업데이트
  • src/components/mypage/matching-status/MatchingNotice.tsx
    • 매칭 유의사항 목록을 표시하는 MatchingNotice 컴포넌트 추가
    • 텍스트 내 특정 형식({텍스트}, **텍스트**)을 파싱하여 스타일링하는 기능 포함
  • src/components/mypage/matching-status/MatchingStatus.tsx
    • 마이페이지 매칭 현황 화면의 메인 컴포넌트 추가
    • 받은 요청/보낸 요청 탭 구조 구현
    • ProjectCard, ProfileCard, MatchingTimerCard, MatchingNotice 등 통합
    • 매칭 액션(거절/수락/취소) 확인 및 성공 모달 (CTAModal 활용) 구현
  • src/components/mypage/matching-status/MatchingTimerCard.tsx
    • 매칭 요청의 타이머와 액션 버튼(수락/거절/취소)을 표시하는 MatchingTimerCard 컴포넌트 추가
    • 요청 타입(받은 요청/보낸 요청) 및 매칭 상태에 따른 UI 변화 처리
  • src/components/mypage/matching-status/ProfileCard.tsx
    • 프로필 이미지, 닉네임, 파트, 소개 및 메시지 버튼을 포함하는 ProfileCard 컴포넌트 추가
  • src/components/mypage/matching-status/ProjectCard.tsx
    • 프로젝트 이름, 카테고리, 설명, 팀원 수를 표시하는 ProjectCard 컴포넌트 추가
  • src/components/mypage/ongoing-project/OngoingProject.tsx
    • CTAModal 컴포넌트의 임포트 경로를 src/components/common/CTAModal로 업데이트
    • 기존 Tabbar 컴포넌트를 SegmentTabButton으로 대체하여 탭 UI 개선
  • src/components/mypage/ongoing-project/Tabbar.tsx
    • 더 이상 사용되지 않는 Tabbar 컴포넌트 제거
  • src/components/mypage/profile-analysis/ProfileAnalysis.tsx
    • CTAModal 컴포넌트의 임포트 경로를 src/components/common/CTAModal로 업데이트
  • src/components/mypage/profile-settings/ProfileSettings.tsx
    • CTAModal 컴포넌트의 임포트 경로를 src/components/common/CTAModal로 업데이트
  • src/constants/matchingNotice.ts
    • 매칭 유의사항 항목을 정의하는 NoticeItem 인터페이스 및 RECEIVED_REQUEST_NOTICES, SENT_REQUEST_NOTICES 상수 배열 추가
Activity
  • 새로운 기능이 추가되었습니다.
  • UI/UX가 개선되었습니다.
  • 코드 리팩토링이 진행되었습니다.
  • 마이페이지 매칭 현황 화면의 스크린샷이 첨부되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

전반적으로 마이페이지 매칭 현황 화면 구현과 관련 컴포넌트 리팩토링이 잘 이루어졌습니다. 특히 CTAModalSegmentTabButton을 공용 컴포넌트로 분리하여 재사용성을 높인 점이 인상적입니다. 코드의 품질을 더욱 향상시키기 위해 타입 안정성 강화, 코드 중복 제거, 일관성 개선에 대한 몇 가지 제안을 드립니다.

Comment on lines 3 to 16
interface CTAModalProps {
message: string
subMessage?: string
isMessageHighlight?: boolean
fixedHeight?: boolean
// 단일 버튼 모드
buttonMsg?: string
onButtonClick?: () => void
// 이중 버튼 모드
leftButtonMsg?: string
rightButtonMsg?: string
onLeftClick?: () => void
onRightClick?: () => void
}

Choose a reason for hiding this comment

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

medium

CTAModalProps 인터페이스는 단일 버튼 모드와 이중 버튼 모드에 대한 props를 모두 옵셔널로 정의하고 있어, 의도치 않은 props 조합(예: buttonMsgleftButtonMsg를 함께 사용)이 전달될 수 있습니다. 이는 타입 안정성을 저해할 수 있습니다.

Discriminated Union 타입을 사용하여 두 모드를 명확히 구분하면 컴포넌트의 의도를 더 명확하게 하고 타입 안정성을 높일 수 있습니다.

interface CTAModalBaseProps {
	message: string
	subMessage?: string
	isMessageHighlight?: boolean
	fixedHeight?: boolean
}

type CTAModalProps = CTAModalBaseProps & (
	| {
			// 단일 버튼 모드
			buttonMsg: string
			onButtonClick?: () => void
			leftButtonMsg?: never
			rightButtonMsg?: never
			onLeftClick?: never
			onRightClick?: never
	  }
	| {
			// 이중 버튼 모드
			buttonMsg?: never
			onButtonClick?: never
			leftButtonMsg: string
			rightButtonMsg: string
			onLeftClick?: () => void
			onRightClick?: () => void
	  }
)

Comment on lines 55 to 63
<div
className={`flex flex-col items-center text-center whitespace-pre-line ${isSingleButtonMode ? 'gap-[18px] py-1' : ''} ${isMessageHighlight ? 'text-primary-500-normal' : 'text-neutral-900'} ${fixedHeight ? ' h-40.5' : ''}`}
>
<span className='leading-[160%] text-[20px] font-bold'>{parseMessage(message)}</span>

<div className={`body-1 font-medium text-neutral-600 ${isSingleButtonMode ? '' : 'mt-4.5'} ${!subMessage ? 'min-h-[24px]' : ''}`}>
{subMessage}
</div>
</div>

Choose a reason for hiding this comment

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

medium

이 컴포넌트 내에서 조건부 클래스명을 문자열 템플릿으로 처리하고 있습니다. 프로젝트의 다른 컴포넌트들과 일관성을 맞추고 가독성을 높이기 위해 cn 유틸리티를 사용하는 것이 좋습니다.

먼저 import { cn } from '@/utils/cn'를 추가한 후, 다음과 같이 수정할 수 있습니다.

				<div
					className={cn(
						'flex flex-col items-center text-center whitespace-pre-line',
						isSingleButtonMode && 'gap-[18px] py-1',
						isMessageHighlight ? 'text-primary-500-normal' : 'text-neutral-900',
						fixedHeight && 'h-40.5'
					)}
				>
					<span className='leading-[160%] text-[20px] font-bold'>{parseMessage(message)}</span>

					<div className={cn('body-1 font-medium text-neutral-600', !isSingleButtonMode && 'mt-4.5', !subMessage && 'min-h-[24px]')}>
						{subMessage}
					</div>
				</div>

nickname={member.nickname}
part={member.part}
introduction={member.introduction}
onMessageClick={() => console.log(`${member.nickname}에게 메시지 보내기`)}

Choose a reason for hiding this comment

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

medium

console.log는 개발 중 디버깅에는 유용하지만, 프로덕션 코드에 포함되어서는 안 됩니다. 실제 기능 구현 시 제거하거나, 필요하다면 적절한 로깅 라이브러리로 대체해야 합니다. 이 파일의 다른 부분들(예: 343, 357, 372, 386, 401, 415행)에도 console.log가 남아있습니다.

Suggested change
onMessageClick={() => console.log(`${member.nickname}에게 메시지 보내기`)}
onMessageClick={() => { /* 메시지 보내기 기능 구현 */ }}

Comment on lines +334 to +430
{/* 매칭 거절 확인 모달 */}
{modalType === 'reject' && (
<CTAModal
message='매칭 요청을 {거절} 하시겠습니까?'
subMessage='거절 후 되돌릴 수 없습니다.'
leftButtonMsg='돌아가기'
rightButtonMsg='매칭 거절'
onLeftClick={() => setModalType(null)}
onRightClick={() => {
console.log('매칭 거절 확인')
setModalType('rejectSuccess')
}}
/>
)}

{/* 매칭 거절 성공 모달 */}
{modalType === 'rejectSuccess' && (
<CTAModal
message='매칭 요청이 거절 되었습니다'
subMessage=''
isMessageHighlight={true}
buttonMsg='확인'
onButtonClick={() => {
console.log('매칭 거절 성공 확인')
setModalType(null)
}}
/>
)}

{/* 매칭 수락 확인 모달 */}
{modalType === 'accept' && (
<CTAModal
message='매칭 요청을 {수락} 하시겠습니까?'
subMessage='수락 후 번복 할 수 없습니다.'
leftButtonMsg='돌아가기'
rightButtonMsg='매칭 수락'
onLeftClick={() => setModalType(null)}
onRightClick={() => {
console.log('매칭 수락 확인')
setModalType('acceptSuccess')
}}
/>
)}

{/* 매칭 수락 성공 모달 */}
{modalType === 'acceptSuccess' && (
<CTAModal
message='매칭이 수락 되었습니다'
subMessage='넥트가 응원할게요 !'
isMessageHighlight={true}
buttonMsg='확인'
onButtonClick={() => {
console.log('매칭 수락 성공 확인')
setModalType(null)
}}
/>
)}

{/* 매칭 취소 확인 모달 */}
{modalType === 'cancel' && (
<CTAModal
message='매칭 요청을 {취소} 하시겠습니까?'
subMessage='취소 후 24시간 동안 해당 프로젝트 매칭 신청이 제한됩니다.'
leftButtonMsg='돌아가기'
rightButtonMsg='매칭 취소'
onLeftClick={() => setModalType(null)}
onRightClick={() => {
console.log('매칭 취소 확인')
setModalType('cancelSuccess')
}}
/>
)}

{/* 매칭 취소 성공 모달 */}
{modalType === 'cancelSuccess' && (
<CTAModal
message='매칭 요청이 취소 되었습니다'
subMessage=''
isMessageHighlight={true}
buttonMsg='확인'
onButtonClick={() => {
console.log('매칭 취소 성공 확인')
setModalType(null)
}}
/>
)}

Choose a reason for hiding this comment

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

medium

모달을 렌더링하는 부분이 여러 조건부 렌더링으로 반복되고 있어 코드가 길고 유지보수가 어렵습니다.

modalType에 따라 모달에 전달될 props를 정의하는 설정(configuration) 객체를 만들고, 이를 기반으로 CTAModal을 한 번만 렌더링하도록 리팩토링하면 코드를 더 간결하고 선언적으로 만들 수 있습니다. 이는 코드 중복을 줄이고 가독성을 향상시킬 것입니다.

@kyeongb-bin kyeongb-bin linked an issue Feb 4, 2026 that may be closed by this pull request
7 tasks
@kyeongb-bin kyeongb-bin force-pushed the feat/57-matching-status branch from ce55809 to a60fcca Compare February 5, 2026 12:21
@kyeongb-bin kyeongb-bin force-pushed the feat/57-matching-status branch from 29c3a30 to 2e17992 Compare February 9, 2026 19:16
@kyeongb-bin kyeongb-bin merged commit 40b1c0f into dev Feb 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 추가 🐶 갱빈 갱빈/김경빈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 마이페이지 매칭 현황 화면 구현

4 participants