Files
saqel/apps/teacher_app/lib/data/models/teacher_models.dart
T

304 lines
9.3 KiB
Dart

/**
* ==============================================================================
* SAQEL TEACHER STUDIO - DATA MODELS
* ==============================================================================
*
* نماذج البيانات الخاصة باستوديو المعلم:
* - نتائج فحص الجودة الإدراكي والأكاديمي (Quality Gate & MIT 20-25 Min Limit)
* - بيانات التسييل المالي وحسابات الحصص (55% المعلم / 15% المديرية / 30% المنصة)
* - أوراق العمل والواجبات المدرسية المصححة آلياً
* - استفسارات وأسئلة الطلبة الميدانية (غرفة الشكوك) والردود السقراطية المسجلة.
*/
class TeacherLessonAuditModel {
final String lessonTitle;
final String subject;
final double durationMinutes;
final bool durationGatePassed;
final String? durationWarning;
final int qualityScore;
final String approvalStatus;
final String curriculumAlignment;
final String audioClarity;
final int socraticStopsCount;
final String decision;
const TeacherLessonAuditModel({
required this.lessonTitle,
required this.subject,
required this.durationMinutes,
required this.durationGatePassed,
this.durationWarning,
required this.qualityScore,
required this.approvalStatus,
required this.curriculumAlignment,
required this.audioClarity,
required this.socraticStopsCount,
required this.decision,
});
factory TeacherLessonAuditModel.fromJson(Map<String, dynamic> json) {
return TeacherLessonAuditModel(
lessonTitle: json['lesson_title'] ?? '',
subject: json['subject'] ?? 'الفيزياء',
durationMinutes: (json['duration_minutes'] as num?)?.toDouble() ?? 22.5,
durationGatePassed: json['duration_gate_passed'] ?? true,
durationWarning: json['duration_warning'],
qualityScore: json['quality_score'] ?? 92,
approvalStatus: json['approval_status'] ?? 'approved_for_broadcast',
curriculumAlignment: json['curriculum_alignment'] ?? '96% تطابق مع مخرجات المنهاج الوزاري',
audioClarity: json['audio_clarity'] ?? '95% نقاء صوتي ممتاز',
socraticStopsCount: json['socratic_stops_count'] ?? 3,
decision: json['decision'] ?? 'الحصة معتمدة ومؤهلة للبث المشفر والعرض للبيع خارج الثقافة العسكرية 🚀',
);
}
}
class TeacherHomeworkModel {
final String id;
final String title;
final String className;
final String submitted;
final String dueDate;
final String averageScore;
final String status; // 'active', 'completed'
const TeacherHomeworkModel({
required this.id,
required this.title,
required this.className,
required this.submitted,
required this.dueDate,
required this.averageScore,
required this.status,
});
}
class StudentDoubtModel {
final String id;
final int studentId;
final String studentName;
final String className;
final String question;
final String time;
final bool replied;
final bool voiceReply;
const StudentDoubtModel({
required this.id,
required this.studentId,
required this.studentName,
required this.className,
required this.question,
required this.time,
required this.replied,
required this.voiceReply,
});
StudentDoubtModel copyWith({
bool? replied,
bool? voiceReply,
}) {
return StudentDoubtModel(
id: id,
studentId: studentId,
studentName: studentName,
className: className,
question: question,
time: time,
replied: replied ?? this.replied,
voiceReply: voiceReply ?? this.voiceReply,
);
}
}
class TeacherCourseModel {
final String id;
final String title;
final String grade;
final int totalLessons;
final int militaryStudents;
final int externalSubscribers;
final double priceJod;
final double netRevenueJod;
const TeacherCourseModel({
required this.id,
required this.title,
required this.grade,
required this.totalLessons,
required this.militaryStudents,
required this.externalSubscribers,
required this.priceJod,
required this.netRevenueJod,
});
}
class TeacherPayoutRequestModel {
final String cliqAlias;
final double amountJod;
final String requestedAt;
final String status; // 'queued', 'approved', 'completed'
const TeacherPayoutRequestModel({
required this.cliqAlias,
required this.amountJod,
required this.requestedAt,
required this.status,
});
}
class TeacherProfileModel {
final int id;
final String uuid;
final String name;
final String specialization;
final String schoolName;
final List<String> gradesTaught;
final String bio;
final double rating;
final int studentsCount;
final int lessonsCount;
const TeacherProfileModel({
required this.id,
required this.uuid,
required this.name,
required this.specialization,
required this.schoolName,
required this.gradesTaught,
required this.bio,
this.rating = 4.9,
this.studentsCount = 42,
this.lessonsCount = 28,
});
factory TeacherProfileModel.fromJson(Map<String, dynamic> json) {
final user = json['user'] as Map<String, dynamic>? ?? {};
final profile = json['profile'] as Map<String, dynamic>? ?? {};
List<String> grades = [];
if (profile['grades_taught'] is List) {
grades = (profile['grades_taught'] as List).map((e) => e.toString()).toList();
} else if (profile['grades_taught'] is String) {
grades = [profile['grades_taught'].toString()];
}
if (grades.isEmpty) {
grades = [];
}
return TeacherProfileModel(
id: user['id'] is int ? user['id'] : 1,
uuid: user['uuid']?.toString() ?? '',
name: user['full_name']?.toString() ?? 'حساب معلم غير مكتمل',
specialization: profile['specialization']?.toString() ?? 'بانتظار استكمال التخصص',
schoolName: profile['school_name']?.toString() ?? '',
gradesTaught: grades,
bio: profile['bio']?.toString() ?? '',
rating: 0,
studentsCount: 0,
lessonsCount: 0,
);
}
TeacherProfileModel copyWith({
String? name,
String? specialization,
String? schoolName,
List<String>? gradesTaught,
String? bio,
}) {
return TeacherProfileModel(
id: id,
uuid: uuid,
name: name ?? this.name,
specialization: specialization ?? this.specialization,
schoolName: schoolName ?? this.schoolName,
gradesTaught: gradesTaught ?? this.gradesTaught,
bio: bio ?? this.bio,
rating: rating,
studentsCount: studentsCount,
lessonsCount: lessonsCount,
);
}
}
class ChatConversationModel {
final int userId;
final String userUuid;
final String fullName;
final String role;
final String? specialization;
final String lastMessage;
final String lastMessageType;
final String? lastMessageAt;
final int unreadCount;
const ChatConversationModel({
required this.userId,
required this.userUuid,
required this.fullName,
required this.role,
this.specialization,
required this.lastMessage,
required this.lastMessageType,
this.lastMessageAt,
this.unreadCount = 0,
});
factory ChatConversationModel.fromJson(Map<String, dynamic> json) {
return ChatConversationModel(
userId: json['user_id'] is int ? json['user_id'] : int.tryParse(json['user_id']?.toString() ?? '0') ?? 0,
userUuid: json['user_uuid']?.toString() ?? '',
fullName: json['full_name']?.toString() ?? 'طالب صَقِل',
role: json['role']?.toString() ?? 'student',
specialization: json['specialization']?.toString(),
lastMessage: json['last_message']?.toString() ?? '',
lastMessageType: json['last_message_type']?.toString() ?? 'text',
lastMessageAt: json['last_message_at']?.toString(),
unreadCount: json['unread_count'] is int ? json['unread_count'] : 0,
);
}
}
class ChatMessageModel {
final int id;
final String uuid;
final bool isMine;
final int senderId;
final int receiverId;
final String message;
final String messageType; // 'text', 'voice', 'image', 'file'
final String? mediaUrl;
final bool isRead;
final String createdAt;
const ChatMessageModel({
required this.id,
required this.uuid,
required this.isMine,
required this.senderId,
required this.receiverId,
required this.message,
required this.messageType,
this.mediaUrl,
required this.isRead,
required this.createdAt,
});
factory ChatMessageModel.fromJson(Map<String, dynamic> json) {
return ChatMessageModel(
id: json['id'] is int ? json['id'] : int.tryParse(json['id']?.toString() ?? '0') ?? 0,
uuid: json['uuid']?.toString() ?? '',
isMine: json['is_mine'] ?? false,
senderId: json['sender_id'] is int ? json['sender_id'] : int.tryParse(json['sender_id']?.toString() ?? '0') ?? 0,
receiverId: json['receiver_id'] is int ? json['receiver_id'] : int.tryParse(json['receiver_id']?.toString() ?? '0') ?? 0,
message: json['message']?.toString() ?? '',
messageType: json['message_type']?.toString() ?? 'text',
mediaUrl: json['media_url']?.toString(),
isRead: json['is_read'] ?? false,
createdAt: json['created_at']?.toString() ?? '',
);
}
}