Files
saqel/apps/admin_app/lib/data/models/directorate_models.dart
T

331 lines
10 KiB
Dart

/// Directorate Model (المظلة المركزية: مديرية الثقافة العسكرية)
class DirectorateOverview {
final String code;
final String name;
final String commanderName;
final int totalSchools;
final int totalStudents;
final int totalTeachers;
final double annualContractValue;
final int recordedLessonsMonth;
final double complianceRate;
final double aiAverageScore;
final int activeUnifiedExams;
DirectorateOverview({
required this.code,
required this.name,
required this.commanderName,
required this.totalSchools,
required this.totalStudents,
required this.totalTeachers,
required this.annualContractValue,
required this.recordedLessonsMonth,
required this.complianceRate,
required this.aiAverageScore,
required this.activeUnifiedExams,
});
factory DirectorateOverview.fromJson(Map<String, dynamic> json) {
return DirectorateOverview(
code: json['code']?.toString() ?? '',
name: json['name']?.toString() ?? '',
commanderName: json['commander_name']?.toString() ?? '',
totalSchools: (json['total_schools'] as num?)?.toInt() ?? 0,
totalStudents: (json['total_students'] as num?)?.toInt() ?? 0,
totalTeachers: (json['total_teachers'] as num?)?.toInt() ?? 0,
annualContractValue: (json['annual_contract_value'] as num?)?.toDouble() ?? 0,
recordedLessonsMonth: (json['recorded_lessons_month'] as num?)?.toInt() ?? 0,
complianceRate: (json['compliance_rate'] as num?)?.toDouble() ?? 0,
aiAverageScore: (json['ai_average_score'] as num?)?.toDouble() ?? 0,
activeUnifiedExams: (json['active_unified_exams'] as num?)?.toInt() ?? 0,
);
}
}
/// School Item Model (المدرسة التابعة وتصنيف الوزن)
class SchoolItem {
final int id;
final String code;
final String name;
final String governorate;
final String weightTier; // tier_a_small, tier_b_medium, tier_c_large
final int studentCount;
final int teacherCount;
final double compliance;
final String status; // excellent, good, warning_under_quota
final double annualFee;
SchoolItem({
required this.id,
required this.code,
required this.name,
required this.governorate,
required this.weightTier,
required this.studentCount,
required this.teacherCount,
required this.compliance,
required this.status,
required this.annualFee,
});
String get weightTierArabic {
switch (weightTier) {
case 'tier_a_small':
return 'الفئة (أ) - صغيرة/نائية';
case 'tier_c_large':
return 'الفئة (ج) - كبرى/مركزية';
case 'tier_b_medium':
default:
return 'الفئة (ب) - قياسية';
}
}
factory SchoolItem.fromJson(Map<String, dynamic> json) {
return SchoolItem(
id: json['id'] ?? 0,
code: json['code'] ?? '',
name: json['name'] ?? '',
governorate: json['governorate']?.toString() ?? '',
weightTier: json['weight_tier']?.toString() ?? '',
studentCount: (json['student_count'] as num?)?.toInt() ?? 0,
teacherCount: (json['teacher_count'] as num?)?.toInt() ?? 0,
compliance: (json['compliance'] as num?)?.toDouble() ?? 0,
status: json['status']?.toString() ?? 'unknown',
annualFee: (json['annual_fee'] as num?)?.toDouble() ?? 0,
);
}
}
/// Detailed school data used by the principal and supervisor dashboards.
class SchoolDetail {
final int id;
final String name;
final String governorate;
final int studentCount;
final int teacherCount;
final String weightTier;
final String directorName;
final String biweeklyCycle;
final String cycleProgress;
const SchoolDetail({
required this.id,
required this.name,
required this.governorate,
required this.studentCount,
required this.teacherCount,
required this.weightTier,
required this.directorName,
required this.biweeklyCycle,
required this.cycleProgress,
});
factory SchoolDetail.fromJson(Map<String, dynamic> json) => SchoolDetail(
id: (json['id'] as num?)?.toInt() ?? 0,
name: json['name']?.toString() ?? '',
governorate: json['governorate']?.toString() ?? '',
studentCount: (json['student_count'] as num?)?.toInt() ?? 0,
teacherCount: (json['teacher_count'] as num?)?.toInt() ?? 0,
weightTier: json['weight_tier']?.toString() ?? '',
directorName: json['director_name']?.toString() ?? '',
biweeklyCycle: json['biweekly_cycle']?.toString() ?? '',
cycleProgress: json['cycle_progress']?.toString() ?? '',
);
}
/// A real computer-lab resource returned by the school dashboard API.
class ComputerLabItem {
final int id;
final String name;
final int deviceCount;
final int onlineDevices;
final String status;
const ComputerLabItem({
required this.id,
required this.name,
required this.deviceCount,
required this.onlineDevices,
required this.status,
});
factory ComputerLabItem.fromJson(Map<String, dynamic> json) => ComputerLabItem(
id: (json['id'] as num?)?.toInt() ?? 0,
name: json['name']?.toString() ?? '',
deviceCount: (json['device_count'] as num?)?.toInt() ?? 0,
onlineDevices: (json['online_devices'] as num?)?.toInt() ?? 0,
status: json['status']?.toString() ?? 'unknown',
);
}
/// Teacher Item Model (المعلم ومؤشر دورية الأسبوعين)
class TeacherItem {
final int id;
final String name;
final String subject;
final String grade;
final String quotaStatus; // completed, pending, overdue
final String lastLesson;
final double aiScore;
final String recordedAt;
TeacherItem({
required this.id,
required this.name,
required this.subject,
required this.grade,
required this.quotaStatus,
required this.lastLesson,
required this.aiScore,
required this.recordedAt,
});
bool get isCompleted => quotaStatus == 'completed';
factory TeacherItem.fromJson(Map<String, dynamic> json) {
return TeacherItem(
id: json['id'] ?? 0,
name: json['name'] ?? '',
subject: json['subject'] ?? '',
grade: json['grade'] ?? '',
quotaStatus: json['quota_status'] ?? 'pending',
lastLesson: json['last_lesson'] ?? '',
aiScore: (json['ai_score'] as num?)?.toDouble() ?? 0,
recordedAt: json['recorded_at']?.toString() ?? '',
);
}
}
/// Recorded Classroom Lesson Result (نتيجة فحص الحصة المرئية)
class RecordedLessonResult {
final String lessonUuid;
final String teacherName;
final String subject;
final String lessonTitle;
final double fileSizeMb;
final int durationMinutes;
final double aiAlignmentScore;
final String teacherTalkRatio;
final String status;
final String reportSummary;
final List<Map<String, String>> socraticCheckpoints;
RecordedLessonResult({
required this.lessonUuid,
required this.teacherName,
required this.subject,
required this.lessonTitle,
required this.fileSizeMb,
required this.durationMinutes,
required this.aiAlignmentScore,
required this.teacherTalkRatio,
required this.status,
required this.reportSummary,
required this.socraticCheckpoints,
});
factory RecordedLessonResult.fromJson(Map<String, dynamic> json) {
var rawCheckpoints = json['socratic_checkpoints'] as List<dynamic>? ?? [];
List<Map<String, String>> checkpoints = rawCheckpoints.map((c) {
if (c is Map) {
return {
'timestamp': c['timestamp']?.toString() ?? '',
'question': c['question']?.toString() ?? '',
'objective': c['objective']?.toString() ?? '',
};
}
return <String, String>{};
}).toList();
return RecordedLessonResult(
lessonUuid: json['lesson_uuid'] ?? '',
teacherName: json['teacher_name'] ?? '',
subject: json['subject'] ?? '',
lessonTitle: json['lesson_title'] ?? '',
fileSizeMb: (json['file_size_mb'] as num?)?.toDouble() ?? 0,
durationMinutes: (json['duration_minutes'] as num?)?.toInt() ?? 0,
aiAlignmentScore: (json['ai_alignment_score'] as num?)?.toDouble() ?? 0,
teacherTalkRatio: json['teacher_talk_ratio']?.toString() ?? '',
status: json['status']?.toString() ?? 'unknown',
reportSummary: json['report_summary']?.toString() ?? '',
socraticCheckpoints: checkpoints,
);
}
}
/// Unified Exam Model (الامتحان الموحد)
class UnifiedExamModel {
final String id;
final String title;
final String subject;
final String gradeLevel;
final String scheduledTime;
final int durationMinutes;
final bool pushedToLab;
final String status;
final List<String> forms;
final Map<String, dynamic> antiCheating;
UnifiedExamModel({
required this.id,
required this.title,
required this.subject,
required this.gradeLevel,
required this.scheduledTime,
required this.durationMinutes,
required this.pushedToLab,
required this.status,
required this.forms,
required this.antiCheating,
});
factory UnifiedExamModel.fromJson(Map<String, dynamic> json) {
return UnifiedExamModel(
id: json['id'] ?? '',
title: json['title'] ?? '',
subject: json['subject'] ?? '',
gradeLevel: json['grade_level'] ?? '',
scheduledTime: json['scheduled_time'] ?? '',
durationMinutes: json['duration_minutes'] ?? 60,
pushedToLab: json['pushed_to_lab'] == true,
status: json['status'] ?? 'scheduled',
forms: (json['forms'] as List<dynamic>?)?.map((e) => e.toString()).toList() ?? ['نموذج أ', 'نموذج ب'],
antiCheating: json['anti_cheating'] as Map<String, dynamic>? ?? {},
);
}
}
/// Exam Anomaly Alert Model (تنبيهات الشذوذ الإحصائي والغش)
class ExamAnomalyAlert {
final String id;
final String type; // speed_impossible, error_clustering, performance_leap
final String schoolName;
final String subject;
final String description;
final String severity;
final String timestamp;
ExamAnomalyAlert({
required this.id,
required this.type,
required this.schoolName,
required this.subject,
required this.description,
required this.severity,
required this.timestamp,
});
factory ExamAnomalyAlert.fromJson(Map<String, dynamic> json) {
return ExamAnomalyAlert(
id: json['id'] ?? '',
type: json['type'] ?? 'speed_impossible',
schoolName: json['school_name'] ?? '',
subject: json['subject'] ?? '',
description: json['description'] ?? '',
severity: json['severity'] ?? 'medium',
timestamp: json['timestamp'] ?? '',
);
}
}