Fix student grade registration: set grade_10 as default, add auto-heal for legacy tawjihi_2008, add student grade selector and update-grade API

This commit is contained in:
Hamza-Ayed
2026-09-09 01:06:35 +03:00
parent 8183e53b86
commit 0a2ca71cb4
13 changed files with 440 additions and 41 deletions
@@ -207,16 +207,16 @@ class _SubjectsGridScreenState extends State<SubjectsGridScreen> {
child: const Icon(CupertinoIcons.lock_shield_fill, color: AppColors.saqelCyan, size: 18),
),
const SizedBox(width: 12),
const Expanded(
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'الصف العاشر الأساسي — المسار الأكاديمي المعتمد',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 13.5),
'${GradeLevelModel.getGradeName(state.selectedGrade)} — المسار الأكاديمي المعتمد',
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w800, fontSize: 13.5),
),
SizedBox(height: 2),
Text(
const SizedBox(height: 2),
const Text(
'خطة دراسية موحدة ومطابقة للمنهاج الوزاري الأردني المطور',
style: TextStyle(color: AppColors.textSecondaryDark, fontSize: 11),
),
@@ -13,6 +13,7 @@ import '../../widgets/luxury_widgets.dart';
import '../curriculum/subjects_grid_screen.dart';
import '../notebook/smart_error_notebook_screen.dart';
import '../vocational/vocational_training_screen.dart';
import '../../../data/repositories/curriculum_repository.dart';
class UnifiedHomeScreen extends StatefulWidget {
final UserModel user;
@@ -38,6 +39,14 @@ class _UnifiedHomeScreenState extends State<UnifiedHomeScreen> {
_refreshData();
}
@override
void didUpdateWidget(covariant UnifiedHomeScreen oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.user.gradeLevel != widget.user.gradeLevel || oldWidget.user.stream != widget.user.stream) {
_refreshData();
}
}
void _refreshData() {
if (_currentRole == 'student') {
context.read<StudentCubit>().fetchLessons(
@@ -57,6 +66,157 @@ class _UnifiedHomeScreenState extends State<UnifiedHomeScreen> {
_refreshData();
}
void _showGradeSelectionModal(BuildContext context) {
String tempGrade = widget.user.gradeLevel ?? 'grade_10';
if (tempGrade == 'tawjihi_2008') tempGrade = 'grade_10';
String tempStream = widget.user.stream ?? 'scientific';
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
isScrollControlled: true,
builder: (ctx) {
return StatefulBuilder(
builder: (context, setModalState) {
return Container(
padding: const EdgeInsets.all(24),
decoration: const BoxDecoration(
color: AppColors.darkSurface,
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
border: Border(top: BorderSide(color: AppColors.darkCardBorder, width: 1.5)),
),
child: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Center(
child: Container(
width: 44,
height: 5,
decoration: BoxDecoration(
color: Colors.white24,
borderRadius: BorderRadius.circular(3),
),
),
),
const SizedBox(height: 20),
Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: AppColors.saqelCyan.withAlpha(30),
borderRadius: BorderRadius.circular(14),
),
child: const Icon(CupertinoIcons.book_fill, color: AppColors.saqelCyan, size: 24),
),
const SizedBox(width: 14),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'تحديد وتعديل الصف الدراسي 🎓',
style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w800),
),
SizedBox(height: 3),
Text(
'اختر صفك لفتح المناهج الوزارية والشروحات المعتمدة',
style: TextStyle(color: AppColors.textSecondaryDark, fontSize: 12),
),
],
),
),
],
),
const SizedBox(height: 20),
...[
('grade_10', 'الصف العاشر الأساسي (Grade 10)', 'يشمل الرياضيات المطور، الفيزياء، والإنجليزية'),
('grade_11', 'الصف الحادي عشر (الأول ثانوي)', 'المسار الأكاديمي للفرعين العلمي والأدبي'),
('grade_12', 'الصف الثاني عشر (التوجيهي الوزاري)', 'منهاج الثانوية العامة التوجيهي الوزاري'),
].map((g) {
final isSelected = tempGrade == g.$1;
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: InkWell(
onTap: () {
setModalState(() {
tempGrade = g.$1;
if (tempGrade == 'grade_10') tempStream = 'general';
});
},
borderRadius: BorderRadius.circular(16),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: isSelected ? AppColors.saqelCyan.withAlpha(25) : AppColors.darkBackground,
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: isSelected ? AppColors.saqelCyan : AppColors.darkCardBorder,
width: isSelected ? 1.5 : 1.0,
),
),
child: Row(
children: [
Icon(
isSelected ? CupertinoIcons.checkmark_circle_fill : CupertinoIcons.circle,
color: isSelected ? AppColors.saqelCyan : AppColors.textMutedDark,
size: 20,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
g.$2,
style: TextStyle(
color: isSelected ? Colors.white : AppColors.textSecondaryDark,
fontWeight: isSelected ? FontWeight.w800 : FontWeight.w600,
fontSize: 14,
),
),
const SizedBox(height: 2),
Text(
g.$3,
style: const TextStyle(color: AppColors.textMutedDark, fontSize: 11),
),
],
),
),
],
),
),
),
);
}),
const SizedBox(height: 16),
LuxuryButton(
text: 'حفظ الصف وتحديث المسار 🚀',
onPressed: () async {
Navigator.of(ctx).pop();
await context.read<AuthCubit>().updateGrade(tempGrade, stream: tempStream);
if (mounted) {
_refreshData();
SaqelToast.showSuccess(
context,
'تم ضبط صفك بنجاح: ${GradeLevelModel.getGradeName(tempGrade)}',
title: 'تحديث المسار الدراسي ✨',
);
}
},
),
],
),
),
);
},
);
},
);
}
@override
Widget build(BuildContext context) {
final isStudent = _currentRole == 'student';
@@ -129,10 +289,39 @@ class _UnifiedHomeScreenState extends State<UnifiedHomeScreen> {
widget.user.name,
style: AppTypography.titleMedium.copyWith(color: Colors.white),
),
Text(
isStudent ? AppStrings.studentPortal : AppStrings.guardianPortal,
style: AppTypography.labelSmall.copyWith(color: AppColors.textMutedDark),
),
const SizedBox(height: 3),
if (isStudent)
GestureDetector(
onTap: () => _showGradeSelectionModal(context),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: AppColors.saqelCyan.withAlpha(30),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColors.saqelCyan.withAlpha(80), width: 0.8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
GradeLevelModel.getGradeName(widget.user.gradeLevel ?? 'grade_10'),
style: const TextStyle(
color: AppColors.saqelCyan,
fontSize: 10.5,
fontWeight: FontWeight.w700,
),
),
const SizedBox(width: 4),
const Icon(CupertinoIcons.chevron_down, color: AppColors.saqelCyan, size: 10),
],
),
),
)
else
Text(
AppStrings.guardianPortal,
style: AppTypography.labelSmall.copyWith(color: AppColors.textMutedDark),
),
],
),
const Spacer(),
@@ -466,18 +655,29 @@ class _UnifiedHomeScreenState extends State<UnifiedHomeScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
decoration: BoxDecoration(
color: AppColors.saqelCyan.withAlpha(30),
borderRadius: BorderRadius.circular(6),
),
child: Text(
widget.user.gradeLevel ?? 'توجيهي 2008',
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w700,
color: AppColors.saqelCyan,
GestureDetector(
onTap: () => _showGradeSelectionModal(context),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
decoration: BoxDecoration(
color: AppColors.saqelCyan.withAlpha(30),
borderRadius: BorderRadius.circular(6),
border: Border.all(color: AppColors.saqelCyan.withAlpha(80), width: 0.8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
GradeLevelModel.getGradeName(widget.user.gradeLevel ?? 'grade_10'),
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w700,
color: AppColors.saqelCyan,
),
),
const SizedBox(width: 4),
const Icon(CupertinoIcons.pencil, color: AppColors.saqelCyan, size: 11),
],
),
),
),