Skip to content

[FE] SISC1-216 [FEAT] 외부페이지 제작(동아리소개, 임원소개, 운용포트폴리오)#175

Merged
DongEun02 merged 9 commits intomainfrom
SISC1-216-FE-external-detail-page
Dec 22, 2025
Merged

[FE] SISC1-216 [FEAT] 외부페이지 제작(동아리소개, 임원소개, 운용포트폴리오)#175
DongEun02 merged 9 commits intomainfrom
SISC1-216-FE-external-detail-page

Conversation

@DongEun02
Copy link
Contributor

@DongEun02 DongEun02 commented Dec 21, 2025

1) 작업한 이슈번호

SISC1-216

2) 변경 요약 (What & Why)

  • 무엇을 변경했는지: 외부페이지 제작
  • 변경했는지(문제/목표):

3) 스크린샷/동영상 (UI 변경 시)

전/후 비교, 반응형(모바일/데스크톱) 캡쳐

  • Before:
  • After:
image image image

4) 상세 변경사항 (전부 다)

  • 라우팅/페이지: Intro.jsx, Leaders.jsx, Portfolio.jsx
  • 컴포넌트: Filter.jsx, Info.jsx, MemberCard.jsx, PortfolioItem.jsx
  • 상태관리:
  • API 호출:
  • 스타일: External.module.css, Filter.module.css, Info.module.css, MemberCard.module.css, PortfolioItem.module.css
  • 기타:

5) 참고사항

API 연동 시에 전체적으로 코드 수정 예정

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 필터 UI 추가로 항목(팀/세대) 선택 가능.
    • 팀별 상세 정보(Info) 표시 컴포넌트 추가.
    • 멤버 카드 뷰 추가 및 목록 렌더링 개선(고유 키 적용).
    • 포트폴리오 아이템 컴포넌트 및 검색·페이지네이션 기능 추가.
    • 리더십 데이터 소스(세대별 구성) 추가.
  • 스타일

    • 필터, 정보, 멤버카드, 포트폴리오 등 UI 전반 스타일 모듈 추가 및 레이아웃 개선.

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

@DongEun02 DongEun02 requested a review from gxuoo as a code owner December 21, 2025 10:15
@coderabbitai
Copy link

coderabbitai bot commented Dec 21, 2025

Walkthrough

외부 페이지용 React 컴포넌트(Filter, Info, MemberCard, PortfolioItem)와 대응 CSS 모듈을 추가하고, Intro·Leaders·Portfolio 페이지를 Filter/Info/MemberCard/PortfolioItem으로 연동하며 External.module.css와 MonthlyReport.module.css를 확장했습니다. executivesByGeneration 유틸도 추가되었습니다.

Changes

Cohort / File(s) Change Summary
Filter 컴포넌트
frontend/src/components/external/Filter.jsx, frontend/src/components/external/Filter.module.css
새로운 presentational Filter 컴포넌트 추가: items, value, onChange props로 버튼 목록 렌더링, 접근성 속성 포함, 활성 상태 스타일 적용
Info 컴포넌트
frontend/src/components/external/Info.jsx, frontend/src/components/external/Info.module.css
팀명→설명 매핑을 렌더링하는 Info 컴포넌트 추가 (team prop 사용)
MemberCard 컴포넌트
frontend/src/components/external/MemberCard.jsx, frontend/src/components/external/MemberCard.module.css
멤버 카드 목록 렌더링 컴포넌트 추가; CSS 모듈 적용 및 각 항목에 key 추가
PortfolioItem 컴포넌트
frontend/src/components/external/PortfolioItem.jsx, frontend/src/components/external/PortfolioItem.module.css
포트폴리오 항목 표시용 컴포넌트 추가(이미지, 역할, 시간, 제목 레이아웃)
페이지 통합
frontend/src/pages/external/Intro.jsx, frontend/src/pages/external/Leaders.jsx, frontend/src/pages/external/Portfolio.jsx
Filter/Info/MemberCard/PortfolioItem 통합, useState 기반 선택 상태 추가; Portfolio에 검색·페이지네이션 로직 도입
스타일 업데이트
frontend/src/pages/external/External.module.css, frontend/src/pages/external/MonthlyReport.module.css
External.module.css에 다중 섹션(.info, .logoSection, .filter, .portfolio 등) 클래스 추가 및 레이아웃/헤더 크기 조정; MonthlyReport.header에 background-size: cover 추가
데이터 유틸리티
frontend/src/utils/executiveByGeneration.js
executivesByGeneration 정적 데이터 객체 추가(세대별 집행부 목록)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 검토 포인트:
    • Portfolio.jsx: 검색→필터→페이지네이션 경계 조건 및 totalPages 계산
    • Leaders/Intro: selected 초기값과 Filter onChange 바인딩 확인
    • MemberCard: 반복 렌더링 시 key 고유성 보장
    • CSS 모듈: 클래스 네이밍 충돌 및 반응형 동작 확인

Possibly related PRs

Suggested reviewers

  • gxuoo

Poem

🐰
새 필터로 팀을 골라 뛰어가고,
정보와 명함이 반짝이며 모여든다.
포트폴리오가 한 페이지씩 춤추고,
작은 당근만큼 기쁜 UI 한 송이.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 외부 페이지 제작 기능 추가라는 주요 변경사항을 명확하게 설명하고 있으며, 구체적으로 동아리소개, 임원소개, 운용포트폴리오 페이지 구현을 언급하고 있습니다.
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 SISC1-216-FE-external-detail-page

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f75091 and e4f1289.

📒 Files selected for processing (3)
  • frontend/src/components/external/Filter.jsx
  • frontend/src/components/external/MemberCard.jsx
  • frontend/src/pages/external/Portfolio.jsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/components/external/MemberCard.jsx
  • frontend/src/pages/external/Portfolio.jsx
  • frontend/src/components/external/Filter.jsx

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.

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: 8

🧹 Nitpick comments (6)
frontend/src/components/external/Filter.module.css (2)

1-6: 고정 너비가 작은 화면에서 문제를 일으킬 수 있습니다.

.wrapwidth: 220px로 고정 너비가 설정되어 있습니다. 모바일이나 좁은 뷰포트에서 레이아웃이 깨지거나 콘텐츠가 잘릴 수 있습니다. max-width를 사용하거나 미디어 쿼리로 반응형으로 만드는 것을 고려해보세요.


66-68: 스크롤바를 숨기면 사용성이 저하될 수 있습니다.

웹킷 스크롤바를 완전히 숨기면 사용자가 스크롤 가능한 콘텐츠가 있다는 것을 인지하기 어렵습니다. 특히 필터 아이템이 많을 경우 문제가 될 수 있습니다. 스크롤바를 얇게 스타일링하거나 다른 시각적 단서를 제공하는 것을 고려해보세요.

frontend/src/components/external/Info.jsx (1)

3-17: 팀 정보 데이터를 외부 파일로 분리하는 것을 고려하세요.

teamInfo 객체가 컴포넌트 내부에 하드코딩되어 있어 유지보수가 어렵습니다. executiveByGeneration.js처럼 별도의 데이터 파일로 분리하면:

  • 데이터 관리가 용이
  • 컴포넌트 코드가 간결
  • 향후 API 연동 시 마이그레이션이 쉬움
frontend/src/pages/external/Portfolio.jsx (1)

7-28: mock 데이터를 별도 파일로 분리하는 것을 고려하세요.

현재 mockPortfolio가 컴포넌트 내부에 정의되어 있습니다. Leaders.jsx에서 사용하는 executivesByGeneration.js처럼 별도의 유틸리티 파일로 분리하면 일관성과 유지보수성이 향상됩니다.

🔎 데이터 분리 예시

frontend/src/utils/mockPortfolio.js 생성:

export const mockPortfolio = [
  {
    id: 1,
    role: '운영진',
    time: '2',
    title: '자산 배분 전략 및 성과 보고서',
  },
  // ... 나머지 항목들
];

Portfolio.jsx에서 import:

+import { mockPortfolio } from '../../utils/mockPortfolio';
 import { useState } from 'react';

-const mockPortfolio = [
-  {
-    role: '운영진',
-    ...
-  },
-];
-
 const Portfolio = () => {
frontend/src/components/external/MemberCard.module.css (1)

14-18: 고정된 카드 크기가 작은 화면에서 문제가 될 수 있습니다.

카드의 너비와 높이가 고정값(260px x 340px)으로 설정되어 있어 모바일 기기나 작은 화면에서 레이아웃이 깨질 수 있습니다. max-width 또는 상대 단위 사용을 고려하세요.

🔎 반응형 개선 예시
 .card {
-  width: 260px;
-  height: 340px;
+  width: 100%;
+  max-width: 260px;
+  aspect-ratio: 260 / 340;
   background-color: #f4f4f4;
 }

또는 컨테이너 기준 상대 크기:

 .card {
-  width: 260px;
-  height: 340px;
+  width: clamp(200px, 100%, 260px);
+  height: clamp(265px, calc(100% * 340 / 260), 340px);
   background-color: #f4f4f4;
 }
frontend/src/pages/external/External.module.css (1)

32-36: 고정 패딩이 작은 화면에서 레이아웃 문제를 일으킬 수 있습니다.

.info와 .portfolio 섹션에 고정 패딩(80px 100px)이 적용되어 있어 모바일 기기에서 콘텐츠 영역이 너무 좁아질 수 있습니다. 반응형 패딩 사용을 고려하세요.

🔎 반응형 패딩 개선 예시
 .info {
   display: flex;
-  padding: 80px 100px;
+  padding: clamp(20px, 5vw, 80px) clamp(20px, 8vw, 100px);
   gap: 45px;
 }

 .portfolio {
   display: flex;
   flex-direction: column;
   justify-content: center;
-  padding: 80px 100px;
+  padding: clamp(20px, 5vw, 80px) clamp(20px, 8vw, 100px);
   gap: 45px;
 }

또는 미디어 쿼리 사용:

.info,
.portfolio {
  padding: 80px 100px;
}

@media (max-width: 768px) {
  .info,
  .portfolio {
    padding: 40px 20px;
  }
}

Also applies to: 68-74

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2f0606 and 9f75091.

📒 Files selected for processing (14)
  • frontend/src/components/external/Filter.jsx (1 hunks)
  • frontend/src/components/external/Filter.module.css (1 hunks)
  • frontend/src/components/external/Info.jsx (1 hunks)
  • frontend/src/components/external/Info.module.css (1 hunks)
  • frontend/src/components/external/MemberCard.jsx (1 hunks)
  • frontend/src/components/external/MemberCard.module.css (1 hunks)
  • frontend/src/components/external/PortfolioItem.jsx (1 hunks)
  • frontend/src/components/external/PortfolioItem.module.css (1 hunks)
  • frontend/src/pages/external/External.module.css (2 hunks)
  • frontend/src/pages/external/Intro.jsx (1 hunks)
  • frontend/src/pages/external/Leaders.jsx (1 hunks)
  • frontend/src/pages/external/MonthlyReport.module.css (1 hunks)
  • frontend/src/pages/external/Portfolio.jsx (1 hunks)
  • frontend/src/utils/executiveByGeneration.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
frontend/src/pages/external/Leaders.jsx (4)
frontend/src/pages/external/Intro.jsx (1)
  • selected (18-18)
frontend/src/components/external/Filter.jsx (1)
  • Filter (3-31)
frontend/src/components/external/MemberCard.jsx (1)
  • MemberCard (3-19)
frontend/src/utils/executiveByGeneration.js (2)
  • executivesByGeneration (1-23)
  • executivesByGeneration (1-23)
frontend/src/pages/external/Portfolio.jsx (3)
frontend/src/components/Board/SearchBar.jsx (1)
  • SearchBar (5-38)
frontend/src/components/external/PortfolioItem.jsx (1)
  • PortfolioItem (4-19)
frontend/src/components/stockgame/Pagination.jsx (1)
  • Pagination (3-77)
frontend/src/pages/external/Intro.jsx (3)
frontend/src/pages/external/Leaders.jsx (1)
  • selected (10-10)
frontend/src/components/external/Filter.jsx (1)
  • Filter (3-31)
frontend/src/components/external/Info.jsx (1)
  • Info (19-26)
🪛 Biome (2.1.2)
frontend/src/components/external/MemberCard.jsx

[error] 8-8: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (7)
frontend/src/components/external/Info.module.css (1)

1-21: LGTM!

CSS 모듈 스타일이 깔끔하고 일관성 있게 작성되었습니다. word-break: keep-all은 한국어 텍스트에 적합한 설정입니다.

frontend/src/pages/external/MonthlyReport.module.css (1)

12-12: LGTM!

background-size: cover 추가로 헤더 배경 이미지가 컨테이너를 올바르게 채우도록 개선되었습니다.

frontend/src/components/external/PortfolioItem.module.css (1)

1-50: LGTM!

포트폴리오 아이템의 레이아웃과 스타일링이 명확하고 일관성 있게 정의되었습니다.

frontend/src/pages/external/Leaders.jsx (2)

7-7: cohort 배열 생성이 올바르게 동작합니다.

24개 기수를 역순으로 생성하는 로직이 정확합니다.


10-10: 초기 상태 설정을 검증하세요.

cohort[0]을 초기값으로 사용하는 것은 좋지만, executivesByGeneration에 해당 데이터가 존재하는지 확인해야 합니다. 위의 데이터 누락 이슈가 해결되면 이 부분도 안전해집니다.

frontend/src/components/external/Filter.jsx (1)

16-16: 현재 코드는 안전하므로 변경이 필요하지 않습니다.

cohort 배열은 Array.from({ length: 24 }, (_, i) => \${24 - i}기`)로 생성되어 '24기'부터 '1기'까지 고유한 값들을 가지며, teams배열도 모두 고유한 팀 이름으로 구성되어 있습니다. 따라서 현재key={label}` 사용은 안전하며 React 경고가 발생하지 않습니다.

재사용성을 위해서는 index 기반 key가 아닌, 데이터에 고유 ID가 있다면 그것을 사용하거나, 없다면 items 배열의 각 요소가 고유한 속성을 갖도록 구조화하는 것이 좋습니다. (index 기반 key는 리스트 재정렬 시 버그를 유발할 수 있으므로 권장되지 않습니다)

Likely an incorrect or invalid review comment.

frontend/src/pages/external/Intro.jsx (1)

17-40: 구현이 깔끔하고 올바릅니다!

Filter와 Info 컴포넌트가 적절히 통합되어 있으며, 상태 관리도 올바르게 구현되었습니다. 선택된 팀 정보가 Info 컴포넌트에 정확히 전달되고 있습니다.

@DongEun02 DongEun02 merged commit f5632c2 into main Dec 22, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant