Melhoria no funcionamento do histórico, Os nomes no dashboard do aluno carregam a primeira vez e ficam salvos para n ficarem sempre a carregar quando se volta ao dashboard, removi o butão de novo chat na interface de introdução da IA, mudei a aparencia dessa introdução e do histórico

This commit is contained in:
2026-05-23 16:20:27 +01:00
parent 7ee262f4c7
commit 895ce64c6f
22 changed files with 1330 additions and 582 deletions

View File

@@ -11,6 +11,14 @@ import '../widgets/profile_section_widget.dart';
class StudentDashboardPage extends StatefulWidget {
const StudentDashboardPage({super.key});
/// Clear the cached user name (call when name is updated in settings)
static void clearCachedUserName() {
_cachedUserName = null;
}
/// Cached user name to prevent flickering
static String? _cachedUserName;
@override
State<StudentDashboardPage> createState() => _StudentDashboardPageState();
}
@@ -21,7 +29,12 @@ class _StudentDashboardPageState extends State<StudentDashboardPage> {
@override
void initState() {
super.initState();
_checkRoleAndLoadData();
// Use cached name if available, otherwise load data
if (StudentDashboardPage._cachedUserName != null) {
_userName = StudentDashboardPage._cachedUserName!;
} else {
_checkRoleAndLoadData();
}
}
Future<void> _checkRoleAndLoadData() async {
@@ -75,6 +88,7 @@ class _StudentDashboardPageState extends State<StudentDashboardPage> {
print('DEBUG: Final displayName to use: "$displayName"');
setState(() {
_userName = displayName;
StudentDashboardPage._cachedUserName = displayName;
});
}
}
@@ -99,14 +113,21 @@ class _StudentDashboardPageState extends State<StudentDashboardPage> {
),
),
child: SafeArea(
top: false,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(24.0),
padding: const EdgeInsets.only(
left: 24.0,
right: 24.0,
bottom: 28.0,
top: 52.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header with logout and settings
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(

View File

@@ -94,14 +94,21 @@ class _TeacherDashboardPageState extends State<TeacherDashboardPage> {
),
),
child: SafeArea(
top: false,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(24.0),
padding: const EdgeInsets.only(
left: 24.0,
right: 24.0,
bottom: 28.0,
top: 52.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header with logout and settings
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(

View File

@@ -17,12 +17,22 @@ class ProgressHeroWidget extends StatefulWidget {
}
class _ProgressHeroWidgetState extends State<ProgressHeroWidget> {
UserStats? _cachedUserStats;
bool _isFirstLoad = true;
@override
Widget build(BuildContext context) {
return FutureBuilder<UserStats?>(
future: _loadUserStats(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// Show cached data while loading to prevent flickering
if (snapshot.connectionState == ConnectionState.waiting &&
_cachedUserStats != null) {
return _buildContent(_cachedUserStats);
}
if (snapshot.connectionState == ConnectionState.waiting &&
_isFirstLoad) {
return _buildLoadingState();
}
@@ -31,6 +41,10 @@ class _ProgressHeroWidgetState extends State<ProgressHeroWidget> {
}
final userStats = snapshot.data;
if (userStats != null) {
_cachedUserStats = userStats;
_isFirstLoad = false;
}
return _buildContent(userStats);
},
);

View File

@@ -107,6 +107,21 @@ class QuickAccessWidget extends StatelessWidget {
titleFontSize: _titleFontSize,
subtitleFontSize: _subtitleFontSize,
padding: _cardPadding,
leadingIcon: Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: const Color(0xFFF9EEE8),
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Image.asset(
'assets/images/epvc.png',
fit: BoxFit.contain,
),
),
),
onTap: () => context.go('/ai-tutor'),
)
.animate()
@@ -227,6 +242,7 @@ class QuickAccessWidget extends StatelessWidget {
subtitle: 'Assistente de estudos',
icon: Icons.psychology,
useGradient: true,
useCustomIcon: true,
onTap: () {
Navigator.pop(context);
context.go('/ai-tutor');
@@ -330,29 +346,47 @@ class QuickAccessWidget extends StatelessWidget {
),
),
child: ListTile(
leading: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: item.useGradient
? Theme.of(
context,
).colorScheme.primary.withOpacity(0.1)
: (item.iconColor ??
Theme.of(
context,
).colorScheme.secondary)
.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
item.icon,
color: item.useGradient
? Theme.of(context).colorScheme.primary
: (item.iconColor ??
Theme.of(context).colorScheme.secondary),
size: 24,
),
),
leading: item.useCustomIcon
? Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: const Color(0xFFF9EEE8),
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Image.asset(
'assets/images/epvc.png',
fit: BoxFit.contain,
),
),
)
: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: item.useGradient
? Theme.of(
context,
).colorScheme.primary.withOpacity(0.1)
: (item.iconColor ??
Theme.of(
context,
).colorScheme.secondary)
.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
item.icon,
color: item.useGradient
? Theme.of(context).colorScheme.primary
: (item.iconColor ??
Theme.of(
context,
).colorScheme.secondary),
size: 24,
),
),
title: Text(
item.title,
style: TextStyle(
@@ -395,6 +429,7 @@ class _QuickAccessItem {
final IconData icon;
final bool useGradient;
final Color? iconColor;
final bool useCustomIcon;
final VoidCallback onTap;
_QuickAccessItem({
@@ -403,6 +438,7 @@ class _QuickAccessItem {
required this.icon,
this.useGradient = false,
this.iconColor,
this.useCustomIcon = false,
required this.onTap,
});
}