Update Saqel Platform: 2026-09-20 16:38:51
This commit is contained in:
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
||||
class ErrorNotebookSummary {
|
||||
final int totalErrors;
|
||||
final int masteredCount;
|
||||
final int inRemediationCount;
|
||||
final int pendingCount;
|
||||
final double masteryPercentage;
|
||||
final Map<String, int> bySubject;
|
||||
@@ -14,6 +15,7 @@ class ErrorNotebookSummary {
|
||||
ErrorNotebookSummary({
|
||||
required this.totalErrors,
|
||||
required this.masteredCount,
|
||||
this.inRemediationCount = 0,
|
||||
required this.pendingCount,
|
||||
required this.masteryPercentage,
|
||||
required this.bySubject,
|
||||
@@ -31,6 +33,7 @@ class ErrorNotebookSummary {
|
||||
return ErrorNotebookSummary(
|
||||
totalErrors: (json['total_errors'] as num?)?.toInt() ?? 0,
|
||||
masteredCount: (json['mastered_count'] as num?)?.toInt() ?? 0,
|
||||
inRemediationCount: (json['in_remediation_count'] as num?)?.toInt() ?? 0,
|
||||
pendingCount: (json['pending_count'] as num?)?.toInt() ?? 0,
|
||||
masteryPercentage: (json['mastery_percentage'] as num?)?.toDouble() ?? 0.0,
|
||||
bySubject: bySub,
|
||||
@@ -74,6 +77,8 @@ class ErrorNotebookItem {
|
||||
});
|
||||
|
||||
bool get isMastered => status == 'mastered';
|
||||
bool get isInRemediation => status == 'in_remediation';
|
||||
bool get isPending => status == 'pending_remediation';
|
||||
|
||||
String get categoryArabicName {
|
||||
switch (errorCategory) {
|
||||
|
||||
+64
-57
@@ -76,33 +76,7 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
errorItem: errorItem,
|
||||
repository: _repository,
|
||||
onRemediationCompleted: () {
|
||||
setState(() {
|
||||
// Optimistically update local item
|
||||
final idx = _items.indexWhere((it) => it.uuid == errorItem.uuid);
|
||||
if (idx != -1) {
|
||||
_items[idx] = _items[idx].copyWith(
|
||||
status: 'mastered',
|
||||
masteredAt: 'الآن',
|
||||
remediationAttemptsCount: _items[idx].remediationAttemptsCount + 1,
|
||||
);
|
||||
}
|
||||
// Update summary
|
||||
if (_summary != null) {
|
||||
final newMastered = _summary!.masteredCount + 1;
|
||||
final newPending = (_summary!.pendingCount - 1).clamp(0, 999);
|
||||
final newRate = _summary!.totalErrors > 0
|
||||
? (newMastered / _summary!.totalErrors) * 100
|
||||
: 100.0;
|
||||
|
||||
_summary = ErrorNotebookSummary(
|
||||
totalErrors: _summary!.totalErrors,
|
||||
masteredCount: newMastered,
|
||||
pendingCount: newPending,
|
||||
masteryPercentage: newRate,
|
||||
bySubject: _summary!.bySubject,
|
||||
);
|
||||
}
|
||||
});
|
||||
_loadNotebookData();
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -286,14 +260,21 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
color: const Color(0xFF94A3B8),
|
||||
icon: CupertinoIcons.scope,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const SizedBox(width: 6),
|
||||
_metricBox(
|
||||
title: 'بحاجة إلى علاج',
|
||||
title: 'بحاجة لعلاج',
|
||||
value: '${summary.pendingCount}',
|
||||
color: const Color(0xFFEF4444),
|
||||
icon: CupertinoIcons.exclamationmark_triangle_fill,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const SizedBox(width: 6),
|
||||
_metricBox(
|
||||
title: 'قيد التثبيت 🌱',
|
||||
value: '${summary.inRemediationCount}',
|
||||
color: const Color(0xFFF59E0B),
|
||||
icon: CupertinoIcons.arrow_2_circlepath_circle_fill,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
_metricBox(
|
||||
title: 'تم الإتقان 🏆',
|
||||
value: '${summary.masteredCount}',
|
||||
@@ -315,7 +296,7 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
}) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF0B111E),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
@@ -323,12 +304,12 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(icon, size: 16, color: color),
|
||||
Icon(icon, size: 15, color: color),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: color,
|
||||
),
|
||||
@@ -336,8 +317,10 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(fontSize: 10.5, color: Color(0xFF64748B)),
|
||||
style: const TextStyle(fontSize: 10, color: Color(0xFF64748B)),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -346,20 +329,28 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
}
|
||||
|
||||
Widget _buildStatusTabs() {
|
||||
return Row(
|
||||
children: [
|
||||
_statusFilterButton('all', 'جميع الأخطاء (${_items.length})'),
|
||||
const SizedBox(width: 8),
|
||||
_statusFilterButton(
|
||||
'pending_remediation',
|
||||
'بحاجة لعلاج (${_items.where((e) => !e.isMastered).length})',
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_statusFilterButton(
|
||||
'mastered',
|
||||
'تم إتقانها (${_items.where((e) => e.isMastered).length})',
|
||||
),
|
||||
],
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
_statusFilterButton('all', 'جميع الفجوات (${_items.length})'),
|
||||
const SizedBox(width: 8),
|
||||
_statusFilterButton(
|
||||
'pending_remediation',
|
||||
'بحاجة لعلاج (${_items.where((e) => e.isPending).length})',
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_statusFilterButton(
|
||||
'in_remediation',
|
||||
'قيد التثبيت 🌱 (${_items.where((e) => e.isInRemediation).length})',
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_statusFilterButton(
|
||||
'mastered',
|
||||
'تم إتقانها 🏆 (${_items.where((e) => e.isMastered).length})',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -474,8 +465,11 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: item.isMastered
|
||||
? const Color(0xFF10B981).withOpacity(0.3)
|
||||
: const Color(0xFFEF4444).withOpacity(0.3),
|
||||
? const Color(0xFF10B981).withOpacity(0.35)
|
||||
: (item.isInRemediation
|
||||
? const Color(0xFFF59E0B).withOpacity(0.4)
|
||||
: const Color(0xFFEF4444).withOpacity(0.3)),
|
||||
width: item.isInRemediation ? 1.5 : 1.0,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
@@ -654,13 +648,22 @@ class _SmartErrorNotebookScreenState extends State<SmartErrorNotebookScreen> {
|
||||
)
|
||||
: ElevatedButton.icon(
|
||||
onPressed: () => _startRemediation(item),
|
||||
icon: const Icon(CupertinoIcons.bolt_horizontal_circle_fill, size: 17),
|
||||
label: const Text(
|
||||
'بدء المسار العلاجي لسد هذه الفجوة (3 أسئلة تفريدية) 🚀',
|
||||
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.w800),
|
||||
icon: Icon(
|
||||
item.isInRemediation
|
||||
? CupertinoIcons.arrow_2_circlepath_circle_fill
|
||||
: CupertinoIcons.bolt_horizontal_circle_fill,
|
||||
size: 17,
|
||||
),
|
||||
label: Text(
|
||||
item.isInRemediation
|
||||
? 'بدء اختبار الاسترجاع والتثبيت (تكرار متباعد 7 أيام) 🎯'
|
||||
: 'بدء المسار العلاجي لسد هذه الفجوة (3 أسئلة تفريدية) 🚀',
|
||||
style: const TextStyle(fontSize: 12.5, fontWeight: FontWeight.w800),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF0284C7),
|
||||
backgroundColor: item.isInRemediation
|
||||
? const Color(0xFFD97706)
|
||||
: const Color(0xFF0284C7),
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: const Size(double.infinity, 42),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -987,7 +990,9 @@ class _RemediationModalSheetState extends State<_RemediationModalSheet> {
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
passed
|
||||
? 'مبارك! تم إتقان المهارة وسد الفجوة بنجاح 🎉'
|
||||
? (widget.errorItem.isInRemediation
|
||||
? 'مبارك! تم اجتياز اختبار التثبيت بنجاح 🎉'
|
||||
: 'تم إنجاز الكويز العلاجي الأولي بنجاح 🌱')
|
||||
: 'أحسنت المحاولة، راجع الشرح وأعد الاختبار',
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
@@ -999,7 +1004,9 @@ class _RemediationModalSheetState extends State<_RemediationModalSheet> {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
passed
|
||||
? 'أجبت عن $_correctAnswersCount من ${_questions.length} أسئلة بشكل سليم. تم ترحيل الخطأ إلى أرشيف المتقنات.'
|
||||
? (widget.errorItem.isInRemediation
|
||||
? 'أجبت عن $_correctAnswersCount من ${_questions.length} أسئلة بشكل سليم. تم تثبيت المفهوم في الذاكرة طويلة المدى وترحيله إلى المتقنات 🏆.'
|
||||
: 'أجبت عن $_correctAnswersCount من ${_questions.length} أسئلة. دخل المفهوم مرحلة التثبيت والتكرار المتباعد (المراجعة بعد 7 أيام لتأكيد الإتقان التام).')
|
||||
: 'أجبت عن $_correctAnswersCount من ${_questions.length}. حاول مجدداً لضمان إتقان السؤال في الامتحان الوزاري.',
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF94A3B8)),
|
||||
textAlign: TextAlign.center,
|
||||
|
||||
Reference in New Issue
Block a user