Update Saqel Platform: 2026-09-10 12:26:22
This commit is contained in:
+30
-14
@@ -28,7 +28,9 @@ class CurriculumDocumentViewerScreen extends StatefulWidget {
|
||||
final String documentType; // 'worksheet', 'summary', 'textbook', 'lesson'
|
||||
final String subjectTitle;
|
||||
final String? subjectId;
|
||||
final String? filePath;
|
||||
final String? assetId;
|
||||
final String? assetType;
|
||||
final String? mimeType;
|
||||
final String? customContent;
|
||||
final String? simulationSlug;
|
||||
|
||||
@@ -38,7 +40,9 @@ class CurriculumDocumentViewerScreen extends StatefulWidget {
|
||||
required this.documentType,
|
||||
required this.subjectTitle,
|
||||
this.subjectId,
|
||||
this.filePath,
|
||||
this.assetId,
|
||||
this.assetType,
|
||||
this.mimeType,
|
||||
this.customContent,
|
||||
this.simulationSlug,
|
||||
});
|
||||
@@ -68,11 +72,10 @@ class _CurriculumDocumentViewerScreenState extends State<CurriculumDocumentViewe
|
||||
widget.subjectTitle.contains('رياضيات') ||
|
||||
(widget.subjectId ?? '').toLowerCase().contains('math') ||
|
||||
widget.title.contains('معادلات') ||
|
||||
widget.title.contains('جيوجبرا') ||
|
||||
(widget.filePath ?? '').toLowerCase().contains('geogebra');
|
||||
widget.title.contains('جيوجبرا');
|
||||
|
||||
String get _effectiveSubjectId => widget.subjectId ?? (_isEnglish ? 'english_10' : (_isPhysics ? 'physics_10' : 'math_10'));
|
||||
String get _effectiveFilePath => widget.filePath ?? widget.title;
|
||||
String get _effectiveFilePath => widget.assetId ?? '';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -110,16 +113,29 @@ class _CurriculumDocumentViewerScreenState extends State<CurriculumDocumentViewe
|
||||
filePath: _effectiveFilePath,
|
||||
);
|
||||
|
||||
// 2. Attempt fetching from Live Server
|
||||
if (widget.assetId == null || widget.assetId!.isEmpty) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_loadError = 'المورد المنشور لا يحمل معرّف أصل صالحاً.';
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget.mimeType != null && !widget.mimeType!.toLowerCase().startsWith('text/')) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_loadError = 'هذا المورد منشور، لكن عرضه داخل التطبيق غير مدعوم بعد.';
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Fetch only the approved asset UUID from the published bundle.
|
||||
try {
|
||||
final res = await _api.get(
|
||||
'/api/curriculum/document',
|
||||
queryParams: {
|
||||
'subject': _effectiveSubjectId,
|
||||
'file': _effectiveFilePath,
|
||||
'type': widget.documentType,
|
||||
},
|
||||
).timeout(const Duration(seconds: 3));
|
||||
final res = await _api.get('/api/curriculum/assets/${widget.assetId}').timeout(const Duration(seconds: 3));
|
||||
|
||||
if (res is Map && res['content'] != null && res['content'].toString().trim().isNotEmpty) {
|
||||
_processContent(res['content'].toString());
|
||||
|
||||
@@ -347,35 +347,14 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
|
||||
/// Tab 2: Worksheets & Summaries
|
||||
Widget _buildWorksheetsTab(BuildContext context) {
|
||||
final s = widget.subject.id.toLowerCase();
|
||||
final isMath = s.contains('math') || widget.subject.title.contains('رياضيات');
|
||||
final isPhys = s.contains('physic') || widget.subject.title.contains('فيزياء');
|
||||
final isEng = s.contains('english') || widget.subject.title.contains('إنجليز');
|
||||
final worksheets = widget.subject.worksheets;
|
||||
|
||||
final defaultWorksheets = isMath
|
||||
? [
|
||||
const ResourceItemModel(title: 'ورقة عمل 1: الأسس والأنظمة والمعادلات الخاصة', filePath: 'grade_10/math_10/semester_1/resources/worksheet_1.md', type: 'worksheet'),
|
||||
const ResourceItemModel(title: 'ملخص شامل: قوانين المعادلات والتحليل إلى العوامل', filePath: 'math_summary.md', type: 'summary'),
|
||||
const ResourceItemModel(title: 'مراجعة تدريبية: حل أنظمة المعادلات بيانياً وجبرياً', filePath: 'math_exam_prep.md', type: 'worksheet'),
|
||||
]
|
||||
: (isPhys
|
||||
? [
|
||||
const ResourceItemModel(title: 'ورقة عمل وتطبيقات: تحليل المتجهات وقوانين نيوتن', filePath: 'physics_ws1.md', type: 'worksheet'),
|
||||
const ResourceItemModel(title: 'ملخص شامل: الكميات القياسية والمتجهة والضرب النقطي', filePath: 'physics_summary.md', type: 'summary'),
|
||||
const ResourceItemModel(title: 'دليل التجارب المخبرية: طاولة القوى والتسارع', filePath: 'physics_lab_guide.md', type: 'worksheet'),
|
||||
]
|
||||
: (isEng
|
||||
? [
|
||||
const ResourceItemModel(title: 'Action Pack 10 — Practice Worksheet: Unit 01 (Looking Good)', filePath: 'english_ws1.md', type: 'worksheet'),
|
||||
const ResourceItemModel(title: 'Grammar & Vocabulary Revision: Articles & First Impressions', filePath: 'english_summary.md', type: 'summary'),
|
||||
const ResourceItemModel(title: 'Unit 02 Reading & Grammar Worksheet (The Digital Mind)', filePath: 'english_ws2.md', type: 'worksheet'),
|
||||
]
|
||||
: [
|
||||
const ResourceItemModel(title: 'ورقة عمل 1: المفاهيم الأساسية والتطبيقات', filePath: 'ws1.md', type: 'worksheet'),
|
||||
const ResourceItemModel(title: 'ملخص شامل: القوانين والمعادلات الوزارية المقررة', filePath: 'summary.md', type: 'summary'),
|
||||
]));
|
||||
|
||||
final worksheets = widget.subject.worksheets.isNotEmpty ? widget.subject.worksheets : defaultWorksheets;
|
||||
if (worksheets.isEmpty) {
|
||||
return _buildUnavailableResourcesState(
|
||||
icon: CupertinoIcons.doc_text,
|
||||
message: 'لا توجد أوراق عمل منشورة لهذه المادة بعد.',
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 20),
|
||||
@@ -416,7 +395,15 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
IconButton(
|
||||
icon: const Icon(CupertinoIcons.arrow_down_circle_fill, color: AppColors.saqelCyan, size: 28),
|
||||
onPressed: () {
|
||||
_showResourceSheet(context, ws.title, 'ورقة عمل ومذكرة مراجعة', 'PDF جاهز للطباعة بدقة عالية', filePath: ws.filePath);
|
||||
_showResourceSheet(
|
||||
context,
|
||||
ws.title,
|
||||
'ورقة عمل منشورة',
|
||||
'مورد تمت مراجعته ونشره لهذه المادة.',
|
||||
assetId: ws.assetId,
|
||||
assetType: ws.assetType,
|
||||
mimeType: ws.mimeType,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -553,32 +540,14 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
|
||||
/// Tab 4: Official Ministry Textbooks
|
||||
Widget _buildTextbooksTab(BuildContext context) {
|
||||
final s = widget.subject.id.toLowerCase();
|
||||
final isMath = s.contains('math') || widget.subject.title.contains('رياضيات');
|
||||
final isPhys = s.contains('physic') || widget.subject.title.contains('فيزياء');
|
||||
final isEng = s.contains('english') || widget.subject.title.contains('إنجليز');
|
||||
final textbooks = widget.subject.textbooks;
|
||||
|
||||
final defaultTextbooks = isMath
|
||||
? [
|
||||
const ResourceItemModel(title: 'كتاب الطالب المقرر — الرياضيات (أنظمة المعادلات والدائرة)', filePath: 'grade_10/math_10/semester_1/math_student_book.md', type: 'textbook'),
|
||||
const ResourceItemModel(title: 'كتاب التمارين والأنشطة الإضافية — الرياضيات 10', filePath: 'grade_10/math_10/semester_1/math_workbook.md', type: 'textbook'),
|
||||
]
|
||||
: (isPhys
|
||||
? [
|
||||
const ResourceItemModel(title: 'كتاب الفيزياء المقرر — الطالب (المتجهات والحركة)', filePath: 'grade_10/physics_10/semester_1/physics_student_book.md', type: 'textbook'),
|
||||
const ResourceItemModel(title: 'كتاب التجارب والأنشطة العلمية والعملية (طاولة القوى)', filePath: 'grade_10/physics_10/semester_1/physics_activities_book.md', type: 'textbook'),
|
||||
]
|
||||
: (isEng
|
||||
? [
|
||||
const ResourceItemModel(title: 'Action Pack 10 — Student\'s Book (Looking Good & The Digital Mind)', filePath: 'grade_10/english_10/semester_1/unit_01.md', type: 'textbook'),
|
||||
const ResourceItemModel(title: 'Action Pack 10 — Activity Book & Literature Spot', filePath: 'grade_10/english_10/semester_1/activity_book.md', type: 'textbook'),
|
||||
]
|
||||
: [
|
||||
const ResourceItemModel(title: 'كتاب الطالب المقرّر — منهاج وزارة التربية والتعليم', filePath: 'book.md', type: 'textbook'),
|
||||
const ResourceItemModel(title: 'كتاب التجارب والأنشطة العلمية والعملية', filePath: 'workbook.md', type: 'textbook'),
|
||||
]));
|
||||
|
||||
final textbooks = widget.subject.textbooks.isNotEmpty ? widget.subject.textbooks : defaultTextbooks;
|
||||
if (textbooks.isEmpty) {
|
||||
return _buildUnavailableResourcesState(
|
||||
icon: CupertinoIcons.book,
|
||||
message: 'لا يوجد كتاب أو ملف مصدر منشور لهذه المادة بعد.',
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 20),
|
||||
@@ -619,7 +588,15 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
IconButton(
|
||||
icon: const Icon(CupertinoIcons.eye_fill, color: AppColors.saqelCyan, size: 24),
|
||||
onPressed: () {
|
||||
_showResourceSheet(context, tb.title, 'الكتاب المدرسي المعتمد', 'نسخة وزارة التربية والتعليم المنقحة والمحدثة', filePath: tb.filePath);
|
||||
_showResourceSheet(
|
||||
context,
|
||||
tb.title,
|
||||
'كتاب أو ملف مصدر منشور',
|
||||
'مورد تمت مراجعته ونشره لهذه المادة.',
|
||||
assetId: tb.assetId,
|
||||
assetType: tb.assetType,
|
||||
mimeType: tb.mimeType,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -630,7 +607,35 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
);
|
||||
}
|
||||
|
||||
void _showResourceSheet(BuildContext context, String title, String subtitle, String description, {String? filePath}) {
|
||||
Widget _buildUnavailableResourcesState({required IconData icon, required String message}) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, color: AppColors.textSecondaryDark, size: 34),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
message,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: AppColors.textSecondaryDark, fontSize: 14, height: 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showResourceSheet(
|
||||
BuildContext context,
|
||||
String title,
|
||||
String subtitle,
|
||||
String description, {
|
||||
required String assetId,
|
||||
required String assetType,
|
||||
required String mimeType,
|
||||
}) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: AppColors.darkSurface,
|
||||
@@ -716,7 +721,9 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
documentType: title.contains('كتاب') ? 'textbook' : 'worksheet',
|
||||
subjectTitle: widget.subject.title,
|
||||
subjectId: widget.subject.id,
|
||||
filePath: filePath,
|
||||
assetId: assetId,
|
||||
assetType: assetType,
|
||||
mimeType: mimeType,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -780,40 +787,9 @@ class _SubjectHubScreenState extends State<SubjectHubScreen> with SingleTickerPr
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
'شروحات هذا الدرس قيد التصوير والمراجعة من قبل نخبة المعلمين المعتمدين وفريق منصة صَقِل.\nيمكنك حالياً دراسة نتاجات وملخص الدرس عبر تبويب الكتب والمذكرات، أو خوض الاختبار التكيفي.',
|
||||
'لا يوجد شرح منشور لهذا الدرس بعد. ستظهر فقط الموارد التي تُراجع وتُنشر لهذا الدرس أو للمادة.',
|
||||
style: TextStyle(color: AppColors.textSecondaryDark, fontSize: 13, height: 1.5),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.appleBlue,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(ctx).pop();
|
||||
Navigator.of(context).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (_) => CurriculumDocumentViewerScreen(
|
||||
title: lesson.title,
|
||||
documentType: 'lesson',
|
||||
subjectTitle: widget.subject.title,
|
||||
subjectId: widget.subject.id,
|
||||
filePath: lesson.markdownFilePath,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: const Icon(CupertinoIcons.book, size: 18),
|
||||
label: const Text('قراءة محتوى وملخص الدرس 📖', style: TextStyle(fontWeight: FontWeight.w800)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user