import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; /// Página para visualizar os alunos de uma turma específica class ClassStudentsPage extends StatelessWidget { final String classId; final String className; const ClassStudentsPage({ super.key, required this.classId, required this.className, }); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF8F9FA), appBar: AppBar( backgroundColor: const Color(0xFF82C9BD), elevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.white), onPressed: () => Navigator.of(context).pop(), ), title: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( className, style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), const Text( 'Alunos Matriculados', style: TextStyle( color: Colors.white70, fontSize: 13, fontWeight: FontWeight.w300, ), ), ], ), ), body: StreamBuilder( stream: FirebaseFirestore.instance .collection('enrollments') .where('classId', isEqualTo: classId) .orderBy('joinedAt', descending: true) .snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator( color: Color(0xFF82C9BD), ), ); } if (snapshot.hasError) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.error_outline, size: 48, color: Colors.grey[400], ), const SizedBox(height: 16), Text( 'Erro ao carregar alunos', style: TextStyle( color: Colors.grey[600], fontSize: 16, ), ), ], ), ); } final enrollments = snapshot.data?.docs ?? []; if (enrollments.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.people_outline, size: 64, color: Colors.grey[300], ), const SizedBox(height: 24), Text( 'Nenhum aluno entrou nesta turma ainda.', style: TextStyle( color: Colors.grey[600], fontSize: 16, ), textAlign: TextAlign.center, ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Text( 'Partilha o código da turma para os alunos se juntarem.', style: TextStyle( color: Colors.grey[500], fontSize: 13, ), textAlign: TextAlign.center, ), ), ], ), ); } return ListView.builder( padding: const EdgeInsets.all(16.0), itemCount: enrollments.length, itemBuilder: (context, index) { final enrollment = enrollments[index].data() as Map; final studentName = enrollment['studentName'] as String? ?? 'Aluno sem nome'; final joinedAt = enrollment['joinedAt'] as Timestamp?; return Container( margin: const EdgeInsets.only(bottom: 12.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16.0), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: ListTile( contentPadding: const EdgeInsets.all(16.0), leading: Container( width: 48, height: 48, decoration: BoxDecoration( color: const Color(0xFF82C9BD).withOpacity(0.1), borderRadius: BorderRadius.circular(12.0), ), child: const Icon( Icons.person, color: Color(0xFF82C9BD), size: 24, ), ), title: Text( studentName, style: const TextStyle( color: Color(0xFF2D3748), fontSize: 16, fontWeight: FontWeight.w600, ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), Text( joinedAt != null ? 'Entrou em ${_formatDate(joinedAt.toDate())}' : 'Data desconhecida', style: TextStyle( color: Colors.grey[600], fontSize: 13, ), ), ], ), ), ); }, ); }, ), ); } String _formatDate(DateTime date) { return DateFormat('dd/MM/yyyy').format(date); } }