Modificações no chatbot (dashboard aluno) e analytics (dashboard stor)

This commit is contained in:
2026-05-18 20:43:13 +01:00
parent 9b53eb06b6
commit c0ade9ef76
6 changed files with 1436 additions and 496 deletions

View File

@@ -9,7 +9,7 @@ import '../../../../core/services/gamification_service.dart';
import '../../../../core/models/class_stats.dart';
import '../../../../core/models/achievement.dart';
import '../widgets/class_analytics_card.dart';
import '../widgets/class_ranking_widget.dart';
import '../widgets/class_students_inline_widget.dart';
import '../widgets/create_achievement_dialog.dart';
/// Analytics page for teachers with class breakdowns and rankings
@@ -26,6 +26,7 @@ class _AnalyticsPageState extends State<AnalyticsPage>
List<ClassStats> _classStats = [];
bool _loading = true;
String? _selectedClassId;
String? _selectedClassName;
@override
void initState() {
@@ -86,89 +87,99 @@ class _AnalyticsPageState extends State<AnalyticsPage>
final themeExtras = AppThemeExtras.of(context);
final cs = Theme.of(context).colorScheme;
return Scaffold(
backgroundColor: cs.surface,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: themeExtras.dashboardBackgroundGradient,
stops: themeExtras.dashboardGradientStops,
return PopScope(
canPop: false,
onPopInvoked: (didPop) {
if (didPop) return;
context.go('/teacher-dashboard');
},
child: Scaffold(
backgroundColor: cs.surface,
resizeToAvoidBottomInset: false,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: themeExtras.dashboardBackgroundGradient,
stops: themeExtras.dashboardGradientStops,
),
),
),
child: SafeArea(
child: Column(
children: [
// Header
Container(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Row(
children: [
IconButton(
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
child: SafeArea(
child: Column(
children: [
// Header
Container(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Row(
children: [
IconButton(
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () => context.go('/teacher-dashboard'),
),
onPressed: () => context.go('/teacher-dashboard'),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Analytics',
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Analytics',
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 4),
Text(
'Acompanhe o desempenho das disciplinas',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.8),
fontSize: 16,
const SizedBox(height: 4),
Text(
'Acompanhe o desempenho das disciplinas',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.8),
fontSize: 16,
),
),
),
],
],
),
),
IconButton(
icon: const Icon(Icons.add, color: Colors.white),
onPressed: _showCreateAchievementDialog,
tooltip: 'Criar Conquista',
),
],
),
const SizedBox(height: 20),
TabBar(
controller: _tabController,
labelColor: Colors.white,
unselectedLabelColor: Colors.white.withValues(
alpha: 0.7,
),
IconButton(
icon: const Icon(Icons.add, color: Colors.white),
onPressed: _showCreateAchievementDialog,
tooltip: 'Criar Conquista',
),
],
),
const SizedBox(height: 20),
TabBar(
controller: _tabController,
labelColor: Colors.white,
unselectedLabelColor: Colors.white.withValues(alpha: 0.7),
indicatorColor: Colors.white,
indicatorWeight: 2,
tabs: const [
Tab(text: 'Disciplinas'),
Tab(text: 'Rankings'),
],
),
],
indicatorColor: Colors.white,
indicatorWeight: 2,
tabs: const [
Tab(text: 'Disciplinas'),
Tab(text: 'Alunos'),
],
),
],
),
),
),
// Content
Expanded(
child: TabBarView(
controller: _tabController,
children: [_buildClassesTab(), _buildRankingsTab()],
// Content
Expanded(
child: TabBarView(
controller: _tabController,
children: [_buildClassesTab(), _buildStudentsTab()],
),
),
),
],
],
),
),
),
),
@@ -248,7 +259,7 @@ class _AnalyticsPageState extends State<AnalyticsPage>
padding: const EdgeInsets.only(bottom: 16),
child: ClassAnalyticsCard(
classStats: stats,
onTap: () => _showClassRanking(stats),
onTap: () => _showClassStudents(stats),
),
),
),
@@ -257,20 +268,20 @@ class _AnalyticsPageState extends State<AnalyticsPage>
);
}
Widget _buildRankingsTab() {
Widget _buildStudentsTab() {
if (_selectedClassId == null) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.leaderboard,
Icons.people_outline,
size: 64,
color: Colors.white.withValues(alpha: 0.5),
),
const SizedBox(height: 16),
Text(
'Selecione uma disciplina',
'Seleciona uma disciplina',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.7),
fontSize: 18,
@@ -278,18 +289,22 @@ class _AnalyticsPageState extends State<AnalyticsPage>
),
const SizedBox(height: 8),
Text(
'Clique em uma disciplina na aba "Disciplinas" para ver o ranking',
'Clica numa disciplina no separador "Disciplinas" para ver os alunos',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.5),
fontSize: 14,
),
textAlign: TextAlign.center,
),
],
),
);
}
return ClassRankingWidget(classId: _selectedClassId!);
return ClassStudentsInlineWidget(
classId: _selectedClassId!,
className: _selectedClassName ?? '',
);
}
Widget _buildOverviewCard(
@@ -331,11 +346,12 @@ class _AnalyticsPageState extends State<AnalyticsPage>
).animate().scale(duration: 600.ms, curve: Curves.elasticOut);
}
void _showClassRanking(ClassStats stats) {
void _showClassStudents(ClassStats stats) {
setState(() {
_selectedClassId = stats.classId;
_selectedClassName = stats.className;
});
_tabController.animateTo(1); // Mudar para aba de rankings
_tabController.animateTo(1);
}
void _showCreateAchievementDialog() {