Historico de quizzes e inicio de atualização da IA para leitura de pdfs de matemática (incompleto)

This commit is contained in:
2026-05-20 01:32:37 +01:00
parent 80ed2b1346
commit 98dcd621c7
12 changed files with 1539 additions and 271 deletions

View File

@@ -200,7 +200,7 @@ class QuickAccessWidget extends StatelessWidget {
Widget _buildJoinClassCard(BuildContext context) {
return DashboardActionCard(
title: 'Entrar numa Disciplina',
title: 'Adicionar uma Disciplina',
subtitle: 'Junta-te a uma disciplina com o código',
icon: Icons.group_add,
layout: DashboardActionCardLayout.horizontal,
@@ -264,7 +264,7 @@ class QuickAccessWidget extends StatelessWidget {
},
),
_QuickAccessItem(
title: 'Entrar numa Disciplina',
title: 'Adicionar uma Disciplina',
subtitle: 'Junta-te a uma disciplina com o código',
icon: Icons.group_add,
onTap: () {

View File

@@ -126,6 +126,7 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
final enrollmentData = enrollmentDoc.data() as Map<String, dynamic>;
final classId = enrollmentData['classId'] as String? ?? '';
final enrollmentId = enrollmentDoc.id;
final customClassName = enrollmentData['customClassName'] as String?;
if (classId.isEmpty) {
return const SizedBox.shrink();
@@ -163,11 +164,12 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
}
final classData = snapshot.data!.data() as Map<String, dynamic>;
final className = classData['name'] as String? ?? 'Sem nome';
final className =
customClassName ?? (classData['name'] as String? ?? 'Sem nome');
final classCode = classData['code'] as String? ?? '----';
return GestureDetector(
onTap: () => _showRemoveClassDialog(context, enrollmentId, className),
onTap: () => _showEditNameDialog(context, enrollmentId, className),
child: Container(
width: 200,
constraints: const BoxConstraints(minHeight: 150),
@@ -187,19 +189,29 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.school,
color: Theme.of(context).colorScheme.primary,
size: 24,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.school,
color: Theme.of(context).colorScheme.primary,
size: 24,
),
),
Icon(
Icons.edit,
color: Theme.of(context).colorScheme.primary,
size: 18,
),
],
),
const SizedBox(height: 12),
Text(
@@ -291,6 +303,7 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
final enrollmentData = enrollmentDoc.data() as Map<String, dynamic>;
final classId = enrollmentData['classId'] as String? ?? '';
final enrollmentId = enrollmentDoc.id;
final customClassName = enrollmentData['customClassName'] as String?;
if (classId.isEmpty) {
return const SizedBox.shrink();
@@ -312,7 +325,8 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
}
final classData = snapshot.data!.data() as Map<String, dynamic>;
final className = classData['name'] as String? ?? 'Sem nome';
final className =
customClassName ?? (classData['name'] as String? ?? 'Sem nome');
final classCode = classData['code'] as String? ?? '----';
return Card(
@@ -351,13 +365,30 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
fontSize: 13,
),
),
trailing: Icon(
Icons.delete_outline,
color: Theme.of(context).colorScheme.error,
size: 20,
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(
Icons.edit,
color: Theme.of(context).colorScheme.primary,
size: 20,
),
onPressed: () =>
_showEditNameDialog(context, enrollmentId, className),
),
IconButton(
icon: Icon(
Icons.delete_outline,
color: Theme.of(context).colorScheme.error,
size: 20,
),
onPressed: () =>
_showRemoveClassDialog(context, enrollmentId, className),
),
],
),
onTap: () =>
_showRemoveClassDialog(context, enrollmentId, className),
onTap: () => _showEditNameDialog(context, enrollmentId, className),
),
);
},
@@ -493,7 +524,7 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Erro ao sair da disciplina: $e'),
backgroundColor: Colors.red,
backgroundColor: Theme.of(context).colorScheme.error,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
@@ -503,4 +534,49 @@ class _StudentClassesListWidgetState extends State<StudentClassesListWidget> {
}
}
}
void _showEditNameDialog(
BuildContext context,
String enrollmentId,
String currentName,
) {
final controller = TextEditingController(text: currentName);
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Editar nome da disciplina'),
content: TextField(
controller: controller,
decoration: const InputDecoration(hintText: 'Nome da disciplina'),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancelar'),
),
TextButton(
onPressed: () async {
final newName = controller.text.trim();
if (newName.isNotEmpty) {
await FirebaseFirestore.instance
.collection('enrollments')
.doc(enrollmentId)
.update({'customClassName': newName});
if (mounted) {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Nome atualizado com sucesso'),
behavior: SnackBarBehavior.floating,
),
);
}
}
},
child: const Text('Salvar'),
),
],
),
);
}
}