# Campus Attendance Frontend Integration

## Purpose

Campus attendance config and daily aggregate summaries follow the frontend three-layer architecture.

```text
View -> Business Logic -> API/Data Access -> Backend
```

## Files

View layer:

- `frontend/src/components/frameworks/CampusAttendance.tsx`
- `frontend/src/components/campus-attendance/AttendanceSummaryCard.tsx`
- `frontend/src/components/campus-attendance/CampusAttendanceEntryForm.tsx`
- `frontend/src/components/campus-attendance/CampusAttendanceHeader.tsx`
- `frontend/src/components/campus-attendance/CampusAttendanceLinkConfig.tsx`
- `frontend/src/components/campus-attendance/CampusAttendanceStatus.tsx`
- `frontend/src/components/campus-attendance/IndividualCampusAttendanceView.tsx`
- `frontend/src/components/campus-attendance/SuperintendentAttendanceView.tsx`
- `frontend/src/components/campus-attendance/styles.ts`
- `frontend/src/components/campus-attendance/types.ts`

Business logic layer:

- `frontend/src/business/campus-attendance/hooks.ts`
- `frontend/src/business/campus-attendance/mappers.ts`
- `frontend/src/business/campus-attendance/printReport.ts`
- `frontend/src/business/campus-attendance/selectors.ts`
- `frontend/src/business/campus-attendance/types.ts`

API/data access layer:

- `frontend/src/shared/api/campusAttendance.ts`
- `frontend/src/shared/api/staffAttendance.ts` (staff summary and office/staff attendance entry)
- `frontend/src/shared/types/campusAttendance.ts`
- `frontend/src/shared/constants/campusAttendance.ts`

## Behavior

- Attendance links load from `GET /api/campus_attendance/configs`.
- Attendance links save through `PUT /api/campus_attendance/configs/:campusKey`.
- Daily campus summaries load from `GET /api/campus_attendance/summaries`.
- Daily campus summaries save through `PUT /api/campus_attendance/summaries/:campusKey/:date`.
- The page derives its mode from the effective scope, not from the signed-in role label:
  - campus/class effective scope shows campus-only attendance.
  - school effective scope aggregates all scoped campus summaries and school staff attendance.
  - organization effective scope aggregates all scoped school/campus summaries plus organization staff attendance.
- Users with `FILL_ATTENDANCE` can enter daily student attendance from organization, school,
  campus, or class effective scope. Campus/class scope can render Present/Late/Absent controls
  per student when a roster is available and derives the aggregate campus summary from those rows.
  Late students count as present and increment the tardy count. When no roster is available, the
  form falls back to manual aggregate totals.
- Class effective scope resolves the class's parent campus for the campus attendance summary, but
  loads the student roster with `users?classId=...` so the classroom form shows only students in
  that classroom.
- Organization/school screens render a student attendance rollup table for every scoped child
  campus. Each row is prefilled from the campus summary for the selected date; campuses without
  child data show empty inputs. Saving writes valid edited rows back to
  `campus_attendance_summaries` per campus. Organization and school totals are computed from those
  campus rows plus staff attendance reports.
- Aggregate cards follow the tenant hierarchy: organization scope shows school cards, and school
  scope shows campus cards. Clicking a child card opens
  `/attendance/details/:level/:tenantId`. The details page shows separate tables for that child
  scope's student attendance summaries and staff attendance records.
- Organization and school screens also expose office staff attendance entry as a batch table.
  Organization office attendance targets organization-owned users without school/campus
  assignment. School office attendance targets school-owned users without campus assignment.
  Each staff row has Present/Late/Absent controls, and saving writes one record per user through
  `PUT /api/staff_attendance/records/:userId/:date`. These records feed the staff attendance
  summary.
- Campus screens expose the same staff attendance table for campus-bound and class-scoped staff
  inside the campus.
- Staff summary loads from `GET /api/staff_attendance/summary?startDate=today&endDate=today` only when the user has `READ_STAFF_ATTENDANCE_REPORTS`.
- Aggregate views render only campus cards represented by scoped attendance/config rows, because the campus catalog endpoint is not the source of scoped reporting data.
- The backend calculates the attendance percentage.
- `CampusAttendance.tsx` is a thin composition wrapper.
- CampusAttendance uses typed business hooks/selectors for access, form state, today, weekly, campus, overall summary calculations, and print report generation.
- Print report generation escapes dynamic strings before writing report HTML.
- Blocked print popups return an explicit print result and show a visible attendance status error.

## Verification

- `frontend/src/business/campus-attendance/selectors.test.ts` covers attendance calculations, scope titles, and combined student/staff summary selectors.
- `frontend/src/business/campus-attendance/printReport.test.ts` covers printable report generation.
- `frontend/src/business/campus-attendance/printReport.test.ts` covers blocked-popup handling for attendance report printing.
- `frontend/src/business/campus-attendance/mappers.test.ts` covers API DTO mapping.
