Skip to content

6.26 업데이트 - #415

Merged
yhi9839 merged 17 commits into
mainfrom
dev
Jun 26, 2026
Merged

yhi9839 merged 17 commits into
mainfrom
dev

Conversation

@yhi9839

@yhi9839 yhi9839 commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added an infinite-scroll participant list on club/group pages, with follow/unfollow actions updating the list automatically.
  • Bug Fixes

    • Fixed multiple responsive spacing/padding issues across group, story, notice, meeting, and account pages (tablet/mobile).
    • Improved layout stability for dropdowns, lists, and content containers to prevent wrapping and overflow.
  • Documentation

    • Added responsive audit and screenshot guidance to standardize breakpoint/padding fixes and verification.

yhi9839 and others added 15 commits June 24, 2026 14:49
- RESPONSIVE_AUDIT_REPORT.md
- docs/hyunil/responsive-audit.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- MeetingPageClient: 본문 t:px-0 → t:px-6 (태블릿에서 가장자리 붙음 해소, 3곳)
- TeamSection: t:px-0 → t:px-6
- NoticeDetailPageClient: 래퍼 px-[18px] → px-4 t:px-6, 댓글 px-[18px] → px-0
  (공지 본문/댓글 이중패딩 어긋남 정렬)
- notice_detail: 본문 min-w-[300px] → min-w-0 t:min-w-[300px] (모바일 압박 해소)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- find-account/result/find-password: 카드 w-[766px] px-[120px] py-[99px]
  → w-full max-w-[766px] mx-auto px-6 t:px-[120px] py-10 t:py-[99px]
- 부모 래퍼에 px-4 추가(모바일 카드 좌우 여백)
- PrimaryButton: w-[258px] → w-full t:w-[258px]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- setting_report_list: 항목 행 w-[1000px] → w-full max-w-[1000px] (모바일/태블릿 오버플로 방지)
- setting_news_list: 날짜 컬럼 min-w-[180px] → min-w-[80px] t:min-w-[180px]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- StoryDetailClient: 본문/댓글 컨테이너 px-5 → px-5 t:px-6 (태블릿 여백 일관성)
- BookStoryInfiniteList 그리드는 의도된 다단 설계(min-[540px]/md/lg)라
  lg:→d: 변환 시 1024~1439px에서 2열로 회귀 위험 → 변경 보류

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ReportModal: 모달 w-[734px] p-[40px] → w-full max-w-[734px] p-5 t:p-[40px],
  제출 영역 w-[614px] → w-full, 종류 버튼 4개 w-[144px] → flex-1 min-w-[100px]
  t:w-[144px] t:flex-none + 컨테이너 flex-wrap (모바일 2x2 줄바꿈)
- NotificationDropdown: w-[364px] → w-[364px] max-w-[calc(100vw-32px)]
  (364px 미만 소형 폰에서 우측 넘침 방지)
- notification_element.tsx는 미사용(dead) 코드라 제외

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- GroupsPageClient: mx-auto px-6 → px-4 t:px-6 (모바일 24→16px, 표준 래퍼 패턴 통일)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- refactor-409 반응형 일괄 수정(Batch A~E + 모임목록)의 모바일/태블릿/데스크탑 before/after 캡처 59장
- docs/hyunil/responsive-shots/README.md: 명명 규칙 + 화면↔배치 매핑

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 커스텀 회원 카드(인라인 article/구독버튼) 제거 → 디자인시스템 FollowItem 재사용
- FollowItem에 선택적 prop 추가(badge/subLabel/hideFollow), 기존 사용처 영향 없음
- 무효 클래스 hover:brightness-98 제거 → 유효한 hover 적용
  (구독 버튼 hover:bg-primary-1/Subbrown-3, 행 hover:bg-Subbrown-5, 닉네임 group-hover:underline)
- "더보기" 버튼 제거 → useInView sentinel 무한 스크롤(FollowList 패턴)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- FindAccountPageClient: 입력/버튼 래퍼에 w-full 추가
  (비밀번호 찾기와 동일) → 입력칸 카드 전체폭, "아이디 찾기" 버튼 한 줄로 표시
- find-account-m-after 스크린샷 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat: 모임 상세 회원 목록 조회 UI 추가
refactor: 반응형 깨짐 일괄 점검·수정 (Batch A~E)
@vercel

vercel Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
checkmo Ready Ready Preview, Comment Jun 26, 2026 6:40am

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds responsive audit documentation, updates Tailwind padding and width classes across public and main screens, and introduces cursor-based club participant pagination with new API, service, hook, and follow-card support.

Changes

Responsive layout sweep

Layer / File(s) Summary
Audit notes and screenshot guide
RESPONSIVE_AUDIT_REPORT.md, docs/hyunil/responsive-audit.md, docs/hyunil/responsive-shots/README.md
Audit and screenshot documents define breakpoint conventions, issue inventories, fix batches, and verification steps.
Public auth containers
src/app/(public)/find-account/*, src/app/(public)/find-password/FindPasswordPageClient.tsx, src/components/common/find-account/PrimaryButton.tsx
Find-account and password recovery pages update outer padding and centered max-width card sizing, and the shared primary button switches to full width below the tablet breakpoint.
Shared control sizing
src/components/common/modals/report-block/ReportModal.tsx, src/components/layout/NotificationDropdown.tsx, src/components/base-ui/home/Club/home_bookclub.tsx, src/components/base-ui/Settings/*
Report modal, dropdown, home bookclub buttons, and settings lists adjust wrapping, width caps, minimum widths, and hover styling.
Main screen wrappers
src/app/(main)/groups/GroupsPageClient.tsx, src/app/(main)/groups/[id]/bookcase/[bookId]/meeting/MeetingPageClient.tsx, src/app/(main)/groups/[id]/notice/[noticeId]/NoticeDetailPageClient.tsx, src/app/(main)/stories/[id]/StoryDetailClient.tsx, src/components/base-ui/Bookcase/bookid/TeamSection.tsx, src/components/base-ui/Group/notice_detail.tsx
Group, meeting, notice, story, and notice-detail screens change top-level padding, gaps, and text width constraints.

Group participants pagination

Layer / File(s) Summary
Participants API and query hook
src/types/groups/grouphome.ts, src/lib/api/endpoints/Clubs.ts, src/services/clubService.ts, src/hooks/queries/useClubhomeQueries.ts
The participants endpoint, service method, response types, and infinite-query hook are added for cursor-based participant fetching.
Participant list and follow cards
src/app/(main)/groups/[id]/GroupDetailClient.tsx, src/components/base-ui/Profile/Follow/FollowItem.tsx
Group detail derives participant state, handles follow mutations, and renders the member list with loading, empty, blocked, error, and infinite-scroll states.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • checkmo2025/FE#154: Changes src/services/clubService.ts in the same club-related area and is directly connected to the new participants service/query plumbing.

Suggested labels

📝 docs

Suggested reviewers

  • shinwokkang

Poem

A bunny hopped through screens so wide,
Then tucked the padding left and right.
At tablet paws, the cards align,
And participant trails now fetch just fine.
Hoppity! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive 제목이 날짜 중심의 포괄적 표현이라 변경 내용을 식별하기 어렵습니다. 핵심 변경을 반영해 예: '반응형 레이아웃 패딩 조정 및 참가자 목록 무한스크롤 추가'처럼 구체적으로 바꾸세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • 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.

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request implements a comprehensive set of responsive layout fixes across the Next.js frontend based on a responsive layout audit, addressing issues like text touching screen edges on tablets and overflow on mobile devices. Additionally, it introduces a new "Group Participants" section on the group detail page, featuring infinite scrolling, follow/unfollow capabilities, and role badges. Feedback on the changes suggests using encodeURIComponent when linking to user profiles in FollowItem.tsx to prevent routing issues with special characters in nicknames.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

<div className="flex w-full max-w-[1040px] p-[20px] justify-between items-center rounded-[8px] border border-Subbrown-4 bg-White">
<Link href={`/profile/${user.nickname}`} className="flex items-center gap-[12px] cursor-pointer">
<div className="flex w-full max-w-[1040px] p-[20px] justify-between items-center gap-[12px] rounded-[8px] border border-Subbrown-4 bg-White transition-colors hover:bg-Subbrown-5">
<Link href={`/profile/${user.nickname}`} className="group flex items-center gap-[12px] cursor-pointer min-w-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.

medium

닉네임에 특수문자나 공백, 한글 등이 포함되어 있을 경우 URL 경로가 깨지거나 잘못된 라우트로 연결될 수 있습니다. 안전한 라우팅을 위해 encodeURIComponent를 사용하여 닉네임을 인코딩하는 것이 좋습니다.

Suggested change
<Link href={`/profile/${user.nickname}`} className="group flex items-center gap-[12px] cursor-pointer min-w-0">
<Link href={`/profile/${encodeURIComponent(user.nickname)}`} className="group flex items-center gap-[12px] cursor-pointer min-w-0">

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/app/(main)/groups/[id]/GroupDetailClient.tsx (1)

131-143: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Follow toggle has no optimistic feedback in this list.

useToggleFollowMutation performs optimistic updates only on the recommend/story/follow caches, not on clubhomeKeys.participants. Here the participant button state changes only after onSettled invalidation refetches, so it feels unresponsive and a fast second click can fire an out-of-order toggle. Consider an optimistic setQueryData on the participants infinite cache, or disabling the button while toggleFollowMutation.isPending.

🤖 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 `@src/app/`(main)/groups/[id]/GroupDetailClient.tsx around lines 131 - 143, The
follow toggle in GroupDetailClient’s handleToggleFollow is only updating
clubhomeKeys.participants after onSettled, so the participant row/button has no
immediate feedback and can be clicked again before the refetch lands. Add an
optimistic update for the participants infinite cache with
queryClient.setQueryData in handleToggleFollow (or in the toggleFollowMutation
lifecycle) so the local participant follow state flips immediately, and keep the
invalidation as a fallback; alternatively also disable the follow button while
toggleFollowMutation.isPending to prevent out-of-order toggles.
🤖 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 `@src/components/common/find-account/PrimaryButton.tsx`:
- Line 11: The new w-full behavior in PrimaryButton causes paired buttons in
horizontal flex containers to overflow on mobile. Update the consuming button
container in FindAccountPageClient (and any similar callers) to use flex-wrap or
switch to a flex-col layout below the breakpoint, so two PrimaryButton siblings
can stack instead of forcing viewport overflow. Keep the existing PrimaryButton
sizing, and fix the layout at the parent container level where the buttons are
rendered together.

---

Nitpick comments:
In `@src/app/`(main)/groups/[id]/GroupDetailClient.tsx:
- Around line 131-143: The follow toggle in GroupDetailClient’s
handleToggleFollow is only updating clubhomeKeys.participants after onSettled,
so the participant row/button has no immediate feedback and can be clicked again
before the refetch lands. Add an optimistic update for the participants infinite
cache with queryClient.setQueryData in handleToggleFollow (or in the
toggleFollowMutation lifecycle) so the local participant follow state flips
immediately, and keep the invalidation as a fallback; alternatively also disable
the follow button while toggleFollowMutation.isPending to prevent out-of-order
toggles.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a1cf522-2569-43b4-8e3a-74d4b56c8e20

📥 Commits

Reviewing files that changed from the base of the PR and between dff4b70 and 66e748a.

⛔ Files ignored due to path filters (59)
  • docs/hyunil/responsive-shots/bookcase-detail-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/bookcase-detail-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/bookcase-detail-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/bookcase-detail-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/bookcase-detail-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/bookcase-detail-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-account-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-account-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-account-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-account-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-account-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-account-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-password-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-password-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-password-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-password-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-password-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/find-password-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/groups-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/groups-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/groups-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/groups-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/groups-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/groups-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/meeting-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/meeting-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/meeting-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/meeting-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/meeting-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/meeting-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notice-detail-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notice-detail-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notice-detail-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notice-detail-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notice-detail-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notice-detail-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notif-dropdown-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notif-dropdown-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/notif-dropdown-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/report-modal-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/report-modal-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-news-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-news-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-news-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-news-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-news-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-news-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-report-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-report-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-report-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-report-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-report-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/setting-report-t-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/story-detail-d-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/story-detail-d-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/story-detail-m-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/story-detail-m-before.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/story-detail-t-after.png is excluded by !**/*.png
  • docs/hyunil/responsive-shots/story-detail-t-before.png is excluded by !**/*.png
📒 Files selected for processing (24)
  • RESPONSIVE_AUDIT_REPORT.md
  • docs/hyunil/responsive-audit.md
  • docs/hyunil/responsive-shots/README.md
  • src/app/(main)/groups/GroupsPageClient.tsx
  • src/app/(main)/groups/[id]/GroupDetailClient.tsx
  • src/app/(main)/groups/[id]/bookcase/[bookId]/meeting/MeetingPageClient.tsx
  • src/app/(main)/groups/[id]/notice/[noticeId]/NoticeDetailPageClient.tsx
  • src/app/(main)/stories/[id]/StoryDetailClient.tsx
  • src/app/(public)/find-account/FindAccountPageClient.tsx
  • src/app/(public)/find-account/result/FindAccountResultPageClient.tsx
  • src/app/(public)/find-password/FindPasswordPageClient.tsx
  • src/components/base-ui/Bookcase/bookid/TeamSection.tsx
  • src/components/base-ui/Group/notice_detail.tsx
  • src/components/base-ui/Profile/Follow/FollowItem.tsx
  • src/components/base-ui/Settings/setting_news_list.tsx
  • src/components/base-ui/Settings/setting_report_list.tsx
  • src/components/base-ui/home/Club/home_bookclub.tsx
  • src/components/common/find-account/PrimaryButton.tsx
  • src/components/common/modals/report-block/ReportModal.tsx
  • src/components/layout/NotificationDropdown.tsx
  • src/hooks/queries/useClubhomeQueries.ts
  • src/lib/api/endpoints/Clubs.ts
  • src/services/clubService.ts
  • src/types/groups/grouphome.ts

return (
<button
className={`flex w-[258px] h-[48px] px-[16px] py-[12px] justify-center items-center rounded-lg bg-primary-1 text-White body_1_1 hover:bg-primary-3 transition-colors cursor-pointer ${className}`}
className={`flex w-full t:w-[258px] h-[48px] px-[16px] py-[12px] justify-center items-center rounded-lg bg-primary-1 text-White body_1_1 hover:bg-primary-3 transition-colors cursor-pointer ${className}`}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Two full-width buttons in a horizontal flex row will overflow on mobile.

PrimaryButton now uses w-full below the t: breakpoint. It's consumed in pairs inside a flex row with gap-[10px] (e.g., FindAccountPageClient.tsx:85). Without flex-wrap or flex-col, two w-full siblings will overflow the viewport on mobile.

Add flex-wrap or switch to flex-col on the parent button container in the consuming pages.

🔧 Suggested fix for button container

In consuming pages (e.g., FindAccountPageClient.tsx:85):

-                    <div className="flex items-center gap-[10px] justify-center w-full">
+                    <div className="flex flex-col t:flex-row items-center gap-[10px] justify-center w-full">
🤖 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 `@src/components/common/find-account/PrimaryButton.tsx` at line 11, The new
w-full behavior in PrimaryButton causes paired buttons in horizontal flex
containers to overflow on mobile. Update the consuming button container in
FindAccountPageClient (and any similar callers) to use flex-wrap or switch to a
flex-col layout below the breakpoint, so two PrimaryButton siblings can stack
instead of forcing viewport overflow. Keep the existing PrimaryButton sizing,
and fix the layout at the parent container level where the buttons are rendered
together.

yhi9839 and others added 2 commits June 26, 2026 12:13
충돌 해결: src/components/common/modals/report-block/ReportModal.tsx
- 신고 API 개편(main: 사유/REPORT_REASONS/reason)과 반응형 수정(dev: flex-wrap/flex-1 버튼, w-full max-w 모달)을 모두 반영

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/common/modals/report-block/ReportModal.tsx (1)

25-44: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Avoid setState directly in useEffect body

Lines 34 and 37 call setReason(defaultReason) synchronously inside the effect, which triggers cascading renders. The ESLint rule react-hooks/set-state-in-effect correctly flags this.

Move the reset logic into the event flow that causes the open/close transition (e.g., reset in onClose or onOpen callbacks) rather than reacting to isOpen in an effect. If that’s not feasible, split into two effects: one for the Escape key subscription, one for the reset—but prefer callback-based reset.

♻️ Suggested refactor
-    useEffect(() => {
-        const handleEscape = (e: KeyboardEvent) => {
-            if (e.key === "Escape" && isOpen) {
-                onClose();
-            }
-        };
-
-        if (isOpen) {
-            document.addEventListener("keydown", handleEscape);
-            setReason(defaultReason);
-        } else {
-            // Reset state when closed
-            setReason(defaultReason);
-            setReportContent("");
-        }
-
-        return () => {
-            document.removeEventListener("keydown", handleEscape);
-        };
-    }, [isOpen, onClose, defaultReason]);
+    useEffect(() => {
+        const handleEscape = (e: KeyboardEvent) => {
+            if (e.key === "Escape" && isOpen) {
+                onClose();
+            }
+        };
+
+        if (isOpen) {
+            document.addEventListener("keydown", handleEscape);
+        }
+
+        return () => {
+            document.removeEventListener("keydown", handleEscape);
+        };
+    }, [isOpen, onClose]);
+
+    // Reset state when modal closes
+    useEffect(() => {
+        if (!isOpen) {
+            setReason(defaultReason);
+            setReportContent("");
+        }
+    }, [isOpen, defaultReason]);
🤖 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 `@src/components/common/modals/report-block/ReportModal.tsx` around lines 25 -
44, The `ReportModal` effect is doing synchronous state resets with `setReason`
and `setReportContent` inside `useEffect`, which triggers the
`react-hooks/set-state-in-effect` warning. Move the reset logic out of the
`useEffect` in `ReportModal` and into the open/close event flow, such as the
`onClose` path or whatever callback toggles `isOpen`; keep the effect only for
the Escape key listener, or split it so the listener and reset are handled
separately.
🤖 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.

Outside diff comments:
In `@src/components/common/modals/report-block/ReportModal.tsx`:
- Around line 25-44: The `ReportModal` effect is doing synchronous state resets
with `setReason` and `setReportContent` inside `useEffect`, which triggers the
`react-hooks/set-state-in-effect` warning. Move the reset logic out of the
`useEffect` in `ReportModal` and into the open/close event flow, such as the
`onClose` path or whatever callback toggles `isOpen`; keep the effect only for
the Escape key listener, or split it so the listener and reset are handled
separately.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3727172a-d216-4ec2-b277-8f1bbab87e29

📥 Commits

Reviewing files that changed from the base of the PR and between 66e748a and 0e172c8.

📒 Files selected for processing (1)
  • src/components/common/modals/report-block/ReportModal.tsx

@yhi9839
yhi9839 merged commit 3a1a188 into main Jun 26, 2026
3 checks passed

This branch was successfully deployed

1 active deployment
Preview — 0e172c85 Deployed Jun 26, 2026 by vercel[bot]
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