Update Saqel Platform: 2026-09-04 21:26:55

This commit is contained in:
Hamza-Ayed
2026-09-04 21:26:55 +03:00
parent 24f6b5a589
commit ae00aa943e
36 changed files with 5621 additions and 1617 deletions
@@ -0,0 +1,100 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../data/models/teacher_models.dart';
import '../../data/repositories/teacher_repository.dart';
/**
* ==============================================================================
* SAQEL TEACHER STUDIO - MONETIZATION CUBIT
* ==============================================================================
*
* إدارة المحفظة المالية والتسييل وسحوبات كليك (CliQ Payouts):
* - حساب عوائد النموذج المزدوج (1,420 مجاني مدعوم مقابل 380 مدفوع خارجي)
* - تقسيم الحصص: 55% للمعلم / 15% لمديرية الثقافة / 30% للمنصة
* - إرسال واعتماد طلبات السحب عبر كليك.
*/
class TeacherMonetizationState {
final double studentSubscribers;
final double pricePerCourse;
final List<TeacherCourseModel> courses;
final List<TeacherPayoutRequestModel> payoutRequests;
final bool isSubmittingPayout;
const TeacherMonetizationState({
required this.studentSubscribers,
required this.pricePerCourse,
required this.courses,
required this.payoutRequests,
required this.isSubmittingPayout,
});
double get grossRevenue => studentSubscribers * pricePerCourse;
double get teacherShare => grossRevenue * 0.55;
double get directorateShare => grossRevenue * 0.15;
double get platformShare => grossRevenue * 0.30;
TeacherMonetizationState copyWith({
double? studentSubscribers,
double? pricePerCourse,
List<TeacherCourseModel>? courses,
List<TeacherPayoutRequestModel>? payoutRequests,
bool? isSubmittingPayout,
}) {
return TeacherMonetizationState(
studentSubscribers: studentSubscribers ?? this.studentSubscribers,
pricePerCourse: pricePerCourse ?? this.pricePerCourse,
courses: courses ?? this.courses,
payoutRequests: payoutRequests ?? this.payoutRequests,
isSubmittingPayout: isSubmittingPayout ?? this.isSubmittingPayout,
);
}
}
class TeacherMonetizationCubit extends Cubit<TeacherMonetizationState> {
final TeacherRepository repository;
TeacherMonetizationCubit({required this.repository})
: super(const TeacherMonetizationState(
studentSubscribers: 380,
pricePerCourse: 20.0,
courses: [],
payoutRequests: [
TeacherPayoutRequestModel(
cliqAlias: 'AHMAD@CLIQ',
amountJod: 2400.0,
requestedAt: 'الأسبوع الماضي',
status: 'completed',
),
],
isSubmittingPayout: false,
));
Future<void> loadMonetization() async {
final courses = await repository.getPublishedCourses();
emit(state.copyWith(courses: courses));
}
void updateSubscribers(double subscribers) {
emit(state.copyWith(studentSubscribers: subscribers));
}
Future<void> submitCliqPayout({
required String cliqAlias,
required double amountJod,
}) async {
emit(state.copyWith(isSubmittingPayout: true));
try {
final req = await repository.requestCliqPayout(
cliqAlias: cliqAlias,
amountJod: amountJod,
);
final updatedList = List<TeacherPayoutRequestModel>.from(state.payoutRequests)..insert(0, req);
emit(state.copyWith(
payoutRequests: updatedList,
isSubmittingPayout: false,
));
} catch (_) {
emit(state.copyWith(isSubmittingPayout: false));
}
}
}
@@ -0,0 +1,90 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../data/models/teacher_models.dart';
import '../../data/repositories/teacher_repository.dart';
/**
* ==============================================================================
* SAQEL TEACHER STUDIO - ASSIGNMENTS & Q&A CUBIT
* ==============================================================================
*
* إدارة الواجبات المدرسية وأوراق العمل وغرفة تساؤلات الطلبة:
* - توليد وإسناد أوراق عمل مؤتمتة التصحيح بنقرة واحدة
* - تسجيل الردود الصوتية السقراطية (Socratic Voice Replies 🎙️)
* - تحديث فوري لحالات الشكوك والتساؤلات.
*/
class TeacherQnAState {
final List<TeacherHomeworkModel> homeworks;
final List<StudentDoubtModel> doubts;
final bool isLoading;
const TeacherQnAState({
required this.homeworks,
required this.doubts,
required this.isLoading,
});
TeacherQnAState copyWith({
List<TeacherHomeworkModel>? homeworks,
List<StudentDoubtModel>? doubts,
bool? isLoading,
}) {
return TeacherQnAState(
homeworks: homeworks ?? this.homeworks,
doubts: doubts ?? this.doubts,
isLoading: isLoading ?? this.isLoading,
);
}
}
class TeacherQnACubit extends Cubit<TeacherQnAState> {
final TeacherRepository repository;
TeacherQnACubit({required this.repository})
: super(const TeacherQnAState(
homeworks: [],
doubts: [],
isLoading: false,
));
Future<void> loadQnA() async {
emit(state.copyWith(isLoading: true));
final hwList = await repository.getHomeworks();
final doubtsList = await repository.getStudentDoubts();
emit(state.copyWith(
homeworks: hwList,
doubts: doubtsList,
isLoading: false,
));
}
void dispatchNewHomework({
required String title,
required String className,
required String dueDate,
}) {
final newHw = TeacherHomeworkModel(
id: 'hw-${DateTime.now().millisecondsSinceEpoch}',
title: title,
className: className,
submitted: '0 من 83 طالباً',
dueDate: dueDate,
averageScore: 'بانتظار الإجابات',
status: 'active',
);
final updated = List<TeacherHomeworkModel>.from(state.homeworks)..insert(0, newHw);
emit(state.copyWith(homeworks: updated));
}
void recordVoiceReply(String doubtId) {
final updated = state.doubts.map((doubt) {
if (doubt.id == doubtId) {
return doubt.copyWith(replied: true, voiceReply: true);
}
return doubt;
}).toList();
emit(state.copyWith(doubts: updated));
}
}
@@ -0,0 +1,78 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../data/models/teacher_models.dart';
import '../../data/repositories/teacher_repository.dart';
/**
* ==============================================================================
* SAQEL TEACHER STUDIO - STUDIO UPLOAD CUBIT
* ==============================================================================
*
* إدارة حالة استوديو رفع الحصص وفحص الجودة الإدراكي:
* - التحقق من معيار معهد ماساتشوستس (20 - 25 دقيقة)
* - استدعاء التدقيق الآلي للدرس ومخرجات المنهاج الوزاري.
*/
class TeacherStudioState {
final String lessonTitle;
final double durationMinutes;
final bool isAuditing;
final TeacherLessonAuditModel? auditResult;
const TeacherStudioState({
required this.lessonTitle,
required this.durationMinutes,
required this.isAuditing,
this.auditResult,
});
TeacherStudioState copyWith({
String? lessonTitle,
double? durationMinutes,
bool? isAuditing,
TeacherLessonAuditModel? auditResult,
}) {
return TeacherStudioState(
lessonTitle: lessonTitle ?? this.lessonTitle,
durationMinutes: durationMinutes ?? this.durationMinutes,
isAuditing: isAuditing ?? this.isAuditing,
auditResult: auditResult ?? this.auditResult,
);
}
}
class TeacherStudioCubit extends Cubit<TeacherStudioState> {
final TeacherRepository repository;
TeacherStudioCubit({required this.repository})
: super(const TeacherStudioState(
lessonTitle: 'شرح قاعدة لنتز والحث الكهرومغناطيسي — فيزياء 2008',
durationMinutes: 22.5,
isAuditing: false,
auditResult: null,
));
void updateLessonTitle(String title) {
emit(state.copyWith(lessonTitle: title));
}
void updateDuration(double duration) {
emit(state.copyWith(durationMinutes: duration));
}
Future<void> runQualityGate() async {
emit(state.copyWith(isAuditing: true));
try {
final result = await repository.auditStudioVideo(
title: state.lessonTitle,
durationMinutes: state.durationMinutes,
subject: 'الفيزياء',
);
emit(state.copyWith(
isAuditing: false,
auditResult: result,
));
} catch (_) {
emit(state.copyWith(isAuditing: false));
}
}
}