validação entre professor e aluno, criação de placeholder para a tela de professores e mudanças na firebase

This commit is contained in:
2026-05-08 16:37:36 +01:00
parent c821ce8e1e
commit 1b7b03034d
6 changed files with 461 additions and 73 deletions

View File

@@ -1,292 +1,590 @@
# 📊 Project Progress - AI Study Assistant
---
## 🎯 OVERVIEW
This document tracks the overall progress of the AI Study Assistant project development. Updated in real-time as features are implemented.
---
## 📈 CURRENT STATUS
### **Overall Progress: 65% Complete**
-**Foundation:** 100% Complete
-**UI/UX:** 90% Complete
-**Internationalization:** 100% Complete
-**Authentication:** 20% Complete
-**Core Features:** 0% Complete
-**Backend Integration:** 0% Complete
---
## ✅ COMPLETED FEATURES
### **🏗️ Project Foundation (100%)**
- [x] Flutter project structure setup
- [x] Core theme and color system
- [x] Navigation system (GoRouter)
- [x] Asset management
- [x] Development environment configuration
### **🎨 UI/UX Components (90%)**
### **🎨 UI/UX Components (95%)**
- [x] Splash screen with animations
- [x] Login page with improved design
- [x] Role selection page (student/teacher)
- [x] Dynamic background effects
- [x] Responsive animations
- [x] Dark/light theme support
- [ ] Signup page (needs update)
- [ ] Dashboard pages (placeholder)
- [x] Dashboard pages (fixed overflow issue)
### **🌍 Internationalization (100%)**
- [x] Portuguese (Portugal) as primary language
- [x] English fallback support
- [x] Localization system setup
- [x] All UI text localized
- [x] Language policy documentation
### **🔧 Development Setup (100%)**
- [x] Flutter SDK configuration
- [x] Device deployment (Samsung S928B)
- [x] Hot reload functionality
- [x] Debug tools setup
- [x] Code structure standards
---
## 🚧 IN PROGRESS
### **📱 Authentication System (20%)**
- [x] Login UI implementation
- [x] Form validation
- [x] Navigation flow
- [ ] Firebase integration
- [ ] Real authentication logic
- [ ] Token management
- [ ] Session persistence
### **📝 Signup Page (0%)**
- [ ] Update signup page design
- [ ] Portuguese localization
- [ ] Improved animations
- [ ] Form validation
- [ ] Role-based signup
- [ ] Terms and conditions
---
## ⏳ PENDING FEATURES
### **🤖 AI Tutor System (0%)**
- [ ] Chat interface design
- [ ] AI integration setup
- [ ] Message handling
- [ ] Response formatting
- [ ] Conversation history
- [ ] Voice input support
### **📝 Quiz System (0%)**
- [ ] Quiz creation interface
- [ ] Question types implementation
- [ ] Scoring system
- [ ] Progress tracking
- [ ] Results display
- [ ] Quiz categories
### **📊 Dashboard System (0%)**
- [ ] Student dashboard
- [ ] Teacher dashboard
- [ ] Analytics display
- [ ] Progress charts
- [ ] Performance metrics
- [ ] Quick actions
### **🔍 RAG Engine (0%)**
- [ ] Vector database setup
- [ ] Document processing
- [ ] Search implementation
- [ ] Context retrieval
- [ ] Answer generation
- [ ] Performance optimization
### **📈 Analytics System (0%)**
- [ ] Learning progress tracking
- [ ] Usage statistics
- [ ] Performance metrics
- [ ] Export functionality
- [ ] Reporting dashboard
- [ ] Data visualization
---
## 🎯 CURRENT SPRINT
### **Sprint 3: Authentication & Signup (In Progress)**
**Duration:** Current Week
**Goal:** Complete authentication flow
#### **Tasks:**
- [x] Fix login page design issues
- [x] Improve animations and background
- [x] Update language policy documentation
- [ ] Update signup page with Portuguese
- [ ] Implement Firebase authentication
- [ ] Add role-based routing
#### **Progress:** 60% Complete
---
## 📅 RELEASE ROADMAP
### **Version 1.0 - MVP (Target: 2 Weeks)**
- ✅ Basic UI/UX
- ✅ Internationalization
- ✅ Navigation flow
- ⏳ Complete authentication
- ⏳ Basic dashboard
- ⏳ Simple quiz system
### **Version 1.1 - Enhanced Features (Target: 4 Weeks)**
- ⏳ AI tutor integration
- ⏳ Advanced quiz features
- ⏳ Analytics dashboard
- ⏳ Performance improvements
### **Version 2.0 - Full Platform (Target: 8 Weeks)**
- ⏳ Complete RAG engine
- ⏳ Advanced analytics
- ⏳ Teacher tools
- ⏳ Content management
- ⏳ Mobile optimizations
---
## 🐛 KNOWN ISSUES
### **Critical Issues (0)**
- None currently
### **Minor Issues (1)**
- [ ] Signup page needs design update
- [ ] Some animations could be optimized
### **Technical Debt (2)**
- [ ] Add comprehensive error handling
- [ ] Implement proper logging system
- [ ] Add unit tests
- [ ] Optimize bundle size
---
## 📊 METRICS
### **Development Metrics:**
- **Total Files:** 45+ Dart files
- **Lines of Code:** ~3,000+ lines
- **Dependencies:** 25+ packages
- **Build Time:** ~15 seconds
- **App Size:** ~25MB (debug)
### **Quality Metrics:**
- **Code Coverage:** 0% (needs testing)
- **Lint Issues:** 0 critical
- **Performance:** Good
- **Accessibility:** Partially compliant
---
## 🔄 RECENT CHANGES
### **Last 24 Hours:**
- ✅ Fixed dashboard overflow issue in QuickAccessWidget
- ✅ Implemented responsive layout with IntrinsicHeight and Flexible
- ✅ Replaced fixed heights with constraints (minHeight: 135, maxHeight: 160)
- ✅ Fixed login page animations
- ✅ Added dynamic background effects
- ✅ Updated language policy
- ✅ Improved text visibility
- ✅ Created progress documentation
### **Last Week:**
- ✅ Implemented role selection page
- ✅ Added Portuguese localization
- ✅ Fixed navigation flow
- ✅ Improved splash screen
- ✅ Setup internationalization
---
## 🎯 NEXT PRIORITIES
### **Immediate (This Week):**
1. **Update signup page** with Portuguese and improved design
2. **Implement Firebase authentication** for real login
3. **Add role-based routing** after login
4. **Create basic dashboard** placeholder
### **Short Term (Next 2 Weeks):**
1. **Complete authentication system**
2. **Build student dashboard**
3. **Implement basic quiz system**
4. **Add analytics tracking**
### **Medium Term (Next Month):**
1. **Integrate AI tutor**
2. **Build teacher dashboard**
3. **Implement RAG engine**
4. **Add comprehensive testing**
---
## 📱 DEVICE COMPATIBILITY
### **Tested Devices:**
-**Samsung S928B (Android 16)** - Primary testing device
-**Windows Desktop** - Development environment
-**Chrome Browser** - Web testing
-**iOS Devices** - Pending testing
-**Other Android** - Pending testing
### **Performance:**
- **Startup Time:** ~3 seconds
- **Navigation Speed:** Fast
- **Animation Performance:** Smooth (60fps)
- **Memory Usage:** ~150MB
---
## 🎉 ACHIEVEMENTS
### **Milestones Reached:**
-**Project Kickoff** - Complete
-**UI/UX Foundation** - Complete
-**Internationalization** - Complete
-**Device Deployment** - Complete
-**User Testing Ready** - Complete
### **Technical Achievements:**
- ✅ Successfully deployed to Samsung device
- ✅ Implemented complex animations
- ✅ Created scalable architecture
- ✅ Established development workflow
- ✅ Set up quality standards
---
## 📞 TEAM STATUS
### **Current Team:**
- **Developer:** Active
- **Testing:** In Progress
- **Documentation:** Up to Date
- **Quality Assurance:** Active
---
**📊 Last Updated: 2024-05-06 21:43**
**🔄 Auto-Update: Enabled**
**📈 Progress Tracking: Real-time**
---
*This document is automatically updated as development progresses. Check back regularly for the latest status.*

View File

@@ -54,13 +54,19 @@ class AppRouter {
GoRoute(
path: login,
name: 'login',
builder: (context, state) => const LoginPage(),
builder: (context, state) {
final selectedRole = state.uri.queryParameters['role'];
return LoginPage(selectedRole: selectedRole);
},
),
GoRoute(
path: signup,
name: 'signup',
builder: (context, state) => const SignupPage(),
builder: (context, state) {
final selectedRole = state.uri.queryParameters['role'];
return SignupPage(selectedRole: selectedRole);
},
),
// Dashboard Routes

View File

@@ -1,15 +1,50 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'session_service.dart';
/// Service for handling Firebase Authentication
class AuthService {
static final FirebaseAuth _auth = FirebaseAuth.instance;
static final FirebaseFirestore _firestore = FirebaseFirestore.instance;
/// Get current user
static User? get currentUser {
return _auth.currentUser;
}
/// Criar documento do usuário na Firestore após signup
static Future<void> createUserRole(String uid, String role) async {
try {
print('DEBUG: Criando documento users/$uid com role: $role');
await _firestore.collection('users').doc(uid).set({
'role': role,
'createdAt': FieldValue.serverTimestamp(),
});
print('DEBUG: Documento criado com sucesso');
} catch (e) {
print('DEBUG: Erro ao criar documento: $e');
throw Exception('Erro ao criar perfil do usuário');
}
}
/// Ler role do usuário na Firestore
static Future<String?> getUserRole(String uid) async {
try {
print('DEBUG: Lendo documento users/$uid');
final doc = await _firestore.collection('users').doc(uid).get();
if (doc.exists) {
final role = doc.data()?['role'] as String?;
print('DEBUG: Role encontrado: $role');
return role;
}
print('DEBUG: Documento não existe');
return null;
} catch (e) {
print('DEBUG: Erro ao ler documento: $e');
return null;
}
}
/// Get auth state changes stream
static Stream<User?> get authStateChanges {
return _auth.authStateChanges();
@@ -41,10 +76,9 @@ class AuthService {
print('DEBUG: Display name atualizado para: $displayName');
}
// Store user role in custom claims or Firestore (simplified for now)
if (role != null) {
print('DEBUG: Papel do usuário: $role');
// TODO: Store role in Firestore for future use
// Criar documento na Firestore com role
if (role != null && result.user != null) {
await createUserRole(result.user!.uid, role);
}
// Verificar se o email foi verificado

View File

@@ -7,7 +7,9 @@ import '../../../../core/services/session_service.dart';
import '../../../../shared/presentation/widgets/custom_notification.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
final String? selectedRole;
const LoginPage({super.key, this.selectedRole});
@override
State<LoginPage> createState() => _LoginPageState();
@@ -62,12 +64,41 @@ class _LoginPageState extends State<LoginPage> {
print('DEBUG: Iniciando processo de login para: $email');
// Attempt login with Firebase
await AuthService.signInWithEmailAndPassword(
final result = await AuthService.signInWithEmailAndPassword(
email: email,
password: password,
);
print('DEBUG: Login Firebase bem-sucedido, salvando sessão');
print('DEBUG: Login Firebase bem-sucedido');
print('DEBUG: Role selecionado na tela anterior: ${widget.selectedRole}');
// Ler role na Firestore
final uid = result?.user?.uid;
if (uid == null) throw Exception('Erro ao obter UID');
final actualRole = await AuthService.getUserRole(uid);
print('DEBUG: Role real do usuário na Firestore: $actualRole');
// Validar se o role selecionado corresponde ao role real
final selectedRole = widget.selectedRole;
if (selectedRole != null && actualRole != null && selectedRole != actualRole) {
// Role não corresponde - mostrar erro
setState(() {
_isLoading = false;
});
String errorMessage;
if (selectedRole == 'teacher' && actualRole == 'student') {
errorMessage = 'Este email está registado como Aluno. Não pode aceder à área de Professores.';
} else if (selectedRole == 'student' && actualRole == 'teacher') {
errorMessage = 'Este email está registado como Professor. Não pode aceder à área de Alunos.';
} else {
errorMessage = 'O tipo de utilizador selecionado não corresponde ao perfil registado.';
}
_showRoleErrorDialog('Acesso Negado', errorMessage);
return;
}
// Save session based on remember me preference
await SessionService.saveSession(
@@ -76,9 +107,6 @@ class _LoginPageState extends State<LoginPage> {
displayName: AuthService.currentUser?.displayName,
);
print('DEBUG: Sessão salva, navegando para dashboard');
// Navigate to student dashboard after successful login
if (mounted) {
setState(() {
_isLoading = false;
@@ -90,8 +118,13 @@ class _LoginPageState extends State<LoginPage> {
message: 'Login realizado com sucesso!',
);
// Redirecionar baseado no role real
if (actualRole == 'teacher') {
context.go('/teacher-dashboard');
} else {
context.go('/student-dashboard');
}
}
} catch (e) {
print('DEBUG: Erro no login: $e');
@@ -110,6 +143,41 @@ class _LoginPageState extends State<LoginPage> {
}
}
void _showRoleErrorDialog(String title, String message) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
title,
style: const TextStyle(
color: Color(0xFF2D3748),
fontWeight: FontWeight.bold,
),
),
content: Text(
message,
style: const TextStyle(color: Color(0xFF2D3748)),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
// Fazer logout para limpar a sessão
AuthService.signOut();
},
child: const Text(
'Voltar',
style: TextStyle(color: Color(0xFF82C9BD)),
),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(

View File

@@ -278,6 +278,28 @@ class _RoleSelectionPageState extends State<RoleSelectionPage> {
),
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),
],
),
),
@@ -288,6 +310,12 @@ class _RoleSelectionPageState extends State<RoleSelectionPage> {
);
}
void _handleGoToLogin() {
if (_selectedRole != null) {
context.go('/login?role=$_selectedRole');
}
}
Widget _buildRoleCard(
BuildContext context,
String title,

View File

@@ -6,7 +6,9 @@ import '../../../../core/services/auth_service.dart';
import '../../../../shared/presentation/widgets/custom_notification.dart';
class SignupPage extends StatefulWidget {
const SignupPage({super.key});
final String? selectedRole;
const SignupPage({super.key, this.selectedRole});
@override
State<SignupPage> createState() => _SignupPageState();
@@ -19,7 +21,14 @@ class _SignupPageState extends State<SignupPage> {
final _passwordController = TextEditingController();
bool _isLoading = false;
bool _obscurePassword = true;
String _selectedRole = 'student'; // 'student' or 'teacher'
late String _selectedRole;
@override
void initState() {
super.initState();
// Usar role passado da tela anterior ou default 'student'
_selectedRole = widget.selectedRole ?? 'student';
}
@override
void dispose() {
@@ -338,61 +347,6 @@ class _SignupPageState extends State<SignupPage> {
return null;
},
),
const SizedBox(height: 16),
// Role selection
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Eu sou:',
style: TextStyle(
color: Color(0xFF2D3748),
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: RadioListTile<String>(
title: const Text(
'Aluno',
style: TextStyle(fontSize: 14),
),
value: 'student',
groupValue: _selectedRole,
onChanged: (String? value) {
setState(() {
_selectedRole = value!;
});
},
activeColor: const Color(0xFF82C9BD),
contentPadding: EdgeInsets.zero,
),
),
Expanded(
child: RadioListTile<String>(
title: const Text(
'Professor',
style: TextStyle(fontSize: 14),
),
value: 'teacher',
groupValue: _selectedRole,
onChanged: (String? value) {
setState(() {
_selectedRole = value!;
});
},
activeColor: const Color(0xFF82C9BD),
contentPadding: EdgeInsets.zero,
),
),
],
),
],
),
const SizedBox(height: 24),
// Signup button
@@ -434,7 +388,7 @@ class _SignupPageState extends State<SignupPage> {
// Login link
GestureDetector(
onTap: () {
context.go('/login');
context.go('/login?role=$_selectedRole');
},
child: Text(
'Já tem conta? Entrar aqui',