Update Saqel Platform: 2026-09-04 21:26:55
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user