Finalização de detalhes e pequenas adições em dashboards de alunos e professores

This commit is contained in:
2026-05-18 22:48:27 +01:00
parent c0ade9ef76
commit 7f12f3eb1f
58 changed files with 1347 additions and 1065 deletions

View File

@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../../../core/services/auth_service.dart';
/// Página para visualizar os alunos de uma disciplina específica
/// Página para visualizar os alunos de uma turma específica
class ClassStudentsPage extends StatefulWidget {
final String classId;
final String className;
@@ -97,7 +97,7 @@ class _ClassStudentsPageState extends State<ClassStudentsPage> {
),
const SizedBox(height: 12),
Text(
'Só podes ver os alunos das tuas próprias disciplinas.',
'Só podes ver os alunos das tuas próprias turmas.',
style: TextStyle(color: cs.onSurfaceVariant, fontSize: 14),
textAlign: TextAlign.center,
),
@@ -183,7 +183,7 @@ class _ClassStudentsPageState extends State<ClassStudentsPage> {
),
const SizedBox(height: 24),
Text(
'Nenhum aluno entrou nesta disciplina ainda.',
'Nenhum aluno entrou nesta turma ainda.',
style: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 16,
@@ -192,7 +192,7 @@ class _ClassStudentsPageState extends State<ClassStudentsPage> {
),
const SizedBox(height: 8),
Text(
'Partilha o código da disciplina para os alunos se juntarem.',
'Partilha o código da turma para os alunos se juntarem.',
style: TextStyle(
color: cs.onSurfaceVariant.withValues(alpha: 0.7),
fontSize: 13,
@@ -215,6 +215,7 @@ class _ClassStudentsPageState extends State<ClassStudentsPage> {
final studentName =
enrollment['studentName'] as String? ?? 'Aluno sem nome';
final joinedAt = enrollment['joinedAt'] as Timestamp?;
final enrollmentId = enrollments[index].id;
return Container(
decoration: BoxDecoration(
@@ -263,6 +264,15 @@ class _ClassStudentsPageState extends State<ClassStudentsPage> {
),
),
),
trailing: IconButton(
icon: Icon(Icons.delete_outline, color: cs.error),
onPressed: () => _showRemoveStudentDialog(
context,
enrollmentId,
studentName,
),
tooltip: 'Remover aluno',
),
),
);
},
@@ -275,4 +285,82 @@ class _ClassStudentsPageState extends State<ClassStudentsPage> {
String _formatDate(DateTime date) {
return DateFormat('dd/MM/yyyy').format(date);
}
Future<void> _showRemoveStudentDialog(
BuildContext context,
String enrollmentId,
String studentName,
) async {
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Remover Aluno'),
content: Text(
'Tem a certeza que deseja remover $studentName desta turma?',
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: const Text('Cancelar'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
style: TextButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.error,
),
child: const Text('Remover'),
),
],
),
);
if (confirmed == true && context.mounted) {
try {
await FirebaseFirestore.instance
.collection('enrollments')
.doc(enrollmentId)
.delete();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(Icons.check_circle, color: Colors.white),
const SizedBox(width: 12),
const Text('Aluno removido com sucesso'),
],
),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
duration: const Duration(seconds: 3),
),
);
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(Icons.error_outline, color: Colors.white),
const SizedBox(width: 12),
Text('Erro ao remover aluno: $e'),
],
),
backgroundColor: Colors.red,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
duration: const Duration(seconds: 4),
),
);
}
}
}
}
}