20260403 fe add adminpage absent list#351
Conversation
Walkthrough뷰포트 높이 조정용 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
frontend/src/components/attendancemanage/AbsenceSummaryModal.module.css (2)
6-6:vh대신--vhfallback 패턴으로 맞추는 것을 권장합니다.이 PR에서 다른 레이아웃들이
calc(var(--vh, 1vh) * 100)으로 통일되고 있어, 여기만100vh/85vh를 유지하면 모바일(특히 주소창 확장/축소)에서 높이 계산이 어긋날 수 있습니다.🔧 제안 수정안
.modalOverlay { @@ - height: 100vh; + height: calc(var(--vh, 1vh) * 100); @@ .modalContent { @@ - max-height: 85vh; + max-height: calc(var(--vh, 1vh) * 85);Also applies to: 20-20
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/attendancemanage/AbsenceSummaryModal.module.css` at line 6, Replace the literal viewport height usage in AbsenceSummaryModal.module.css (the rule that currently has "height: 100vh;") with the --vh fallback pattern used elsewhere; e.g. set height to calc(var(--vh, 1vh) * 100) (or calc(var(--vh, 1vh) * 85) if the intended height was 85vh) so the component follows the same mobile address-bar-safe sizing convention.
24-24: 코드베이스의 keyframe 명명 규칙을 일관되게 적용해주세요.현재 파일의
modalAppear는 camelCase를 사용하고 있으며, 코드베이스의 다른 파일들(fadeIn,slideIn등)도 동일한 패턴을 따르고 있습니다. Stylelint 기본 설정은 kebab-case(modal-appear)를 권장하므로, 일관된 명명 규칙을 적용하거나 Stylelint 설정을 명시적으로 조정하는 것이 좋습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/attendancemanage/AbsenceSummaryModal.module.css` at line 24, Rename the keyframe name from modalAppear to kebab-case modal-appear and update all references accordingly: change any animation: modalAppear to animation: modal-appear and rename the corresponding `@keyframes` modalAppear { ... } block to `@keyframes` modal-appear { ... }; ensure any other usages (e.g., animation-name, shorthand declarations) in the project that reference modalAppear are updated to modal-appear to keep naming consistent with stylelint conventions.
🤖 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/AbsenceSummaryModal.jsx`:
- Around line 22-27: The modal markup in AbsenceSummaryModal.jsx lacks semantic
accessibility attributes and the close button is missing an explicit type;
update the modal container div (e.g., the element currently rendered as <div
className={styles.modalContent}>) to include role="dialog", aria-modal="true",
and aria-labelledby pointing to the heading by giving the <h2> an id (e.g.,
id="absence-summary-title"), and ensure the overlay and content keep
e.stopPropagation() behavior; also change the close button element (the one with
className={styles.closeButton}) to include type="button" to prevent accidental
form submits and add an accessible label (aria-label="Close" or use the heading
id) as needed.
In `@frontend/src/components/attendancemanage/AttendanceManagementCard.jsx`:
- Around line 172-175: The current selection uses UTC-based todayStr and an
unsorted array slice, causing off-by-one picks; instead compute the local date
string using the same locale format used to store roundDate (e.g., new
Date().toLocaleDateString('sv-SE')) and use that as todayStr when matching; also
ensure attendanceData.rounds is deterministically ordered before picking
fallback by sorting attendanceData.rounds by their roundDate (lexicographic sort
is fine for 'YYYY-MM-DD' strings) and then select targetRound by finding a round
with roundDate === todayStr or falling back to the last element of the sorted
array; update the code around todayStr, targetRound and any direct
attendanceData.rounds indexing accordingly.
In
`@frontend/src/components/attendancemanage/AttendanceManagementCard.module.css`:
- Around line 628-648: Add visible keyboard focus styles for the
.absenceSummaryButton so keyboard users can see focus: implement :focus and
preferably :focus-visible rules that mirror hover/active states while adding a
high-contrast outline or subtle box-shadow (e.g., 2px solid or 3px ring) and
ensure focus styles respect existing border-radius and color contrast; update
the CSS selectors .absenceSummaryButton:focus and
.absenceSummaryButton:focus-visible and ensure the focus state does not rely
solely on :hover or :active.
In `@frontend/src/hooks/useAuthGuard.js`:
- Around line 18-24: The 401 check in the useAuthGuard hook is brittle because
it inspects error.status directly; update the conditional to check
error.response?.status (using optional chaining) so token-refresh axios errors
are detected consistently (match AdminRoute pattern). Locate the block that does
the 401 handling inside useAuthGuard (the branch that calls toast.error,
computes returnUrl and calls nav(`/login?returnUrl=${returnUrl}`)) and replace
the error.status check with error.response?.status (or a combined check if
needed) to ensure reliable detection of HTTP 401 responses from axios errors.
---
Nitpick comments:
In `@frontend/src/components/attendancemanage/AbsenceSummaryModal.module.css`:
- Line 6: Replace the literal viewport height usage in
AbsenceSummaryModal.module.css (the rule that currently has "height: 100vh;")
with the --vh fallback pattern used elsewhere; e.g. set height to calc(var(--vh,
1vh) * 100) (or calc(var(--vh, 1vh) * 85) if the intended height was 85vh) so
the component follows the same mobile address-bar-safe sizing convention.
- Line 24: Rename the keyframe name from modalAppear to kebab-case modal-appear
and update all references accordingly: change any animation: modalAppear to
animation: modal-appear and rename the corresponding `@keyframes` modalAppear {
... } block to `@keyframes` modal-appear { ... }; ensure any other usages (e.g.,
animation-name, shorthand declarations) in the project that reference
modalAppear are updated to modal-appear to keep naming consistent with stylelint
conventions.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e226f687-2ba1-4434-a537-da1afbe746b4
📒 Files selected for processing (20)
frontend/src/App.jsxfrontend/src/components/AdminRoute.jsxfrontend/src/components/Layout.jsxfrontend/src/components/Sidebar.jsxfrontend/src/components/Sidebar.module.cssfrontend/src/components/attendancemanage/AbsenceSummaryModal.jsxfrontend/src/components/attendancemanage/AbsenceSummaryModal.module.cssfrontend/src/components/attendancemanage/AttendanceManagementCard.jsxfrontend/src/components/attendancemanage/AttendanceManagementCard.module.cssfrontend/src/components/login/LoginForm.jsxfrontend/src/components/protectedRoute.jsxfrontend/src/components/signup/SignUpForm.jsxfrontend/src/hooks/useAuthGuard.jsfrontend/src/index.cssfrontend/src/pages/AdminDashboard.module.cssfrontend/src/pages/AdminHome.module.cssfrontend/src/pages/Board.module.cssfrontend/src/pages/Home.module.cssfrontend/src/pages/LoginAndSignUp.module.cssfrontend/src/pages/external/External.module.css
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/components/attendancemanage/AttendanceManagementCard.jsx (1)
618-624: 조건부 렌더링과isOpenprop이 중복됩니다.
isAbsenceModalOpen &&로 조건부 렌더링하면서 동시에isOpen={isAbsenceModalOpen}prop을 전달하고 있습니다. 현재 패턴에서는 모달이 렌더링될 때isOpen이 항상true입니다.모달 컴포넌트가 닫힘 애니메이션을 사용한다면, 조건부 렌더링 대신 항상 렌더링하고
isOpen으로 visibility를 제어하는 것이 좋습니다. 그렇지 않다면isOpenprop을 제거하고 조건부 렌더링만 사용하여 단순화할 수 있습니다.♻️ 옵션 1: 조건부 렌더링 제거 (애니메이션 필요 시)
- {isAbsenceModalOpen && ( - <AbsenceSummaryModal - isOpen={isAbsenceModalOpen} - onClose={() => setIsAbsenceModalOpen(false)} - userRows={attendanceData.userRows} - /> - )} + <AbsenceSummaryModal + isOpen={isAbsenceModalOpen} + onClose={() => setIsAbsenceModalOpen(false)} + userRows={attendanceData.userRows} + />♻️ 옵션 2: isOpen prop 제거 (애니메이션 불필요 시)
{isAbsenceModalOpen && ( <AbsenceSummaryModal - isOpen={isAbsenceModalOpen} onClose={() => setIsAbsenceModalOpen(false)} userRows={attendanceData.userRows} /> )}🤖 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 618 - 624, The code redundantly both conditionally renders AbsenceSummaryModal with "isAbsenceModalOpen &&" and also passes isOpen={isAbsenceModalOpen}; choose one approach: either always render <AbsenceSummaryModal ... userRows={attendanceData.userRows} isOpen={isAbsenceModalOpen} onClose={() => setIsAbsenceModalOpen(false)} /> (remove the leading "isAbsenceModalOpen &&" so the modal can run close animations) or remove the isOpen prop and keep conditional rendering (keep "isAbsenceModalOpen && <AbsenceSummaryModal userRows={attendanceData.userRows} onClose={() => setIsAbsenceModalOpen(false)} />") and update the component accordingly; make the change around the AbsenceSummaryModal usage and ensure setIsAbsenceModalOpen and isAbsenceModalOpen remain the single source of truth for visibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@frontend/src/components/attendancemanage/AttendanceManagementCard.jsx`:
- Around line 618-624: The code redundantly both conditionally renders
AbsenceSummaryModal with "isAbsenceModalOpen &&" and also passes
isOpen={isAbsenceModalOpen}; choose one approach: either always render
<AbsenceSummaryModal ... userRows={attendanceData.userRows}
isOpen={isAbsenceModalOpen} onClose={() => setIsAbsenceModalOpen(false)} />
(remove the leading "isAbsenceModalOpen &&" so the modal can run close
animations) or remove the isOpen prop and keep conditional rendering (keep
"isAbsenceModalOpen && <AbsenceSummaryModal userRows={attendanceData.userRows}
onClose={() => setIsAbsenceModalOpen(false)} />") and update the component
accordingly; make the change around the AbsenceSummaryModal usage and ensure
setIsAbsenceModalOpen and isAbsenceModalOpen remain the single source of truth
for visibility.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5e01f4d7-03f2-4495-86c0-6f09cf40339f
📒 Files selected for processing (4)
frontend/src/components/AdminRoute.jsxfrontend/src/components/attendancemanage/AbsenceSummaryModal.jsxfrontend/src/components/attendancemanage/AttendanceManagementCard.jsxfrontend/src/hooks/useAuthGuard.js
🚧 Files skipped from review as they are similar to previous changes (3)
- frontend/src/hooks/useAuthGuard.js
- frontend/src/components/AdminRoute.jsx
- frontend/src/components/attendancemanage/AbsenceSummaryModal.jsx
특정 세션 내 모든 유저의 결석(ABSENT) 및 지각(LATE) 횟수를 한눈에 파악할 수 있는 요약 모달을 구현했습니다.
주요 로직: 결석 또는 지각 기록이 최소 1회 이상 있는 유저만 필터링하여 표시합니다.
결석 횟수 내림차순, 지각 횟수 내림차순으로 자동 정렬하여 효율적인 관리가 가능합니다.
AttendanceManagementCard 헤더에 '결석 인원 모아보기' 버튼을 통해 접근할 수 있습니다.
관리자가 주목해야 할 인원을 상단에 배치하도록 AttendanceManagementCard 내 userRows 정렬 로직을 강화했습니다.
정렬 우선순위: 출석 상태: 오늘(또는 마지막) 회차의 상태가 결석 > 지각 > 기타 순으로 상단에 노출됩니다.
역할(Role): 동일 상태 내에서는 소유자 > 관리자 > 팀원 순으로 정렬됩니다.
이름: 모든 조건이 같을 경우 가나다순으로 정렬됩니다.
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선사항
버그 수정