Skip to content

feat:동아리 상세페이지 구현#309

Merged
ParkSungju01 merged 2 commits into
developfrom
308-feat-동아리-상세페이지-구현
May 22, 2026

Hidden character warning

The head ref may contain hidden characters: "308-feat-\ub3d9\uc544\ub9ac-\uc0c1\uc138\ud398\uc774\uc9c0-\uad6c\ud604"
Merged

feat:동아리 상세페이지 구현#309
ParkSungju01 merged 2 commits into
developfrom
308-feat-동아리-상세페이지-구현

Conversation

@ParkSungju01
Copy link
Copy Markdown
Contributor

@ParkSungju01 ParkSungju01 commented May 22, 2026

✨ 요약

동아리 선택시 동아리 상세페이지가 나오도록 구현했습니다.
모집기간의 경우 추후 삭제 예정 가능성이 있어 기본적으로 모집기간이 나오거나 상시모집이 뜨도록만 구현해두었습니다.



😎 해결한 이슈



image

Summary by CodeRabbit

새로운 기능 및 개선 사항

  • 새로운 기능

    • 동아리 상세 정보 페이지 추가 (대학, 카테고리, 모집 정보 포함)
    • 동아리 목록에서 상세 페이지로의 네비게이션 추가
  • 개선 사항

    • 동아리 카테고리별 일관된 색상 스타일링 적용
    • UI 레이아웃 및 이미지 크기 최적화

Review Change Stack

@ParkSungju01 ParkSungju01 linked an issue May 22, 2026 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Warning

Rate limit exceeded

@ParkSungju01 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 45 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bf64220f-5229-467e-a350-357593a71ba9

📥 Commits

Reviewing files that changed from the base of the PR and between ef22929 and afca1ce.

📒 Files selected for processing (2)
  • apps/web/src/pages/ClubDetail/index.tsx
  • apps/web/src/pages/UniversityClubList/index.tsx

Walkthrough

이 PR은 동아리 상세 페이지 기능을 전체적으로 구현합니다. ClubDetail API 계약(ClubCategory, ClubDetailResponse, Recruitment)을 정의하고, React Query 쿼리 키와 옵션을 설정합니다. 신규 ClubDetail 페이지 컴포넌트는 대학/동아리 정보, 모집 상태, 소개 콘텐츠를 렌더링하며, CATEGORY_TEXT_COLORS 상수로 카테고리 색상을 적용합니다. App.tsx에 /clubs/:clubId 라우트를 추가하고, UniversityClubList 페이지의 카드 컴포넌트에 네비게이션 기능을 추가하여 상세 페이지로 이동하도록 합니다.

Possibly related PRs

  • BCSDLab/KONECT_FRONT_END#303: App.tsx의 Layout 및 라우터 기초 설정과 관련되어 있으며, 본 PR이 그 위에 /clubs/:clubId 라우트를 추가합니다.
  • BCSDLab/KONECT_FRONT_END#307: App.tsx에서 동아리 관련 라우트 설정을 다루며, 본 PR과 라우팅 구조 관점에서 연관됩니다.
  • BCSDLab/KONECT_FRONT_END#189: 동일한 /clubs/:clubId 라우트에 대한 App.tsx 설정 변경과 관련됩니다.

Suggested labels

✨ Feature

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 정확하게 주요 변경사항(동아리 상세페이지 구현)을 명확하고 간결하게 설명하고 있습니다.
Linked Issues check ✅ Passed 동아리 상세페이지 구현 요구사항(#308)이 충분히 충족되었습니다. ClubDetail 페이지, API 레이어, 라우팅, 타입 정의가 모두 구현되어 있습니다.
Out of Scope Changes check ✅ Passed UniversityClubList의 UI 업데이트와 CATEGORY_TEXT_COLORS 추가 같은 관련 지원 작업들이 포함되어 있습니다.
Description check ✅ Passed PR 설명에서 모집기간 처리 방식과 구현 내용이 잘 설명되어 있고, 디자인 이미지도 포함되어 있습니다.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 308-feat-동아리-상세페이지-구현

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
Copy Markdown
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: 4

🧹 Nitpick comments (4)
apps/web/src/apis/clubDetail/entity.ts (1)

1-1: ⚡ Quick win

내부 import는 @/* 별칭으로 통일해주세요.

상대 경로 대신 앱 내부 별칭을 쓰는 편이 유지보수에 유리합니다.

♻️ 제안 수정
-import type { UniversitySummary } from '../universityClub/entity';
+import type { UniversitySummary } from '`@/apis/universityClub/entity`';

As per coding guidelines, **/*.{ts,tsx}: Use path alias @/* for internal app imports (preferred over relative paths).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/apis/clubDetail/entity.ts` at line 1, Replace the relative
import for UniversitySummary with the app alias import: change the existing
import of UniversitySummary from '../universityClub/entity' to use the internal
path alias (e.g. import type { UniversitySummary } from
'`@/apis/universityClub/entity`') so all internal imports use the `@/*`
convention; update the import statement that references UniversitySummary in the
clubDetail entity module accordingly.
apps/web/src/pages/ClubDetail/index.tsx (1)

15-25: ⚡ Quick win

임의값 유틸리티 대신 디자인 토큰/시맨틱 타이포 클래스로 정리해주세요.

bg-[#F8FAFC], text-[20px] 같은 값은 토큰 기반 스타일링 원칙과 맞지 않습니다.

As per coding guidelines, **/*.{ts,tsx,css}: Use CSS export from @konect/design-tokens for design tokens, prioritized over inline values. As per coding guidelines, **/*.{ts,tsx}: Prioritize semantic typography utilities (e.g., text-h1, text-body1) over generic utilities.

Also applies to: 108-113

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/pages/ClubDetail/index.tsx` around lines 15 - 25, Replace
hard-coded utility values in the ClubDetail sections (the two <section> blocks
that render AddPhoto and AddMov) with design-token classes and semantic
typography utilities: remove bg-[`#F8FAFC`] and text-[20px] (and any other
arbitrary numeric utilities in those blocks and at lines 108-113) and use the
CSS exports from `@konect/design-tokens` for background colors and borders, and
swap the raw font-size utility for a semantic typography class such as
text-body1 or text-hX per the token map; update the className strings on the
section elements and the span elements that render "활동 사진" and "소개 영상" to use
the token-based bg/border classes and the semantic text-* class instead of
inline bracketed values.
apps/web/src/constants/club.ts (1)

8-8: ⚡ Quick win

카테고리 색상은 하드코딩 HEX 대신 디자인 토큰 클래스를 사용해주세요.

text-[#cd3bf6]는 토큰 일관성을 깨서 테마/브랜딩 변경 시 유지보수가 어려워집니다.

As per coding guidelines, **/*.{ts,tsx,css}: Use CSS export from @konect/design-tokens for design tokens, prioritized over inline values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/constants/club.ts` at line 8, The PERFORMANCE category color is
hardcoded as 'text-[`#cd3bf6`]'—replace it with the appropriate design-token class
from the CSS export in `@konect/design-tokens` to keep theming consistent: update
the exported constant where PERFORMANCE is defined (the key named PERFORMANCE in
the constants object) to use the token classname instead, and add/import the CSS
tokens from '`@konect/design-tokens`' (prefer the provided token name that maps to
the purple color) rather than an inline HEX value.
apps/web/src/apis/clubDetail/index.ts (1)

1-2: ⚡ Quick win

API 레이어 import도 @/* 별칭으로 맞춰주세요.

현재 상대 경로 import가 섞여 있어 컨벤션 일관성이 깨집니다.

♻️ 제안 수정
-import { apiClient } from '../client';
-import type { ClubDetailResponse } from './entity';
+import { apiClient } from '`@/apis/client`';
+import type { ClubDetailResponse } from '`@/apis/clubDetail/entity`';

As per coding guidelines, **/*.{ts,tsx}: Use path alias @/* for internal app imports (preferred over relative paths).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/apis/clubDetail/index.ts` around lines 1 - 2, Replace the
relative imports for apiClient and ClubDetailResponse with the project
path-alias form (use `@/`*) so imports are consistent with the app convention;
update the import statements that currently reference '../client' and './entity'
to their equivalent '`@/`...' alias imports (ensuring the symbols apiClient and
ClubDetailResponse are imported), and adjust any affected import paths or
tsconfig path mappings if necessary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/pages/ClubDetail/index.tsx`:
- Line 79: The UI displays clubDetail.university.clubCount directly which can
render "undefined개 동아리" if clubCount is optional; update the rendering in the
ClubDetail component to use a safe fallback (e.g.,
clubDetail.university?.clubCount ?? 0 or String(clubDetail.university?.clubCount
?? 0)) so the text always shows a valid number like "0개 동아리" and avoid breaking
UX when clubCount is missing.
- Line 66: The breadcrumb Link in the ClubDetail component is hardcoded to
"/universities/1/clubs"; replace that static path with a dynamic path derived
from the university id available in this component (for example use the route
params via useParams() or the club data's universityId/university.id) so the
Link navigates to `/universities/${universityId}/clubs` (or use
generatePath/route helper if available); update the Link rendering in ClubDetail
(index.tsx) to reference the dynamic variable instead of the literal string.

In `@apps/web/src/pages/UniversityClubList/index.tsx`:
- Line 92: The root div className in the UniversityClubList component (the JSX
line containing "mx-auto flex w-full max-w-369.5 flex-col px-5 pt-12 pb-20
sm:px-8 lg:pt-25.5 xl:px-0") and the other listed locations use hardcoded
Tailwind arbitrary values (e.g., max-w-369.5, rounded-[40px], h-19.5,
size-17.5); replace each arbitrary class with the corresponding shared
design-token utility from `@konect/design-tokens` (import the CSS tokens export if
not already imported) so e.g., swap max-w-369.5 → the token-based max-width
class, rounded-[40px] → token rounded class, h-19.5 → token height class,
size-17.5 → token font-size class; apply the same replacements at the other
occurrences you noted (lines 109, 119, 146, 203, 207, 226) to ensure consistent
token-based styling across the UniversityClubList component.
- Line 205: Replace the card click handlers that call useNavigate/onClick with
semantic links: in the components RecentClubCard and ClubCard, remove the
onClick={() => navigate(`/clubs/${club.id}`)} handlers and wrap the card (or its
interactive container) with a React Router <Link to={`/clubs/${club.id}`}> so
the target URL is used for navigation; ensure any button role or keyboard
handlers are removed or adjusted and that the Link preserves styling and props
previously applied to the clickable card element to retain visuals and
accessibility.

---

Nitpick comments:
In `@apps/web/src/apis/clubDetail/entity.ts`:
- Line 1: Replace the relative import for UniversitySummary with the app alias
import: change the existing import of UniversitySummary from
'../universityClub/entity' to use the internal path alias (e.g. import type {
UniversitySummary } from '`@/apis/universityClub/entity`') so all internal imports
use the `@/*` convention; update the import statement that references
UniversitySummary in the clubDetail entity module accordingly.

In `@apps/web/src/apis/clubDetail/index.ts`:
- Around line 1-2: Replace the relative imports for apiClient and
ClubDetailResponse with the project path-alias form (use `@/`*) so imports are
consistent with the app convention; update the import statements that currently
reference '../client' and './entity' to their equivalent '`@/`...' alias imports
(ensuring the symbols apiClient and ClubDetailResponse are imported), and adjust
any affected import paths or tsconfig path mappings if necessary.

In `@apps/web/src/constants/club.ts`:
- Line 8: The PERFORMANCE category color is hardcoded as
'text-[`#cd3bf6`]'—replace it with the appropriate design-token class from the CSS
export in `@konect/design-tokens` to keep theming consistent: update the exported
constant where PERFORMANCE is defined (the key named PERFORMANCE in the
constants object) to use the token classname instead, and add/import the CSS
tokens from '`@konect/design-tokens`' (prefer the provided token name that maps to
the purple color) rather than an inline HEX value.

In `@apps/web/src/pages/ClubDetail/index.tsx`:
- Around line 15-25: Replace hard-coded utility values in the ClubDetail
sections (the two <section> blocks that render AddPhoto and AddMov) with
design-token classes and semantic typography utilities: remove bg-[`#F8FAFC`] and
text-[20px] (and any other arbitrary numeric utilities in those blocks and at
lines 108-113) and use the CSS exports from `@konect/design-tokens` for background
colors and borders, and swap the raw font-size utility for a semantic typography
class such as text-body1 or text-hX per the token map; update the className
strings on the section elements and the span elements that render "활동 사진" and
"소개 영상" to use the token-based bg/border classes and the semantic text-* class
instead of inline bracketed values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6241cb60-cba5-4172-bb0b-595464620a2a

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb2f5d and ef22929.

⛔ Files ignored due to path filters (3)
  • apps/web/src/assets/None-image.png is excluded by !**/*.png, !apps/*/src/assets/** and included by **
  • apps/web/src/assets/add-mov.svg is excluded by !**/*.svg, !apps/*/src/assets/** and included by **
  • apps/web/src/assets/add-photo.svg is excluded by !**/*.svg, !apps/*/src/assets/** and included by **
📒 Files selected for processing (8)
  • apps/web/src/App.tsx
  • apps/web/src/apis/clubDetail/entity.ts
  • apps/web/src/apis/clubDetail/index.ts
  • apps/web/src/apis/clubDetail/queries.ts
  • apps/web/src/apis/universityClub/entity.ts
  • apps/web/src/constants/club.ts
  • apps/web/src/pages/ClubDetail/index.tsx
  • apps/web/src/pages/UniversityClubList/index.tsx

Comment thread apps/web/src/pages/ClubDetail/index.tsx Outdated
Comment thread apps/web/src/pages/ClubDetail/index.tsx Outdated
return (
<main className="bg-web-background min-h-screen text-black">
<div className="mx-auto flex w-full max-w-[1478px] flex-col px-5 pt-12 pb-20 sm:px-8 lg:pt-[102px] xl:px-0">
<div className="mx-auto flex w-full max-w-369.5 flex-col px-5 pt-12 pb-20 sm:px-8 lg:pt-25.5 xl:px-0">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

하드코딩된 Tailwind 임의값 대신 디자인 토큰 클래스로 통일해주세요.

변경된 구간에 max-w-369.5, rounded-[40px], h-19.5, size-17.5 같은 임의값 클래스가 섞여 있어 토큰 기반 스타일 일관성이 깨집니다. 공용 토큰(또는 토큰 기반 유틸 클래스)으로 치환하는 쪽이 안전합니다.

As per coding guidelines, "**/*.{ts,tsx,css}: Use Tailwind CSS v4 with shared design tokens from @konect/design-tokens / Use CSS export from @konect/design-tokens for design tokens, prioritized over inline values".

Also applies to: 109-109, 119-119, 146-146, 203-203, 207-207, 226-226

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/pages/UniversityClubList/index.tsx` at line 92, The root div
className in the UniversityClubList component (the JSX line containing "mx-auto
flex w-full max-w-369.5 flex-col px-5 pt-12 pb-20 sm:px-8 lg:pt-25.5 xl:px-0")
and the other listed locations use hardcoded Tailwind arbitrary values (e.g.,
max-w-369.5, rounded-[40px], h-19.5, size-17.5); replace each arbitrary class
with the corresponding shared design-token utility from `@konect/design-tokens`
(import the CSS tokens export if not already imported) so e.g., swap max-w-369.5
→ the token-based max-width class, rounded-[40px] → token rounded class, h-19.5
→ token height class, size-17.5 → token font-size class; apply the same
replacements at the other occurrences you noted (lines 109, 119, 146, 203, 207,
226) to ensure consistent token-based styling across the UniversityClubList
component.

Comment thread apps/web/src/pages/UniversityClubList/index.tsx Outdated
@ParkSungju01 ParkSungju01 requested a review from ff1451 May 22, 2026 11:00
Copy link
Copy Markdown
Collaborator

@ff1451 ff1451 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다

@ParkSungju01 ParkSungju01 merged commit 6ca58ac into develop May 22, 2026
3 checks 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.

[feat] 동아리 상세페이지 구현

2 participants