Update Saqel Platform: 2026-09-04 02:57:19

This commit is contained in:
Hamza-Ayed
2026-09-04 02:57:19 +03:00
parent 1fe97bf3eb
commit 882541a56a
17 changed files with 4002 additions and 206 deletions
@@ -0,0 +1,176 @@
import 'package:flutter/material.dart';
/// ==============================================================================
/// SAQEL ENTERPRISE - SMART ERROR NOTEBOOK & REMEDIATION MODELS
/// ==============================================================================
class ErrorNotebookSummary {
final int totalErrors;
final int masteredCount;
final int pendingCount;
final double masteryPercentage;
final Map<String, int> bySubject;
ErrorNotebookSummary({
required this.totalErrors,
required this.masteredCount,
required this.pendingCount,
required this.masteryPercentage,
required this.bySubject,
});
factory ErrorNotebookSummary.fromJson(Map<String, dynamic> json) {
final rawBySubject = json['by_subject'] as Map<String, dynamic>? ?? {};
final bySub = <String, int>{};
rawBySubject.forEach((k, v) {
bySub[k] = (v is num) ? v.toInt() : 0;
});
return ErrorNotebookSummary(
totalErrors: (json['total_errors'] as num?)?.toInt() ?? 0,
masteredCount: (json['mastered_count'] as num?)?.toInt() ?? 0,
pendingCount: (json['pending_count'] as num?)?.toInt() ?? 0,
masteryPercentage: (json['mastery_percentage'] as num?)?.toDouble() ?? 0.0,
bySubject: bySub,
);
}
}
class ErrorNotebookItem {
final int id;
final String uuid;
final String subjectId;
final String subjectName;
final String topicName;
final String sourceType;
final String questionText;
final String studentWrongAnswer;
final String correctAnswer;
final String socraticHint;
final String errorCategory; // 'conceptual', 'calculation', 'rushed', 'misinterpretation'
final String status; // 'pending_remediation', 'in_remediation', 'mastered'
final int remediationAttemptsCount;
final String? masteredAt;
final String createdAt;
ErrorNotebookItem({
required this.id,
required this.uuid,
required this.subjectId,
required this.subjectName,
required this.topicName,
required this.sourceType,
required this.questionText,
required this.studentWrongAnswer,
required this.correctAnswer,
required this.socraticHint,
required this.errorCategory,
required this.status,
required this.remediationAttemptsCount,
this.masteredAt,
required this.createdAt,
});
bool get isMastered => status == 'mastered';
String get categoryArabicName {
switch (errorCategory) {
case 'conceptual':
return 'خطأ مفاهيمي جوهري';
case 'calculation':
return 'خطأ حسابي في الأرقام';
case 'rushed':
return 'تسرع في قراءة المعطيات';
case 'misinterpretation':
return 'التباس في صياغة السؤال';
default:
return 'فجوة معرفية';
}
}
Color get categoryColor {
switch (errorCategory) {
case 'conceptual':
return const Color(0xFF8B5CF6); // Purple
case 'calculation':
return const Color(0xFFF59E0B); // Amber
case 'rushed':
return const Color(0xFFEF4444); // Red
case 'misinterpretation':
return const Color(0xFF38BDF8); // Cyan
default:
return const Color(0xFF64748B);
}
}
factory ErrorNotebookItem.fromJson(Map<String, dynamic> json) {
return ErrorNotebookItem(
id: (json['id'] as num?)?.toInt() ?? 0,
uuid: json['uuid']?.toString() ?? '',
subjectId: json['subject_id']?.toString() ?? 'physics_10',
subjectName: json['subject_name']?.toString() ?? 'الفيزياء',
topicName: json['topic_name']?.toString() ?? 'مفهوم دراسي',
sourceType: json['source_type']?.toString() ?? 'socratic_checkpoint',
questionText: json['question_text']?.toString() ?? '',
studentWrongAnswer: json['student_wrong_answer']?.toString() ?? '',
correctAnswer: json['correct_answer']?.toString() ?? '',
socraticHint: json['socratic_hint']?.toString() ?? '',
errorCategory: json['error_category']?.toString() ?? 'conceptual',
status: json['status']?.toString() ?? 'pending_remediation',
remediationAttemptsCount: (json['remediation_attempts_count'] as num?)?.toInt() ?? 0,
masteredAt: json['mastered_at']?.toString(),
createdAt: json['created_at']?.toString() ?? '',
);
}
ErrorNotebookItem copyWith({
String? status,
int? remediationAttemptsCount,
String? masteredAt,
}) {
return ErrorNotebookItem(
id: id,
uuid: uuid,
subjectId: subjectId,
subjectName: subjectName,
topicName: topicName,
sourceType: sourceType,
questionText: questionText,
studentWrongAnswer: studentWrongAnswer,
correctAnswer: correctAnswer,
socraticHint: socraticHint,
errorCategory: errorCategory,
status: status ?? this.status,
remediationAttemptsCount: remediationAttemptsCount ?? this.remediationAttemptsCount,
masteredAt: masteredAt ?? this.masteredAt,
createdAt: createdAt,
);
}
}
class RemedialQuestion {
final int id;
final String question;
final List<String> options;
final int correctIndex;
final String explanation;
RemedialQuestion({
required this.id,
required this.question,
required this.options,
required this.correctIndex,
required this.explanation,
});
factory RemedialQuestion.fromJson(Map<String, dynamic> json) {
final rawOptions = json['options'] as List? ?? [];
return RemedialQuestion(
id: (json['id'] as num?)?.toInt() ?? 0,
question: json['question']?.toString() ?? '',
options: rawOptions.map((e) => e.toString()).toList(),
correctIndex: (json['correct_index'] as num?)?.toInt() ?? 0,
explanation: json['explanation']?.toString() ?? '',
);
}
}