Skip to content

[feat] 학교별 동아리 목록 페이지 구현#307

Merged
ff1451 merged 11 commits into
developfrom
306-feat-학교별-동아리-목록-페이지-구현
May 20, 2026

Hidden character warning

The head ref may contain hidden characters: "306-feat-\ud559\uad50\ubcc4-\ub3d9\uc544\ub9ac-\ubaa9\ub85d-\ud398\uc774\uc9c0-\uad6c\ud604"
Merged

[feat] 학교별 동아리 목록 페이지 구현#307
ff1451 merged 11 commits into
developfrom
306-feat-학교별-동아리-목록-페이지-구현

Conversation

@ff1451
Copy link
Copy Markdown
Collaborator

@ff1451 ff1451 commented May 20, 2026

✨ 요약

-  대학별 동아리 목록 조회 API 타입/쿼리 훅을 추가했습니다.
- 피그마 기반 학교별 동아리 목록 페이지를 구현했습니다.
- 동아리명 검색, 분과 필터, 무한 스크롤과  대학 카드 라우팅을 연결했습니다.



😎 해결한 이슈



Summary by CodeRabbit

릴리스 노트

  • New Features
    • 특정 대학의 동아리 목록을 조회할 수 있는 새로운 페이지 추가
    • 동아리 목록 페이지에서 검색, 카테고리별 필터링 기능 제공
    • 무한 스크롤을 통한 동아리 리스트 탐색 지원
    • 홈 페이지의 대학 카드에서 해당 대학의 동아리 목록으로 바로 이동 가능

Review Change Stack

ff1451 and others added 11 commits April 1, 2026 23:01
* 205 feat 이미지 전처리 기능 구현 (#206)

* feat: 전처리 로직 및 WebWorker 구현

* feat: 전처리 적용 및 preview 동시성 제어 로직 추가

* refactor: 리뷰 반영

* [hotfix] 하단바 너비 수정 (#208)

* hotfix: 하단바 너비 수정

* chore: 불필요한 값 제거

* refactor: 고정 gap 제거

* Reapply "[feat] 광고 배너 추가 (#200)"

This reverts commit c51ec85.

* [feat] 하단바 리디자인 (#213)

* chore: asset 추가

* feat: 하단바 리디자인 반영 및 레이아웃 수정

* [refactor] 광고 카드 레이아웃 밀림 수정 (#215)

* refactor: 광고 개수 측정 시기 변경 및 기본값 제거

* feat: 스켈레톤 UI 추가

* feat: 인앱 알림 페이지 및 토스트 구현 (#217)

* feat: 알림 API 및 스트림 기반 추가

* feat: 인앱 알림 레이어 추가

* feat: 알림 페이지 및 헤더 진입 구현

* fix: 알림 스트림 401 재시도 조건 정리

* fix: 알림 목록 이동 차단 제거

* refactor: 알림 공용 훅 위치 정리

* fix: 알림 재연결 캐시 동기화 추가

* fix: 알림 목록 토스트 큐 누적 방지

* fix: 알림 읽음 카운트 감소 조건 보강

* [refactor] 도메인별 TanStack Query 훅 정리 (#219)

* chore: pwa용 이미지 제거

* refactor: auth 도메인 쿼리와 뮤테이션 정리

* refactor: council과 schedule 조회 훅 정리

* refactor: chat과 notification 캐시 처리 정리

* refactor: club 조회와 지원 플로우 정리

* refactor: manager 도메인 캐시 처리 정리

* refactor: studyTime 도메인 쿼리와 뮤테이션 정리

* refactor: 광고와 업로드 도메인 훅 정리

* [refactor] mutaton query 및 hook 추가 수정 (#221)

* refactor: auth와 user myInfo 훅 정리

* refactor: club과 schedule 조회 훅 정리

* refactor: chat과 notification 훅 구조 정리

* refactor: club 지원 뮤테이션 훅 정리

* refactor: manager 뮤테이션 훅 구조 정리

* refactor: mutation 훅 cache 정리

* refactor: 컨벤션 통일

* refactor: isRead 조건 정리

* fix: 채팅 스크롤 문제 수정

* refactor: 불필요한 코드 제거

* [fix] 모바일 환경 입력창과 키보드 간의 간격이 큰 문제 수정 (#223)

* chore: 가공용 safeArea 변수 선언

* refactor: 고정 패딩 값 수정 및 safeArea 적용 변경

* feat: 키보드 활성화 감지 및 safeArea 적용 여부 기능 추가

* refactor: 매직넘버 상수화 및 가로모드 처리

* [fix] 키보드 활성화 시 화면 흔들림 문제 수정 (#225)

* refactor: 채팅 viewport 훅 네이밍 정리

* refactor: viewport 높이 잠금 훅 적용 시점 조정

* [fix] 키보드 활성화 시 채팅 화면 전체가 흔들리는 문제 수정 (#227)

* refactor: 채팅 viewport 훅 네이밍 정리

* refactor: viewport 높이 잠금 훅 적용 시점 조정

* fix: 채팅 화면 스크롤 잠금으로 키보드 흔들림 완화

* fix: 입력 포커스 중 viewport offset 고정 (#229)

* fix: 문서 루트 스크롤 잠금으로 빈 공간 잔류 방지 (#232)

* [fix] 키보드 활성화 시 채팅 화면 상단 고정이 깨지고 빈 공간이 남는 문제 수정 (#234)

* fix: 채팅 화면 상단 고정 깨짐과 빈 공간 잔류 수정

* refactor: 라우트 조건 수정

* fix: 문서 스크롤 위치 감지 보강

* refactor: 입력 요소 판별 유틸과 스크롤 주석 정리

* [fix] 키보드 활성화 시 채팅 화면에서 문서 스크롤이 발생하는 문제 수정 (#236)

* fix: 채팅 문서 스크롤 제스처 차단

* fix: 입력 요소 터치 동작 예외 처리

* [fix] 키보드 활성화 시 채팅방이 마지막 메시지 위치를 유지하지 못하는 문제 수정 (#238)

* fix: 키보드 활성화 시 채팅 하단 정렬 유지

* refactor: 채팅 리사이즈 관찰 안정화

* fix: mypage 연계 약관 페이지 뒤로가기 수정 (#240)

* refactor: alias import 경로 정리

* fix: query 설정과 suspense 분기 정리

* refactor: 관리자 화면 스타일 유틸 정리

* fix: 이미지 전처리 예외 처리 보강

* fix: 헤더와 회비 화면 동작 정리

* fix: 공통 유틸 안정성 개선

* fix: 이미지 전처리 실패 처리를 보정

* fix: 모집 공고 저장 후 설정 반영 순서 조정

* fix: 부원 직책 변경 실패 처리를 보강

* fix: 약관 링크 접근성을 개선

* fix: 공통 쿼리와 유틸 안정성을 보완

* [feat] 동적 버전 정보 표시 구현 (#211)

* feat: 동적 버전 정보 표시 구현

* refactor: 버전 정보 미 존재시 v 표시 제거

* [feat] 메인화면 동아리 카드 디자인 수정 반영 (#242)

* feat: 메인화면 동아리 카드 디자인 수정

* chore: 하단바 아이콘 수정

* refactor: 코드래빗 리뷰 반영

* refactor: and 연산자로 변경

* apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화 (#244)

* refactor: apiClient 코드 중복 제거 및 네이티브 브릿지 인증 동기화 중앙화

* refactor: body 직렬화 가드를 plain object/array로 한정

* fix: body 읽기 중 AbortError가 ParseError로 오분류되는 문제 수정

* [refactor] 에러 처리 유틸 및 utils 구조 정리 (#246)

* refactor: 에러 처리 유틸 및 공통 토스트 흐름 정리

* refactor: utils 폴더 구조를 역할별로 정리

* refactor: 코드래빗 리뷰 반영

* refactor: 코드래빗 리뷰 반영

* Update src/pages/Home/components/HomeClubSection.tsx

* fix: 인증 세션 복구 흐름 정리

* fix: 홈 동아리 카드 레이아웃 정리

* [feat] 총동아리 페이지 리디자인 및 하단 오버레이 정리 (#249)

* refactor: 하단 오버레이 처리 공통화

* feat: 총동아리 페이지와 헤더 리디자인 반영

* fix: 채팅 하단 여백과 외부 링크 속성 수정

* refactor: 총동아리 헤더 설정 정리

* fix: 총동아리 상세 접근성과 스타일 보완

* [feat] 마이페이지 관리자 카드 분리 및 채팅 미확인 배지 반영 (#251)

* feat: 하단 채팅 배지 표시 및 조회 조건 보완

* refactor: 관리자 정보 카드 컴포넌트 분리

* feat: 채팅 페이지 리디자인 (#252)

* feat: 채팅 페이지 리디자인

* fix:tailwind 문법 수정

* fix: 코드 수정

* fix: 폰트 색상 및 위치 수정

* fix: 채팅방 사람수 정렬

* fix: 오타 수정

* chore: conflict 해결 중 누락된 부분 수정

* [refactor] 광고 렌더링 조건 수정 (#254)

* refactor: 광고 렌더링 조건 수정

* docs: 문서명 변경

---------

Co-authored-by: 박성주 <145267904+ParkSungju01@users.noreply.github.com>
@ff1451 ff1451 added the ✨ Feature 기능 개발 label May 20, 2026
@ff1451 ff1451 self-assigned this May 20, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Walkthrough

이 PR은 대학별 동아리 목록 페이지를 구현합니다. 새 API 데이터 모델(ClubCategory, UniversityClub, UniversityClubListResponse)과 getUniversityClubs 클라이언트 함수를 정의하고, React Query 설정으로 단일/무한 페이지 쿼리를 구성합니다. 352줄의 UniversityClubList 페이지는 라우트 파라미터 검증, URL 기반 검색/필터링, 디바운싱된 검색 입력, IntersectionObserver 무한 스크롤, 최근 동아리 섹션, 카테고리 필터 버튼, 빈 상태 메시지를 구현합니다. App.tsx에서 라우트를 추가하고 Home 페이지 대학 카드를 Link로 변경하여 새 페이지로 라우팅합니다.

Possibly related PRs

  • BCSDLab/KONECT_FRONT_END#303: App.tsx 라우터 구조 개선으로 Layout과 Route 트리 연결을 선행했으며, 이 PR에서 /universities/:universityId/clubs 라우트를 추가하는 기반이 됩니다.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 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 API 타입 정의, 쿼리 훅, 무한 스크롤, 검색/필터 기능, 라우팅 연결 등 #306의 모든 요구사항이 충실하게 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 학교별 동아리 목록 페이지 구현과 직접 관련되며, 범위를 벗어난 변경은 없습니다.

✏️ 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 306-feat-학교별-동아리-목록-페이지-구현

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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

🧹 Nitpick comments (4)
apps/web/src/apis/universityClub/index.ts (1)

1-2: ⚡ Quick win

내부 import는 상대경로 대신 경로 별칭(@/*)으로 통일해주세요.

현재 상대경로 import는 프로젝트 컨벤션과 맞지 않습니다.

diff 제안
-import { apiClient } from '../client';
-import type { UniversityClubListRequestParams, UniversityClubListResponse } from './entity';
+import { apiClient } from '`@/apis/client`';
+import type { UniversityClubListRequestParams, UniversityClubListResponse } 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/universityClub/index.ts` around lines 1 - 2, Summary: The
file uses relative imports; replace them with the project's path alias. Fix:
change the import of apiClient from '../client' to the path-alias equivalent
(e.g., import { apiClient } from '`@/apis/client`') and change the entity types
import from './entity' to the alias form (e.g., import type {
UniversityClubListRequestParams, UniversityClubListResponse } from
'`@/apis/universityClub/entity`'); ensure you update both import statements to use
the '`@/`...' alias and keep the same identifiers (apiClient,
UniversityClubListRequestParams, UniversityClubListResponse).
apps/web/src/apis/universityClub/queries.ts (1)

3-4: ⚡ Quick win

여기도 내부 import를 @/* 별칭으로 맞춰주세요.

쿼리 파일만 상대경로를 쓰면 import 규칙 일관성이 깨집니다.

diff 제안
-import type { UniversityClubListRequestParams, UniversityClubListResponse } from './entity';
-import { getUniversityClubs } from '.';
+import type { UniversityClubListRequestParams, UniversityClubListResponse } from '`@/apis/universityClub/entity`';
+import { getUniversityClubs } from '`@/apis/universityClub`';
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/universityClub/queries.ts` around lines 3 - 4, The import
uses a relative path for an internal module which violates the alias rule;
change the imports in this file to use the app path alias: replace the relative
import of getUniversityClubs from '.' with the alias form (e.g., import {
getUniversityClubs } from '`@/apis/universityClub`' or the correct alias root for
that module) and likewise ensure the type imports
(UniversityClubListRequestParams, UniversityClubListResponse) use the '`@/`...'
alias; update the import statements that reference the symbols
getUniversityClubs, UniversityClubListRequestParams, and
UniversityClubListResponse to the `@/`* path alias.
apps/web/src/App.tsx (1)

6-6: ⚡ Quick win

내부 import는 alias(@/)로 맞춰주세요.

상대 경로 대신 alias를 사용해 import 일관성을 맞추는 편이 좋습니다.
As per coding guidelines, "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/App.tsx` at line 6, The import in App.tsx uses a relative path
for UniversityClubList; replace the relative import with the project path alias
format used across the app (e.g. import UniversityClubList from
'`@/pages/UniversityClubList`') so internal imports follow the "`@/`..." convention
and stay consistent with the codebase; update the import line that references
UniversityClubList accordingly.
apps/web/src/pages/UniversityClubList/index.tsx (1)

33-97: 🏗️ Heavy lift

페이지 비즈니스 로직을 커스텀 훅으로 분리해주세요.

UniversityClubListContent에 URL 상태, 쿼리 파라미터 조합, observer 로직이 밀집되어 있어 라우트 엔트리 페이지 책임이 과합니다. useUniversityClubListState 같은 훅으로 분리하면 유지보수성이 좋아집니다.
As per coding guidelines, "apps/*/src/pages/**/index.tsx: 라우트 엔트리 페이지 패턴을 확인해주세요: - 비즈니스 로직은 커스텀 훅으로 분리되어 있는지".

🤖 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` around lines 33 - 97,
Extract the business logic from UniversityClubListContent into a new custom hook
(e.g., useUniversityClubListState) that accepts universityId and encapsulates
URL/search param handling (useSearchParams, selectedCategory, query,
updateSearchQuery), local state (searchKeyword, setSearchKeyword), requestParams
creation, data fetching via
useSuspenseInfiniteQuery(universityClubQueries.infiniteList(...)), observer
setup (observerRef and the IntersectionObserver effect), and handlers
(handleSearchKeywordChange, handleCategoryChange); have the hook return
observerRef plus derived values (university, clubs, total counts, recentClubs,
hasNextPage, isFetchingNextPage, fetchNextPage) and the handler setters so
UniversityClubListContent keeps only JSX and presentation logic while the new
useUniversityClubListState contains all moved logic.
🤖 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/Home/index.tsx`:
- Line 137: The Tailwind class string in the JSX div's className contains a typo
"xl: mt-7" which leaves "xl:" isolated; update the class value used in the Home
page component (the div with className "xl: mt-7 grid ...") by removing the
space so the token reads "xl:mt-7" to enable the intended responsive margin.

In `@apps/web/src/pages/UniversityClubList/index.tsx`:
- Around line 207-238: RecentClubCard and ClubCard render inert <button>
elements with no onClick; replace them with an appropriate non-interactive
container or a navigable link: if the cards are purely presentational, swap the
<button> in RecentClubCard and ClubCard for a semantic <article> or <div>
(remove type="button") and keep existing classes; if the cards are intended to
navigate, wrap the card contents with the app's Link component (e.g., next/link)
and move the className to the link element so keyboard users get correct
behavior. Ensure to update imports (add Link if used) and remove any
button-specific attributes (type="button", focus styles tied to button) or adapt
them for the chosen element.

---

Nitpick comments:
In `@apps/web/src/apis/universityClub/index.ts`:
- Around line 1-2: Summary: The file uses relative imports; replace them with
the project's path alias. Fix: change the import of apiClient from '../client'
to the path-alias equivalent (e.g., import { apiClient } from '`@/apis/client`')
and change the entity types import from './entity' to the alias form (e.g.,
import type { UniversityClubListRequestParams, UniversityClubListResponse } from
'`@/apis/universityClub/entity`'); ensure you update both import statements to use
the '`@/`...' alias and keep the same identifiers (apiClient,
UniversityClubListRequestParams, UniversityClubListResponse).

In `@apps/web/src/apis/universityClub/queries.ts`:
- Around line 3-4: The import uses a relative path for an internal module which
violates the alias rule; change the imports in this file to use the app path
alias: replace the relative import of getUniversityClubs from '.' with the alias
form (e.g., import { getUniversityClubs } from '`@/apis/universityClub`' or the
correct alias root for that module) and likewise ensure the type imports
(UniversityClubListRequestParams, UniversityClubListResponse) use the '`@/`...'
alias; update the import statements that reference the symbols
getUniversityClubs, UniversityClubListRequestParams, and
UniversityClubListResponse to the `@/`* path alias.

In `@apps/web/src/App.tsx`:
- Line 6: The import in App.tsx uses a relative path for UniversityClubList;
replace the relative import with the project path alias format used across the
app (e.g. import UniversityClubList from '`@/pages/UniversityClubList`') so
internal imports follow the "`@/`..." convention and stay consistent with the
codebase; update the import line that references UniversityClubList accordingly.

In `@apps/web/src/pages/UniversityClubList/index.tsx`:
- Around line 33-97: Extract the business logic from UniversityClubListContent
into a new custom hook (e.g., useUniversityClubListState) that accepts
universityId and encapsulates URL/search param handling (useSearchParams,
selectedCategory, query, updateSearchQuery), local state (searchKeyword,
setSearchKeyword), requestParams creation, data fetching via
useSuspenseInfiniteQuery(universityClubQueries.infiniteList(...)), observer
setup (observerRef and the IntersectionObserver effect), and handlers
(handleSearchKeywordChange, handleCategoryChange); have the hook return
observerRef plus derived values (university, clubs, total counts, recentClubs,
hasNextPage, isFetchingNextPage, fetchNextPage) and the handler setters so
UniversityClubListContent keeps only JSX and presentation logic while the new
useUniversityClubListState contains all moved logic.
🪄 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: 960310f5-3a66-457a-865a-2a88297610b9

📥 Commits

Reviewing files that changed from the base of the PR and between e82166d and 51a70ea.

📒 Files selected for processing (6)
  • apps/web/src/App.tsx
  • apps/web/src/apis/universityClub/entity.ts
  • apps/web/src/apis/universityClub/index.ts
  • apps/web/src/apis/universityClub/queries.ts
  • apps/web/src/pages/Home/index.tsx
  • apps/web/src/pages/UniversityClubList/index.tsx

>
<section className="min-h-0 overflow-hidden" aria-hidden={isSearching}>
<SectionTitle title="최근에 본 동아리" description="관심있게 봤던 동아리를 다시 확인해보세요." />
<div className="xl: mt-7 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Tailwind 클래스 오타를 수정해주세요 (xl:).

Line 137의 classNamexl: mt-7가 있어 xl:가 단독 토큰으로 남습니다. xl:mt-7로 붙여야 의도한 반응형 마진이 적용됩니다.

🤖 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/Home/index.tsx` at line 137, The Tailwind class string in
the JSX div's className contains a typo "xl: mt-7" which leaves "xl:" isolated;
update the class value used in the Home page component (the div with className
"xl: mt-7 grid ...") by removing the space so the token reads "xl:mt-7" to
enable the intended responsive margin.

Comment on lines +207 to +238
function RecentClubCard({ club }: { club: UniversityClub }) {
return (
<button
className="border-primary-200 bg-web-background hover:border-primary-500 focus-visible:outline-primary-500 flex h-[122px] max-h-[122px] min-h-[122px] w-full shrink-0 items-center gap-7 overflow-hidden rounded-[20px] border px-7.5 py-6.5 text-left transition-colors focus-visible:outline-2 focus-visible:outline-offset-2"
type="button"
>
<ClubImage className="size-[70px]" imageUrl={club.imageUrl} name={club.name} />
<ClubMeta
club={club}
titleClassName="w-57 text-[20px]"
categoryClassName="text-[16px]"
descriptionClassName="text-[16px]"
/>
</button>
);
}

function ClubCard({ club }: { club: UniversityClub }) {
return (
<button
className="border-text-100 hover:border-primary-500 focus-visible:outline-primary-500 flex h-35 items-center gap-5 overflow-hidden rounded-[20px] border bg-white px-5.5 py-8 text-left transition-colors hover:shadow-[0_0_30px_0_rgba(105,191,223,0.18)] focus-visible:outline-2 focus-visible:outline-offset-2"
type="button"
>
<ClubImage className="size-[50px]" imageUrl={club.imageUrl} name={club.name} />
<ClubMeta
club={club}
titleClassName="w-57 text-[20px]"
categoryClassName="text-[14px]"
descriptionClassName="text-[14px]"
/>
</button>
);
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

동작 없는 button은 비대화형 요소로 바꿔주세요.

Line 207, Line 226의 카드가 button이지만 실제 액션이 없습니다. 키보드/스크린리더 사용자에게 “눌리지만 아무 일도 안 일어나는” 컨트롤로 노출됩니다. 클릭 동작이 없다면 article/div로 바꾸거나, 이동 의도가 있으면 Link로 연결해주세요.

🤖 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` around lines 207 - 238,
RecentClubCard and ClubCard render inert <button> elements with no onClick;
replace them with an appropriate non-interactive container or a navigable link:
if the cards are purely presentational, swap the <button> in RecentClubCard and
ClubCard for a semantic <article> or <div> (remove type="button") and keep
existing classes; if the cards are intended to navigate, wrap the card contents
with the app's Link component (e.g., next/link) and move the className to the
link element so keyboard users get correct behavior. Ensure to update imports
(add Link if used) and remove any button-specific attributes (type="button",
focus styles tied to button) or adapt them for the chosen element.

@ff1451 ff1451 merged commit 8eb2f5d into develop May 20, 2026
3 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] 학교별 동아리 목록 페이지 구현

1 participant