Modificação nos modos, correção de textos cortados

This commit is contained in:
2026-05-17 14:02:42 +01:00
parent 14509c04d3
commit 51ea446ae9
24 changed files with 906 additions and 933 deletions

View File

@@ -7,6 +7,7 @@ import 'package:go_router/go_router.dart';
import '../../../../core/services/auth_service.dart';
import '../../../../features/materials/presentation/pages/teacher_materials_page.dart';
import 'dashboard_action_card.dart';
/// Quick access cards for teacher actions
class TeacherQuickActionsWidget extends StatefulWidget {
@@ -20,8 +21,25 @@ class TeacherQuickActionsWidget extends StatefulWidget {
class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
bool _isCreatingClass = false;
/// Mesmas dimensões dos cards em "As Minhas Turmas".
static const double _scrollCardWidth = 200;
static const double _scrollRowHeight = 150;
static const double _cardMinHeight = 150;
static const EdgeInsets _cardPadding = EdgeInsets.all(16);
static const double _titleFontSize = 16;
static const double _subtitleFontSize = 13;
static const double _iconSize = 24;
static const double _iconPadding = 10;
@override
Widget build(BuildContext context) {
final cards = [
_buildUploadContentCard(context),
_buildCreateClassCard(context),
_buildCreateQuizCard(context),
_buildViewAnalyticsCard(context),
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -33,29 +51,20 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
// 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: [
// View Analytics Card
Expanded(child: _buildViewAnalyticsCard(context)),
],
const SizedBox(height: 12),
SizedBox(
height: _scrollRowHeight,
child: ListView.separated(
scrollDirection: Axis.horizontal,
clipBehavior: Clip.none,
padding: const EdgeInsets.only(right: 16),
itemCount: cards.length,
separatorBuilder: (_, __) => const SizedBox(width: 12),
itemBuilder: (context, index) => SizedBox(
width: _scrollCardWidth,
child: cards[index],
),
),
),
],
)
@@ -70,284 +79,77 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
Widget _buildUploadContentCard(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child:
Container(
height: 150,
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),
),
],
),
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(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
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: 20,
),
),
const Spacer(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
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,
),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: const [
Text(
'Upload Conteúdo',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 2),
Text(
'PDFs, textos, imagens',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 11,
),
),
],
),
],
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 100)),
child: DashboardActionCard(
title: 'Upload Conteúdo',
subtitle: 'PDFs, textos, imagens',
icon: Icons.upload_file,
useGradient: true,
minHeight: _cardMinHeight,
iconSize: _iconSize,
iconPadding: _iconPadding,
titleFontSize: _titleFontSize,
subtitleFontSize: _subtitleFontSize,
padding: _cardPadding,
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const TeacherMaterialsPage(),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 100)),
);
}
Widget _buildCreateQuizCard(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child:
Container(
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(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.all(8),
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: 20,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Criar Quiz',
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
Text(
'Avaliações interativas',
maxLines: 1,
overflow: TextOverflow.ellipsis,
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: 200)),
child: DashboardActionCardSurface(
title: 'Criar Quiz',
subtitle: 'Avaliações interativas',
icon: Icons.quiz,
minHeight: _cardMinHeight,
titleFontSize: _titleFontSize,
subtitleFontSize: _subtitleFontSize,
iconSize: _iconSize,
padding: _cardPadding,
onTap: () => context.go('/teacher/quiz/create'),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 200)),
);
}
Widget _buildViewAnalyticsCard(BuildContext context) {
return Container(
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: Theme.of(
context,
).colorScheme.primary.withOpacity(0.8),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.analytics,
color: Theme.of(context).colorScheme.primary,
size: 20,
),
),
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,
),
),
],
),
],
),
),
final cs = Theme.of(context).colorScheme;
return DashboardActionCardSurface(
title: 'Analytics',
subtitle: 'Desempenho da turma',
icon: Icons.analytics,
minHeight: _cardMinHeight,
titleFontSize: _titleFontSize,
subtitleFontSize: _subtitleFontSize,
iconSize: _iconSize,
padding: _cardPadding,
iconColor: cs.primary,
leadingWidget: Container(
padding: const EdgeInsets.all(_iconPadding),
decoration: BoxDecoration(
color: cs.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(Icons.analytics, color: cs.primary, size: _iconSize),
),
onTap: () => context.go('/teacher/analytics'),
)
.animate()
.scale(
@@ -358,110 +160,45 @@ class _TeacherQuickActionsWidgetState extends State<TeacherQuickActionsWidget> {
}
Widget _buildCreateClassCard(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return ClipRRect(
borderRadius: BorderRadius.circular(16),
child:
Container(
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: _isCreatingClass
? null
: () => _showCreateClassDialog(context),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(
context,
).colorScheme.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: _isCreatingClass
? SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Theme.of(
context,
).colorScheme.primary,
),
)
: Icon(
Icons.school,
color: Theme.of(
context,
).colorScheme.primary,
size: 20,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Criar Turma',
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
Text(
'Gerar código de acesso',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurfaceVariant,
fontSize: 11,
),
),
],
),
],
child: DashboardActionCardSurface(
title: 'Criar Turma',
subtitle: 'Gerar código de acesso',
icon: Icons.school,
minHeight: _cardMinHeight,
titleFontSize: _titleFontSize,
subtitleFontSize: _subtitleFontSize,
iconSize: _iconSize,
padding: _cardPadding,
iconColor: cs.primary,
onTapDisabled: _isCreatingClass,
onTap: () => _showCreateClassDialog(context),
leadingWidget: Container(
padding: const EdgeInsets.all(_iconPadding),
decoration: BoxDecoration(
color: cs.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: _isCreatingClass
? SizedBox(
width: _iconSize,
height: _iconSize,
child: CircularProgressIndicator(
strokeWidth: 2,
color: cs.primary,
),
),
),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 150)),
)
: Icon(Icons.school, color: cs.primary, size: _iconSize),
),
)
.animate()
.scale(
duration: const Duration(milliseconds: 600),
curve: Curves.elasticOut,
)
.then(delay: const Duration(milliseconds: 150)),
);
}