Skip to content

배포 최신화#141

Merged
shinwokkang merged 115 commits intomainfrom
dev
Feb 26, 2026
Merged

배포 최신화#141
shinwokkang merged 115 commits intomainfrom
dev

Conversation

@shinwokkang
Copy link
Contributor

@shinwokkang shinwokkang commented Feb 26, 2026

📌 개요 (Summary)

  • 변경 사항에 대한 간략한 요약을 적어주세요.
  • 관련 이슈가 있다면 링크를 걸어주세요 (예: [fix] cicd / build 문제 #123).

🛠️ 변경 사항 (Changes)

  • 새로운 기능 추가
  • 버그 수정
  • 코드 리팩토링
  • 문서 업데이트
  • 기타 (설명: )

📸 스크린샷 (Screenshots)

(UI 변경 사항이 있다면 첨부해주세요)

✅ 체크리스트 (Checklist)

  • 빌드가 성공적으로 수행되었나요? (pnpm build)
  • 린트 에러가 없나요? (pnpm lint)
  • 불필요한 콘솔 로그나 주석을 제거했나요?

Summary by CodeRabbit

Release Notes

  • New Features

    • Added admin dashboard with pages for managing users, groups, news, and stories featuring search and pagination capabilities
    • Integrated real book search, recommendations, and detail views
    • Enabled story creation and management with automatic publishing workflows
    • Added notification preferences and settings management
    • Launched team management interface for group meetings
    • Implemented profile editing with image uploads and nickname validation
    • Added infinite scrolling to news, notifications, and story feeds
  • Improvements

    • Enhanced user feedback with loading states, success confirmations, and error messages
    • Improved navigation flows across main and admin sections

김기현 and others added 30 commits February 19, 2026 20:45
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
shinwokkang and others added 21 commits February 25, 2026 19:03
[feat] 관리자 로그인 및 기본 관리 페이지 UI 구현
@shinwokkang shinwokkang added the ✨ feat 새로운 기능 추가 label Feb 26, 2026
@vercel
Copy link

vercel bot commented Feb 26, 2026

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

Project Deployment Actions Updated (UTC)
check-mo Ready Ready Preview Feb 26, 2026 1:52pm

@shinwokkang shinwokkang merged commit 126709a into main Feb 26, 2026
4 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4327ca and 171d8e5.

⛔ Files ignored due to path filters (5)
  • package-lock.json is excluded by !**/package-lock.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • public/ArrowLeft3.svg is excluded by !**/*.svg
  • public/Polygon7.svg is excluded by !**/*.svg
  • public/icon_plus_2.svg is excluded by !**/*.svg
📒 Files selected for processing (115)
  • .env.example
  • .gitignore
  • next.config.ts
  • package.json
  • src/app/(admin)/admin/(app)/groups/page.tsx
  • src/app/(admin)/admin/(app)/layout.tsx
  • src/app/(admin)/admin/(app)/news/page.tsx
  • src/app/(admin)/admin/(app)/page.tsx
  • src/app/(admin)/admin/(app)/stories/page.tsx
  • src/app/(admin)/admin/(app)/users/page.tsx
  • src/app/(admin)/admin/(auth)/login/page.tsx
  • src/app/(main)/books/[id]/page.tsx
  • src/app/(main)/news/page.tsx
  • src/app/(main)/page.tsx
  • src/app/(main)/search/page.tsx
  • src/app/(main)/setting/news/page.tsx
  • src/app/(main)/setting/notifications/page.tsx
  • src/app/(main)/setting/password/page.tsx
  • src/app/(main)/setting/profile/page.tsx
  • src/app/(main)/stories/[id]/page.tsx
  • src/app/(main)/stories/new/page.tsx
  • src/app/(main)/stories/page.tsx
  • src/app/groups/[id]/admin/bookcase/[meetingId]/dummy.ts
  • src/app/groups/[id]/admin/bookcase/[meetingId]/layout.tsx
  • src/app/groups/[id]/admin/bookcase/[meetingId]/page.tsx
  • src/app/groups/[id]/admin/bookcase/new/page.tsx
  • src/app/groups/[id]/admin/bookcase/page.tsx
  • src/app/groups/[id]/bookcase/[bookId]/MeetingTabSection.tsx
  • src/app/groups/[id]/bookcase/[bookId]/meeting/page.tsx
  • src/app/groups/[id]/bookcase/[bookId]/page.tsx
  • src/app/groups/[id]/bookcase/page.tsx
  • src/app/groups/[id]/layout.tsx
  • src/app/groups/[id]/page.tsx
  • src/app/layout.tsx
  • src/app/providers.tsx
  • src/components/base-ui/Book/BookCoverCard.tsx
  • src/components/base-ui/BookStory/bookstory_card.tsx
  • src/components/base-ui/BookStory/bookstory_card_large.tsx
  • src/components/base-ui/BookStory/bookstory_detail.tsx
  • src/components/base-ui/Bookcase/Admin/.gitkeep
  • src/components/base-ui/Bookcase/Admin/bookdetailgrouping/MemberItem.tsx
  • src/components/base-ui/Bookcase/Admin/bookdetailgrouping/MemberPool.tsx
  • src/components/base-ui/Bookcase/Admin/bookdetailgrouping/TeamBoard.tsx
  • src/components/base-ui/Bookcase/BookDetailNav.tsx
  • src/components/base-ui/Bookcase/BookcaseCard.tsx
  • src/components/base-ui/Bookcase/ChatTeamSelectModal.tsx
  • src/components/base-ui/Bookcase/MeetingInfo.tsx
  • src/components/base-ui/Comment/comment_item.tsx
  • src/components/base-ui/Comment/comment_section.tsx
  • src/components/base-ui/Group/BookshelfModal.tsx
  • src/components/base-ui/Join/JoinButton.tsx
  • src/components/base-ui/Login/useLoginForm.tsx
  • src/components/base-ui/MyPage/MyBookStoryList.tsx
  • src/components/base-ui/MyPage/MyMeetingList.tsx
  • src/components/base-ui/MyPage/MyNotificationList.tsx
  • src/components/base-ui/MyPage/UserProfile.tsx
  • src/components/base-ui/MyPage/items/MyMeetingCard.tsx
  • src/components/base-ui/MyPage/items/MyNotificationItem.tsx
  • src/components/base-ui/News/recommendbook_element.tsx
  • src/components/base-ui/News/today_recommended_books.tsx
  • src/components/base-ui/Search/search_recommendbook.tsx
  • src/components/base-ui/Settings/EditProfile/CategorySelector.tsx
  • src/components/base-ui/Settings/EditProfile/ProfileImageSection.tsx
  • src/components/base-ui/Settings/Notification/NotificationItem.tsx
  • src/components/base-ui/Settings/SettingsInputGroup.tsx
  • src/components/base-ui/home/home_bookclub.tsx
  • src/components/base-ui/home/list_subscribe_element.tsx
  • src/components/base-ui/home/list_subscribe_large.tsx
  • src/components/common/ConfirmModal.tsx
  • src/components/layout/AdminHeader.tsx
  • src/components/layout/AdminNavItem.tsx
  • src/components/layout/AdminSearchHeader.tsx
  • src/components/layout/BookSelectModal.tsx
  • src/components/layout/Header.tsx
  • src/components/layout/SearchModal.tsx
  • src/hooks/mutations/useMemberMutations.ts
  • src/hooks/mutations/useNotificationMutations.ts
  • src/hooks/mutations/useStoryMutations.ts
  • src/hooks/queries/useBookQueries.ts
  • src/hooks/queries/useClubQueries.ts
  • src/hooks/queries/useMemberQueries.ts
  • src/hooks/queries/useNewsQueries.ts
  • src/hooks/queries/useNotificationQueries.ts
  • src/hooks/queries/useStoryQueries.ts
  • src/hooks/useDebounce.ts
  • src/lib/api/client.ts
  • src/lib/api/client/index.ts
  • src/lib/api/endpoints/auth.ts
  • src/lib/api/endpoints/base.ts
  • src/lib/api/endpoints/book.ts
  • src/lib/api/endpoints/bookstory.ts
  • src/lib/api/endpoints/club.ts
  • src/lib/api/endpoints/index.ts
  • src/lib/api/endpoints/member.ts
  • src/lib/api/endpoints/news.ts
  • src/lib/api/endpoints/notification.ts
  • src/lib/api/errors/ApiError.ts
  • src/lib/api/errors/errorMapper.ts
  • src/lib/api/errors/index.ts
  • src/services/bookService.ts
  • src/services/clubService.ts
  • src/services/memberService.ts
  • src/services/newsService.ts
  • src/services/notificationService.ts
  • src/services/storyService.ts
  • src/types/book.ts
  • src/types/club.ts
  • src/types/groups/bookcasedetail.ts
  • src/types/groups/bookcasehome.ts
  • src/types/member.ts
  • src/types/news.ts
  • src/types/notification.ts
  • src/types/story.ts
  • src/utils/time.ts
  • src/utils/url.ts

📝 Walkthrough

Walkthrough

This pull request introduces a comprehensive API integration layer with React Query for data fetching, adds an admin dashboard with multiple management pages, implements drag-and-drop team management for meetings, and refactors numerous pages to consume real API data instead of mock data. It also adds configuration for remote image loading, environment variable support, and new dependencies for query management and drag-and-drop functionality.

Changes

Cohort / File(s) Summary
Configuration & Environment
.env.example, .gitignore, next.config.ts, package.json
Added API base URL environment variable, permitted .env.example in git, configured remote image domains (aladin.co.kr, S3), and added dependencies for React Query, dnd-kit, and intersection observer.
API Infrastructure
src/lib/api/client*, src/lib/api/errors/*, src/lib/api/endpoints/*, src/lib/api/client.ts
Established centralized API client with timeout, error handling, credential handling, and 401 logout logic; created error utilities (ApiError, errorMapper); defined endpoint constants for auth, books, stories, clubs, members, news, notifications.
Service Layer
src/services/*.ts
Introduced service objects (bookService, clubService, memberService, newsService, notificationService, storyService) providing typed API wrappers with consistent request/response handling.
React Query Hooks
src/hooks/queries/*.ts, src/hooks/mutations/*.ts, src/hooks/useDebounce.ts
Added query hooks for books, clubs, members, stories, news, notifications; mutation hooks for comments, stories, profile, password, notifications; implemented debounce utility.
Admin Dashboard Pages
src/app/(admin)/admin/(app)/*.tsx, src/app/(admin)/admin/(auth)/login/page.tsx
Created admin interface with groups, users, news, stories pages featuring searchable, paginated tables; added admin login page; implemented AdminHeader and AdminSearchHeader layout components.
Main App Pages - Data Integration
src/app/(main)/page.tsx, src/app/(main)/news/page.tsx, src/app/(main)/search/page.tsx, src/app/(main)/stories/page.tsx, src/app/(main)/setting/*.tsx
Replaced mock data with real API queries; added infinite scroll via useInView; integrated React Query for stories, recommendations, notifications, news; updated field mappings to new API shapes; added loading/error states.
Book & Story Detail Pages
src/app/(main)/books/[id]/page.tsx, src/app/(main)/stories/[id]/page.tsx, src/app/(main)/stories/new/page.tsx
Converted from server-side to client-side fetching; integrated useBookDetailQuery and useStoryDetailQuery; updated ISBN-based identification; added loading/error UI; wired create mutations.
Group & Meeting Pages
src/app/groups/[id]/*, src/app/groups/[id]/bookcase/*
Refactored bookcase pages to consume API mock data; created meeting team management admin page with drag-and-drop (dnd-kit); added MeetingTabSection; updated navigation to meetingId-based routing; enhanced chat modal integration.
Base UI Components - Enhanced Props
src/components/base-ui/BookStory/*.tsx, src/components/base-ui/Bookcase/*.tsx, src/components/base-ui/Settings/*.tsx, src/components/base-ui/home/*.tsx
Added hideSubscribeButton and onClick props to BookStoryCard variants; introduced MemberItem, MemberPool, TeamBoard drag-drop components; externalized CategorySelector; enhanced ProfileImageSection and NotificationItem with callbacks; made subscriber counts optional.
Reusable Components & Layout
src/components/base-ui/Book/BookCoverCard.tsx, src/components/layout/*.tsx, src/components/common/ConfirmModal.tsx
Created BookCoverCard component variant; built AdminHeader, AdminNavItem, AdminSearchHeader, BookSelectModal with infinite search; added ConfirmModal for confirmations; updated SearchModal with real data; enhanced Header with user profile image.
Type Definitions & Utilities
src/types/*.ts, src/utils/*.ts, src/app/providers.tsx
Defined API response types for books, stories, clubs, members, news, notifications; added utility functions for time formatting (formatTimeAgo) and URL validation (isValidUrl); created QueryClientProvider wrapper in new providers module; added bookcase-specific types with team management utilities.
Removed Components
src/components/base-ui/News/recommendbook_element.tsx, src/components/base-ui/Search/search_recommendbook.tsx, src/app/groups/[id]/admin/bookcase/page.tsx
Deleted duplicate BookCoverCard implementations in favor of centralized version; removed admin bookcase list page.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Browser/Client
    participant Cache as React Query<br/>Cache
    participant API as API Client
    participant Server as Backend API

    Client->>Cache: useQuery/useInfiniteQuery
    activate Cache
    Cache->>API: Check cache/needs fetch?
    alt Cache Hit & Fresh
        Cache-->>Client: Return cached data
    else Cache Miss or Stale
        Cache->>API: Trigger request
        activate API
        API->>API: Add headers, handle auth
        API->>Server: GET/POST/PATCH/DELETE<br/>(with AbortController timeout)
        activate Server
        Server-->>API: ApiResponse<T>
        deactivate Server
        API->>API: Parse JSON, extract result
        alt 401 Unauthorized
            API->>API: Logout via authStore
            API-->>Client: Toast error
        else Success
            API-->>Cache: Return result
        end
        deactivate API
        Cache->>Cache: Store in cache<br/>(staleTime: 60s)
        Cache-->>Client: Update UI with data
    end
    deactivate Cache
    Client->>Client: Render with fetched data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

🚀 enhancement, 📡 api, 🎨 ui, ♻️ refactor

Poem

🐰 From mock data dreams to queries so keen,
React Query caches keep the UI clean,
Drag-and-drop teams in meetings aligned,
Admin dashboards serve data refined,
An API layer, so well designed!

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @shinwokkang, 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!

이 Pull Request는 애플리케이션의 데이터 관리 방식을 혁신하고, 새로운 관리자 기능을 도입하며, 사용자 경험을 향상시키는 데 중점을 둡니다. 주요 변경 사항은 tanstack/react-query를 활용한 API 서비스 통합, 회원 및 콘텐츠 관리를 위한 관리자 페이지 구현, 그리고 독서 모임 조 편성을 위한 드래그 앤 드롭 인터페이스 추가입니다. 또한, 프로필 및 댓글 관리 기능이 개선되고, 전반적인 코드 구조가 최신 웹 개발 표준에 맞춰 재정비되었습니다.

Highlights

  • API 서비스 및 React Query 통합: 기존 더미 데이터를 사용하던 여러 페이지(홈, 소식, 검색, 책 이야기 상세, 마이페이지 등)에 tanstack/react-query를 도입하여 실제 API 서비스(bookService, storyService, memberService, newsService, notificationService, clubService)와 연동했습니다. 이를 통해 데이터 페칭, 캐싱, 동기화 및 무한 스크롤 기능을 효율적으로 관리합니다.
  • 관리자 페이지 추가: 회원, 모임, 책 이야기, 소식 관리를 위한 새로운 관리자 페이지(src/app/(admin))와 관리자 로그인 페이지가 추가되었습니다. 관리자 헤더 컴포넌트(AdminHeader, AdminNavItem, AdminSearchHeader)도 함께 구현되었습니다.
  • 독서 모임 조 편성 기능 (DND-kit): 독서 모임의 정기 모임 상세 페이지에서 조를 편성하고 멤버를 할당할 수 있는 드래그 앤 드롭(DND-kit) 기반의 관리 기능이 추가되었습니다. 미배정 멤버 풀과 팀 보드를 통해 직관적인 조 편성이 가능합니다.
  • 프로필 및 비밀번호 설정 기능 개선: 프로필 편집 페이지에서 프로필 이미지 업로드 및 초기화, 닉네임 중복 확인 기능이 추가되었으며, 비밀번호 변경 기능도 API 연동과 함께 유효성 검사가 강화되었습니다.
  • 댓글 수정 및 삭제 기능 추가: 책 이야기 댓글에 수정 및 삭제 기능이 추가되어 사용자 경험을 개선했습니다.
  • Next.js 설정 및 의존성 업데이트: Next.js 이미지 최적화를 위한 remotePatterns 설정이 next.config.ts에 추가되었고, package.jsonpnpm-lock.yaml에 새로운 라이브러리(@dnd-kit, @tanstack/react-query, react-intersection-observer)가 추가되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .env.example
    • API 엔드포인트 환경 변수 예시가 추가되었습니다.
  • .gitignore
    • .env.example 파일이 .gitignore에서 제외되도록 업데이트되었습니다.
  • next.config.ts
    • 원격 이미지 호스트(image.aladin.co.kr, checkmo-s3-presigned.s3.ap-northeast-2.amazonaws.com)가 Next.js 이미지 설정에 추가되었습니다.
  • package-lock.json
    • 새로운 의존성인 @dnd-kit/core, @dnd-kit/utilities가 추가되었습니다.
  • package.json
    • @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities, @tanstack/react-query, @tanstack/react-query-devtools, react-intersection-observer 등 새로운 라이브러리 의존성이 추가되었습니다.
  • pnpm-lock.yaml
    • 새로운 의존성 및 관련 패키지 버전 정보가 업데이트되었습니다.
  • public/ArrowLeft3.svg
    • 왼쪽 화살표 SVG 아이콘이 추가되었습니다.
  • public/Polygon7.svg
    • 오른쪽 삼각형 SVG 아이콘이 추가되었습니다.
  • public/icon_plus_2.svg
    • 플러스 SVG 아이콘이 추가되었습니다.
  • src/app/(admin)/admin/(app)/groups/page.tsx
    • 관리자 모임 관리 페이지가 추가되었습니다.
  • src/app/(admin)/admin/(app)/layout.tsx
    • 관리자 페이지의 레이아웃 컴포넌트가 추가되었습니다.
  • src/app/(admin)/admin/(app)/news/page.tsx
    • 관리자 소식 관리 페이지가 추가되었습니다.
  • src/app/(admin)/admin/(app)/page.tsx
    • 관리자 홈 페이지가 회원 관리 페이지로 리다이렉트되도록 설정되었습니다.
  • src/app/(admin)/admin/(app)/stories/page.tsx
    • 관리자 책 이야기 관리 페이지가 추가되었습니다.
  • src/app/(admin)/admin/(app)/users/page.tsx
    • 관리자 회원 관리 페이지가 추가되었습니다.
  • src/app/(admin)/admin/(auth)/login/page.tsx
    • 관리자 로그인 페이지가 추가되었습니다.
  • src/app/(main)/books/[id]/page.tsx
    • 도서 상세 페이지가 useBookDetailQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, bookId 대신 isbn을 사용하도록 변경되었습니다.
  • src/app/(main)/news/page.tsx
    • 소식 페이지가 useRecommendedBooksQuery를 사용하여 추천 도서를 가져오도록 업데이트되었고, 더미 데이터 사용이 제거되었습니다.
  • src/app/(main)/page.tsx
    • 메인 홈 페이지가 useStoriesQuery, useRecommendedMembersQuery, useMyClubsQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, 더미 데이터 사용이 제거되었습니다.
  • src/app/(main)/search/page.tsx
    • 검색 페이지가 useInfiniteBookSearchQueryuseInView를 사용하여 무한 스크롤을 지원하도록 업데이트되었고, bookId 대신 isbn을 사용하도록 변경되었습니다.
  • src/app/(main)/setting/news/page.tsx
    • 내 소식 관리 페이지가 useInfiniteNewsQueryuseInView를 사용하여 무한 스크롤을 지원하도록 업데이트되었고, 더미 데이터 사용이 제거되었습니다.
  • src/app/(main)/setting/notifications/page.tsx
    • 알림 관리 페이지가 useNotificationSettingsQueryuseToggleNotificationMutation을 사용하여 API와 연동되도록 업데이트되었고, 더미 데이터 사용이 제거되었습니다.
  • src/app/(main)/setting/password/page.tsx
    • 비밀번호 변경 페이지가 useUpdatePasswordMutation을 사용하여 API와 연동되도록 업데이트되었고, 비밀번호 유효성 검사가 추가되었습니다.
  • src/app/(main)/setting/profile/page.tsx
    • 프로필 편집 페이지가 useUpdateProfileMutation을 사용하여 API와 연동되도록 업데이트되었고, 프로필 이미지 업로드 및 닉네임 중복 확인 기능이 추가되었습니다.
  • src/app/(main)/stories/[id]/page.tsx
    • 책 이야기 상세 페이지가 useStoryDetailQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, 댓글 섹션이 API와 연동되도록 변경되었습니다.
  • src/app/(main)/stories/new/page.tsx
    • 새 책 이야기 작성 페이지가 useBookDetailQueryuseCreateBookStoryMutation을 사용하여 API와 연동되도록 업데이트되었고, bookId 대신 isbn을 사용하도록 변경되었습니다.
  • src/app/(main)/stories/page.tsx
    • 책 이야기 목록 페이지가 useInfiniteStoriesQuery, useRecommendedMembersQuery, useMyClubsQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, 무한 스크롤 기능이 추가되었습니다.
  • src/app/groups/[id]/admin/bookcase/[meetingId]/dummy.ts
    • 독서 모임 조 편성 기능의 더미 데이터가 추가되었습니다.
  • src/app/groups/[id]/admin/bookcase/[meetingId]/layout.tsx
    • 독서 모임 조 편성 페이지의 레이아웃이 추가되었습니다.
  • src/app/groups/[id]/admin/bookcase/[meetingId]/page.tsx
    • 독서 모임 조 편성 관리 페이지가 dnd-kit을 사용하여 드래그 앤 드롭 기능을 구현하도록 추가되었습니다.
  • src/app/groups/[id]/admin/bookcase/new/page.tsx
    • 새 책장 도서 추가 페이지가 useBookDetailQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, bookId 대신 isbn을 사용하도록 변경되었습니다.
  • src/app/groups/[id]/admin/bookcase/page.tsx
    • 관리자 책장 목록 페이지가 삭제되었습니다.
  • src/app/groups/[id]/bookcase/[bookId]/MeetingTabSection.tsx
    • 모임 탭 섹션 컴포넌트가 추가되었습니다.
  • src/app/groups/[id]/bookcase/[bookId]/meeting/page.tsx
    • 모임 페이지에 채팅 조 선택 모달이 추가되었고, 발제 목록 정렬 및 체크 기능이 개선되었습니다.
  • src/app/groups/[id]/bookcase/[bookId]/page.tsx
    • 독서 모임 책장 상세 페이지가 탭 전환 시 URL 쿼리 파라미터를 사용하도록 변경되었고, MeetingTabSection 컴포넌트가 통합되었습니다.
  • src/app/groups/[id]/bookcase/page.tsx
    • 독서 모임 책장 목록 페이지가 groupByGeneration 유틸리티를 사용하여 API 데이터를 기수별로 그룹화하도록 업데이트되었고, 더미 데이터 사용이 제거되었습니다.
  • src/app/groups/[id]/layout.tsx
    • 독서 모임 레이아웃에서 관리자 책장 관련 페이지의 적용 예외 처리가 업데이트되었습니다.
  • src/app/groups/[id]/page.tsx
    • 독서 모임 홈 페이지의 '이번 모임 바로가기' 버튼 링크가 업데이트되었습니다.
  • src/app/layout.tsx
    • Providers 컴포넌트가 추가되어 tanstack/react-query를 전역적으로 설정하도록 변경되었습니다.
  • src/app/providers.tsx
    • tanstack/react-queryQueryClientProviderReactQueryDevtools를 설정하는 Providers 컴포넌트가 추가되었습니다.
  • src/components/base-ui/Book/BookCoverCard.tsx
    • 도서 커버 카드 컴포넌트가 추가되어 검색 및 추천 도서 표시를 통합했습니다.
  • src/components/base-ui/BookStory/bookstory_card.tsx
    • 책 이야기 카드 컴포넌트가 formatTimeAgo 유틸리티를 사용하도록 변경되었고, 구독 버튼 숨김 기능 및 클릭 이벤트 핸들러가 추가되었습니다.
  • src/components/base-ui/BookStory/bookstory_card_large.tsx
    • 큰 책 이야기 카드 컴포넌트가 formatTimeAgo 유틸리티를 사용하도록 변경되었고, 구독 버튼 숨김 기능이 추가되었습니다.
  • src/components/base-ui/BookStory/bookstory_detail.tsx
    • 책 이야기 상세 컴포넌트가 isValidUrl 유틸리티를 사용하여 이미지 URL 유효성을 검사하고, 구독 버튼 숨김 기능이 추가되었습니다.
  • src/components/base-ui/Bookcase/Admin/bookdetailgrouping/MemberItem.tsx
    • 조 편성 관리 페이지에서 사용되는 멤버 아이템 컴포넌트가 추가되었습니다.
  • src/components/base-ui/Bookcase/Admin/bookdetailgrouping/MemberPool.tsx
    • 조 편성 관리 페이지에서 미배정 멤버 풀 컴포넌트가 추가되었습니다.
  • src/components/base-ui/Bookcase/Admin/bookdetailgrouping/TeamBoard.tsx
    • 조 편성 관리 페이지에서 팀 보드 컴포넌트가 추가되었습니다.
  • src/components/base-ui/Bookcase/BookDetailNav.tsx
    • 도서 상세 내비게이션 컴포넌트의 탭 키 타입이 Tab으로 변경되었고, 탭 라벨 매핑이 추가되었습니다.
  • src/components/base-ui/Bookcase/BookcaseCard.tsx
    • 책장 카드 컴포넌트의 imageUrl prop이 필수로 변경되었습니다.
  • src/components/base-ui/Bookcase/ChatTeamSelectModal.tsx
    • 채팅 조 선택 모달 컴포넌트가 추가되었습니다.
  • src/components/base-ui/Bookcase/MeetingInfo.tsx
    • 모임 정보 컴포넌트가 isAdmin prop을 받아 관리자일 경우에만 조 관리 버튼을 표시하도록 변경되었습니다.
  • src/components/base-ui/Comment/comment_item.tsx
    • 댓글 아이템 컴포넌트에 수정 모드와 저장/취소 버튼이 추가되었습니다.
  • src/components/base-ui/Comment/comment_section.tsx
    • 댓글 섹션 컴포넌트가 useCreateCommentMutation, useUpdateCommentMutation, useDeleteCommentMutation을 사용하여 API와 연동되도록 업데이트되었고, ConfirmModal이 추가되었습니다.
  • src/components/base-ui/Group/BookshelfModal.tsx
    • 책장 모달 컴포넌트의 BookcaseCardimageUrl prop이 추가되었습니다.
  • src/components/base-ui/Join/JoinButton.tsx
    • 가입 버튼 컴포넌트의 primarysecondary 변형에 호버 효과 및 커서 스타일이 추가되었습니다.
  • src/components/base-ui/Login/useLoginForm.tsx
    • 로그인 폼 훅에서 ApiError 임포트 경로가 업데이트되었습니다.
  • src/components/base-ui/MyPage/MyBookStoryList.tsx
    • 내 책 이야기 목록 컴포넌트가 useMyInfiniteStoriesQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, 무한 스크롤 기능이 추가되었습니다.
  • src/components/base-ui/MyPage/MyMeetingList.tsx
    • 내 모임 목록 컴포넌트가 useMyClubsQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, 더미 데이터 사용이 제거되었습니다.
  • src/components/base-ui/MyPage/MyNotificationList.tsx
    • 내 알림 목록 컴포넌트가 useInfiniteNotificationsQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, 무한 스크롤 기능이 추가되었습니다.
  • src/components/base-ui/MyPage/UserProfile.tsx
    • 사용자 프로필 컴포넌트가 useProfileQuery를 사용하여 API 데이터를 가져오도록 업데이트되었고, '내 책 이야기 쓰기' 버튼에 라우터 푸시 기능이 추가되었습니다.
  • src/components/base-ui/News/recommendbook_element.tsx
    • 추천 도서 요소 컴포넌트가 삭제되었습니다.
  • src/components/base-ui/News/today_recommended_books.tsx
    • 오늘의 추천 책 컴포넌트가 BookCoverCard를 사용하도록 변경되었고, bookId 타입이 string | number로 확장되었습니다.
  • src/components/base-ui/Search/search_recommendbook.tsx
    • 검색 추천 도서 컴포넌트가 삭제되었습니다.
  • src/components/base-ui/Settings/EditProfile/CategorySelector.tsx
    • 카테고리 선택기 컴포넌트가 CATEGORIES 상수를 constants/categories에서 임포트하도록 변경되었습니다.
  • src/components/base-ui/Settings/EditProfile/ProfileImageSection.tsx
    • 프로필 이미지 섹션 컴포넌트에 이미지 미리보기, 업로드, 초기화 기능이 추가되었습니다.
  • src/components/base-ui/Settings/Notification/NotificationItem.tsx
    • 알림 아이템 컴포넌트가 isChecked, onToggle, disabled prop을 받도록 변경되었고, 내부 상태 관리가 제거되었습니다.
  • src/components/base-ui/Settings/SettingsInputGroup.tsx
    • 설정 입력 그룹 컴포넌트에 valueonChange prop이 추가되었습니다.
  • src/components/base-ui/home/home_bookclub.tsx
    • 홈 북클럽 컴포넌트가 MyClubInfo 타입을 사용하도록 변경되었고, 모임 생성 페이지로 이동하는 버튼이 추가되었습니다.
  • src/components/base-ui/home/list_subscribe_element.tsx
    • 구독 목록 요소 컴포넌트의 subscribingCountsubscribersCount prop이 선택 사항으로 변경되었습니다.
  • src/components/base-ui/home/list_subscribe_large.tsx
    • 큰 구독 목록 컴포넌트가 usersisError prop을 받도록 변경되었고, 더미 데이터 사용이 제거되었습니다.
  • src/components/common/ConfirmModal.tsx
    • 확인 모달 컴포넌트가 추가되었습니다.
  • src/components/layout/AdminHeader.tsx
    • 관리자 헤더 컴포넌트가 추가되었습니다.
  • src/components/layout/AdminNavItem.tsx
    • 관리자 내비게이션 아이템 컴포넌트가 추가되었습니다.
  • src/components/layout/AdminSearchHeader.tsx
    • 관리자 검색 헤더 컴포넌트가 추가되었습니다.
  • src/components/layout/BookSelectModal.tsx
    • 도서 선택 모달이 useInfiniteBookSearchQueryuseInView를 사용하여 무한 스크롤을 지원하도록 업데이트되었고, bookId 대신 isbn을 사용하도록 변경되었습니다.
  • src/components/layout/Header.tsx
    • 메인 헤더 컴포넌트가 useAuthStore를 사용하여 사용자 프로필 이미지를 표시하도록 업데이트되었습니다.
  • src/components/layout/SearchModal.tsx
    • 검색 모달이 useInfiniteBookSearchQuery, useRecommendedBooksQuery, useDebounce, useInView를 사용하여 API 데이터를 가져오고 무한 스크롤을 지원하도록 업데이트되었고, BookCoverCard를 사용하도록 변경되었습니다.
  • src/hooks/mutations/useMemberMutations.ts
    • 회원 프로필 업데이트 및 비밀번호 변경을 위한 useUpdateProfileMutationuseUpdatePasswordMutation 훅이 추가되었습니다.
  • src/hooks/mutations/useNotificationMutations.ts
    • 알림 설정 토글 및 알림 읽음 처리를 위한 useToggleNotificationMutationuseReadNotificationMutation 훅이 추가되었습니다.
  • src/hooks/mutations/useStoryMutations.ts
    • 책 이야기 생성, 댓글 생성, 댓글 업데이트, 댓글 삭제를 위한 useCreateBookStoryMutation, useCreateCommentMutation, useUpdateCommentMutation, useDeleteCommentMutation 훅이 추가되었습니다.
  • src/hooks/queries/useBookQueries.ts
    • 도서 검색, 추천 도서, 도서 상세 정보를 위한 useBookSearchQuery, useInfiniteBookSearchQuery, useRecommendedBooksQuery, useBookDetailQuery 훅과 관련 쿼리 키가 추가되었습니다.
  • src/hooks/queries/useClubQueries.ts
    • 내 모임 목록을 위한 useMyClubsQuery 훅과 관련 쿼리 키가 추가되었습니다.
  • src/hooks/queries/useMemberQueries.ts
    • 추천 멤버 및 프로필 정보를 위한 useRecommendedMembersQueryuseProfileQuery 훅과 관련 쿼리 키가 추가되었습니다.
  • src/hooks/queries/useNewsQueries.ts
    • 소식 목록을 위한 useInfiniteNewsQuery 훅과 관련 쿼리 키가 추가되었습니다.
  • src/hooks/queries/useNotificationQueries.ts
    • 알림 설정 및 알림 목록을 위한 useNotificationSettingsQueryuseInfiniteNotificationsQuery 훅과 관련 쿼리 키가 추가되었습니다.
  • src/hooks/queries/useStoryQueries.ts
    • 책 이야기 목록, 상세, 내 책 이야기 목록을 위한 useStoriesQuery, useStoryDetailQuery, useInfiniteStoriesQuery, useMyInfiniteStoriesQuery 훅과 관련 쿼리 키가 추가되었습니다.
  • src/hooks/useDebounce.ts
    • 디바운스 기능을 제공하는 useDebounce 훅이 추가되었습니다.
  • src/lib/api/client.ts
    • API 클라이언트의 put 메서드에 patch 메서드가 추가되었습니다.
  • src/lib/api/client/index.ts
    • API 클라이언트가 useAuthStore를 사용하여 401 에러를 처리하고, ApiErrorgetErrorMessage를 사용하여 에러를 표준화하도록 업데이트되었습니다.
  • src/lib/api/endpoints/auth.ts
    • 인증 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/endpoints/base.ts
    • API 기본 URL 상수가 추가되었습니다.
  • src/lib/api/endpoints/book.ts
    • 도서 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/endpoints/bookstory.ts
    • 책 이야기 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/endpoints/club.ts
    • 모임 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/endpoints/index.ts
    • 모든 API 엔드포인트 상수를 내보내도록 업데이트되었습니다.
  • src/lib/api/endpoints/member.ts
    • 회원 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/endpoints/news.ts
    • 소식 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/endpoints/notification.ts
    • 알림 관련 API 엔드포인트 상수가 추가되었습니다.
  • src/lib/api/errors/ApiError.ts
    • 커스텀 API 에러 클래스 ApiError가 추가되었습니다.
  • src/lib/api/errors/errorMapper.ts
    • API 에러 코드에 따른 메시지를 매핑하는 ERROR_MESSAGESgetErrorMessage 유틸리티가 추가되었습니다.
  • src/lib/api/errors/index.ts
    • 모든 에러 관련 유틸리티를 내보내도록 업데이트되었습니다.
  • src/services/bookService.ts
    • 도서 검색, 추천 도서, 도서 상세 정보를 가져오는 bookService가 추가되었습니다.
  • src/services/clubService.ts
    • 내 모임 목록을 가져오는 clubService가 추가되었습니다.
  • src/services/memberService.ts
    • 추천 멤버, 프로필 업데이트, 비밀번호 업데이트, 프로필 정보를 가져오는 memberService가 추가되었습니다.
  • src/services/newsService.ts
    • 소식 목록을 가져오는 newsService가 추가되었습니다.
  • src/services/notificationService.ts
    • 알림 설정 및 알림 목록을 가져오고 업데이트하는 notificationService가 추가되었습니다.
  • src/services/storyService.ts
    • 책 이야기 목록, 상세, 생성, 댓글 생성/수정/삭제를 위한 storyService가 추가되었습니다.
  • src/types/book.ts
    • 도서 관련 타입(Book, BookSearchResponse)이 추가되었습니다.
  • src/types/club.ts
    • 모임 관련 타입(MyClubInfo, MyClubListResponse)이 추가되었습니다.
  • src/types/groups/bookcasedetail.ts
    • 독서 모임 책장 상세 및 조 편성 관련 타입(MemberInfo, TeamMember, GetMeetingTeamsResult, TeamMemberListPutBody) 및 유틸리티가 추가되었습니다.
  • src/types/groups/bookcasehome.ts
    • 독서 모임 책장 홈 관련 타입(BookcaseApiResponse, BookcaseApiResult, BookShelfInfo, MeetingInfo, BookInfo, BookcaseCardCategory, BookcaseCardModel, BookcaseSectionModel) 및 유틸리티가 추가되었습니다.
  • src/types/member.ts
    • 회원 관련 타입(RecommendedMember, RecommendResponse, UpdateProfileRequest, UpdatePasswordRequest, ProfileResponse)이 추가되었습니다.
  • src/types/news.ts
    • 소식 관련 타입(NewsBasicInfo, NewsListResponse)이 추가되었습니다.
  • src/types/notification.ts
    • 알림 관련 타입(NotificationSettingType, NotificationSettings, NotificationBasicInfo, NotificationListResponse)이 추가되었습니다.
  • src/types/story.ts
    • 책 이야기 관련 타입(BookStory, BookStoryListResponse, BookInfo, AuthorInfo, CommentInfo, BookStoryDetail, CreateBookStoryRequest, CreateCommentRequest)이 추가되었습니다.
  • src/utils/time.ts
    • 시간을 '방금 전', '몇 분 전' 등으로 포맷하는 formatTimeAgo 유틸리티가 추가되었습니다.
  • src/utils/url.ts
    • URL 유효성을 검사하는 isValidUrl 유틸리티가 추가되었습니다.
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
Contributor

@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

이 Pull Request는 애플리케이션 전반에 걸쳐 더미 데이터를 실제 API 연동으로 전환하는 대규모 리팩토링을 포함하고 있습니다. React Query를 도입하여 데이터 페칭 및 캐싱을 관리하고, 관련 서비스와 타입, 커스텀 훅을 체계적으로 구현한 점이 인상적입니다. 또한, 관리자 페이지와 여러 UI 컴포넌트가 추가 및 개선되었습니다. 전반적으로 코드 품질과 아키텍처가 크게 향상되었습니다. 다만, 몇 가지 중요한 버그와 개선점이 발견되어 리뷰 코멘트를 남겼습니다. 특히 관리자 로그인 로직, 깨진 네비게이션 경로, 잘못된 API 설정 토글 등은 배포 전에 반드시 수정해야 합니다.

Comment on lines +13 to +17
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
if (isDisabled) return;
setToastMsg("토스트 테스트");
};
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

로그인 핸들러에 실제 로그인 로직 대신 테스트용 토스트 메시지가 하드코딩되어 있습니다. 이대로 배포될 경우 관리자 로그인이 불가능하므로, 실제 API를 호출하는 로그인 로직으로 교체해야 합니다.

Suggested change
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
if (isDisabled) return;
setToastMsg("토스트 테스트");
};
const handleLogin = (e: React.FormEvent) => {
e.preventDefault();
if (isDisabled) return;
// TODO: 실제 로그인 API 호출 로직 구현
console.log("로그인 시도:", { id, pw });
};

<ButtonWithoutImg
text="이번 모임 바로가기"
onClick={() => router.push(joinUrl)}
onClick={() => router.push(`${Number(groupId)}/notice/4`)}
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

버튼 클릭 시 이동 경로가 router.push(${Number(groupId)}/notice/4)로 하드코딩되어 있습니다. 이는 상대 경로로 해석되어 /groups/[id]/[groupId]/notice/4와 같은 잘못된 URL로 이동하게 됩니다. 올바른 절대 경로로 수정해야 합니다.

Suggested change
onClick={() => router.push(`${Number(groupId)}/notice/4`)}
onClick={() => router.push(`/groups/${groupId}/notice/4`)}

Comment on lines +13 to +15
const isAuthPage =
pathname.startsWith("/login") ||
pathname.startsWith("/signup");
Copy link
Contributor

Choose a reason for hiding this comment

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

high

인증 페이지에서 헤더를 숨기는 로직이 의도와 다르게 동작할 수 있습니다. 현재 pathname.startsWith("/login")은 루트 경로의 /login에도 해당될 수 있습니다. 이 레이아웃은 /admin 경로 하위에 적용되므로, /admin/login과 같이 전체 경로를 확인하는 것이 더 안전합니다. 그렇지 않으면 예기치 않은 페이지에서 헤더가 사라지는 버그가 발생할 수 있습니다.

Suggested change
const isAuthPage =
pathname.startsWith("/login") ||
pathname.startsWith("/signup");
const isAuthPage =
pathname === "/admin/login" ||
pathname === "/admin/signup";

Comment on lines +73 to +80
title="모임 댓글/답글 알림"
description="작성한 게시글에 대한 댓글 및 답글 알림 수신"
// There isn't a single clear match for this string in standard setting schema besides what Swagger provided.
// Currently matching clubMeetingCreated here based on structure, although naming implies 'meeting/gathering'.
isChecked={settings?.clubMeetingCreated}
onToggle={() => handleToggle("CLUB_MEETING_CREATED")}
disabled={isPending}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

high

UI에 표시된 '모임 댓글/답글 알림'과 실제 토글되는 설정인 clubMeetingCreated 사이에 의미상 불일치가 있어 보입니다. clubMeetingCreated는 이름으로 보아 새로운 모임 일정이 생성되었을 때의 알림으로 추측됩니다. 이로 인해 사용자가 의도하지 않은 설정을 켜고 끄게 될 수 있습니다. API 명세와 일치하는 올바른 설정 키로 수정해야 합니다.

onTopicClick={() => { } }
onReviewClick={() => { } }
onMeetingClick={() => { } }
imageUrl={''} />
Copy link
Contributor

Choose a reason for hiding this comment

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

high

BookcaseCard 컴포넌트의 imageUrl prop은 필수 항목으로 변경되었으나, 여기서는 빈 문자열('')을 전달하고 있습니다. 이로 인해 렌더링 시 깨진 이미지 아이콘이 표시될 수 있습니다. 더미 데이터에 이미지 URL을 추가하거나, 유효한 기본 이미지 경로를 전달해야 합니다.

                  imageUrl={book.imageUrl || '/dummy_book_cover.png'}

}, [filtered, page, pageSize]);

const handleSearch = () => {
console.log("검색:", keyword);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

제품 코드에 console.log가 남아있습니다. 디버깅 목적으로 사용된 것으로 보이며, 실제 배포 시에는 제거하는 것이 좋습니다. 이 패턴은 news/page.tsx, stories/page.tsx, users/page.tsx 등 다른 관리자 페이지에서도 반복적으로 발견되었습니다. 불필요한 로그는 브라우저 콘솔을 어지럽히고 잠재적으로 민감한 정보를 노출할 수 있으므로 일괄적으로 제거하는 것을 권장합니다.

<div className="flex flex-col items-start gap-[12px] self-stretch">
<label className="self-stretch body_1_2 text-primary-3">이름</label>
<div className={`${inputContainerClass} self-stretch`}>
<div className={`${inputContainerClass} self-stretch !bg-Gray-1 !border-Gray-3`}>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Tailwind CSS에서 !(important) 한정자는 다른 스타일과의 충돌을 해결하기 위해 사용되지만, 꼭 필요한 경우가 아니라면 남용을 피하는 것이 좋습니다. 스타일 우선순위 관리를 복잡하게 만들 수 있기 때문입니다. disabled 상태 스타일을 적용하기 위해 disabled: variant를 사용하는 것을 고려해볼 수 있습니다.

Suggested change
<div className={`${inputContainerClass} self-stretch !bg-Gray-1 !border-Gray-3`}>
<div className={`${inputContainerClass} self-stretch bg-Gray-1 border-Gray-3`}>

Comment on lines +30 to +31
const meetingIdParam = (params.meetingId ?? params.bookId) as string; // 폴더명 차이 커버
const meetingId = Number(meetingIdParam);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

페이지 파일 경로의 동적 세그먼트가 [bookId]이지만, 내부 로직에서는 meetingId로 사용되고 있어 혼란을 줄 수 있습니다. 이는 향후 유지보수 시 버그의 원인이 될 수 있습니다. 폴더명을 [meetingId]로 변경하여 경로와 변수명의 의미를 일치시키는 것을 권장합니다.

Comment on lines +17 to +37
<div
draggable={draggable}
onDragStart={(e) => {
if (!draggable) return;
e.dataTransfer.setData(
"application/x-checkmo-member",
JSON.stringify({
clubMemberId: member.clubMemberId,
fromTeamNumber: member.teamNumber,
})
);
e.dataTransfer.effectAllowed = "move";
}}
className={[
"flex items-center gap-2.5",
"w-full self-stretch",
"px-5 py-4",
"rounded-[8px]",
"bg-White",
draggable ? "cursor-grab active:cursor-grabbing" : "",
].join(" ")}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

이 컴포넌트는 @dnd-kit을 사용하는 부모 컴포넌트 내에서 렌더링됩니다. @dnd-kit은 자체적인 이벤트 리스너와 상태 관리를 통해 드래그 앤 드롭을 구현하므로, 네이티브 HTML5의 draggable 속성과 onDragStart 이벤트 핸들러는 필요하지 않으며 오히려 혼란을 줄 수 있습니다. @dnd-kit의 작동 방식과 일관성을 유지하기 위해 해당 속성들을 제거하는 것이 좋습니다.

Suggested change
<div
draggable={draggable}
onDragStart={(e) => {
if (!draggable) return;
e.dataTransfer.setData(
"application/x-checkmo-member",
JSON.stringify({
clubMemberId: member.clubMemberId,
fromTeamNumber: member.teamNumber,
})
);
e.dataTransfer.effectAllowed = "move";
}}
className={[
"flex items-center gap-2.5",
"w-full self-stretch",
"px-5 py-4",
"rounded-[8px]",
"bg-White",
draggable ? "cursor-grab active:cursor-grabbing" : "",
].join(" ")}
<div
className={[
"flex items-center gap-2.5",
"w-full self-stretch",
"px-5 py-4",
"rounded-[8px]",
"bg-White",
draggable ? "cursor-grab active:cursor-grabbing" : "",
].join(" ")}
>

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

Labels

✨ feat 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants