Muitas coisas e já me esqueci delas todas, cenas principalmente no dashboard do aluno bug fixes e etc
This commit is contained in:
@@ -34,7 +34,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
.collection('users')
|
||||
.doc(user.uid)
|
||||
.get();
|
||||
|
||||
|
||||
if (userDoc.exists) {
|
||||
setState(() {
|
||||
_userRole = userDoc.data()?['role'] ?? '';
|
||||
@@ -49,7 +49,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
if (user == null) return;
|
||||
|
||||
Query query;
|
||||
|
||||
|
||||
if (_userRole == 'teacher') {
|
||||
// Professor: ver todos os quizzes criados
|
||||
query = FirebaseFirestore.instance
|
||||
@@ -59,7 +59,10 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
} else {
|
||||
// Aluno: ver quizzes criados pelo próprio aluno + conceitos dominados
|
||||
final results = await Future.wait([
|
||||
FirebaseFirestore.instance.collection('userStats').doc(user.uid).get(),
|
||||
FirebaseFirestore.instance
|
||||
.collection('userStats')
|
||||
.doc(user.uid)
|
||||
.get(),
|
||||
FirebaseFirestore.instance
|
||||
.collection('quizHistory')
|
||||
.doc(user.uid)
|
||||
@@ -67,12 +70,12 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
.orderBy('createdAt', descending: true)
|
||||
.get(),
|
||||
]);
|
||||
|
||||
|
||||
final userStatsSnapshot = results[0] as DocumentSnapshot;
|
||||
final studentQuizzesSnapshot = results[1] as QuerySnapshot;
|
||||
|
||||
|
||||
List<Map<String, dynamic>> quizList = [];
|
||||
|
||||
|
||||
// Adicionar quizzes criados pelo aluno
|
||||
for (final doc in studentQuizzesSnapshot.docs) {
|
||||
final data = Map<String, dynamic>.from(doc.data() as Map);
|
||||
@@ -81,15 +84,17 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
data['type'] = 'created';
|
||||
quizList.add(data);
|
||||
}
|
||||
|
||||
|
||||
// Adicionar conceitos dominados
|
||||
if (userStatsSnapshot.exists) {
|
||||
final stats = userStatsSnapshot.data() as Map<String, dynamic>?;
|
||||
if (stats != null) {
|
||||
final masteredConcepts = (stats['masteredConcepts'] as List<dynamic>?)
|
||||
?.map((c) => Map<String, dynamic>.from(c as Map))
|
||||
.toList() ?? [];
|
||||
|
||||
final masteredConcepts =
|
||||
(stats['masteredConcepts'] as List<dynamic>?)
|
||||
?.map((c) => Map<String, dynamic>.from(c as Map))
|
||||
.toList() ??
|
||||
[];
|
||||
|
||||
for (final concept in masteredConcepts) {
|
||||
quizList.add({
|
||||
'id': concept['conceptName'] ?? '',
|
||||
@@ -102,7 +107,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setState(() {
|
||||
_quizHistory = quizList;
|
||||
_loading = false;
|
||||
@@ -111,13 +116,16 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
}
|
||||
|
||||
final snapshot = await query.get();
|
||||
|
||||
|
||||
setState(() {
|
||||
_quizHistory = snapshot.docs.map((doc) {
|
||||
final data = Map<String, dynamic>.from(doc.data() as Map);
|
||||
data['id'] = doc.id;
|
||||
return data;
|
||||
}).cast<Map<String, dynamic>>().toList();
|
||||
_quizHistory = snapshot.docs
|
||||
.map((doc) {
|
||||
final data = Map<String, dynamic>.from(doc.data() as Map);
|
||||
data['id'] = doc.id;
|
||||
return data;
|
||||
})
|
||||
.cast<Map<String, dynamic>>()
|
||||
.toList();
|
||||
_loading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
@@ -132,21 +140,27 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
try {
|
||||
String confirmMessage;
|
||||
String successMessage;
|
||||
|
||||
|
||||
if (_userRole == 'teacher') {
|
||||
confirmMessage = 'Tem certeza que deseja eliminar o quiz "$quizTitle"? Esta ação não pode ser desfeita.';
|
||||
confirmMessage =
|
||||
'Tem certeza que deseja eliminar o quiz "$quizTitle"? Esta ação não pode ser desfeita.';
|
||||
successMessage = 'Quiz eliminado com sucesso!';
|
||||
} else {
|
||||
if (type == 'created') {
|
||||
confirmMessage = 'Tem certeza que deseja eliminar seu quiz "$quizTitle"?';
|
||||
confirmMessage =
|
||||
'Tem certeza que deseja eliminar seu quiz "$quizTitle"?';
|
||||
successMessage = 'Quiz eliminado com sucesso!';
|
||||
} else {
|
||||
confirmMessage = 'Tem certeza que deseja remover o conceito "$quizTitle" do seu histórico?';
|
||||
confirmMessage =
|
||||
'Tem certeza que deseja remover o conceito "$quizTitle" do seu histórico?';
|
||||
successMessage = 'Conceito removido com sucesso!';
|
||||
}
|
||||
}
|
||||
|
||||
final confirmed = await _showDeleteConfirmation(quizTitle, confirmMessage);
|
||||
|
||||
final confirmed = await _showDeleteConfirmation(
|
||||
quizTitle,
|
||||
confirmMessage,
|
||||
);
|
||||
if (!confirmed) return;
|
||||
|
||||
if (_userRole == 'teacher') {
|
||||
@@ -155,13 +169,13 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
.collection('teacherQuizzes')
|
||||
.doc(quizId)
|
||||
.delete();
|
||||
|
||||
|
||||
// Também eliminar do histórico de alunos
|
||||
final historySnapshot = await FirebaseFirestore.instance
|
||||
.collection('quizHistory')
|
||||
.where('quizId', isEqualTo: quizId)
|
||||
.get();
|
||||
|
||||
|
||||
for (final doc in historySnapshot.docs) {
|
||||
await doc.reference.delete();
|
||||
}
|
||||
@@ -186,26 +200,30 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
.collection('userStats')
|
||||
.doc(user.uid)
|
||||
.get();
|
||||
|
||||
|
||||
if (userStatsDoc.exists) {
|
||||
final userStats = userStatsDoc.data() as Map<String, dynamic>;
|
||||
final masteredConcepts = (userStats['masteredConcepts'] as List<dynamic>?)
|
||||
?.map((c) => Map<String, dynamic>.from(c as Map))
|
||||
.toList() ?? [];
|
||||
|
||||
final masteredConcepts =
|
||||
(userStats['masteredConcepts'] as List<dynamic>?)
|
||||
?.map((c) => Map<String, dynamic>.from(c as Map))
|
||||
.toList() ??
|
||||
[];
|
||||
|
||||
// Encontrar o conceito específico para remover
|
||||
final conceptToRemove = masteredConcepts.firstWhere(
|
||||
(c) => c['conceptName'] == quizId,
|
||||
orElse: () => {},
|
||||
);
|
||||
|
||||
|
||||
if (conceptToRemove.isNotEmpty) {
|
||||
await FirebaseFirestore.instance
|
||||
.collection('userStats')
|
||||
.doc(user.uid)
|
||||
.update({
|
||||
'masteredConcepts': FieldValue.arrayRemove([conceptToRemove])
|
||||
});
|
||||
'masteredConcepts': FieldValue.arrayRemove([
|
||||
conceptToRemove,
|
||||
]),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +231,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
}
|
||||
|
||||
_loadQuizHistory(); // Recarregar lista
|
||||
|
||||
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
@@ -239,7 +257,9 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
final result = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(_userRole == 'teacher' ? 'Eliminar Quiz' : 'Confirmar Eliminação'),
|
||||
title: Text(
|
||||
_userRole == 'teacher' ? 'Eliminar Quiz' : 'Confirmar Eliminação',
|
||||
),
|
||||
content: Text(message),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -264,15 +284,25 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
return Scaffold(
|
||||
backgroundColor: cs.surface,
|
||||
appBar: AppBar(
|
||||
title: Text(_userRole == 'teacher' ? 'Gerenciar Quizzes' : 'Meu Histórico'),
|
||||
title: Text(
|
||||
_userRole == 'teacher' ? 'Gerenciar Quizzes' : 'Meu Histórico',
|
||||
),
|
||||
backgroundColor: cs.surface,
|
||||
foregroundColor: cs.onSurface,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () => context.go(_userRole == 'teacher'
|
||||
? '/teacher-dashboard'
|
||||
: '/student-dashboard'),
|
||||
onPressed: () {
|
||||
if (Navigator.of(context).canPop()) {
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
context.go(
|
||||
_userRole == 'teacher'
|
||||
? '/teacher-dashboard'
|
||||
: '/student-dashboard',
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
@@ -280,34 +310,31 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
cs.primary.withValues(alpha: 0.05),
|
||||
cs.surface,
|
||||
],
|
||||
colors: [cs.primary.withValues(alpha: 0.05), cs.surface],
|
||||
),
|
||||
),
|
||||
child: _loading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: _quizHistory.isEmpty
|
||||
? _buildEmptyState()
|
||||
: ListView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: _quizHistory.length,
|
||||
itemBuilder: (context, index) {
|
||||
final quiz = _quizHistory[index];
|
||||
return _buildQuizCard(quiz)
|
||||
.animate()
|
||||
.slideX(duration: const Duration(milliseconds: 300))
|
||||
.then(delay: Duration(milliseconds: index * 50));
|
||||
},
|
||||
),
|
||||
? _buildEmptyState()
|
||||
: ListView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: _quizHistory.length,
|
||||
itemBuilder: (context, index) {
|
||||
final quiz = _quizHistory[index];
|
||||
return _buildQuizCard(quiz)
|
||||
.animate()
|
||||
.slideX(duration: const Duration(milliseconds: 300))
|
||||
.then(delay: Duration(milliseconds: index * 50));
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEmptyState() {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
@@ -315,13 +342,17 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
_userRole == 'teacher' ? Icons.quiz_outlined : Icons.history_edu_outlined,
|
||||
_userRole == 'teacher'
|
||||
? Icons.quiz_outlined
|
||||
: Icons.history_edu_outlined,
|
||||
size: 64,
|
||||
color: cs.onSurfaceVariant,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
_userRole == 'teacher' ? 'Nenhum quiz criado' : 'Nenhum quiz no histórico',
|
||||
_userRole == 'teacher'
|
||||
? 'Nenhum quiz criado'
|
||||
: 'Nenhum quiz no histórico',
|
||||
style: TextStyle(
|
||||
color: cs.onSurface,
|
||||
fontSize: 20,
|
||||
@@ -331,13 +362,10 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
_userRole == 'teacher'
|
||||
_userRole == 'teacher'
|
||||
? 'Crie seu primeiro quiz para começar!'
|
||||
: 'Complete alguns quizzes para ver seu histórico aqui.',
|
||||
style: TextStyle(
|
||||
color: cs.onSurfaceVariant,
|
||||
fontSize: 14,
|
||||
),
|
||||
style: TextStyle(color: cs.onSurfaceVariant, fontSize: 14),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
@@ -348,7 +376,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
|
||||
Widget _buildQuizCard(Map<String, dynamic> quiz) {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 12),
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -405,11 +433,12 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => _deleteQuiz(quiz['id'], quiz['title'] ?? 'Quiz', quiz['type'] ?? 'unknown'),
|
||||
icon: Icon(
|
||||
Icons.delete_outline,
|
||||
color: Colors.red,
|
||||
onPressed: () => _deleteQuiz(
|
||||
quiz['id'],
|
||||
quiz['title'] ?? 'Quiz',
|
||||
quiz['type'] ?? 'unknown',
|
||||
),
|
||||
icon: Icon(Icons.delete_outline, color: Colors.red),
|
||||
tooltip: _userRole == 'teacher' ? 'Eliminar Quiz' : 'Remover',
|
||||
),
|
||||
],
|
||||
@@ -420,13 +449,16 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
spacing: 4,
|
||||
children: (quiz['classIds'] as List<dynamic>).map((classId) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: cs.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
'Turma: $classId',
|
||||
'Disciplina: $classId',
|
||||
style: TextStyle(
|
||||
color: cs.onPrimaryContainer,
|
||||
fontSize: 10,
|
||||
@@ -443,7 +475,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
|
||||
String _formatDate(dynamic date) {
|
||||
if (date == null) return 'Data desconhecida';
|
||||
|
||||
|
||||
DateTime dateTime;
|
||||
if (date is Timestamp) {
|
||||
dateTime = date.toDate();
|
||||
@@ -452,7 +484,7 @@ class _QuizManagementPageState extends State<QuizManagementPage> {
|
||||
} else {
|
||||
return 'Data desconhecida';
|
||||
}
|
||||
|
||||
|
||||
return '${dateTime.day}/${dateTime.month}/${dateTime.year}';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user