선생님 대시보드에 학년 필터 칩 추가
출석자/미출석자 필터처럼 학년 전체/1학년/2학년/3학년 칩을 추가해서 선택한 학년만 볼 수 있게 함. 상태 필터와 조합해서 같이 적용됨. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ class TeacherAttendanceController extends ChangeNotifier {
|
|||||||
bool _isLoading = true;
|
bool _isLoading = true;
|
||||||
bool _isRefreshing = false; // 새로고침 버튼 클릭 시 잠깐 도는 표시용
|
bool _isRefreshing = false; // 새로고침 버튼 클릭 시 잠깐 도는 표시용
|
||||||
String _filterType = "ALL"; // "ALL", "CHECKED_IN", "ABSENT"
|
String _filterType = "ALL"; // "ALL", "CHECKED_IN", "ABSENT"
|
||||||
|
String _gradeFilter = "ALL"; // "ALL", "1", "2", "3"
|
||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
@@ -34,6 +35,7 @@ class TeacherAttendanceController extends ChangeNotifier {
|
|||||||
bool get isLoading => _isLoading;
|
bool get isLoading => _isLoading;
|
||||||
bool get isRefreshing => _isRefreshing;
|
bool get isRefreshing => _isRefreshing;
|
||||||
String get filterType => _filterType;
|
String get filterType => _filterType;
|
||||||
|
String get gradeFilter => _gradeFilter;
|
||||||
String? get attendanceTime => _attendanceTime;
|
String? get attendanceTime => _attendanceTime;
|
||||||
String? get globalPermissionUntil => _globalPermissionUntil;
|
String? get globalPermissionUntil => _globalPermissionUntil;
|
||||||
|
|
||||||
@@ -214,6 +216,12 @@ class TeacherAttendanceController extends ChangeNotifier {
|
|||||||
_safeNotify();
|
_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 {
|
List<Map<String, dynamic>> get filteredStudents {
|
||||||
final all = combinedStudentStatus;
|
var result = combinedStudentStatus;
|
||||||
if (_filterType == "CHECKED_IN") {
|
if (_filterType == "CHECKED_IN") {
|
||||||
return all.where((s) => s['isAttendanceComplete'] == true).toList();
|
result = result.where((s) => s['isAttendanceComplete'] == true).toList();
|
||||||
} else if (_filterType == "ABSENT") {
|
} 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학년) 순서로 묶는다.
|
/// 🏫 [학년별 카테고리] filteredStudents를 학년(1~3학년) 순서로 묶는다.
|
||||||
|
|||||||
@@ -706,20 +706,23 @@ class _TeacherAttendancePageState extends State<TeacherAttendancePage> {
|
|||||||
Widget _buildFilterChips() {
|
Widget _buildFilterChips() {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
child: Row(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Wrap(
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 8,
|
||||||
children: [
|
children: [
|
||||||
FilterChip(
|
FilterChip(
|
||||||
label: const Text("전체"),
|
label: const Text("전체"),
|
||||||
selected: _controller.filterType == "ALL",
|
selected: _controller.filterType == "ALL",
|
||||||
onSelected: (_) => _controller.setFilter("ALL"),
|
onSelected: (_) => _controller.setFilter("ALL"),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
|
||||||
FilterChip(
|
FilterChip(
|
||||||
label: const Text("🟢 출석자"),
|
label: const Text("🟢 출석자"),
|
||||||
selected: _controller.filterType == "CHECKED_IN",
|
selected: _controller.filterType == "CHECKED_IN",
|
||||||
onSelected: (_) => _controller.setFilter("CHECKED_IN"),
|
onSelected: (_) => _controller.setFilter("CHECKED_IN"),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
|
||||||
FilterChip(
|
FilterChip(
|
||||||
label: const Text("🔴 미출석자"),
|
label: const Text("🔴 미출석자"),
|
||||||
selected: _controller.filterType == "ABSENT",
|
selected: _controller.filterType == "ABSENT",
|
||||||
@@ -727,6 +730,35 @@ class _TeacherAttendancePageState extends State<TeacherAttendancePage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
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"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user