diff --git a/lib/ui/teacher_student_management_page.dart b/lib/ui/teacher_student_management_page.dart index 23ef52a..3dd83ca 100644 --- a/lib/ui/teacher_student_management_page.dart +++ b/lib/ui/teacher_student_management_page.dart @@ -6,6 +6,10 @@ import 'package:flutter/material.dart'; import '../function/excel_file_picker.dart'; import '../function/teacher_student_management_controller.dart'; +// πŸ“ "μ‹€μ‹œκ°„ μΆœμ„ 확인" λͺ©λ‘(teacher_attendance_page.dart)의 타일 규격과 λ™μΌν•˜κ²Œ λ§žμΆ˜λ‹€. +const double kAttendanceTileWidth = 220; +const double kAttendanceTileHeight = 148; + // ----------------------------------------------------------------------------- // πŸ‘₯ [μ„œλΈŒ ν™”λ©΄ 2] 학생 계정 관리 λž€ (μΆ”κ°€ 양식 폼 + κ°•μ œ μ‚­μ œ λ‹€μ΄μ–Όλ‘œκ·Έ μ™„μ „ λ‚΄μž₯) // ----------------------------------------------------------------------------- @@ -545,28 +549,37 @@ class _TeacherStudentManagementPageState final bool needsReset = student['device'] == 'μ΄ˆκΈ°ν™” ν•„μš”'; return Container( - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.circular(14), + borderRadius: BorderRadius.circular(20), boxShadow: [ - BoxShadow(color: Colors.black.withValues(alpha: 0.04), blurRadius: 8), + BoxShadow( + color: Colors.black.withValues(alpha: 0.03), + blurRadius: 12, + offset: const Offset(0, 4), + ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - CircleAvatar( - radius: 20, - backgroundColor: needsReset ? Colors.red[50] : Colors.blue[50], + Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: (needsReset ? Colors.red : Colors.blue).withValues( + alpha: 0.1, + ), + shape: BoxShape.circle, + ), child: Icon( needsReset ? Icons.lock_reset : Icons.person, - size: 20, + size: 18, color: needsReset ? Colors.red : Colors.blue, ), ), - const SizedBox(height: 6), + const SizedBox(height: 8), Text( '$studentName ($studentId)', textAlign: TextAlign.center, @@ -574,13 +587,13 @@ class _TeacherStudentManagementPageState overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15), ), - const SizedBox(height: 2), + const SizedBox(height: 4), Text( needsReset ? 'μ΄ˆκΈ°ν™” λŒ€κΈ°μ€‘' : '정상 등둝', textAlign: TextAlign.center, style: TextStyle( - fontSize: 12, - color: needsReset ? Colors.red : Colors.grey, + fontSize: 11.5, + color: needsReset ? Colors.red[700] : Colors.grey[600], fontWeight: needsReset ? FontWeight.bold : FontWeight.normal, ), ), @@ -597,7 +610,7 @@ class _TeacherStudentManagementPageState labelPadding: const EdgeInsets.symmetric(horizontal: 6), label: Text( grade != null ? '$gradeν•™λ…„' : 'λ―Έλ°°μ •', - style: const TextStyle(fontSize: 12), + style: const TextStyle(fontSize: 11), ), onPressed: () => _showGradeMenu( chipContext, @@ -611,22 +624,22 @@ class _TeacherStudentManagementPageState icon: const Icon( Icons.lock_reset, color: Colors.purple, - size: 20, + size: 18, ), tooltip: 'κΈ°κΈ° 리셋', padding: EdgeInsets.zero, - constraints: const BoxConstraints(minWidth: 30, minHeight: 30), + constraints: const BoxConstraints(minWidth: 28, minHeight: 28), onPressed: () => _confirmResetDevice(studentId, studentName), ), IconButton( icon: const Icon( Icons.delete_forever_rounded, color: Colors.redAccent, - size: 20, + size: 18, ), tooltip: '계정 영ꡬ μ‚­μ œ', padding: EdgeInsets.zero, - constraints: const BoxConstraints(minWidth: 30, minHeight: 30), + constraints: const BoxConstraints(minWidth: 28, minHeight: 28), onPressed: () => _confirmDeleteStudent(studentId, studentName), ), ], @@ -656,14 +669,10 @@ class _TeacherStudentManagementPageState padding: const EdgeInsets.all(24.0), child: LayoutBuilder( builder: (context, constraints) { - // πŸ–₯️ μ›Ή(넓은 ν™”λ©΄)은 계정 μΆ”κ°€/μ—‘μ…€ 등둝을 μ •μ‚¬κ°ν˜• 2칸으둜 λ‚˜λž€νžˆ, 폰은 기쑴처럼 μ„Έλ‘œλ‘œ μŒ“λŠ”λ‹€. + // πŸ–₯️ μ›Ή(넓은 ν™”λ©΄)은 계정 μΆ”κ°€/μ—‘μ…€ 등둝을 λ‚˜λž€νžˆ, 폰은 기쑴처럼 μ„Έλ‘œλ‘œ μŒ“λŠ”λ‹€. + // πŸ“ 크기/폰트 λΉ„μœ¨μ€ "μ‹€μ‹œκ°„ μΆœμ„ 확인" λͺ©λ‘μ˜ 타일(220x148)κ³Ό λ™μΌν•˜κ²Œ λ§žμΆ˜λ‹€. final bool isWide = constraints.maxWidth >= 800; final double listWidth = constraints.maxWidth; - // πŸ“ 학생 λͺ©λ‘ 타일과 λ™μΌν•œ 크기λ₯Ό 계정 μΆ”κ°€/μ—‘μ…€ 등둝 칸에도 μ‚¬μš©ν•œλ‹€. - final double tileSize = - ((listWidth - (isWide ? 7 : 3) * 10) / (isWide ? 8 : 4)) * - 1.5; - final double formSquareSize = tileSize; final Widget addBoxColumn = Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -671,8 +680,8 @@ class _TeacherStudentManagementPageState _sectionTitle('μ‹ κ·œ 학생 계정 μΆ”κ°€'), const SizedBox(height: 16), SizedBox( - width: isWide ? formSquareSize : double.infinity, - height: isWide ? formSquareSize : null, + width: isWide ? kAttendanceTileWidth : double.infinity, + height: isWide ? kAttendanceTileHeight : null, child: _buildAddAccountBox(), ), ], @@ -684,8 +693,8 @@ class _TeacherStudentManagementPageState _sectionTitle('μ—‘μ…€λ‘œ ν•œλ²ˆμ— μΆ”κ°€ (μ‹ μž…μƒ λ“±)'), const SizedBox(height: 16), SizedBox( - width: isWide ? formSquareSize : double.infinity, - height: isWide ? formSquareSize : 240, + width: isWide ? kAttendanceTileWidth : double.infinity, + height: isWide ? kAttendanceTileHeight : 240, child: _buildExcelBox(), ), ], @@ -762,11 +771,12 @@ class _TeacherStudentManagementPageState shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: - SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: tileSize, - crossAxisSpacing: 10, - mainAxisSpacing: 10, - childAspectRatio: 1, + const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: + kAttendanceTileWidth, + mainAxisExtent: kAttendanceTileHeight, + crossAxisSpacing: 12, + mainAxisSpacing: 12, ), itemCount: _controller.students.length, itemBuilder: (context, index) =>