Skip to content

[FE] 314 기능개선전체 전반적 fe uiux 개선#315

Merged
discipline24 merged 8 commits into
mainfrom
FE]-314-기능개선전체-전반적-fe-uiux-개선
Mar 21, 2026

Hidden character warning

The head ref may contain hidden characters: "FE]-314-\uae30\ub2a5\uac1c\uc120\uc804\uccb4-\uc804\ubc18\uc801-fe-uiux-\uac1c\uc120"
Merged

[FE] 314 기능개선전체 전반적 fe uiux 개선#315
discipline24 merged 8 commits into
mainfrom
FE]-314-기능개선전체-전반적-fe-uiux-개선

Conversation

@sangkyu39
Copy link
Copy Markdown
Contributor

@sangkyu39 sangkyu39 commented Mar 21, 2026

출석 조회 목록 및 관리 핸드폰 기준 ui 적용
기타 모바일 반응형 ui 적용
비밀번호 입력 시 확인 기능 추가 및 회원가입 시 비밀번호 확인 불일치 시 문구로 확인 가능하게 수정
권한별 사이드바 목록 제한 반영 등

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 로그인/회원가입에 비밀번호 표시 토글 및 확인일치 실시간 피드백 추가
    • 출석 관리: 역할 우선 정렬 및 클라이언트 페이지네이션(페이지 버튼) 추가
    • 사용자 추가 모달에 팀 필터 및 필터 기반 전체선택 동작 추가
  • 버그 수정

    • 여러 모달의 오버레이 레이어링 개선(z-index 조정)
    • 외부 클릭으로 메뉴 자동 닫힘 동작 개선
    • 테이블 수평 스크롤 및 레이아웃 안정성 개선
  • 스타일

    • 반응형 레이아웃·패딩 개선 및 게시판 페이지당 표시 항목 10개로 증가

@sangkyu39 sangkyu39 requested a review from discipline24 as a code owner March 21, 2026 06:45
@sangkyu39 sangkyu39 linked an issue Mar 21, 2026 that may be closed by this pull request
Copilot AI review requested due to automatic review settings March 21, 2026 06:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 21, 2026

Walkthrough

여러 UI/스타일과 접근 제어를 변경합니다: 다수 모달의 z-index 통일(3000), 로그인/회원가입 비밀번호 가시성 토글 추가, 출석관리 역할 기반 메뉴 표시 및 여러 출석관리 컴포넌트·테이블의 레이아웃·페이징·정렬 로직 개선, 게시판 관련 외부 클릭 감지 및 댓글 메뉴 토글 개선.

Changes

Cohort / File(s) Summary
모달 오버레이 z-index 통일
frontend/src/components/AdminMemberApproval/AdminMemberApproval.module.css, frontend/src/components/AdminMemberManage/AdminMemberManage.module.css, frontend/src/components/Board/CreateSubBoardModal.module.css, frontend/src/components/Board/Modal.module.css, frontend/src/components/VerificationModal.module.css, frontend/src/components/backtest/BacktestTemplateSaveModal.module.css, frontend/src/components/mypage/ActivityModal.module.css, frontend/src/components/mypage/EditProfileModal.module.css, frontend/src/components/quantbot/ReportModal.css
여러 모달 오버레이의 z-index 값을 3000으로 변경하여 스택 순서 통일
로그인·회원가입 비밀번호 토글 UI
frontend/src/components/LoginAndSignUpForm.module.css, frontend/src/components/login/LoginForm.jsx, frontend/src/components/signup/SignUpForm.jsx
비밀번호 표시/숨김 토글 상태와 버튼 추가, 관련 CSS 클래스(.inputWithToggle 등) 추가 및 확인 메시지 UI 도입
사이드바 역할 기반 출석관리 메뉴
frontend/src/components/Sidebar.jsx
canSeeAttendanceManageMenu 플래그와 ATTENDANCE_MANAGE_VISIBLE_ROLES 추가, 로그인/오류 시 권한 강제 false 처리, 조건부 렌더링으로 메뉴 노출 제어
출석관리 테이블 래핑 및 스크롤
frontend/src/components/attendance/SessionManage.jsx, frontend/src/components/attendance/SessionManage.module.css
테이블을 .tableWrap으로 래핑하여 가로 스크롤 허용, 테이블 최소 너비·스크롤바 스타일 조정
출석관리 카드: 정렬·페이징·열 스타일
frontend/src/components/attendancemanage/AttendanceManagementCard.jsx, frontend/src/components/attendancemanage/AttendanceManagementCard.module.css
역할별 라벨·우선순위 정렬, 클라이언트 페이징 추가, CSS로 인라인 스타일 대체, 고정/최소 열 너비 및 sticky 헤더·페이징 UI 추가
세션 카드 레이아웃·입력 스타일 개선
frontend/src/components/attendancemanage/SessionManagementCard.jsx, frontend/src/components/attendancemanage/SessionManagementCard.module.css, frontend/src/components/attendancemanage/SessionSettingCard.jsx, frontend/src/components/attendancemanage/SessionSettingCard.module.css
헤더/컨트롤에 모듈 클래스 추가, 수평 스크롤·반응형 개선, .compactTextInput/.compactMinuteInput 클래스 도입으로 입력 폭 제약
RoundDayPicker 시간 고정화
frontend/src/components/attendancemanage/RoundDayPicker.jsx
DEFAULT_END_TIME_MINUTES = 60 도입 — endTime 계산을 고정 60분 기준으로 변경(기존 allowedMinutes 의존 제거)
PostDetail 외부 클릭 감지·댓글 메뉴 토글
frontend/src/pages/PostDetail.jsx, frontend/src/components/Board/PostDetail/CommentSection.jsx, frontend/src/pages/PostDetail.module.css
문서 mousedown 리스너로 메뉴 외부 클릭 시 메뉴 닫기 추가, 댓글 메뉴 버튼에 기능적 토글(같은 버튼으로 닫기/열기) 적용 및 모바일 패딩 변수 추가
AddUsersModal 팀 필터링·선택 로직 변경
frontend/src/components/attendancemanage/AddUsersModal.jsx
팀 기반 필터 상태 및 필터된 사용자 기준의 전체 선택/헤더 체크 로직으로 변경, 필터 UI 및 빈문구 수정
게시판 페이지네이션 항목 수 변경
frontend/src/pages/Board.jsx
한 페이지 표시 항목 itemsPerPage를 4→10으로 증가

Sequence Diagram(s)

(생성 조건 미충족 — 생략)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested labels

FE

Suggested reviewers

  • DongEun02
  • gxuoo
  • discipline24

🐰 모달은 3000에 올라가 뛰고,
출석은 역할로 줄을 세우고,
비밀번호는 눈 깜짝이면 보이고 숨고,
테이블은 옆으로 흘러가며 정렬되네. 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive PR 제목이 너무 광범위하고 모호하여 주요 변경사항을 명확히 파악하기 어렵습니다. 구체적이고 명확한 제목으로 변경하세요. 예: '[FE] 출석 관리 모바일 UI 개선 및 권한 기반 사이드바 제어' 또는 '[FE] 모바일 반응형 및 권한 제어 기능 개선'
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ 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 FE]-314-기능개선전체-전반적-fe-uiux-개선

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.

Tip

You can get early access to new features in CodeRabbit.

Enable the early_access setting to enable early access features such as new models, tools, and more.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

모바일(핸드폰) 기준으로 출석/게시판/모달/로그인·회원가입 등 주요 화면의 UI·UX를 개선하고, 비밀번호 표시 토글 및 권한별 사이드바 노출 제한을 반영하는 프론트엔드 변경입니다.

Changes:

  • 출석 관리/조회 화면의 모바일 레이아웃 및 테이블 스크롤/고정 헤더 등 반응형 UI 개선
  • 로그인/회원가입 폼에 비밀번호 보기/숨기기 토글 및 비밀번호 확인 불일치 안내 추가
  • 모달/오버레이 z-index 상향 및 사이드바 메뉴를 역할 기반으로 제한

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
frontend/src/pages/PostDetail.module.css PostDetail 모바일 패딩/콘텐츠 폭 변수 조정
frontend/src/pages/PostDetail.jsx 게시글/댓글 메뉴 외부 클릭 시 닫기 처리 추가
frontend/src/pages/Board.jsx 게시판 페이지네이션 페이지당 아이템 수 변경(4→10)
frontend/src/pages/AttendanceManage.module.css 출석관리 페이지 레이아웃(플렉스/그리드) 및 오버플로우 개선
frontend/src/components/signup/SignUpForm.jsx 비밀번호 토글, 비밀번호 확인 일치/불일치 메시지 추가
frontend/src/components/quantbot/ReportModal.css 모달 overlay z-index 상향
frontend/src/components/mypage/EditProfileModal.module.css 프로필 수정 모달 z-index 상향
frontend/src/components/mypage/ActivityModal.module.css 활동 모달 z-index 상향
frontend/src/components/login/LoginForm.jsx 로그인 비밀번호 토글 추가
frontend/src/components/backtest/BacktestTemplateSaveModal.module.css 저장 모달 z-index 상향
frontend/src/components/attendancemanage/SessionSettingCard.module.css 세션 설정 카드 입력 폭/반응형 정리 및 오버플로우 개선
frontend/src/components/attendancemanage/SessionSettingCard.jsx 세션 설정 입력에 compact 스타일 클래스 적용
frontend/src/components/attendancemanage/SessionManagementCard.module.css 세션 관리 카드 헤더/테이블 스크롤 및 반응형 정리
frontend/src/components/attendancemanage/SessionManagementCard.jsx 공통 헤더에 반응형 헤더 스타일 결합
frontend/src/components/attendancemanage/RoundDayPicker.jsx 회차 추가 모달의 종료시간 기본 계산 로직 변경
frontend/src/components/attendancemanage/AttendanceManagementCard.module.css 출석부 테이블 고정 헤더/컬럼 폭 및 스크롤 UX 개선
frontend/src/components/attendancemanage/AttendanceManagementCard.jsx 테이블 헤더 스타일 클래스화 및 역할 표시 라벨링 추가
frontend/src/components/attendance/SessionManage.module.css 출석 조회 테이블 래퍼 추가로 가로 스크롤 UX 개선
frontend/src/components/attendance/SessionManage.jsx 테이블을 스크롤 래퍼로 감싸 모바일 대응
frontend/src/components/VerificationModal.module.css 오버레이/모달 최대높이 및 모바일 safe-area 대응, z-index 상향
frontend/src/components/Sidebar.jsx 출석관리 메뉴를 역할 기반으로 조건부 노출
frontend/src/components/LoginAndSignUpForm.module.css 비밀번호 토글 UI 및 비밀번호 일치 메시지 스타일 추가
frontend/src/components/Board/PostDetail/CommentSection.jsx 댓글 메뉴 버튼 토글 동작(열기/닫기) 개선
frontend/src/components/Board/Modal.module.css 게시판 모달 overlay z-index 상향
frontend/src/components/Board/CreateSubBoardModal.module.css 서브보드 생성 모달 z-index 상향
frontend/src/components/AdminMemberManage/AdminMemberManage.module.css 관리자 회원관리 모달 z-index 상향
frontend/src/components/AdminMemberApproval/AdminMemberApproval.module.css 관리자 가입승인 모달 z-index 상향

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/src/components/login/LoginForm.jsx
Comment thread frontend/src/components/signup/SignUpForm.jsx
Comment thread frontend/src/components/signup/SignUpForm.jsx
Comment thread frontend/src/components/attendancemanage/RoundDayPicker.jsx
Copy link
Copy Markdown

@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: 3

Caution

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

⚠️ Outside diff range comments (2)
frontend/src/components/attendancemanage/SessionSettingCard.jsx (1)

94-102: ⚠️ Potential issue | 🟡 Minor

maxLength 속성이 type="number" 입력에서는 동작하지 않습니다.

Line 99의 maxLength="3"type="number" 입력 필드에서 무시됩니다. 3자리 제한이 필요하다면 max 속성이나 onChange 핸들러에서 유효성 검사를 추가해야 합니다.

🔧 max 속성을 사용한 수정 제안
              <input
                type="number"
                id="sessionAvailableTime"
                className={styles.compactMinuteInput}
                value={allowedMinutes}
-               maxLength="3"
+               min="1"
+               max="999"
                onChange={(e) => setAllowedMinutes(e.target.value)}
                placeholder="분(MM)"
              />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionSettingCard.jsx` around lines
94 - 102, The number input with id "sessionAvailableTime" in
SessionSettingCard.jsx uses maxLength="3" which is ignored for type="number";
change to a proper numeric limit by adding a max="999" attribute and enforce
validation in the onChange handler: when handling e.target.value in the
setAllowedMinutes call, coerce/validate the value (e.g., strip non-digits, limit
length to 3 or clamp to 0–999) before calling setAllowedMinutes so the stored
state respects the 3-digit constraint. Ensure you update the input attributes
and the onChange logic that references allowedMinutes and setAllowedMinutes.
frontend/src/pages/AttendanceManage.module.css (1)

34-38: ⚠️ Potential issue | 🟠 Major

CSS 그리드 영역이 JSX 구조와 맞지 않습니다.

.cardLayout은 3개의 그리드 영역(settings, session, roster)을 정의하지만 실제로는 2개의 직접 자식 요소(.leftColumnAttendanceManagementCard)만 존재합니다. 또한 SessionSettingCard, SessionManagementCard, AttendanceManagementCard.settings, .session, .roster 클래스를 적용하지 않아 그리드 레이아웃이 의도대로 작동하지 않을 수 있습니다.

이를 해결하려면 다음 중 하나를 수행해야 합니다:

  • 컴포넌트에 해당하는 그리드 영역 클래스를 적용하거나
  • CSS 그리드 정의를 JSX 구조에 맞게 조정하기
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/pages/AttendanceManage.module.css` around lines 34 - 38,
.cardLayout defines three grid areas ('settings','session','roster') but JSX
only renders two direct children (.leftColumn and AttendanceManagementCard) and
the child components (SessionSettingCard, SessionManagementCard,
AttendanceManagementCard) do not have the corresponding area classes, so the
grid won't lay out as intended; fix by either adding the grid-area classes to
the rendered elements (apply className="settings" to the container wrapping
SessionSettingCard/SessionManagementCard and className="session"/"roster" where
appropriate, or add className="settings"/"session"/"roster" to those component
root elements) or simplify .cardLayout to match the actual JSX structure (remove
unused grid-template-areas or combine them), targeting the .cardLayout,
.leftColumn, SessionSettingCard, SessionManagementCard, and
AttendanceManagementCard symbols to implement the change.
🧹 Nitpick comments (18)
frontend/src/pages/PostDetail.module.css (1)

860-869: 모바일 반응형 스타일이 적절하게 추가되었습니다.

브레이크포인트 767px이 기존 태블릿 쿼리 min-width: 768px과 잘 맞물리며, 모바일에서 콘텐츠 너비를 100%로 확장하는 것은 좋은 UX 개선입니다.

한 가지 참고사항: CSS Modules에서 :root는 스코핑되지 않고 전역으로 적용됩니다. 현재는 --width-content가 이 파일에서만 정의되어 문제가 없지만, 향후 다른 CSS 모듈에서 동일한 변수를 정의하면 충돌이 발생할 수 있습니다. 필요시 .postDetail 내에서 직접 값을 사용하거나 더 구체적인 변수명을 고려해 볼 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/pages/PostDetail.module.css` around lines 860 - 869, The CSS
uses a global :root custom property (--width-content) inside the mobile media
query which can conflict with other CSS Modules later; change the rule so the
variable is scoped or inlined—either move the value into .postDetail (e.g., set
.postDetail { --postDetail-width-content: 100%; } and use that locally) or
rename the variable to a more specific name (e.g., --postDetail-width-content)
and update all references, and ensure the media query remains `@media` (max-width:
767px) for .postDetail.
frontend/src/components/Board/Modal.module.css (1)

11-11: z-index 매직넘버는 공용 토큰으로 통합하는 걸 권장합니다.

Line 11처럼 3000이 여러 파일에 반복되어 있어, 다음 레이어 충돌 시 수정 범위가 커질 수 있습니다. 공용 CSS 변수로 통일하면 유지보수가 쉬워집니다.

♻️ 제안 수정안
 .overlay {
   position: fixed;
@@
-  z-index: 3000;
+  z-index: var(--z-modal-overlay);
 }
/* 공통 루트 스타일(예: 전역 stylesheet)에 1회 정의 */
:root {
  --z-modal-overlay: 3000;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/Board/Modal.module.css` at line 11, Replace the
hardcoded z-index value in Modal.module.css (the CSS rule containing "z-index:
3000;") with a shared CSS custom property to avoid magic numbers; add a global
variable (e.g. --z-modal-overlay) in your root/global stylesheet and update the
Modal.module.css rule to use that variable instead of 3000 so all components
reference the same token.
frontend/src/components/login/LoginForm.jsx (1)

102-109: 토글 버튼에 상태(aria-pressed)를 함께 노출해 주세요.

라벨 변경만으로도 동작은 전달되지만, 토글 버튼 패턴에서는 pressed 상태를 같이 주는 편이 더 명확합니다.

접근성 속성 보강 예시
               <button
                 type="button"
                 className={styles.passwordToggleButton}
                 onClick={() => setShowPassword((prev) => !prev)}
                 aria-label={showPassword ? '비밀번호 숨기기' : '비밀번호 보기'}
+                aria-pressed={showPassword}
               >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/login/LoginForm.jsx` around lines 102 - 109, The
password toggle button in LoginForm.jsx should expose its pressed state via
aria-pressed; update the button that uses setShowPassword and showPassword
(className styles.passwordToggleButton) to include aria-pressed={showPassword}
so the attribute reflects the boolean state, ensuring it stays a proper toggle
button for assistive tech.
frontend/src/components/signup/SignUpForm.jsx (2)

296-308: 일치/불일치 안내 문구에 aria-live를 추가해 주세요.

문구가 동적으로 바뀌는 영역이라 스크린리더가 변경을 읽어줄 수 있도록 live region 지정이 있으면 좋습니다.

접근성 보강 예시
             {hasConfirmPasswordInput && (
               <p
                 className={`${styles.passwordMatchMessage} ${
                   isPasswordMatch
                     ? styles.passwordMatchMessageSuccess
                     : styles.passwordMatchMessageError
                 }`}
+                role="status"
+                aria-live="polite"
               >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/signup/SignUpForm.jsx` around lines 296 - 308, The
password match message block (controlled by hasConfirmPasswordInput and
isPasswordMatch) is a dynamic live region for screen readers; add an aria-live
attribute (e.g., aria-live="polite") to the outer <p> and consider
aria-atomic="true" so updates are fully announced, keeping the existing
classNames (styles.passwordMatchMessage, styles.passwordMatchMessageSuccess,
styles.passwordMatchMessageError) and message logic intact; ensure you update
the JSX for the <p> rendered by the conditional that references
hasConfirmPasswordInput and isPasswordMatch.

248-265: 토글 입력 UI 중복은 공통 컴포넌트로 추출을 고려해도 좋겠습니다.

동일 패턴이 반복되어 있어 PasswordFieldWithToggle 형태로 분리하면 유지보수가 쉬워집니다.

Also applies to: 279-295

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/signup/SignUpForm.jsx` around lines 248 - 265,
Extract the repeated password input + toggle block into a reusable component
(e.g., PasswordFieldWithToggle) and replace both occurrences in SignUpForm.jsx
with that component; the new component should accept props for value, onChange
(use handlePasswordChange), id, placeholder, autoComplete and any className (use
styles.inputWithToggle and styles.passwordToggleButton) and internally manage
its own showPassword state and render Eye / EyeOff icons accordingly, preserving
aria-label behavior and button type="button".
frontend/src/components/LoginAndSignUpForm.module.css (1)

87-106: 키보드 사용자용 포커스 스타일을 명시해 주세요.

현재 hover 상태만 정의되어 있어, 버튼 포커스 표시를 명시하면 접근성이 더 안정적입니다.

접근성 보강 예시
 .passwordToggleButton:hover {
   color: `#111827`;
 }
 
+.passwordToggleButton:focus-visible {
+  outline: 2px solid `#1d80f4`;
+  outline-offset: 2px;
+  border-radius: 6px;
+}
+
 .passwordToggleButton svg {
   pointer-events: none;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/LoginAndSignUpForm.module.css` around lines 87 - 106,
The .passwordToggleButton styles only define hover state; add explicit keyboard
focus styles so keyboard users can see focus—implement
.passwordToggleButton:focus and/or .passwordToggleButton:focus-visible rules
(matching or complementing the hover color change) that provide a clear,
high-contrast visible indicator (e.g., outline or box-shadow) while preserving
the existing layout and sizing for the passwordToggleButton element.
frontend/src/components/attendancemanage/SessionSettingCard.module.css (1)

97-107: 반응형 입력 필드 너비 제어 클래스가 추가되었습니다.

clamp() 함수를 사용한 유연한 너비 조절이 좋습니다. 다만 !important 사용이 많아 향후 스타일 오버라이드 시 유지보수가 어려울 수 있습니다. 가능하다면 CSS 특이성(specificity)을 활용한 방식을 고려해보세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionSettingCard.module.css`
around lines 97 - 107, The current .compactTextInput and .compactMinuteInput
rules rely on multiple !important flags which make future overrides fragile;
remove the !important declarations and instead increase selector specificity
(for example by scoping under the parent component class or combining selectors
like .sessionSettingCard .compactTextInput / .sessionSettingCard
.compactMinuteInput) or adjust the CSS module export so the styles win without
!important, keeping the clamp(...) values intact and preserving
width/min-width/max-width behavior.
frontend/src/components/attendancemanage/AttendanceManagementCard.jsx (1)

45-64: 역할 표시 라벨 헬퍼 함수가 잘 구현되었습니다.

백엔드 SessionRole enum(OWNER, MANAGER, PARTICIPANT)과 매핑되어 한글 라벨을 반환합니다. 다만, includes('MANAGE') 방식의 부분 문자열 매칭은 의도치 않은 매칭을 유발할 수 있습니다.

♻️ 정확한 매칭을 위한 개선 제안
 const getRoleDisplayLabel = (role) => {
   const roleText = String(role || '').trim();
   const normalized = roleText.toUpperCase();

   if (normalized.includes('OWNER')) {
     return '소유자';
   }

-  if (normalized.includes('MANAGE')) {
+  if (normalized.includes('MANAGER') || normalized === 'MANAGE') {
     return '관리자';
   }

   if (
     normalized.includes('PARTICIPANT')
   ) {
     return '팀원';
   }

   return roleText || '팀원';
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/AttendanceManagementCard.jsx` around
lines 45 - 64, getRoleDisplayLabel currently uses substring checks (e.g.,
normalized.includes('MANAGE')) which can produce false positives; change the
matching to exact enum comparisons on the normalized role (e.g., compare
normalized === 'OWNER' / 'MANAGER' / 'PARTICIPANT' or use a strict set lookup)
so the function maps only the intended backend SessionRole values to Korean
labels; update getRoleDisplayLabel to normalize role and then do exact matches
(or a lookup map) and keep the fallback to roleText || '팀원'.
frontend/src/pages/AttendanceManage.module.css (1)

52-61: .roster > * 선택자 범위 확인이 필요합니다.

.roster 클래스가 실제로 사용되지 않는다면 이 규칙은 적용되지 않습니다. 현재 JSX 구조에서 AttendanceManagementCard.roster 클래스 없이 직접 렌더링되고 있어, width: 100% 규칙이 의도한 대로 적용되지 않을 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/pages/AttendanceManage.module.css` around lines 52 - 61, The
`.roster > *` CSS rule is not applying because the rendered JSX doesn’t use the
`.roster` class; check where AttendanceManagementCard is rendered and either (a)
add the roster module class to the container element that wraps
AttendanceManagementCard (so `.roster > * { width:100% }` applies), or (b)
change the selector in AttendanceManage.module.css to target the actual class
name used in the JSX (the wrapper/component class around
AttendanceManagementCard) so child elements get width:100%; update the JSX/class
names accordingly and verify the layout.
frontend/src/components/attendancemanage/AttendanceManagementCard.module.css (4)

1-13: 중복된 .attendanceManagementCardContainer 선택자가 존재합니다.

Lines 1-13과 Lines 534-547에서 동일한 선택자가 두 번 정의되어 있습니다. 두 정의를 하나로 병합하여 유지보수성을 개선하세요. 현재 구조에서는 나중 정의가 이전 속성을 덮어쓰기 때문에 의도치 않은 스타일 손실이 발생할 수 있습니다.

Also applies to: 534-547

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/AttendanceManagementCard.module.css`
around lines 1 - 13, Duplicate .attendanceManagementCardContainer rules exist;
merge them into one definition by consolidating all properties from both
occurrences (lines showing .attendanceManagementCardContainer) into a single
block, remove the later duplicate, and ensure any conflicting properties are
resolved by choosing the intended value (prefer the later value if that was
intentional). Update any comments and run a quick UI check to confirm
box-shadow, border, padding, background, transition, overflow, and sizing behave
as expected.

381-406: 테이블 컬럼 너비가 중복 정의되어 있습니다.

Lines 381-406에서 정의한 너비 규칙이 Lines 642-658에서 다른 값으로 재정의됩니다. 예: 2번째 컬럼이 120px에서 76px로 변경. 의도적인 변경이라면 이전 정의를 정리하세요.

Also applies to: 642-658

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/AttendanceManagementCard.module.css`
around lines 381 - 406, There are duplicate column-width rules for the table
(selectors like .table thead th:nth-child(1) / tbody td:nth-child(1) through
.table thead th:nth-child(n + 5) / tbody td:nth-child(n + 5)) that conflict with
another block (e.g., the 2nd column defined as 120px here but redefined as 76px
later); pick the intended widths and remove or consolidate the redundant CSS
block so only one authoritative set of widths remains (either keep the 381–406
definitions and delete the later overrides, or merge the final values into this
set), ensuring selectors (.table thead th:nth-child(n) and .table tbody
td:nth-child(n)) match exactly and preserve min-width where needed.

136-139: 여러 !important 선언을 제거하세요.

text-align: center !important (Lines 138, 268, 278)이 여러 곳에서 사용됩니다. 이는 specificity 문제를 우회하는 안티패턴입니다. CSS 선택자 구조를 개선하거나 클래스 조합을 통해 specificity를 자연스럽게 높이세요.

Also applies to: 268-275, 277-279

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/AttendanceManagementCard.module.css`
around lines 136 - 139, Remove the !important usages on .checkboxHeader and
.checkboxCell by increasing selector specificity or adding a dedicated utility
class; for example, replace the rules using ".checkboxHeader, .checkboxCell {
text-align: center !important; }" with a more specific selector such as
".attendanceCard .checkboxHeader, .attendanceCard .checkboxCell { text-align:
center; }" or add a new ".centerText" class with "text-align: center;" and apply
it in the component JSX where CheckboxHeader/CheckboxCell are rendered; ensure
any conflicting rules (other selectors targeting these elements) are adjusted or
removed so the new non-!important rules take effect.

200-206: z-index 값을 체계적으로 관리하세요.

z-index 값이 1, 2, 30, 40, 120, 220 등으로 산발적으로 사용됩니다. 예측 가능한 스태킹 컨텍스트를 위해 CSS 변수나 주석으로 z-index 계층을 문서화하세요.

💡 권장 패턴 예시
:root {
  --z-base: 1;
  --z-sticky-header: 30;
  --z-dropdown: 100;
  --z-modal: 200;
}

Also applies to: 238-238, 252-252, 270-270, 274-274, 315-315, 321-321, 550-550

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/AttendanceManagementCard.module.css`
around lines 200 - 206, 파일 전반에 흩어진 하드코딩된 z-index 값을 시스템화해야 합니다: 루트에 :root {
--z-base:1; --z-sticky-header:30; --z-dropdown:100; --z-modal:200; } 같은 CSS 변수를
정의하고 기존의 고정 값들을 해당 변수로 대체하세요 (예: .attendanceSelectWrap.open의 z-index: 40 →
z-index: var(--z-dropdown)). 같은 방식으로 파일 내 다른 셀렉터들(문제된 위치들에서 사용한 z-index
1,2,30,40,120,220 등)을 찾아 적절한 변수로 매핑하고 주석으로 계층 설명을 추가해 스태킹 컨텍스트를 문서화하세요.
frontend/src/components/attendancemanage/SessionManagementCard.module.css (5)

513-521: !important 사용을 피하세요.

flex-wrap: nowrap !important;는 specificity 문제를 암시합니다. !important는 디버깅을 어렵게 하고 향후 스타일 오버라이드를 복잡하게 만듭니다. 선택자 specificity를 조정하거나 CSS 구조를 재검토하세요.

♻️ 권장 수정안
 .headerControls {
-  flex-wrap: nowrap !important;
+  flex-wrap: nowrap;
   width: 100%;
   min-width: 0;
   overflow-x: auto;
   overflow-y: hidden;
   padding-bottom: 2px;
   margin-left: 0;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionManagementCard.module.css`
around lines 513 - 521, The .headerControls rule in
SessionManagementCard.module.css uses "flex-wrap: nowrap !important;" which
should be removed; instead, eliminate the !important and resolve the specificity
conflict by making the selector more specific (e.g., target the parent +
.headerControls or add a dedicated modifier class used in the component) or by
placing the rule later in the stylesheet/module so it naturally overrides the
competing rule; update the component markup if needed to add the modifier class
(referencing .headerControls) so the plain "flex-wrap: nowrap" applies without
!important.

1-13: 중복된 .sessionManagementCardContainer 선택자가 존재합니다.

동일한 선택자가 두 번 정의되어 있습니다 (Lines 1-13, Lines 471-478). 나중에 정의된 규칙이 이전 규칙을 덮어씁니다. 유지보수성을 위해 하나의 선택자로 통합하는 것이 좋습니다.

Also applies to: 471-478

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionManagementCard.module.css`
around lines 1 - 13, There are duplicate .sessionManagementCardContainer rules;
consolidate them by locating both definitions for the
.sessionManagementCardContainer selector, merge their CSS properties into a
single rule (preserve all unique declarations and resolve any conflicting values
by choosing the intended one), remove the redundant duplicate block, and ensure
the final single .sessionManagementCardContainer contains the combined styles so
the later rule no longer silently overrides the earlier one.

168-193: 테이블 컬럼 너비 정의가 중복되어 충돌합니다.

Lines 168-193에서 백분율 기반 너비(width: 22% 등)로 정의한 후, Lines 562-598에서 픽셀 기반 고정 너비(width: 96px 등)로 재정의합니다. 의도적인 변경이라면 이전 정의를 제거하세요.

Also applies to: 562-598

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionManagementCard.module.css`
around lines 168 - 193, The CSS sets column widths twice (percent-based
selectors like ".table thead th:nth-child(1)"/"...td:nth-child(1)" and later
pixel-based selectors for the same nth-child columns), causing conflicting
rules; pick one sizing strategy and remove the other to avoid override
conflicts—either keep the percent-based rules (remove the pixel-based block
around the later ".table thead th:nth-child(n)" / ".table tbody td:nth-child(n)"
rules with widths like 96px) or replace the percent rules with the pixel ones so
only one set remains, and if you must keep both, make intent explicit by
renaming classes or increasing specificity (e.g., add a modifier class to the
table) so selectors don't collide.

86-92: .table 선택자의 너비 전략이 중복 정의되어 있습니다.

Lines 86-92에서 min-width: 600px로 정의되었다가 Lines 541-544에서 width: max-content; min-width: 100%로 재정의됩니다. CSS 캐스케이드로 인해 나중 정의가 적용되지만, 코드 가독성과 유지보수를 위해 하나로 통합하세요.

Also applies to: 541-544

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionManagementCard.module.css`
around lines 86 - 92, The .table selector has conflicting width rules defined in
two places (one set using width: 100%; min-width: 600px and the other using
width: max-content; min-width: 100%); pick the intended sizing strategy and
consolidate into a single .table rule: remove the duplicate/contradicting
declaration and keep only the correct combination (e.g., width: 100% with
min-width: 600px OR width: max-content with min-width: 100%), update any layout
assumptions in related CSS if needed, and ensure only the chosen properties
remain so the cascade is not relied upon to resolve contradictions.

315-355: 미디어 쿼리 순서 및 중복에 주의하세요.

min-widthmax-width 미디어 쿼리가 혼재되어 있고 일부 브레이크포인트에서 규칙이 중복됩니다. 예를 들어 Lines 315-355의 @media (min-width: 768px)와 Lines 632-670의 @media (max-width: 768px)가 768px에서 충돌할 수 있습니다. 일관된 모바일 퍼스트 또는 데스크톱 퍼스트 전략을 사용하세요.

Also applies to: 632-670, 672-692

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/attendancemanage/SessionManagementCard.module.css`
around lines 315 - 355, There are overlapping min-width and max-width media
queries around 768px causing duplicate/conflicting rules (see selectors like
.sessionManagementCardContainer, .selectGroup, .sessionSelect, .tableGroup,
.table thead th, .table tbody td, .menuButton, .noData). Pick a consistent
strategy (mobile-first using only min-width or desktop-first using only
max-width), consolidate duplicated rules across the `@media` (min-width: 768px)
and `@media` (max-width: 768px) blocks into a single breakpoint block, and
remove/merge conflicting declarations so the final CSS for each selector appears
only once per breakpoint; if you must keep both styles, shift one breakpoint off
768px (e.g., use max-width: 767px or min-width: 769px) to eliminate the 768px
overlap.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/attendancemanage/RoundDayPicker.jsx`:
- Line 8: DEFAULT_END_TIME_MINUTES is hard-coded to 60 and causes closeAt to be
computed incorrectly, ignoring per-session allowedMinutes; update the logic so
handleComplete uses the actual session.allowedMinutes when computing closeAt
instead of DEFAULT_END_TIME_MINUTES: remove reliance on DEFAULT_END_TIME_MINUTES
in RoundDayPicker.jsx (and any uses at lines referenced), read the
allowedMinutes from the selected session object, compute end time = start time +
session.allowedMinutes, and pass that computed closeAt to the API (preserving
timezone/formatting used by AttendanceContext.jsx and
utils/attendanceManage.js).

In `@frontend/src/components/mypage/EditProfileModal.module.css`:
- Around line 10-12: In EditProfileModal.module.css remove the stray blank line
between the two declarations so the block reads "padding: 20px; z-index: 3000;"
(i.e., place the z-index declaration immediately after the padding declaration)
to satisfy the declaration-empty-line-before rule; if the blank line was
intentional, instead add a stylelint disable comment for
declaration-empty-line-before scoped to the z-index line.

In `@frontend/src/components/VerificationModal.module.css`:
- Around line 604-608: The overlay currently uses a fixed padding-bottom which
ignores the mobile safe-area inset and can cause extra scroll; change the
.overlay padding-bottom to account for env(safe-area-inset-bottom) (e.g., use
max(12px, env(safe-area-inset-bottom))) and also update any modal container
max-height calculation (the rule that subtracts fixed vertical offsets) to
include subtracting env(safe-area-inset-bottom) so the modal's max-height
accounts for the bottom inset and prevents unwanted extra scrolling.

---

Outside diff comments:
In `@frontend/src/components/attendancemanage/SessionSettingCard.jsx`:
- Around line 94-102: The number input with id "sessionAvailableTime" in
SessionSettingCard.jsx uses maxLength="3" which is ignored for type="number";
change to a proper numeric limit by adding a max="999" attribute and enforce
validation in the onChange handler: when handling e.target.value in the
setAllowedMinutes call, coerce/validate the value (e.g., strip non-digits, limit
length to 3 or clamp to 0–999) before calling setAllowedMinutes so the stored
state respects the 3-digit constraint. Ensure you update the input attributes
and the onChange logic that references allowedMinutes and setAllowedMinutes.

In `@frontend/src/pages/AttendanceManage.module.css`:
- Around line 34-38: .cardLayout defines three grid areas
('settings','session','roster') but JSX only renders two direct children
(.leftColumn and AttendanceManagementCard) and the child components
(SessionSettingCard, SessionManagementCard, AttendanceManagementCard) do not
have the corresponding area classes, so the grid won't lay out as intended; fix
by either adding the grid-area classes to the rendered elements (apply
className="settings" to the container wrapping
SessionSettingCard/SessionManagementCard and className="session"/"roster" where
appropriate, or add className="settings"/"session"/"roster" to those component
root elements) or simplify .cardLayout to match the actual JSX structure (remove
unused grid-template-areas or combine them), targeting the .cardLayout,
.leftColumn, SessionSettingCard, SessionManagementCard, and
AttendanceManagementCard symbols to implement the change.

---

Nitpick comments:
In `@frontend/src/components/attendancemanage/AttendanceManagementCard.jsx`:
- Around line 45-64: getRoleDisplayLabel currently uses substring checks (e.g.,
normalized.includes('MANAGE')) which can produce false positives; change the
matching to exact enum comparisons on the normalized role (e.g., compare
normalized === 'OWNER' / 'MANAGER' / 'PARTICIPANT' or use a strict set lookup)
so the function maps only the intended backend SessionRole values to Korean
labels; update getRoleDisplayLabel to normalize role and then do exact matches
(or a lookup map) and keep the fallback to roleText || '팀원'.

In
`@frontend/src/components/attendancemanage/AttendanceManagementCard.module.css`:
- Around line 1-13: Duplicate .attendanceManagementCardContainer rules exist;
merge them into one definition by consolidating all properties from both
occurrences (lines showing .attendanceManagementCardContainer) into a single
block, remove the later duplicate, and ensure any conflicting properties are
resolved by choosing the intended value (prefer the later value if that was
intentional). Update any comments and run a quick UI check to confirm
box-shadow, border, padding, background, transition, overflow, and sizing behave
as expected.
- Around line 381-406: There are duplicate column-width rules for the table
(selectors like .table thead th:nth-child(1) / tbody td:nth-child(1) through
.table thead th:nth-child(n + 5) / tbody td:nth-child(n + 5)) that conflict with
another block (e.g., the 2nd column defined as 120px here but redefined as 76px
later); pick the intended widths and remove or consolidate the redundant CSS
block so only one authoritative set of widths remains (either keep the 381–406
definitions and delete the later overrides, or merge the final values into this
set), ensuring selectors (.table thead th:nth-child(n) and .table tbody
td:nth-child(n)) match exactly and preserve min-width where needed.
- Around line 136-139: Remove the !important usages on .checkboxHeader and
.checkboxCell by increasing selector specificity or adding a dedicated utility
class; for example, replace the rules using ".checkboxHeader, .checkboxCell {
text-align: center !important; }" with a more specific selector such as
".attendanceCard .checkboxHeader, .attendanceCard .checkboxCell { text-align:
center; }" or add a new ".centerText" class with "text-align: center;" and apply
it in the component JSX where CheckboxHeader/CheckboxCell are rendered; ensure
any conflicting rules (other selectors targeting these elements) are adjusted or
removed so the new non-!important rules take effect.
- Around line 200-206: 파일 전반에 흩어진 하드코딩된 z-index 값을 시스템화해야 합니다: 루트에 :root {
--z-base:1; --z-sticky-header:30; --z-dropdown:100; --z-modal:200; } 같은 CSS 변수를
정의하고 기존의 고정 값들을 해당 변수로 대체하세요 (예: .attendanceSelectWrap.open의 z-index: 40 →
z-index: var(--z-dropdown)). 같은 방식으로 파일 내 다른 셀렉터들(문제된 위치들에서 사용한 z-index
1,2,30,40,120,220 등)을 찾아 적절한 변수로 매핑하고 주석으로 계층 설명을 추가해 스태킹 컨텍스트를 문서화하세요.

In `@frontend/src/components/attendancemanage/SessionManagementCard.module.css`:
- Around line 513-521: The .headerControls rule in
SessionManagementCard.module.css uses "flex-wrap: nowrap !important;" which
should be removed; instead, eliminate the !important and resolve the specificity
conflict by making the selector more specific (e.g., target the parent +
.headerControls or add a dedicated modifier class used in the component) or by
placing the rule later in the stylesheet/module so it naturally overrides the
competing rule; update the component markup if needed to add the modifier class
(referencing .headerControls) so the plain "flex-wrap: nowrap" applies without
!important.
- Around line 1-13: There are duplicate .sessionManagementCardContainer rules;
consolidate them by locating both definitions for the
.sessionManagementCardContainer selector, merge their CSS properties into a
single rule (preserve all unique declarations and resolve any conflicting values
by choosing the intended one), remove the redundant duplicate block, and ensure
the final single .sessionManagementCardContainer contains the combined styles so
the later rule no longer silently overrides the earlier one.
- Around line 168-193: The CSS sets column widths twice (percent-based selectors
like ".table thead th:nth-child(1)"/"...td:nth-child(1)" and later pixel-based
selectors for the same nth-child columns), causing conflicting rules; pick one
sizing strategy and remove the other to avoid override conflicts—either keep the
percent-based rules (remove the pixel-based block around the later ".table thead
th:nth-child(n)" / ".table tbody td:nth-child(n)" rules with widths like 96px)
or replace the percent rules with the pixel ones so only one set remains, and if
you must keep both, make intent explicit by renaming classes or increasing
specificity (e.g., add a modifier class to the table) so selectors don't
collide.
- Around line 86-92: The .table selector has conflicting width rules defined in
two places (one set using width: 100%; min-width: 600px and the other using
width: max-content; min-width: 100%); pick the intended sizing strategy and
consolidate into a single .table rule: remove the duplicate/contradicting
declaration and keep only the correct combination (e.g., width: 100% with
min-width: 600px OR width: max-content with min-width: 100%), update any layout
assumptions in related CSS if needed, and ensure only the chosen properties
remain so the cascade is not relied upon to resolve contradictions.
- Around line 315-355: There are overlapping min-width and max-width media
queries around 768px causing duplicate/conflicting rules (see selectors like
.sessionManagementCardContainer, .selectGroup, .sessionSelect, .tableGroup,
.table thead th, .table tbody td, .menuButton, .noData). Pick a consistent
strategy (mobile-first using only min-width or desktop-first using only
max-width), consolidate duplicated rules across the `@media` (min-width: 768px)
and `@media` (max-width: 768px) blocks into a single breakpoint block, and
remove/merge conflicting declarations so the final CSS for each selector appears
only once per breakpoint; if you must keep both styles, shift one breakpoint off
768px (e.g., use max-width: 767px or min-width: 769px) to eliminate the 768px
overlap.

In `@frontend/src/components/attendancemanage/SessionSettingCard.module.css`:
- Around line 97-107: The current .compactTextInput and .compactMinuteInput
rules rely on multiple !important flags which make future overrides fragile;
remove the !important declarations and instead increase selector specificity
(for example by scoping under the parent component class or combining selectors
like .sessionSettingCard .compactTextInput / .sessionSettingCard
.compactMinuteInput) or adjust the CSS module export so the styles win without
!important, keeping the clamp(...) values intact and preserving
width/min-width/max-width behavior.

In `@frontend/src/components/Board/Modal.module.css`:
- Line 11: Replace the hardcoded z-index value in Modal.module.css (the CSS rule
containing "z-index: 3000;") with a shared CSS custom property to avoid magic
numbers; add a global variable (e.g. --z-modal-overlay) in your root/global
stylesheet and update the Modal.module.css rule to use that variable instead of
3000 so all components reference the same token.

In `@frontend/src/components/login/LoginForm.jsx`:
- Around line 102-109: The password toggle button in LoginForm.jsx should expose
its pressed state via aria-pressed; update the button that uses setShowPassword
and showPassword (className styles.passwordToggleButton) to include
aria-pressed={showPassword} so the attribute reflects the boolean state,
ensuring it stays a proper toggle button for assistive tech.

In `@frontend/src/components/LoginAndSignUpForm.module.css`:
- Around line 87-106: The .passwordToggleButton styles only define hover state;
add explicit keyboard focus styles so keyboard users can see focus—implement
.passwordToggleButton:focus and/or .passwordToggleButton:focus-visible rules
(matching or complementing the hover color change) that provide a clear,
high-contrast visible indicator (e.g., outline or box-shadow) while preserving
the existing layout and sizing for the passwordToggleButton element.

In `@frontend/src/components/signup/SignUpForm.jsx`:
- Around line 296-308: The password match message block (controlled by
hasConfirmPasswordInput and isPasswordMatch) is a dynamic live region for screen
readers; add an aria-live attribute (e.g., aria-live="polite") to the outer <p>
and consider aria-atomic="true" so updates are fully announced, keeping the
existing classNames (styles.passwordMatchMessage,
styles.passwordMatchMessageSuccess, styles.passwordMatchMessageError) and
message logic intact; ensure you update the JSX for the <p> rendered by the
conditional that references hasConfirmPasswordInput and isPasswordMatch.
- Around line 248-265: Extract the repeated password input + toggle block into a
reusable component (e.g., PasswordFieldWithToggle) and replace both occurrences
in SignUpForm.jsx with that component; the new component should accept props for
value, onChange (use handlePasswordChange), id, placeholder, autoComplete and
any className (use styles.inputWithToggle and styles.passwordToggleButton) and
internally manage its own showPassword state and render Eye / EyeOff icons
accordingly, preserving aria-label behavior and button type="button".

In `@frontend/src/pages/AttendanceManage.module.css`:
- Around line 52-61: The `.roster > *` CSS rule is not applying because the
rendered JSX doesn’t use the `.roster` class; check where
AttendanceManagementCard is rendered and either (a) add the roster module class
to the container element that wraps AttendanceManagementCard (so `.roster > * {
width:100% }` applies), or (b) change the selector in
AttendanceManage.module.css to target the actual class name used in the JSX (the
wrapper/component class around AttendanceManagementCard) so child elements get
width:100%; update the JSX/class names accordingly and verify the layout.

In `@frontend/src/pages/PostDetail.module.css`:
- Around line 860-869: The CSS uses a global :root custom property
(--width-content) inside the mobile media query which can conflict with other
CSS Modules later; change the rule so the variable is scoped or inlined—either
move the value into .postDetail (e.g., set .postDetail {
--postDetail-width-content: 100%; } and use that locally) or rename the variable
to a more specific name (e.g., --postDetail-width-content) and update all
references, and ensure the media query remains `@media` (max-width: 767px) for
.postDetail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5d08c1e0-2042-4c9a-8589-a4e64fe6ab4c

📥 Commits

Reviewing files that changed from the base of the PR and between 9d755ea and 0abe18d.

📒 Files selected for processing (27)
  • frontend/src/components/AdminMemberApproval/AdminMemberApproval.module.css
  • frontend/src/components/AdminMemberManage/AdminMemberManage.module.css
  • frontend/src/components/Board/CreateSubBoardModal.module.css
  • frontend/src/components/Board/Modal.module.css
  • frontend/src/components/Board/PostDetail/CommentSection.jsx
  • frontend/src/components/LoginAndSignUpForm.module.css
  • frontend/src/components/Sidebar.jsx
  • frontend/src/components/VerificationModal.module.css
  • frontend/src/components/attendance/SessionManage.jsx
  • frontend/src/components/attendance/SessionManage.module.css
  • frontend/src/components/attendancemanage/AttendanceManagementCard.jsx
  • frontend/src/components/attendancemanage/AttendanceManagementCard.module.css
  • frontend/src/components/attendancemanage/RoundDayPicker.jsx
  • frontend/src/components/attendancemanage/SessionManagementCard.jsx
  • frontend/src/components/attendancemanage/SessionManagementCard.module.css
  • frontend/src/components/attendancemanage/SessionSettingCard.jsx
  • frontend/src/components/attendancemanage/SessionSettingCard.module.css
  • frontend/src/components/backtest/BacktestTemplateSaveModal.module.css
  • frontend/src/components/login/LoginForm.jsx
  • frontend/src/components/mypage/ActivityModal.module.css
  • frontend/src/components/mypage/EditProfileModal.module.css
  • frontend/src/components/quantbot/ReportModal.css
  • frontend/src/components/signup/SignUpForm.jsx
  • frontend/src/pages/AttendanceManage.module.css
  • frontend/src/pages/Board.jsx
  • frontend/src/pages/PostDetail.jsx
  • frontend/src/pages/PostDetail.module.css

Comment thread frontend/src/components/attendancemanage/RoundDayPicker.jsx
Comment thread frontend/src/components/mypage/EditProfileModal.module.css
Comment thread frontend/src/components/VerificationModal.module.css
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/attendancemanage/AttendanceManagementCard.jsx`:
- Around line 157-175: The header "select all" and related selection logic
currently uses attendanceData.userRows (all users) while the table renders
paginatedUserRows; update toggleAllUsers, the header checkbox
checked/indeterminate calculations, and any selection-count logic to operate on
paginatedUserRows (derived from sortedUserRows using currentPage and
USERS_PER_PAGE) instead of attendanceData.userRows so the selection scope
matches the visible page; also adjust any other places referencing
attendanceData.userRows for selection (see occurrences near the other mentions)
to use paginatedUserRows or subsets thereof.
- Around line 45-64: getRoleDisplayLabel currently checks for
OWNER/MANAGE/PARTICIPANT tokens but backend sends roles as Korean strings
("관리자"/"일반") and there is a separate getRoleSortPriority mapping for "세션 생성자";
update getRoleDisplayLabel (and the similar logic around lines 72-84) to
normalize incoming role value and map the exact backend strings ("세션 생성자",
"관리자", "일반") to the correct display labels ("소유자"/"관리자"/"팀원") so display and
getRoleSortPriority use the same canonical set of role identifiers; ensure
trimming/upper/lower normalization is consistent before comparisons and fall
back to '팀원' when unknown.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7a93edc6-cd71-4d3f-9a7d-3a04fe1e26bd

📥 Commits

Reviewing files that changed from the base of the PR and between 0abe18d and c76aa11.

📒 Files selected for processing (4)
  • frontend/src/components/VerificationModal.module.css
  • frontend/src/components/attendancemanage/AddUsersModal.jsx
  • frontend/src/components/attendancemanage/AttendanceManagementCard.jsx
  • frontend/src/components/attendancemanage/AttendanceManagementCard.module.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/VerificationModal.module.css

Copy link
Copy Markdown
Contributor

@discipline24 discipline24 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다~

@discipline24 discipline24 merged commit dd392d2 into main Mar 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 [기능개선][전체] 전반적 FE UI/UX 개선

3 participants