diff --git a/lib/function/teacher_attendance_controller.dart b/lib/function/teacher_attendance_controller.dart index 6250aa2..b778604 100644 --- a/lib/function/teacher_attendance_controller.dart +++ b/lib/function/teacher_attendance_controller.dart @@ -26,6 +26,7 @@ class TeacherAttendanceController extends ChangeNotifier { bool _isLoading = true; bool _isRefreshing = false; // 새로고침 버튼 클릭 시 잠깐 도는 표시용 String _filterType = "ALL"; // "ALL", "CHECKED_IN", "ABSENT" + String _gradeFilter = "ALL"; // "ALL", "1", "2", "3" bool _disposed = false; // ---------------------------------------------------------------- @@ -34,6 +35,7 @@ class TeacherAttendanceController extends ChangeNotifier { bool get isLoading => _isLoading; bool get isRefreshing => _isRefreshing; String get filterType => _filterType; + String get gradeFilter => _gradeFilter; String? get attendanceTime => _attendanceTime; String? get globalPermissionUntil => _globalPermissionUntil; @@ -214,6 +216,12 @@ class TeacherAttendanceController extends ChangeNotifier { _safeNotify(); } + /// 🏫 학년 필터. "ALL"이면 전체, "1"/"2"/"3"이면 그 학년만 보이게 한다. + void setGradeFilter(String grade) { + _gradeFilter = grade; + _safeNotify(); + } + // ---------------------------------------------------------------- // 파생 로직 (출석 상태 계산) // ---------------------------------------------------------------- @@ -301,13 +309,17 @@ class TeacherAttendanceController extends ChangeNotifier { } List> get filteredStudents { - final all = combinedStudentStatus; + var result = combinedStudentStatus; if (_filterType == "CHECKED_IN") { - return all.where((s) => s['isAttendanceComplete'] == true).toList(); + result = result.where((s) => s['isAttendanceComplete'] == true).toList(); } else if (_filterType == "ABSENT") { - return all.where((s) => s['isAttendanceComplete'] == false).toList(); + result = result.where((s) => s['isAttendanceComplete'] == false).toList(); } - return all; + if (_gradeFilter != "ALL") { + final int? grade = int.tryParse(_gradeFilter); + result = result.where((s) => s['grade'] == grade).toList(); + } + return result; } /// 🏫 [학년별 카테고리] filteredStudents를 학년(1~3학년) 순서로 묶는다. diff --git a/lib/ui/teacher_attendance_page.dart b/lib/ui/teacher_attendance_page.dart index 125eb10..d15ce44 100644 --- a/lib/ui/teacher_attendance_page.dart +++ b/lib/ui/teacher_attendance_page.dart @@ -706,24 +706,56 @@ class _TeacherAttendancePageState extends State { Widget _buildFilterChips() { return Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - child: Row( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - FilterChip( - label: const Text("전체"), - selected: _controller.filterType == "ALL", - onSelected: (_) => _controller.setFilter("ALL"), + Wrap( + spacing: 8, + runSpacing: 8, + children: [ + FilterChip( + label: const Text("전체"), + selected: _controller.filterType == "ALL", + onSelected: (_) => _controller.setFilter("ALL"), + ), + FilterChip( + label: const Text("🟢 출석자"), + selected: _controller.filterType == "CHECKED_IN", + onSelected: (_) => _controller.setFilter("CHECKED_IN"), + ), + FilterChip( + label: const Text("🔴 미출석자"), + selected: _controller.filterType == "ABSENT", + onSelected: (_) => _controller.setFilter("ABSENT"), + ), + ], ), - const SizedBox(width: 8), - FilterChip( - label: const Text("🟢 출석자"), - selected: _controller.filterType == "CHECKED_IN", - onSelected: (_) => _controller.setFilter("CHECKED_IN"), - ), - const SizedBox(width: 8), - FilterChip( - label: const Text("🔴 미출석자"), - selected: _controller.filterType == "ABSENT", - onSelected: (_) => _controller.setFilter("ABSENT"), + const SizedBox(height: 8), + Wrap( + spacing: 8, + runSpacing: 8, + children: [ + ChoiceChip( + label: const Text("학년 전체"), + selected: _controller.gradeFilter == "ALL", + onSelected: (_) => _controller.setGradeFilter("ALL"), + ), + ChoiceChip( + label: const Text("1학년"), + selected: _controller.gradeFilter == "1", + onSelected: (_) => _controller.setGradeFilter("1"), + ), + ChoiceChip( + label: const Text("2학년"), + selected: _controller.gradeFilter == "2", + onSelected: (_) => _controller.setGradeFilter("2"), + ), + ChoiceChip( + label: const Text("3학년"), + selected: _controller.gradeFilter == "3", + onSelected: (_) => _controller.setGradeFilter("3"), + ), + ], ), ], ),