// πŸ‘¨β€πŸ« ꡐ사 λŒ€μ‹œλ³΄λ“œ. μ‹€μ‹œκ°„ μΆœμ„ 확인, 학생 계정 관리 ν™”λ©΄μœΌλ‘œ κ°€λŠ” λ©”λ‰΄λ§Œ λ‹΄λ‹Ήν•œλ‹€. import 'package:flutter/material.dart'; import 'login_screen.dart'; import 'teacher_attendance_page.dart'; import 'teacher_student_management_page.dart'; // ========================================== // πŸ‘¨β€πŸ« 4. μ„ μƒλ‹˜ λŒ€μ‹œλ³΄λ“œ (κΈ°μ‘΄ 3초 타이머 μ™„λ²½ μœ μ§€) // ========================================== class TeacherDashboard extends StatefulWidget { final String? teacherId; final String? teacherName; const TeacherDashboard({super.key, this.teacherId, this.teacherName}); @override State createState() => _TeacherDashboardState(); } class _TeacherDashboardState extends State { // 🧼 [μˆ˜μ •] μ‚¬μš©ν•˜μ§€ μ•Šλ˜ _isLoading λ³€μˆ˜λ₯Ό μ‚­μ œν•˜μ—¬ κ²½κ³ λ₯Ό μ™„λ²½νžˆ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€! @override Widget build(BuildContext context) { // λ‹€λ₯Έ ν™”λ©΄μ—μ„œ null이 λ„˜μ–΄μ™”μ„ λ•Œλ₯Ό λŒ€λΉ„ν•œ μ•ˆμ „λ§ 방탄 μ½”λ“œ final String displayName = widget.teacherName ?? "κ°„νŽΈμΈμ¦ 선생"; final String displayId = widget.teacherId ?? "κ°„νŽΈμΈμ¦"; return Scaffold( backgroundColor: Colors.grey[100], appBar: AppBar( title: const Text( 'πŸ‘¨β€πŸ« TEACHER PORTAL', style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1.2), ), centerTitle: true, backgroundColor: Colors.green[700], // ꡐ사 μ „μš© κ·Έλ¦° ν…Œλ§ˆ 컬러 foregroundColor: Colors.white, elevation: 0, actions: [ IconButton( icon: const Icon(Icons.logout_rounded), onPressed: () => Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const LoginScreen()), ), ), ], ), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // πŸ’³ [상단 λ°°λ„ˆ κ°€μ΄λ“œ] StudentDashboard와 100% μΌμΉ˜ν•˜λŠ” ν”„λ‘œν•„ μΉ΄λ“œ λ ˆμ΄μ•„μ›ƒ Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28), decoration: BoxDecoration( color: Colors.green[700], borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(32), bottomRight: Radius.circular(32), ), ), child: Row( children: [ Container( padding: const EdgeInsets.all(4), decoration: const BoxDecoration( color: Colors.white, shape: BoxShape.circle, ), child: CircleAvatar( radius: 30, backgroundColor: Colors.green[50], child: Icon( Icons.admin_panel_settings_rounded, size: 32, color: Colors.green[700], ), ), ), const SizedBox(width: 18), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '$displayName λ‹˜', style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 4), Text( 'ꡐ직원 번호: $displayId | ꡐ사 κΆŒν•œ ν™œμ„±ν™”λ¨', style: TextStyle( color: Colors.white.withValues(alpha: 0.8), fontSize: 14, ), ), ], ), ], ), ), const SizedBox(height: 32), // 🏷️ [μ„Έλ‘œ λ°” 타이틀 인디케이터] ꡬ쑰 μΌμΉ˜ν™” Padding( padding: const EdgeInsets.symmetric(horizontal: 24.0), child: Row( children: [ Container( width: 4, height: 18, decoration: BoxDecoration( color: Colors.green[700], borderRadius: BorderRadius.circular(2), ), ), const SizedBox(width: 10), const Text( '슀마트 κ΅μ‚¬μš© 관리 메뉴', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ], ), ), const SizedBox(height: 16), // πŸ“Š [κ·Έλ¦¬λ“œ λ ˆμ΄μ•„μ›ƒ 메뉴] μ‹œν›„μ˜ μΉ΄λ“œ μ»΄ν¬λ„ŒνŠΈ μŠ€νƒ€μΌ 적용 Padding( padding: const EdgeInsets.symmetric(horizontal: 24.0), child: GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 0.95, children: [ _buildModernCard( icon: Icons.assignment_turned_in_rounded, title: 'μ‹€μ‹œκ°„ μΆœμ„ 확인', subtitle: '학생 제좜 둜그 λͺ¨λ‹ˆν„°λ§', color: Colors.blue, onTap: () => Navigator.push( context, MaterialPageRoute( builder: (context) => const TeacherAttendancePage(), ), ), ), _buildModernCard( icon: Icons.manage_accounts_rounded, title: '학생 계정 관리', subtitle: '계정 μΆ”κ°€ 및 κ°•μ œ 리셋', color: Colors.orange, onTap: () => Navigator.push( context, MaterialPageRoute( builder: (context) => const TeacherStudentManagementPage(), ), ), ), ], ), ), const SizedBox(height: 32), ], ), ), ); } // πŸ’Ž [μ‹œν›„ λŒ€μ‹œλ³΄λ“œ μ „μš© μΉ΄λ“œ μœ„μ ― 이식 μ™„λ£Œ] Widget _buildModernCard({ required IconData icon, required String title, required String subtitle, required Color color, required VoidCallback onTap, bool isActionButton = false, bool isLoading = false, }) { return InkWell( onTap: isLoading ? null : onTap, borderRadius: BorderRadius.circular(24), child: Ink( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.04), blurRadius: 16, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: color.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), ), child: Icon(icon, color: color, size: 28), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( title, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ), if (isLoading) const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) else if (isActionButton) Icon( Icons.touch_app_rounded, size: 16, color: color.withValues(alpha: 0.5), ), ], ), const SizedBox(height: 4), Text( subtitle, style: TextStyle( fontSize: 12, color: Colors.grey[500], height: 1.2, ), ), ], ), ], ), ), ); } }