- Dark / light mode a funcionar no lado do aluno

- Atualização dos ficheiros markdown.
This commit is contained in:
2026-05-14 22:07:03 +01:00
parent 55ec2521cf
commit 62b9a107bc
30 changed files with 2582 additions and 1839 deletions

View File

@@ -76,15 +76,15 @@ class _StudentDashboardPageState extends State<StudentDashboardPage> {
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF82C9BD),
Color(0xFF7BA89C),
Color(0xFFF68D2D),
Color(0xFFF8F9FA),
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.8),
Theme.of(context).colorScheme.secondary,
Theme.of(context).colorScheme.background,
],
stops: [0.0, 0.2, 0.6, 1.0],
),

View File

@@ -71,15 +71,15 @@ class _TeacherDashboardPageState extends State<TeacherDashboardPage> {
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF82C9BD),
Color(0xFF7BA89C),
Color(0xFFF68D2D),
Color(0xFFF8F9FA),
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.8),
Theme.of(context).colorScheme.secondary,
Theme.of(context).colorScheme.background,
],
stops: [0.0, 0.2, 0.6, 1.0],
),

View File

@@ -17,12 +17,14 @@ class ProfileSectionWidget extends StatelessWidget {
margin: const EdgeInsets.only(top: 24),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0)),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
@@ -38,8 +40,13 @@ class ProfileSectionWidget extends StatelessWidget {
width: 48,
height: 48,
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF82C9BD), Color(0xFF6BA8A0)],
gradient: LinearGradient(
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(
context,
).colorScheme.primary.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(24),
),
@@ -56,8 +63,8 @@ class ProfileSectionWidget extends StatelessWidget {
children: [
Text(
userName,
style: const TextStyle(
color: Color(0xFF2D3748),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 18,
fontWeight: FontWeight.bold,
),
@@ -70,16 +77,20 @@ class ProfileSectionWidget extends StatelessWidget {
children: [
Text(
userEmail,
style: const TextStyle(
color: Color(0xFF718096),
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),
if (userEmail.length > 20) ...[
const SizedBox(width: 8),
const Icon(
Icon(
Icons.more_horiz,
color: Color(0xFF718096),
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
size: 16,
),
],
@@ -96,12 +107,14 @@ class ProfileSectionWidget extends StatelessWidget {
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D).withOpacity(0.1),
color: Theme.of(
context,
).colorScheme.secondary.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(
child: Icon(
Icons.settings,
color: Color(0xFFF68D2D),
color: Theme.of(context).colorScheme.secondary,
size: 20,
),
),
@@ -113,16 +126,16 @@ class ProfileSectionWidget extends StatelessWidget {
// Achievements
Row(
children: [
const Icon(
Icon(
Icons.emoji_events,
color: Color(0xFFF68D2D),
color: Theme.of(context).colorScheme.secondary,
size: 20,
),
const SizedBox(width: 8),
const Text(
Text(
'Conquistas',
style: TextStyle(
color: Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
@@ -137,25 +150,27 @@ class ProfileSectionWidget extends StatelessWidget {
_buildAchievementBadge(
icon: Icons.local_fire_department,
label: '7 dias',
color: const Color(0xFFF68D2D),
color: Theme.of(context).colorScheme.secondary,
),
const SizedBox(width: 12),
_buildAchievementBadge(
icon: Icons.school,
label: '3 conceitos',
color: const Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(width: 12),
_buildAchievementBadge(
icon: Icons.speed,
label: 'Rápido',
color: const Color(0xFF6BA8A0),
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.8),
),
const SizedBox(width: 12),
_buildAchievementBadge(
icon: Icons.star,
label: '100%',
color: const Color(0xFF4CAF50),
color: Theme.of(context).colorScheme.tertiary,
),
],
),
@@ -165,15 +180,21 @@ class ProfileSectionWidget extends StatelessWidget {
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFFF8F9FA),
color: Theme.of(context).brightness == Brightness.dark
? Theme.of(context).colorScheme.surfaceContainerHighest
: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFFE2E8F0)),
border: Border.all(
color: Theme.of(
context,
).colorScheme.outline.withOpacity(0.2),
),
),
child: Row(
children: [
const Icon(
Icon(
Icons.trending_up,
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
size: 20,
),
const SizedBox(width: 12),
@@ -181,10 +202,10 @@ class ProfileSectionWidget extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
Text(
'Ótimo progresso!',
style: TextStyle(
color: Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
@@ -192,8 +213,10 @@ class ProfileSectionWidget extends StatelessWidget {
const SizedBox(height: 2),
Text(
'Você está 15% acima da média esta semana',
style: const TextStyle(
color: Color(0xFF718096),
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 12,
),
),

View File

@@ -39,7 +39,7 @@ class ProgressHeroWidget extends StatelessWidget {
Text(
'Seu Progresso',
style: TextStyle(
color: const Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 24,
fontWeight: FontWeight.bold,
),
@@ -48,7 +48,7 @@ class ProgressHeroWidget extends StatelessWidget {
Text(
'Continue assim, $userName!',
style: TextStyle(
color: const Color(0xFF718096),
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 16,
),
),
@@ -56,9 +56,12 @@ class ProgressHeroWidget extends StatelessWidget {
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: const Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
@@ -93,8 +96,8 @@ class ProgressHeroWidget extends StatelessWidget {
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF82C9BD),
const Color(0xFF6BA8A0),
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(20),
@@ -132,7 +135,7 @@ class ProgressHeroWidget extends StatelessWidget {
],
),
const SizedBox(height: 16),
// Progress Bar
Container(
height: 12,
@@ -186,77 +189,90 @@ class ProgressHeroWidget extends StatelessWidget {
// Mastered Concepts
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.school,
color: Color(0xFFF68D2D),
size: 20,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(
context,
).colorScheme.outline.withOpacity(0.2),
),
boxShadow: [
BoxShadow(
color: Theme.of(
context,
).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
const SizedBox(width: 8),
const Text(
'Conceitos Dominados',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.bold,
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.school,
color: Theme.of(context).colorScheme.secondary,
size: 20,
),
const SizedBox(width: 8),
Text(
'Conceitos Dominados',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
...masteredConcepts.map(
(concept) => Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
shape: BoxShape.circle,
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
concept,
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),
),
Icon(
Icons.check_circle,
color: Theme.of(context).colorScheme.primary,
size: 16,
),
],
),
),
),
],
),
const SizedBox(height: 12),
...masteredConcepts.map((concept) => Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
Container(
width: 8,
height: 8,
decoration: const BoxDecoration(
color: Color(0xFF82C9BD),
shape: BoxShape.circle,
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
concept,
style: const TextStyle(
color: Color(0xFF4A5568),
fontSize: 14,
),
),
),
const Icon(
Icons.check_circle,
color: Color(0xFF82C9BD),
size: 16,
),
],
),
)),
],
),
).animate().slideX(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
).then(delay: const Duration(milliseconds: 200)),
)
.animate()
.slideX(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
)
.then(delay: const Duration(milliseconds: 200)),
],
),
);
@@ -272,10 +288,7 @@ class ProgressHeroWidget extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 1,
),
border: Border.all(color: Colors.white.withOpacity(0.3), width: 1),
),
child: Column(
children: [
@@ -292,10 +305,7 @@ class ProgressHeroWidget extends StatelessWidget {
const SizedBox(height: 4),
Text(
label,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
style: const TextStyle(color: Colors.white, fontSize: 12),
textAlign: TextAlign.center,
),
],

View File

@@ -15,7 +15,7 @@ class QuickAccessWidget extends StatelessWidget {
Text(
'Acesso Rápido',
style: TextStyle(
color: const Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 20,
fontWeight: FontWeight.bold,
),
@@ -48,15 +48,18 @@ class QuickAccessWidget extends StatelessWidget {
return Container(
height: 150,
decoration: BoxDecoration(
gradient: const LinearGradient(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0xFF82C9BD), Color(0xFF6BA8A0)],
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: const Color(0xFF82C9BD).withOpacity(0.3),
color: Theme.of(context).colorScheme.primary.withOpacity(0.3),
blurRadius: 15,
offset: const Offset(0, 8),
),
@@ -102,7 +105,7 @@ class QuickAccessWidget extends StatelessWidget {
vertical: 4,
),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D),
color: Theme.of(context).colorScheme.secondary,
borderRadius: BorderRadius.circular(12),
),
child: const Text(
@@ -159,12 +162,15 @@ class QuickAccessWidget extends StatelessWidget {
return Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0), width: 1),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
@@ -192,34 +198,38 @@ class QuickAccessWidget extends StatelessWidget {
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D).withOpacity(0.1),
color: Theme.of(
context,
).colorScheme.secondary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
child: Icon(
Icons.quiz,
color: Color(0xFFF68D2D),
color: Theme.of(context).colorScheme.secondary,
size: 24,
),
),
const SizedBox(height: 12),
const Column(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Quiz',
style: TextStyle(
color: Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
const SizedBox(height: 4),
Text(
'Teste conhecimentos',
'Testa os teus conhecimentos',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Color(0xFF718096),
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 12,
height: 1.2,
),
@@ -242,14 +252,17 @@ class QuickAccessWidget extends StatelessWidget {
Widget _buildJoinClassCard(BuildContext context) {
return Container(
height: 80,
height: 86,
decoration: BoxDecoration(
color: Colors.white,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE2E8F0), width: 1),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
@@ -262,9 +275,7 @@ class QuickAccessWidget extends StatelessWidget {
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const JoinClassPage(),
),
MaterialPageRoute(builder: (_) => const JoinClassPage()),
);
},
child: Padding(
@@ -274,17 +285,19 @@ class QuickAccessWidget extends StatelessWidget {
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFF82C9BD).withOpacity(0.1),
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
child: Icon(
Icons.group_add,
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
size: 24,
),
),
const SizedBox(width: 16),
const Expanded(
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
@@ -292,27 +305,29 @@ class QuickAccessWidget extends StatelessWidget {
Text(
'Entrar numa Turma',
style: TextStyle(
color: Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
const SizedBox(height: 4),
Text(
'Junta-te a uma turma com o código',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Color(0xFF718096),
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 13,
),
),
],
),
),
const Icon(
Icon(
Icons.arrow_forward_ios,
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
size: 16,
),
],

View File

@@ -23,11 +23,11 @@ class StudentClassesListWidget extends StatelessWidget {
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
return Center(
child: Padding(
padding: EdgeInsets.all(16.0),
padding: const EdgeInsets.all(16.0),
child: CircularProgressIndicator(
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
),
),
);
@@ -44,10 +44,7 @@ class StudentClassesListWidget extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: Text(
'Ainda não entraste em nenhuma turma.',
style: TextStyle(
color: Colors.grey[600],
fontSize: 14,
),
style: TextStyle(color: Colors.grey[600], fontSize: 14),
),
);
}
@@ -58,9 +55,9 @@ class StudentClassesListWidget extends StatelessWidget {
Text(
'As Minhas Turmas',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: const Color(0xFF2D3748),
fontWeight: FontWeight.bold,
),
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
SizedBox(
@@ -102,7 +99,10 @@ class StudentClassesListWidget extends StatelessWidget {
}
return FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance.collection('classes').doc(classId).get(),
future: FirebaseFirestore.instance
.collection('classes')
.doc(classId)
.get(),
builder: (context, snapshot) {
if (!snapshot.hasData || !snapshot.data!.exists) {
return Container(
@@ -110,19 +110,19 @@ class StudentClassesListWidget extends StatelessWidget {
height: 150,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: const Center(
child: Center(
child: CircularProgressIndicator(
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
strokeWidth: 2,
),
),
@@ -138,11 +138,11 @@ class StudentClassesListWidget extends StatelessWidget {
height: 150,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
@@ -155,20 +155,20 @@ class StudentClassesListWidget extends StatelessWidget {
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFF82C9BD).withOpacity(0.1),
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
child: Icon(
Icons.school,
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
size: 24,
),
),
const SizedBox(height: 12),
Text(
className,
style: const TextStyle(
color: Color(0xFF2D3748),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
@@ -179,7 +179,7 @@ class StudentClassesListWidget extends StatelessWidget {
Text(
'Código: $classCode',
style: TextStyle(
color: Colors.grey[600],
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 13,
),
),

View File

@@ -13,207 +13,248 @@ class TeacherAnalyticsPreviewWidget extends StatelessWidget {
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,
),
margin: const EdgeInsets.only(top: 24),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userName,
style: const TextStyle(
color: Color(0xFF2D3748),
fontSize: 18,
fontWeight: FontWeight.bold,
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Profile Header
Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(
context,
).colorScheme.primary.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(24),
),
const SizedBox(height: 2),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
child: const Icon(
Icons.school,
color: Colors.white,
size: 24,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userName,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
userEmail,
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),
if (userEmail.length > 20) ...[
const SizedBox(width: 8),
Icon(
Icons.more_horiz,
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
size: 16,
),
],
],
),
),
],
),
),
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.secondary.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(
Icons.settings,
color: Theme.of(context).colorScheme.secondary,
size: 20,
),
),
],
),
const SizedBox(height: 20),
// Quick Stats Row
Row(
children: [
_buildQuickStat(
icon: Icons.check_circle,
label: 'Alunos Ativos',
value: '18/24',
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(width: 12),
_buildQuickStat(
icon: Icons.warning_amber,
label: 'Precisam Apoio',
value: '3',
color: Theme.of(context).colorScheme.secondary,
),
const SizedBox(width: 12),
_buildQuickStat(
icon: Icons.emoji_events,
label: 'Média Turma',
value: '72%',
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.8),
),
],
),
const SizedBox(height: 20),
// Top Performing Students Preview
Row(
children: [
Icon(
Icons.leaderboard,
color: Theme.of(context).colorScheme.secondary,
size: 20,
),
const SizedBox(width: 8),
Text(
'Melhores Desempenhos',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
// Student List Preview
_buildStudentPerformanceItem(
context,
'Ana Silva',
95,
Theme.of(context).colorScheme.tertiary,
),
const SizedBox(height: 8),
_buildStudentPerformanceItem(
context,
'João Costa',
88,
Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 8),
_buildStudentPerformanceItem(
context,
'Maria Santos',
82,
Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 8),
_buildStudentPerformanceItem(
context,
'Pedro Lima',
45,
Theme.of(context).colorScheme.secondary,
),
const SizedBox(height: 20),
// Content Quality Alert
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Theme.of(
context,
).colorScheme.outline.withOpacity(0.2),
),
),
child: Row(
children: [
Icon(
Icons.info_outline,
color: Theme.of(context).colorScheme.primary,
size: 20,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userEmail,
style: const TextStyle(
color: Color(0xFF718096),
'Qualidade do Conteúdo',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
if (userEmail.length > 20) ...[
const SizedBox(width: 8),
const Icon(
Icons.more_horiz,
color: Color(0xFF718096),
size: 16,
const SizedBox(height: 2),
Text(
'12 conteúdos verificados • 2 pendentes de revisão',
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 12,
),
],
),
],
),
),
],
),
),
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));
)
.animate()
.slideY(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
)
.then(delay: const Duration(milliseconds: 400));
}
Widget _buildQuickStat({
@@ -245,10 +286,7 @@ class TeacherAnalyticsPreviewWidget extends StatelessWidget {
const SizedBox(height: 2),
Text(
label,
style: TextStyle(
color: color.withOpacity(0.8),
fontSize: 10,
),
style: TextStyle(color: color.withOpacity(0.8), fontSize: 10),
textAlign: TextAlign.center,
),
],
@@ -257,7 +295,12 @@ class TeacherAnalyticsPreviewWidget extends StatelessWidget {
);
}
Widget _buildStudentPerformanceItem(String name, int score, Color color) {
Widget _buildStudentPerformanceItem(
BuildContext context,
String name,
int score,
Color color,
) {
return Row(
children: [
Container(
@@ -282,8 +325,8 @@ class TeacherAnalyticsPreviewWidget extends StatelessWidget {
Expanded(
child: Text(
name,
style: const TextStyle(
color: Color(0xFF4A5568),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),

View File

@@ -24,11 +24,11 @@ class TeacherClassesListWidget extends StatelessWidget {
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
return Center(
child: Padding(
padding: EdgeInsets.all(16.0),
padding: const EdgeInsets.all(16.0),
child: CircularProgressIndicator(
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
),
),
);
@@ -46,7 +46,7 @@ class TeacherClassesListWidget extends StatelessWidget {
child: Text(
'Ainda não criaste nenhuma turma.',
style: TextStyle(
color: Colors.grey[600],
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),
@@ -59,9 +59,9 @@ class TeacherClassesListWidget extends StatelessWidget {
Text(
'As Minhas Turmas',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: const Color(0xFF2D3748),
fontWeight: FontWeight.bold,
),
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
SizedBox(
@@ -105,10 +105,8 @@ class TeacherClassesListWidget extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ClassStudentsPage(
classId: classId,
className: className,
),
builder: (_) =>
ClassStudentsPage(classId: classId, className: className),
),
);
},
@@ -117,11 +115,11 @@ class TeacherClassesListWidget extends StatelessWidget {
height: 150,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
@@ -134,20 +132,20 @@ class TeacherClassesListWidget extends StatelessWidget {
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFF82C9BD).withOpacity(0.1),
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
child: Icon(
Icons.school,
color: Color(0xFF82C9BD),
color: Theme.of(context).colorScheme.primary,
size: 24,
),
),
const SizedBox(height: 12),
Text(
className,
style: const TextStyle(
color: Color(0xFF2D3748),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
@@ -158,7 +156,7 @@ class TeacherClassesListWidget extends StatelessWidget {
Text(
'Código: $classCode',
style: TextStyle(
color: Colors.grey[600],
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 13,
),
),

View File

@@ -35,7 +35,7 @@ class TeacherHeroWidget extends StatelessWidget {
Text(
'Visão Geral da Turma',
style: TextStyle(
color: const Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontSize: 24,
fontWeight: FontWeight.bold,
),
@@ -44,7 +44,7 @@ class TeacherHeroWidget extends StatelessWidget {
Text(
'Acompanhe o progresso dos seus alunos',
style: TextStyle(
color: const Color(0xFF718096),
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 16,
),
),
@@ -52,19 +52,18 @@ class TeacherHeroWidget extends StatelessWidget {
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D),
color: Theme.of(context).colorScheme.secondary,
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.people,
color: Colors.white,
size: 16,
),
const Icon(Icons.people, color: Colors.white, size: 16),
const SizedBox(width: 4),
Text(
'$totalStudents alunos',
@@ -89,14 +88,14 @@ class TeacherHeroWidget extends StatelessWidget {
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF82C9BD),
const Color(0xFF6BA8A0),
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
color: Theme.of(context).colorScheme.shadow.withOpacity(0.1),
blurRadius: 20,
offset: const Offset(0, 10),
),
@@ -128,7 +127,7 @@ class TeacherHeroWidget extends StatelessWidget {
],
),
const SizedBox(height: 16),
// Progress Bar
Container(
height: 12,
@@ -182,64 +181,76 @@ class TeacherHeroWidget extends StatelessWidget {
// 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,
),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(
context,
).colorScheme.outline.withOpacity(0.2),
),
boxShadow: [
BoxShadow(
color: Theme.of(
context,
).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
const SizedBox(height: 12),
_buildActivityItem(
'15 alunos completaram o quiz de Derivadas',
'Hoje, 14:30',
const Color(0xFF82C9BD),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.trending_up,
color: Theme.of(context).colorScheme.secondary,
size: 20,
),
const SizedBox(width: 8),
Text(
'Atividade Recente',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
_buildActivityItem(
context,
'15 alunos completaram o quiz de Derivadas',
'Hoje, 14:30',
Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 8),
_buildActivityItem(
context,
'Novo conteúdo: Regra da Cadeia',
'Ontem, 09:15',
Theme.of(context).colorScheme.secondary,
),
const SizedBox(height: 8),
_buildActivityItem(
context,
'3 alunos precisam de apoio em Limites',
'Ontem, 16:45',
Theme.of(context).colorScheme.error,
),
],
),
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)),
)
.animate()
.slideX(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
)
.then(delay: const Duration(milliseconds: 200)),
],
),
);
@@ -255,10 +266,7 @@ class TeacherHeroWidget extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.white.withOpacity(0.3),
width: 1,
),
border: Border.all(color: Colors.white.withOpacity(0.3), width: 1),
),
child: Column(
children: [
@@ -275,10 +283,7 @@ class TeacherHeroWidget extends StatelessWidget {
const SizedBox(height: 4),
Text(
label,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
style: const TextStyle(color: Colors.white, fontSize: 12),
textAlign: TextAlign.center,
),
],
@@ -286,16 +291,18 @@ class TeacherHeroWidget extends StatelessWidget {
);
}
Widget _buildActivityItem(String text, String time, Color color) {
Widget _buildActivityItem(
BuildContext context,
String text,
String time,
Color color,
) {
return Row(
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
),
const SizedBox(width: 12),
Expanded(
@@ -304,16 +311,18 @@ class TeacherHeroWidget extends StatelessWidget {
children: [
Text(
text,
style: const TextStyle(
color: Color(0xFF4A5568),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),
const SizedBox(height: 2),
Text(
time,
style: const TextStyle(
color: Color(0xFF718096),
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant.withOpacity(0.7),
fontSize: 12,
),
),

View File

@@ -13,7 +13,8 @@ class TeacherQuickActionsWidget extends StatefulWidget {
const TeacherQuickActionsWidget({super.key});
@override
State<TeacherQuickActionsWidget> createState() => _TeacherQuickActionsWidgetState();
State<TeacherQuickActionsWidget> createState() =>
_TeacherQuickActionsWidgetState();
}
class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
@@ -22,463 +23,494 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
@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(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Upload Content Card (Primary)
Expanded(flex: 2, child: _buildUploadContentCard(context)),
const SizedBox(width: 16),
// Create Class Card
Expanded(flex: 2, child: _buildCreateClassCard(context)),
const SizedBox(width: 16),
// Create Quiz Card (Secondary)
Expanded(flex: 2, child: _buildCreateQuizCard(context)),
],
),
const SizedBox(height: 16),
Text(
'Ações Rápidas',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
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)),
// Primary Actions Row
Row(
children: [
// Upload Content Card (Primary)
Expanded(flex: 2, child: _buildUploadContentCard(context)),
const SizedBox(width: 16),
// Create Class Card
Expanded(flex: 2, child: _buildCreateClassCard(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));
)
.animate()
.slideY(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOut,
)
.then(delay: const Duration(milliseconds: 200));
}
Widget _buildUploadContentCard(BuildContext context) {
return Container(
constraints: const BoxConstraints(minHeight: 135, maxHeight: 160),
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: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const TeacherMaterialsPage(),
),
),
child: Padding(
padding: const EdgeInsets.all(14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.upload_file,
color: Colors.white,
size: 22,
),
),
const Spacer(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 3,
),
decoration: BoxDecoration(
color: const Color(0xFFF68D2D),
borderRadius: BorderRadius.circular(10),
),
child: const Text(
'NOVO',
style: TextStyle(
color: Colors.white,
fontSize: 9,
fontWeight: FontWeight.bold,
),
),
),
],
),
const Spacer(),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Upload Conteúdo',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
Text(
'PDFs, textos, imagens',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 12,
height: 1.2,
),
),
],
),
constraints: const BoxConstraints(minHeight: 135, maxHeight: 160),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.primary.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.primary.withOpacity(0.3),
blurRadius: 15,
offset: const Offset(0, 8),
),
],
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 100));
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (_) => const TeacherMaterialsPage()),
),
child: Padding(
padding: const EdgeInsets.all(14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.upload_file,
color: Colors.white,
size: 22,
),
),
const Spacer(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 3,
),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondary,
borderRadius: BorderRadius.circular(10),
),
child: const Text(
'NOVO',
style: TextStyle(
color: Colors.white,
fontSize: 9,
fontWeight: FontWeight.bold,
),
),
),
],
),
const Spacer(),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Upload Conteúdo',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
Text(
'PDFs, textos, imagens',
maxLines: 2,
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),
height: 150,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.shadow.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,
),
),
Column(
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: [
const Text(
'Criar Quiz',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.bold,
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.secondary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.quiz,
color: Theme.of(context).colorScheme.secondary,
size: 24,
),
),
const SizedBox(height: 4),
Text(
'Avaliações interativas',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: const Color(0xFF718096),
fontSize: 12,
height: 1.2,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Criar Quiz',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'Avaliações interativas',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 12,
height: 1.2,
),
),
],
),
],
),
],
),
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 200));
)
.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),
height: 120,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.shadow.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(
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: [
Text(
'Gerir Alunos',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 14,
fontWeight: FontWeight.bold,
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.people,
color: Theme.of(context).colorScheme.primary,
size: 20,
),
),
Text(
'Acesso e permissões',
style: TextStyle(
color: Color(0xFF718096),
fontSize: 11,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Gerir Alunos',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Text(
'Acesso e permissões',
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 11,
),
),
],
),
],
),
],
),
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 300));
)
.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),
height: 120,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.shadow.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(
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: [
Text(
'Analytics',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 14,
fontWeight: FontWeight.bold,
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.8),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.analytics,
color: Theme.of(context).colorScheme.primary,
size: 20,
),
),
Text(
'Desempenho da turma',
style: TextStyle(
color: Color(0xFF718096),
fontSize: 11,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Analytics',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Text(
'Desempenho da turma',
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 11,
),
),
],
),
],
),
],
),
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 400));
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 400));
}
Widget _buildCreateClassCard(BuildContext context) {
return Container(
constraints: const BoxConstraints(minHeight: 135, maxHeight: 160),
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),
constraints: const BoxConstraints(minHeight: 135, maxHeight: 160),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
width: 1,
),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.shadow.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: _isCreatingClass ? null : () => _showCreateClassDialog(context),
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(0xFF82C9BD).withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: _isCreatingClass
? const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Color(0xFF82C9BD),
),
)
: const Icon(
Icons.school,
color: Color(0xFF82C9BD),
size: 24,
),
),
Column(
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: _isCreatingClass
? null
: () => _showCreateClassDialog(context),
child: Padding(
padding: const EdgeInsets.all(14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Criar Turma',
style: TextStyle(
color: const Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.bold,
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: _isCreatingClass
? SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Theme.of(context).colorScheme.primary,
),
)
: Icon(
Icons.school,
color: Theme.of(context).colorScheme.primary,
size: 24,
),
),
const SizedBox(height: 4),
Text(
'Gerar código de acesso',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: const Color(0xFF718096),
fontSize: 12,
height: 1.2,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Criar Turma',
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
'Gerar código de acesso',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 12,
height: 1.2,
),
),
],
),
],
),
],
),
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 150));
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 150));
}
void _showCreateClassDialog(BuildContext context) {
@@ -491,10 +523,10 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
title: const Text(
title: Text(
'Criar Nova Turma',
style: TextStyle(
color: Color(0xFF2D3748),
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold,
),
),
@@ -502,10 +534,10 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
Text(
'Digite o nome da turma:',
style: TextStyle(
color: Color(0xFF718096),
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontSize: 14,
),
),
@@ -515,7 +547,9 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
decoration: InputDecoration(
hintText: 'Ex: Matemática 9º Ano',
filled: true,
fillColor: const Color(0xFFF7FAFC),
fillColor: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
@@ -526,8 +560,8 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(
color: Color(0xFF82C9BD),
borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 2,
),
),
@@ -538,9 +572,11 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
actions: [
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(),
child: const Text(
child: Text(
'Cancelar',
style: TextStyle(color: Color(0xFF718096)),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
ElevatedButton(
@@ -552,7 +588,7 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
}
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF82C9BD),
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
@@ -601,8 +637,10 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Turma "$className" criada com sucesso! Código: $classCode'),
backgroundColor: const Color(0xFF82C9BD),
content: Text(
'Turma "$className" criada com sucesso! Código: $classCode',
),
backgroundColor: Theme.of(context).colorScheme.primary,
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),