Skip to content

Conversation

@oesnuj
Copy link
Member

@oesnuj oesnuj commented Dec 23, 2025

#️⃣연관된 이슈

#이슈번호

📝작업 내용

✨ 새로운 동아리 상세 페이지 (ClubDetailPage2) 구현

1. 반응형 2단 레이아웃

  • 모바일/태블릿: 세로 스택 레이아웃으로 전환 (확장형)
  • 노트북/데스크탑: ClubProfileCard 고정, 탭 콘텐츠 영역 나란히 배치 (고정형)
  • 디바이스별 Header 조건부 렌더링
default.mp4

2. ClubProfileCard 컴포넌트

  • 동아리 커버 이미지, 로고, 기본 정보를 포함한 카드 UI
  • 모집 상태 뱃지, SNS 링크 버튼 통합
  • 고정된 프로필 영역으로 일관된 정보 제공
모바일, 테블릿 노트북, 데스크탑
image image

3. 탭 네비게이션 & 이벤트 추적

  • 소개 내용 / 활동사진 탭 전환 기능 (RightSection)
  • Mixpanel 이벤트 연동
    • CLUB_INTRO_TAB_CLICKED: 소개 탭 클릭 추적
    • CLUB_FEED_TAB_CLICKED: 피드 탭 클릭 추적

임시 변경사항 (추후 수정 예정)

  • 페이지명 ClubDetailPage2 사용 중 (기존 페이지와 구분을 위한 임시 네이밍)
  • 라우트 /club2/:clubId 사용 중
  • Mock 데이터로 개발 및 테스트 진행 (mockData.ts)
  • 추후 계획:
    • 안정화 후 기존 ClubDetailPage 대체 또는 병합 예정
    • 실제 API 데이터 연동 필요

🫡 참고사항

  • 현재 Mock 데이터 사용 중 (추후 실제 API 연동 필요)
  • 기존 ClubDetailPage(/club/:clubId)는 그대로 유지
  • 테스트 경로: /club2/67ee2b97b35e3c267e3c2485
  • Mixpanel 이벤트는 설정 완료되어 즉시 수집 가능

Summary by CodeRabbit

릴리스 노트

  • New Features
    • 개선된 클럽 상세 정보 페이지 추가 - 클럽 프로필 카드, 커버 이미지, 로고 포함
    • 클럽 소개 및 사진 탭 네비게이션 기능 추가
    • 클럽 소셜 미디어 링크(Instagram, YouTube) 디스플레이 추가
    • 사용자 상호작용 추적을 통한 분석 개선

✏️ Tip: You can customize this high-level summary in your review settings.

- Instagram, YouTube 아이콘 교체
- ClubProfileCard 컴포넌트 추가 (커버, 로고, 클럽명, SNS 링크, 소개)
- 반응형 레이아웃 지원 (모바일/태블릿/데스크탑)
- 새 라우트 및 페이지 구조 추가
- 프로필 카드 컴포넌트 사용
- 탭 기반 콘텐츠 전환 구현
- CLUB_INTRO_TAB_CLICKED 이벤트 추가
- CLUB_FEED_TAB_CLICKED 이벤트 추가
- 동아리 기본 정보 (이름, 로고, 커버 이미지)
- 상세 설명 (소개, 활동 내용, 수상 내역, FAQ 등)
- 모집 정보 및 SNS 링크 데이터
@vercel
Copy link

vercel bot commented Dec 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
moadong Ready Ready Preview, Comment Dec 23, 2025 1:33pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Invalid regex pattern for base branch. Received: "**" at "reviews.auto_review.base_branches[0]"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

동아리 상세페이지 2 컴포넌트와 관련 UI 레이아웃을 새로 구현합니다. 새로운 라우트(/club2/:clubId), 프로필 카드 컴포넌트, 탭 인터페이스, 타입 정의, 스타일 및 모의 데이터를 추가하여 동아리 상세 정보 표시 기능을 구축합니다.

Changes

Cohort / File(s) 변경 사항 요약
라우팅 및 상수
frontend/src/App.tsx, frontend/src/constants/eventName.ts
새로운 /club2/:clubId 라우트 추가, ClubDetailPage2를 Suspense로 감싸기; 탭 클릭 이벤트 추가 (CLUB_INTRO_TAB_CLICKED, CLUB_FEED_TAB_CLICKED)
ClubDetailPage2 주요 컴포넌트
frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx, frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts
클럽 데이터 조회 후 렌더링하는 페이지 컴포넌트 구현; 탭 관리, Mixpanel 추적, 반응형 레이아웃 포함
ClubProfileCard 서브컴포넌트
frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx, frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts
커버 이미지, 로고, 클럽명, 채용 배지, SNS 링크, 소개 섹션을 렌더링하는 프로필 카드 컴포넌트; 플랫폼별 아이콘 매핑 포함
타입 및 모의 데이터
frontend/src/types/club.ts, frontend/src/pages/clubDetailPage2/mockData.ts
새로운 타입 정의 (Award, IdealCandidate, FAQ, DetailedDescription, ClubApiResponse); 클럽 상세 정보용 모의 데이터 추가

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Router as App Router
    participant Page as ClubDetailPage2
    participant Hook as useGetClubDetail
    participant API as API
    participant Analytics as Mixpanel
    participant Card as ClubProfileCard

    User->>Router: Navigate to /club2/:clubId
    Router->>Page: Render with clubId
    Page->>Hook: Fetch club data
    Hook->>API: GET /club/:clubId
    API-->>Hook: Club data response
    Hook-->>Page: Data loaded
    Page->>Analytics: Track page view
    Page->>Card: Pass club data
    Card-->>Page: Render profile card
    Page-->>User: Display page with tabs
    
    rect rgb(200, 220, 255)
    Note over User,Analytics: Tab Interaction Flow
    User->>Page: Click intro/feed tab
    Page->>Page: Update active tab state
    Page->>Analytics: Track tab click event
    Analytics-->>Page: Event recorded
    Page-->>User: Render tab content
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

✨ Feature, 💻 FE

Suggested reviewers

  • lepitaaar
  • Zepelown
  • seongwon030

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive PR 제목 'Feature/#951 club detail layout moa 445'는 변경 사항의 주요 내용(ClubDetailPage2 구현, 반응형 레이아웃, 탭 네비게이션)을 충분히 반영하지 못하고 있으며, 이슈 번호와 약자(moa, 445)를 포함하여 명확성과 가독성이 낮습니다. 제목을 더 명확하게 수정하세요. 예: 'Add ClubDetailPage2 with responsive layout and tab navigation' 또는 'Implement club detail page layout with profile card and tabs'로 변경하면 변경 사항이 더 명확해집니다.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed PR의 모든 주요 목표가 MOA-445 요구사항을 충족합니다: 상세페이지 기본 레이아웃 구성, 모바일/데스크탑 반응형 스타일 적용, 하위 섹션 삽입 가능한 구조, 레이아웃 안정성 확보.
Out of Scope Changes check ✅ Passed 모든 변경사항이 MOA-445의 클럽 상세페이지 공통 레이아웃 구현 범위 내에 있으며, 범위를 벗어난 변경은 없습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/#951-club-detail-layout-MOA-445

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.

@oesnuj oesnuj requested a review from seongwon030 December 23, 2025 13:34
@oesnuj oesnuj added ✨ Feature 기능 개발 🎨 Design 마크업 & 스타일링 💻 FE Frontend labels Dec 23, 2025
@oesnuj oesnuj changed the title Feature/#951 club detail layout moa 445 [feature] 동아리 상세페이지 > 공통 레이아웃(UI 틀) 구현 Dec 23, 2025
Copy link
Contributor

@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: 3

🧹 Nitpick comments (9)
frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts (5)

5-16: 매직 넘버를 명명된 상수로 교체하세요.

  • max-width: 375px: 모바일 너비는 명명된 상수로 정의해야 합니다.
  • border-radius: 20px: 이 값은 파일 전체에서 반복되므로 상수로 추출하면 일관성과 유지보수성이 향상됩니다.
  • background-color: #ffffff: 테마의 colors.base.white를 사용해야 합니다.

코딩 가이드라인에 따라 매직 넘버를 명명된 상수로 교체하여 명확성을 높여야 합니다.

🔎 제안하는 개선 방안

상수 파일이나 파일 상단에 정의:

const MOBILE_MAX_WIDTH = 375;
const CARD_BORDER_RADIUS = 20;

그런 다음 스타일에서 사용:

 export const Container = styled.div`
   position: relative;
   width: 100%;
-  max-width: 375px;
-  background-color: #ffffff;
-  border-radius: 20px;
+  max-width: ${MOBILE_MAX_WIDTH}px;
+  background-color: ${colors.base.white};
+  border-radius: ${CARD_BORDER_RADIUS}px;
   overflow: hidden;

18-24: 매직 넘버를 명명된 상수로 교체하세요.

height: 213px는 디자인 사양에서 온 값으로 보입니다. 명명된 상수로 추출하면 디자인 변경 시 유지보수가 용이합니다.

🔎 제안하는 개선 방안
const COVER_IMAGE_HEIGHT = 213;
 export const CoverImage = styled.img`
   width: 100%;
-  height: 213px;
+  height: ${COVER_IMAGE_HEIGHT}px;
   position: relative;
   z-index: 1;
   object-fit: cover;

26-44: 매직 넘버와 하드코딩된 색상을 상수로 교체하세요.

LogoWrapper와 Logo 컴포넌트에 여러 매직 넘버와 하드코딩된 색상이 있습니다:

  • 위치 값: top: 165px, left: 16px
  • 크기 값: width: 64px, height: 64px
  • 테두리 반경: border-radius: 16px, 14px
  • 패딩: padding: 2px
  • 색상: background-color: #ffffffcolors.base.white 사용 필요
🔎 제안하는 개선 방안
const LOGO_SIZE = 64;
const LOGO_TOP_OFFSET = 165;
const LOGO_LEFT_OFFSET = 16;
const LOGO_BORDER_RADIUS = 16;
const LOGO_INNER_BORDER_RADIUS = 14;
const LOGO_PADDING = 2;
 export const LogoWrapper = styled.div`
   position: absolute;
-  top: 165px;
-  left: 16px;
-  width: 64px;
-  height: 64px;
-  border-radius: 16px;
-  background-color: #ffffff;
-  padding: 2px;
+  top: ${LOGO_TOP_OFFSET}px;
+  left: ${LOGO_LEFT_OFFSET}px;
+  width: ${LOGO_SIZE}px;
+  height: ${LOGO_SIZE}px;
+  border-radius: ${LOGO_BORDER_RADIUS}px;
+  background-color: ${colors.base.white};
+  padding: ${LOGO_PADDING}px;
   z-index: 3;
 `;

 export const Logo = styled.img`
   width: 100%;
   height: 100%;
-  border-radius: 14px;
+  border-radius: ${LOGO_INNER_BORDER_RADIUS}px;
   object-fit: cover;
   border: 0.5px solid var(--Gray-400, #dcdcdc);

46-61: 하드코딩된 색상을 테마 색상으로 교체하세요.

  • Line 51: background-color: #f5f5f5colors.gray[100] 사용
  • Line 55: background-color: #ffffffcolors.base.white 사용
  • 여러 패딩 값(42px, 20px, 40px, 16px)과 마진 값(-20px)은 명명된 상수로 추출하는 것을 고려하세요.

132-144: 하드코딩된 색상을 테마에 추가하거나 기존 테마 색상을 사용하세요.

  • Line 133: color: #0066cc는 URL 링크 색상으로 보이지만 테마에 정의되어 있지 않습니다. 이 색상을 테마에 추가하거나 기존 accent 색상(예: colors.accent[1][900])을 사용하는 것을 고려하세요.
  • Lines 139, 142: 하드코딩된 배경색 대신 colors.base.whitecolors.gray[100]을 사용하세요.
frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx (2)

27-29: 로딩 상태에서 사용자 피드백을 제공하세요.

현재 clubDetail이 없으면 null을 반환하여 빈 화면이 표시됩니다. 사용자에게 로딩 중임을 알리는 인디케이터를 표시하는 것이 좋습니다.

🔎 제안하는 개선 방안
  if (!clubDetail) {
-   return null;
+   return <div>로딩 중...</div>; // 또는 적절한 로딩 스피너 컴포넌트
  }

31-33: 에러 처리를 개선하여 더 나은 사용자 경험을 제공하세요.

현재 에러 메시지가 너무 단순합니다. 에러 유형에 따른 구체적인 안내와 재시도 옵션을 제공하는 것을 고려하세요.

🔎 제안하는 개선 방안
  if (error) {
-   return <div>에러가 발생했습니다.</div>;
+   return (
+     <ErrorFallback 
+       message="클럽 정보를 불러오는 중 문제가 발생했습니다."
+       onRetry={() => window.location.reload()}
+     />
+   );
  }
frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx (1)

25-32: 플랫폼 이름 매핑을 상수로 추출하세요.

하드코딩된 플랫폼 이름 매핑은 여러 곳에서 사용될 수 있으므로 공유 상수 파일로 추출하는 것이 좋습니다. 이렇게 하면 플랫폼 이름 변경 시 한 곳에서만 수정하면 됩니다.

🔎 제안하는 개선 방안

상수 파일(예: @/constants/snsConfig.ts)에 추가:

export const SNS_PLATFORM_NAMES: Record<string, string> = {
  instagram: '인스타그램',
  youtube: '유튜브',
  x: 'X',
} as const;

그런 다음 컴포넌트에서 사용:

+ import { SNS_PLATFORM_NAMES } from '@/constants/snsConfig';

  const getSocialPlatformName = (platform: string) => {
-   const names: Record<string, string> = {
-     instagram: '인스타그램',
-     youtube: '유튜브',
-     x: 'X',
-   };
-   return names[platform] || platform;
+   return SNS_PLATFORM_NAMES[platform] || platform;
  };
frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts (1)

10-28: 레이아웃 관련 매직 넘버를 명명된 상수로 교체하는 것을 고려하세요.

여러 레이아웃 값들이 하드코딩되어 있습니다:

  • max-width: 1180px: 콘텐츠 최대 너비
  • margin-top: 100px: 헤더 오프셋으로 보임
  • gap: 24px: 그리드 간격

이러한 값들을 명명된 상수로 추출하면 디자인 시스템 변경 시 유지보수가 용이합니다.

🔎 제안하는 개선 방안
const CONTENT_MAX_WIDTH = 1180;
const HEADER_HEIGHT_OFFSET = 100;
const CONTENT_GAP = 24;
 export const ContentWrapper = styled.div`
-  max-width: 1180px;
+  max-width: ${CONTENT_MAX_WIDTH}px;
   width: 100%;
   margin: 0 auto;
   display: flex;
-  gap: 24px;
-  margin-top: 100px;
+  gap: ${CONTENT_GAP}px;
+  margin-top: ${HEADER_HEIGHT_OFFSET}px;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between aab9273 and f8c5915.

⛔ Files ignored due to path filters (2)
  • frontend/src/assets/images/icons/sns/instagram_icon.svg is excluded by !**/*.svg
  • frontend/src/assets/images/icons/sns/youtube_icon.svg is excluded by !**/*.svg
📒 Files selected for processing (8)
  • frontend/src/App.tsx
  • frontend/src/constants/eventName.ts
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx
  • frontend/src/pages/clubDetailPage2/mockData.ts
  • frontend/src/types/club.ts
🧰 Additional context used
📓 Path-based instructions (3)
frontend/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (frontend/.cursorrules)

frontend/**/*.{ts,tsx,js,jsx}: Replace magic numbers with named constants for clarity
Replace complex/nested ternaries with if/else or IIFEs for readability
Assign complex boolean conditions to named variables for explicit meaning
Avoid hidden side effects; functions should only perform actions implied by their signature (Single Responsibility Principle)
Use unique and descriptive names for custom wrappers/functions to avoid ambiguity
Define constants near related logic or ensure names link them clearly to avoid silent failures
Break down broad state management into smaller, focused hooks/contexts to reduce coupling

Files:

  • frontend/src/types/club.ts
  • frontend/src/constants/eventName.ts
  • frontend/src/App.tsx
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts
  • frontend/src/pages/clubDetailPage2/mockData.ts
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx
frontend/**/*.{ts,tsx}

📄 CodeRabbit inference engine (frontend/.cursorrules)

Use consistent return types for similar functions/hooks

Files:

  • frontend/src/types/club.ts
  • frontend/src/constants/eventName.ts
  • frontend/src/App.tsx
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts
  • frontend/src/pages/clubDetailPage2/mockData.ts
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx
frontend/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (frontend/.cursorrules)

frontend/**/*.{tsx,jsx}: Abstract complex logic/interactions into dedicated components/HOCs
Separate significantly different conditional UI/logic into distinct components
Colocate simple, localized logic or use inline definitions to reduce context switching
Choose field-level or form-level cohesion based on form requirements when using form libraries like react-hook-form
Use Component Composition instead of Props Drilling to reduce coupling

Files:

  • frontend/src/App.tsx
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx
🧠 Learnings (7)
📓 Common learnings
Learnt from: seongwon030
Repo: Moadong/moadong PR: 195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.
📚 Learning: 2025-03-19T05:18:07.818Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 195
File: frontend/src/pages/AdminPage/AdminPage.tsx:7-7
Timestamp: 2025-03-19T05:18:07.818Z
Learning: AdminPage.tsx에서 현재 하드코딩된 클럽 ID('67d2e3b9b15c136c6acbf20b')는 로그인 기능 구현 후 동적으로 가져오는 방식으로 수정될 예정입니다.

Applied to files:

  • frontend/src/App.tsx
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{tsx,jsx} : Abstract complex logic/interactions into dedicated components/HOCs

Applied to files:

  • frontend/src/App.tsx
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{tsx,jsx} : Separate significantly different conditional UI/logic into distinct components

Applied to files:

  • frontend/src/App.tsx
  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts
  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts
📚 Learning: 2025-05-16T06:25:11.193Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 418
File: frontend/src/mocks/api/clubHandlers.test.ts:0-0
Timestamp: 2025-05-16T06:25:11.193Z
Learning: API 관련 상수(예: API_BASE)는 frontend/src/mocks/constants/api.ts에 정의되어 있으며, 다른 파일에서 재정의하지 말고 이 파일에서 import하여 사용해야 합니다.

Applied to files:

  • frontend/src/pages/clubDetailPage2/mockData.ts
📚 Learning: 2025-11-25T14:08:23.253Z
Learnt from: CR
Repo: Moadong/moadong PR: 0
File: frontend/.cursorrules:0-0
Timestamp: 2025-11-25T14:08:23.253Z
Learning: Applies to frontend/**/*.{ts,tsx,js,jsx} : Replace magic numbers with named constants for clarity

Applied to files:

  • frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts
📚 Learning: 2025-07-19T05:05:10.196Z
Learnt from: seongwon030
Repo: Moadong/moadong PR: 548
File: frontend/src/pages/ClubDetailPage/ClubDetailPage.tsx:17-57
Timestamp: 2025-07-19T05:05:10.196Z
Learning: ClubDetailPage.tsx에서 notJoinedClubNames 배열의 하드코딩은 의도적인 설계 결정입니다. 개발자가 명시적으로 하드코딩을 선택했으므로 이에 대한 리팩토링 제안을 하지 않아야 합니다.

Applied to files:

  • frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx
🧬 Code graph analysis (5)
frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx (1)
frontend/src/types/club.ts (1)
  • SNSPlatform (14-14)
frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts (2)
frontend/src/styles/mediaQuery.ts (1)
  • media (8-14)
frontend/src/styles/theme/colors.ts (1)
  • colors (1-81)
frontend/src/pages/clubDetailPage2/mockData.ts (1)
frontend/src/types/club.ts (1)
  • ClubApiResponse (60-75)
frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.styles.ts (2)
frontend/src/styles/mediaQuery.ts (1)
  • media (8-14)
frontend/src/styles/theme/colors.ts (1)
  • colors (1-81)
frontend/src/pages/clubDetailPage2/ClubDetailPage2.tsx (3)
frontend/src/pages/clubDetailPage2/mockData.ts (1)
  • mockClubApi (3-43)
frontend/src/hooks/queries/club/useGetClubDetail.ts (1)
  • useGetClubDetail (6-20)
frontend/src/constants/eventName.ts (2)
  • PAGE_VIEW (81-95)
  • USER_EVENT (1-37)
🔇 Additional comments (6)
frontend/src/constants/eventName.ts (1)

21-22: LGTM!

새로운 탭 클릭 이벤트 상수가 올바르게 추가되었으며 기존 네이밍 패턴을 따릅니다.

frontend/src/App.tsx (1)

10-10: LGTM!

새로운 라우트가 기존 패턴을 따라 올바르게 추가되었습니다. Suspense 경계 내에서 lazy-loading이 적절히 구현되어 있습니다.

Also applies to: 47-54

frontend/src/pages/clubDetailPage2/mockData.ts (1)

6-7: 에셋 경로가 프로덕션 환경에서 작동하지 않을 수 있습니다.

/src/assets/...로 시작하는 경로는 개발 환경에서만 작동할 수 있습니다. 빌드된 앱에서는 적절한 public 경로나 import된 에셋을 사용해야 합니다.

모크 데이터이므로 테스트 목적으로는 괜찮지만, 실제 API 통합 시 이 경로들이 올바른 에셋 URL로 교체되어야 합니다.

frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx (1)

51-51: 기본 이미지 경로를 확인하세요.

'/default-cover.jpg''/default-logo.jpg' 경로가 실제로 존재하는지 확인이 필요합니다. 존재하지 않으면 이미지 로딩 오류가 발생합니다.

프로젝트의 다른 부분에서 사용하는 기본 이미지 패턴(예: /src/assets/images/logos/default_profile_image.svg)을 따르는 것을 권장합니다.

🔎 제안하는 수정 방안
+ import defaultLogo from '@/assets/images/logos/default_profile_image.svg';
+ import defaultCover from '@/assets/images/banners/default_banner.png';

- <Styled.CoverImage src={cover || '/default-cover.jpg'} alt="클럽 커버" />
+ <Styled.CoverImage src={cover || defaultCover} alt="클럽 커버" />

- <Styled.Logo src={logo || '/default-logo.jpg'} alt={`${name} 로고`} />
+ <Styled.Logo src={logo || defaultLogo} alt={`${name} 로고`} />

Also applies to: 55-55

frontend/src/types/club.ts (1)

36-75: LGTM!

새로운 타입 정의가 잘 구조화되어 있고 TypeScript 모범 사례를 따릅니다. DetailedDescription의 중첩 구조(Award, IdealCandidate, FAQ)가 명확하며, ClubApiResponse 인터페이스가 모든 필요한 필드를 포함하고 있습니다.

frontend/src/pages/clubDetailPage2/ClubDetailPage2.styles.ts (1)

41-56: TabButton의 전이 속성(transient prop) 사용이 올바릅니다.

$active prop에 $ 접두사를 사용하여 DOM에 전달되지 않도록 한 것은 styled-components v5.1+ 모범 사례를 잘 따르고 있습니다. 이는 React의 알 수 없는 prop 경고를 방지합니다.

Comment on lines +34 to +40
const getSocialIcon = (platform: string) => {
const icons: Record<string, string> = {
instagram: InstagramIcon,
youtube: YoutubeIcon,
};
return icons[platform];
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

'x' 플랫폼 아이콘이 누락되었습니다.

getSocialIcon 함수에 'x' 플랫폼에 대한 아이콘 매핑이 없습니다. Line 71-72에서 아이콘이 없으면 null을 반환하므로 x 링크는 렌더링되지 않습니다.

SNSPlatform 타입에 'x'가 포함되어 있다면 해당 아이콘을 추가하거나, 지원하지 않는 플랫폼이라면 타입에서 제거해야 합니다.

🔎 제안하는 수정 방안

Option 1: X 아이콘 추가

+ import XIcon from '@/assets/images/icons/sns/x_icon.svg';

  const getSocialIcon = (platform: string) => {
    const icons: Record<string, string> = {
      instagram: InstagramIcon,
      youtube: YoutubeIcon,
+     x: XIcon,
    };
    return icons[platform];
  };

Option 2: 기본 아이콘 제공

+ import DefaultSnsIcon from '@/assets/images/icons/sns/default_icon.svg';

  const getSocialIcon = (platform: string) => {
    const icons: Record<string, string> = {
      instagram: InstagramIcon,
      youtube: YoutubeIcon,
+     x: DefaultSnsIcon,
    };
-   return icons[platform];
+   return icons[platform] || DefaultSnsIcon;
  };

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
frontend/src/pages/clubDetailPage2/components/ClubProfileCard/ClubProfileCard.tsx
around lines 34 to 40, the getSocialIcon function lacks a mapping for the 'x'
platform so X links render as null; add an entry for 'x' in the icons record
pointing to the X icon asset (or, if X should not be supported, remove 'x' from
the SNSPlatform type) and ensure the function returns that icon (or supply a
sensible default icon) so X links render correctly.

Copy link
Member

@seongwon030 seongwon030 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 Design 마크업 & 스타일링 💻 FE Frontend ✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants