선생님 대시보드에 학년 필터 칩 추가

출석자/미출석자 필터처럼 학년 전체/1학년/2학년/3학년 칩을 추가해서
선택한 학년만 볼 수 있게 함. 상태 필터와 조합해서 같이 적용됨.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-31 01:07:38 +09:00
co-authored by Claude Sonnet 5
parent 94ba3efff7
commit ccff219874
2 changed files with 64 additions and 20 deletions
@@ -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<Map<String, dynamic>> 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학년) 순서로 묶는다.
+48 -16
View File
@@ -706,24 +706,56 @@ class _TeacherAttendancePageState extends State<TeacherAttendancePage> {
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"),
),
],
),
],
),