criação da tela home dos professores e aniquilação do placeholder da home dos professores

(talzes o "já tenho conta" desapareça, talvez nao, que seja oq deus quiser)
This commit is contained in:
2026-05-10 15:10:26 +01:00
parent 1b7b03034d
commit 85157b8673
6 changed files with 1160 additions and 44 deletions

View File

@@ -192,11 +192,11 @@ This document tracks the overall progress of the AI Study Assistant project deve
### **📊 Dashboard System (0%)** ### **📊 Dashboard System (50%)**
- [ ] Student dashboard - [x] Student dashboard
- [ ] Teacher dashboard - [x] Teacher dashboard
- [ ] Analytics display - [ ] Analytics display
@@ -204,7 +204,7 @@ This document tracks the overall progress of the AI Study Assistant project deve
- [ ] Performance metrics - [ ] Performance metrics
- [ ] Quick actions - [x] Quick actions
@@ -452,7 +452,7 @@ This document tracks the overall progress of the AI Study Assistant project deve
3. **Add role-based routing** after login 3. **Add role-based routing** after login
4. **Create basic dashboard** placeholder 4. ~~**Create basic dashboard** placeholder~~**Student & Teacher dashboards implemented**

View File

@@ -278,28 +278,6 @@ class _RoleSelectionPageState extends State<RoleSelectionPage> {
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
// Login link
GestureDetector(
onTap: _selectedRole != null ? _handleGoToLogin : null,
child: Text(
'Já tenho conta',
style: TextStyle(
color: _selectedRole != null
? AppColors.primaryBlue
: Colors.grey,
fontWeight: FontWeight.w500,
decoration: TextDecoration.underline,
),
),
)
.animate()
.fadeIn(
duration: const Duration(milliseconds: 800),
delay: const Duration(milliseconds: 1400),
),
const SizedBox(height: 32),
], ],
), ),
), ),
@@ -432,4 +410,4 @@ class _RoleSelectionPageState extends State<RoleSelectionPage> {
context.go('/signup?role=$_selectedRole'); context.go('/signup?role=$_selectedRole');
} }
} }
} }

View File

@@ -1,26 +1,153 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../core/theme/app_colors.dart'; import 'package:go_router/go_router.dart';
import '../../../../core/services/auth_service.dart';
import '../widgets/teacher_hero_widget.dart';
import '../widgets/teacher_quick_actions_widget.dart';
import '../widgets/teacher_analytics_preview_widget.dart';
class TeacherDashboardPage extends StatelessWidget { class TeacherDashboardPage extends StatefulWidget {
const TeacherDashboardPage({super.key}); const TeacherDashboardPage({super.key});
@override
State<TeacherDashboardPage> createState() => _TeacherDashboardPageState();
}
class _TeacherDashboardPageState extends State<TeacherDashboardPage> {
String _userName = 'Professor';
@override
void initState() {
super.initState();
_loadUserData();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_loadUserData();
}
Future<void> _loadUserData() async {
try {
final user = AuthService.currentUser;
if (user != null) {
print('DEBUG: Loading teacher data for dashboard');
print('DEBUG: User email: ${user.email}');
print('DEBUG: User displayName before reload: ${user.displayName}');
await user.reload();
final updatedUser = AuthService.currentUser;
if (updatedUser != null) {
print(
'DEBUG: User displayName after reload: ${updatedUser.displayName}',
);
String displayName = updatedUser.displayName ?? '';
print('DEBUG: Initial displayName value: "$displayName"');
if (displayName.isEmpty && updatedUser.email != null) {
displayName = updatedUser.email!.split('@')[0];
print('DEBUG: Extracted name from email: "$displayName"');
}
if (displayName.isEmpty) {
displayName = 'Professor';
print('DEBUG: Using fallback "Professor"');
}
print('DEBUG: Final displayName to use: "$displayName"');
setState(() {
_userName = displayName;
});
}
}
} catch (e) {
print('DEBUG: Error loading user data: $e');
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: AppColors.background, body: Container(
appBar: AppBar( decoration: const BoxDecoration(
title: const Text('Teacher Dashboard'), gradient: LinearGradient(
backgroundColor: AppColors.surface, begin: Alignment.topCenter,
foregroundColor: AppColors.textPrimary, end: Alignment.bottomCenter,
elevation: 0, colors: [
), Color(0xFF82C9BD),
body: const Center( Color(0xFF7BA89C),
child: Text( Color(0xFFF68D2D),
'Teacher Dashboard - Coming Soon', Color(0xFFF8F9FA),
style: TextStyle( ],
fontSize: 24, stops: [0.0, 0.2, 0.6, 1.0],
fontWeight: FontWeight.bold, ),
color: AppColors.textPrimary, ),
child: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header with logout
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Bem-vindo, $_userName!',
style: const TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
const Text(
'Painel de Gestão de Conteúdo',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w300,
),
),
],
),
),
IconButton(
icon: const Icon(Icons.logout, color: Colors.white),
onPressed: () async {
await AuthService.signOut();
if (mounted) {
context.go('/login');
}
},
tooltip: 'Sair',
),
],
),
const SizedBox(height: 32),
// Hero Section - Class Overview
TeacherHeroWidget(userName: _userName),
const SizedBox(height: 24),
// Quick Actions Section
const TeacherQuickActionsWidget(),
const SizedBox(height: 24),
// Analytics Preview Section
const TeacherAnalyticsPreviewWidget(),
const SizedBox(height: 40),
],
),
),
), ),
), ),
), ),

View File

@@ -0,0 +1,309 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import '../../../../core/services/auth_service.dart';
/// Analytics preview section for teacher dashboard
class TeacherAnalyticsPreviewWidget extends StatelessWidget {
const TeacherAnalyticsPreviewWidget({super.key});
@override
Widget build(BuildContext context) {
final user = AuthService.currentUser;
final userName = user?.displayName ?? 'Professor';
final userEmail = user?.email ?? '';
return Container(
margin: const EdgeInsets.only(top: 24),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Profile Header
Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF82C9BD), Color(0xFF6BA8A0)],
),
borderRadius: BorderRadius.circular(24),
),
child: const Icon(
Icons.school,
color: Colors.white,
size: 24,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userName,
style: const TextStyle(
color: Color(0xFF2D3748),
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
userEmail,
style: const TextStyle(
color: Color(0xFF718096),
fontSize: 14,
),
),
if (userEmail.length > 20) ...[
const SizedBox(width: 8),
const Icon(
Icons.more_horiz,
color: Color(0xFF718096),
size: 16,
),
],
],
),
),
],
),
),
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D).withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(
Icons.settings,
color: Color(0xFFF68D2D),
size: 20,
),
),
],
),
const SizedBox(height: 20),
// Quick Stats Row
Row(
children: [
_buildQuickStat(
icon: Icons.check_circle,
label: 'Alunos Ativos',
value: '18/24',
color: const Color(0xFF82C9BD),
),
const SizedBox(width: 12),
_buildQuickStat(
icon: Icons.warning_amber,
label: 'Precisam Apoio',
value: '3',
color: const Color(0xFFF68D2D),
),
const SizedBox(width: 12),
_buildQuickStat(
icon: Icons.emoji_events,
label: 'Média Turma',
value: '72%',
color: const Color(0xFF6BA8A0),
),
],
),
const SizedBox(height: 20),
// Top Performing Students Preview
Row(
children: [
const Icon(
Icons.leaderboard,
color: Color(0xFFF68D2D),
size: 20,
),
const SizedBox(width: 8),
const Text(
'Melhores Desempenhos',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
// Student List Preview
_buildStudentPerformanceItem('Ana Silva', 95, const Color(0xFF4CAF50)),
const SizedBox(height: 8),
_buildStudentPerformanceItem('João Costa', 88, const Color(0xFF82C9BD)),
const SizedBox(height: 8),
_buildStudentPerformanceItem('Maria Santos', 82, const Color(0xFF82C9BD)),
const SizedBox(height: 8),
_buildStudentPerformanceItem('Pedro Lima', 45, const Color(0xFFF68D2D)),
const SizedBox(height: 20),
// Content Quality Alert
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFFF8F9FA),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFFE2E8F0)),
),
child: Row(
children: [
const Icon(
Icons.info_outline,
color: Color(0xFF82C9BD),
size: 20,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Qualidade do Conteúdo',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
Text(
'12 conteúdos verificados • 2 pendentes de revisão',
style: const TextStyle(
color: Color(0xFF718096),
fontSize: 12,
),
),
],
),
),
],
),
),
],
),
)
.animate()
.slideY(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
)
.then(delay: const Duration(milliseconds: 400));
}
Widget _buildQuickStat({
required IconData icon,
required String label,
required String value,
required Color color,
}) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color.withOpacity(0.3), width: 1),
),
child: Column(
children: [
Icon(icon, color: color, size: 20),
const SizedBox(height: 6),
Text(
value,
style: TextStyle(
color: color,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
Text(
label,
style: TextStyle(
color: color.withOpacity(0.8),
fontSize: 10,
),
textAlign: TextAlign.center,
),
],
),
),
);
}
Widget _buildStudentPerformanceItem(String name, int score, Color color) {
return Row(
children: [
Container(
width: 32,
height: 32,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(16),
),
child: Center(
child: Text(
name.split(' ').map((n) => n[0]).take(2).join(),
style: TextStyle(
color: color,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
name,
style: const TextStyle(
color: Color(0xFF4A5568),
fontSize: 14,
),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'$score%',
style: TextStyle(
color: color,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
],
);
}
}

View File

@@ -0,0 +1,326 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
/// Hero section for teacher dashboard showing class overview
class TeacherHeroWidget extends StatelessWidget {
final String userName;
final int totalStudents;
final int activeQuizzes;
final int uploadedContent;
final double classAverageProgress;
const TeacherHeroWidget({
super.key,
required this.userName,
this.totalStudents = 24,
this.activeQuizzes = 3,
this.uploadedContent = 12,
this.classAverageProgress = 0.72,
});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Visão Geral da Turma',
style: TextStyle(
color: const Color(0xFF2D3748),
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'Acompanhe o progresso dos seus alunos',
style: TextStyle(
color: const Color(0xFF718096),
fontSize: 16,
),
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D),
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.people,
color: Colors.white,
size: 16,
),
const SizedBox(width: 4),
Text(
'$totalStudents alunos',
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
const SizedBox(height: 20),
// Main Class Progress Card
Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF82C9BD),
const Color(0xFF6BA8A0),
],
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Overall Progress
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Progresso Médio da Turma',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
'${(classAverageProgress * 100).toInt()}%',
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 16),
// Progress Bar
Container(
height: 12,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.3),
borderRadius: BorderRadius.circular(6),
),
child: FractionallySizedBox(
alignment: Alignment.centerLeft,
widthFactor: classAverageProgress,
child: Container(
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Colors.white, Color(0xFFF8F9FA)],
),
borderRadius: BorderRadius.circular(6),
),
),
),
),
const SizedBox(height: 20),
// Stats Grid
Row(
children: [
Expanded(
child: _buildStatCard(
icon: Icons.quiz,
value: '$activeQuizzes',
label: 'Quizzes Ativos',
),
),
const SizedBox(width: 12),
Expanded(
child: _buildStatCard(
icon: Icons.upload_file,
value: '$uploadedContent',
label: 'Conteúdos',
),
),
],
),
],
),
).animate().scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
),
const SizedBox(height: 20),
// Recent Activity
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.trending_up,
color: Color(0xFFF68D2D),
size: 20,
),
const SizedBox(width: 8),
const Text(
'Atividade Recente',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
_buildActivityItem(
'15 alunos completaram o quiz de Derivadas',
'Hoje, 14:30',
const Color(0xFF82C9BD),
),
const SizedBox(height: 8),
_buildActivityItem(
'Novo conteúdo: Regra da Cadeia',
'Ontem, 09:15',
const Color(0xFFF68D2D),
),
const SizedBox(height: 8),
_buildActivityItem(
'3 alunos precisam de apoio em Limites',
'Ontem, 16:45',
const Color(0xFFE53E3E),
),
],
),
).animate().slideX(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
).then(delay: const Duration(milliseconds: 200)),
],
),
);
}
Widget _buildStatCard({
required IconData icon,
required String value,
required String label,
}) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 1,
),
),
child: Column(
children: [
Icon(icon, color: Colors.white, size: 24),
const SizedBox(height: 8),
Text(
value,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
label,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
textAlign: TextAlign.center,
),
],
),
);
}
Widget _buildActivityItem(String text, String time, Color color) {
return Row(
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
text,
style: const TextStyle(
color: Color(0xFF4A5568),
fontSize: 14,
),
),
const SizedBox(height: 2),
Text(
time,
style: const TextStyle(
color: Color(0xFF718096),
fontSize: 12,
),
),
],
),
),
],
);
}
}

View File

@@ -0,0 +1,376 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:go_router/go_router.dart';
/// Quick access cards for teacher actions
class TeacherQuickActionsWidget extends StatelessWidget {
const TeacherQuickActionsWidget({super.key});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Ações Rápidas',
style: TextStyle(
color: const Color(0xFF2D3748),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
// Primary Actions Row
Row(
children: [
// Upload Content Card (Primary)
Expanded(flex: 3, child: _buildUploadContentCard(context)),
const SizedBox(width: 16),
// Create Quiz Card (Secondary)
Expanded(flex: 2, child: _buildCreateQuizCard(context)),
],
),
const SizedBox(height: 16),
// Secondary Actions Row
Row(
children: [
// Manage Students Card
Expanded(child: _buildManageStudentsCard(context)),
const SizedBox(width: 16),
// View Analytics Card
Expanded(child: _buildViewAnalyticsCard(context)),
],
),
],
)
.animate()
.slideY(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
)
.then(delay: const Duration(milliseconds: 200));
}
Widget _buildUploadContentCard(BuildContext context) {
return Container(
height: 150,
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0xFF82C9BD), Color(0xFF6BA8A0)],
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: const Color(0xFF82C9BD).withOpacity(0.3),
blurRadius: 15,
offset: const Offset(0, 8),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: () => context.go('/teacher/upload'),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(7),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.upload_file,
color: Colors.white,
size: 24,
),
),
const Spacer(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 4,
),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D),
borderRadius: BorderRadius.circular(12),
),
child: const Text(
'NOVO',
style: TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold,
),
),
),
],
),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Upload Conteúdo',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
'PDFs, textos, imagens',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 12,
height: 1.2,
),
),
],
),
],
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 100));
}
Widget _buildCreateQuizCard(BuildContext context) {
return Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0), width: 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: () => context.go('/teacher/quiz/create'),
child: Padding(
padding: const EdgeInsets.all(14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D).withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.quiz,
color: Color(0xFFF68D2D),
size: 24,
),
),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Criar Quiz',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
Text(
'Avaliações',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Color(0xFF718096),
fontSize: 12,
height: 1.2,
),
),
],
),
],
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 200));
}
Widget _buildManageStudentsCard(BuildContext context) {
return Container(
height: 120,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0), width: 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: () => context.go('/teacher/students'),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xFF82C9BD).withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.people,
color: Color(0xFF82C9BD),
size: 20,
),
),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Gerir Alunos',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Text(
'Acesso e permissões',
style: TextStyle(
color: Color(0xFF718096),
fontSize: 11,
),
),
],
),
],
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 300));
}
Widget _buildViewAnalyticsCard(BuildContext context) {
return Container(
height: 120,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0), width: 1),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: () => context.go('/teacher/analytics'),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xFF6BA8A0).withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.analytics,
color: Color(0xFF6BA8A0),
size: 20,
),
),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Analytics',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Text(
'Desempenho da turma',
style: TextStyle(
color: Color(0xFF718096),
fontSize: 11,
),
),
],
),
],
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 400));
}
}