Update Saqel Platform: 2026-08-28 15:41:53
This commit is contained in:
@@ -10,6 +10,7 @@ class CurriculumStudio
|
||||
{
|
||||
$tree = CurriculumService::getCurriculumTree();
|
||||
$treeJson = json_encode($tree, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
|
||||
$serverStorageDir = realpath(__DIR__ . '/../../storage/curriculum') ?: (dirname(__DIR__, 2) . '/storage/curriculum');
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
@@ -25,6 +26,7 @@ class CurriculumStudio
|
||||
<link href="https://fonts.googleapis.com/css2?family=Alexandria:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<script>
|
||||
window.CURRICULUM_TREE = <?= $treeJson ?>;
|
||||
window.SERVER_STORAGE_DIR = "<?= addslashes($serverStorageDir) ?>";
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
@@ -51,7 +53,7 @@ class CurriculumStudio
|
||||
|
||||
.container { max-width: 1400px; margin: 24px auto; padding: 0 20px; }
|
||||
|
||||
.main-layout { display: grid; grid-template-columns: 360px 1fr; gap: 24px; }
|
||||
.main-layout { display: grid; grid-template-columns: 380px 1fr; gap: 24px; }
|
||||
@media (max-width: 900px) { .main-layout { grid-template-columns: 1fr; } }
|
||||
|
||||
.tree-sidebar {
|
||||
@@ -72,7 +74,7 @@ class CurriculumStudio
|
||||
font-size: 12px; font-weight: 600; color: var(--text-secondary); margin: 4px 20px; padding: 3px 6px;
|
||||
}
|
||||
.tree-lesson {
|
||||
font-size: 11.5px; color: var(--text-muted); margin: 3px 30px; padding: 5px 10px; border-radius: 8px;
|
||||
font-size: 11.5px; color: var(--text-muted); margin: 3px 30px; padding: 6px 10px; border-radius: 8px;
|
||||
cursor: pointer; transition: all 0.2s;
|
||||
}
|
||||
.tree-lesson:hover, .tree-lesson.active {
|
||||
@@ -98,13 +100,15 @@ class CurriculumStudio
|
||||
.search-box:focus { border-color: var(--accent-cyan); }
|
||||
|
||||
.md-editor {
|
||||
width: 100%; height: 420px; background: rgba(0,0,0,0.5); border: 1px solid var(--border);
|
||||
width: 100%; height: 480px; background: rgba(0,0,0,0.5); border: 1px solid var(--border);
|
||||
border-radius: 14px; padding: 16px; color: #F1F5F9; font-family: monospace; font-size: 13px;
|
||||
line-height: 1.6; resize: vertical; outline: none;
|
||||
line-height: 1.7; resize: vertical; outline: none;
|
||||
}
|
||||
|
||||
.empty-tree-state {
|
||||
padding: 40px 20px; text-align: center; color: var(--text-muted); font-size: 13px; line-height: 1.6;
|
||||
.server-path-box {
|
||||
background: rgba(0,0,0,0.4); border: 1px solid var(--border); border-radius: 8px; padding: 6px 12px;
|
||||
font-size: 11.5px; font-family: monospace; color: var(--accent-cyan); margin-bottom: 14px;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -115,7 +119,7 @@ class CurriculumStudio
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<img src="/assets/images/saqel_logo.jpg" alt="صَقِل" style="width: 36px; height: 36px; border-radius: 10px;">
|
||||
<span style="font-weight: 800; font-size: 18px; color: #FFF;">صَقِل Enterprise</span>
|
||||
<span style="font-size: 11px; font-weight: 700; color: var(--accent-gold); background: rgba(255,209,102,0.12); padding: 2px 10px; border-radius: 980px;">استوديو إدارة وفهرسة المناهج الحية 📚</span>
|
||||
<span style="font-size: 11px; font-weight: 700; color: var(--accent-gold); background: rgba(255,209,102,0.12); padding: 2px 10px; border-radius: 980px;">استوديو تفريغ وفهرسة المناهج الحية 📚</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="/teacher" style="font-size: 12px; color: var(--accent-cyan); text-decoration: none; border: 1px solid rgba(0,245,212,0.3); padding: 5px 14px; border-radius: 980px;">استوديو المعلم 👨🏫</a>
|
||||
@@ -129,13 +133,13 @@ class CurriculumStudio
|
||||
<div class="workspace-card" style="margin-bottom: 24px; background: linear-gradient(135deg, rgba(30, 41, 59, 0.7), rgba(15, 23, 42, 0.9));">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;">
|
||||
<div>
|
||||
<h2 style="font-size: 20px; font-weight: 900; color: #FFF; margin-bottom: 4px;">رفع وتحليل كتاب المنهاج الوزاري PDF (معالجة حية 100%) 📑</h2>
|
||||
<p style="font-size: 12.5px; color: var(--text-secondary);" id="upload_status_desc">اختر ملف كتاب المنهاج (PDF) ليقوم الخادم والذكاء الاصطناعي بفك تشفيره واستخراج الفصول والوحدات والدروس الحقيقية فوراً.</p>
|
||||
<h2 style="font-size: 20px; font-weight: 900; color: #FFF; margin-bottom: 4px;">رفع وتفريغ كتب المناهج الوزارية (PDF ⟵ Markdown Tree) 📑</h2>
|
||||
<p style="font-size: 12.5px; color: var(--text-secondary);" id="upload_status_desc">اختر ملف كتاب المنهاج (PDF) ليقوم الخادم بتفريغه وفهرسة وحداته ودروسه الحقيقية على القرص وتوليد ملفات المارك داون.</p>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; align-items: center;">
|
||||
<input type="file" id="curriculum_pdf_input" accept=".pdf" style="display: none;" onchange="handleRealPdfUpload(this)">
|
||||
<button type="button" id="btn_upload_pdf" onclick="document.getElementById('curriculum_pdf_input').click()" class="btn-primary">
|
||||
<span>📤 رفع ملف المنهاج PDF الحقيقي</span>
|
||||
<span>📤 رفع كتاب المنهاج PDF الحقيقي</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -155,23 +159,29 @@ class CurriculumStudio
|
||||
<div class="workspace-card" id="workspace_content_area">
|
||||
<div id="empty_selection_view" style="display: none; text-align: center; padding: 60px 20px;">
|
||||
<div style="font-size: 48px; margin-bottom: 12px;">📚</div>
|
||||
<h3 style="font-size: 18px; font-weight: 800; color: #FFF; margin-bottom: 8px;">لا يوجد درس محدد حالياً</h3>
|
||||
<p style="font-size: 13px; color: var(--text-muted); max-width: 480px; margin: 0 auto;">ارفع كتاب المنهاج PDF أو اختر درساً من الشجرة الجانبية لمعاينة نتاجات التعلم والمارك داون المعتمد.</p>
|
||||
<h3 style="font-size: 18px; font-weight: 800; color: #FFF; margin-bottom: 8px;">لا توجد مناهج مضافة حالياً</h3>
|
||||
<p style="font-size: 13px; color: var(--text-muted); max-width: 480px; margin: 0 auto;">ارفع كتاب المنهاج PDF لبناء الشجرة وتفريغ الدروس بالمارك داون على السيرفر.</p>
|
||||
</div>
|
||||
|
||||
<div id="active_lesson_view" style="display: none;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 10px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; flex-wrap: wrap; gap: 10px;">
|
||||
<div>
|
||||
<span style="font-size: 11px; font-weight: 800; color: var(--accent-cyan); background: rgba(0,245,212,0.1); padding: 2px 8px; border-radius: 6px;" id="current_breadcrumb"></span>
|
||||
<h3 style="font-size: 18px; font-weight: 900; color: #FFF; margin-top: 6px;" id="current_lesson_title_display"></h3>
|
||||
</div>
|
||||
<button type="button" onclick="saveActiveMarkdown()" class="btn-primary" style="background: linear-gradient(135deg, #10B981, #059669);">
|
||||
💾 حفظ واعتماد الدرس في الشجرة
|
||||
💾 حفظ التعديلات على السيرفر
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Exact Server Storage Path Readout -->
|
||||
<div class="server-path-box">
|
||||
<span>📁 مسار الملف على السيرفر: <strong id="server_file_path_display" style="color: #FFF;"></strong></span>
|
||||
<span style="color: var(--accent-gold); font-size: 11px;">(ملف Markdown حي على القرص)</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 14px;">
|
||||
<span style="font-size: 12px; font-weight: 700; color: var(--text-muted); display: block; margin-bottom: 6px;">نتاجات التعلم والمفاهيم المستهدفة المستخرجة من الكتاب:</span>
|
||||
<span style="font-size: 12px; font-weight: 700; color: var(--text-muted); display: block; margin-bottom: 6px;">نتاجات التعلم والمفاهيم المستهدفة:</span>
|
||||
<div id="current_outcomes_tags" style="display: flex; gap: 8px; flex-wrap: wrap;"></div>
|
||||
</div>
|
||||
|
||||
@@ -195,7 +205,7 @@ class CurriculumStudio
|
||||
|
||||
if (entries.length === 0) {
|
||||
container.innerHTML = `
|
||||
<div class="empty-tree-state">
|
||||
<div style="padding: 40px 20px; text-align: center; color: var(--text-muted); font-size: 13px;">
|
||||
<div style="font-size: 32px; margin-bottom: 8px;">📂</div>
|
||||
<strong>لا توجد مناهج مفهرسة بعد</strong>
|
||||
<p style="margin-top: 4px;">ارفع كتاب المنهاج الوزاري (PDF) عبر الزر بالأعلى ليتم بناء الشجرة وفهرستها تلقائياً.</p>
|
||||
@@ -257,6 +267,7 @@ class CurriculumStudio
|
||||
|
||||
document.getElementById('current_breadcrumb').textContent = breadcrumb;
|
||||
document.getElementById('current_lesson_title_display').textContent = title;
|
||||
document.getElementById('server_file_path_display').textContent = `backend/storage/curriculum/${filePath}`;
|
||||
|
||||
// Render Outcomes
|
||||
const tags = document.getElementById('current_outcomes_tags');
|
||||
@@ -276,6 +287,9 @@ class CurriculumStudio
|
||||
const data = await res.json();
|
||||
if (res.ok && data.status === 'success') {
|
||||
document.getElementById('lesson_markdown_editor').value = data.content || '';
|
||||
if (data.server_full_path) {
|
||||
document.getElementById('server_file_path_display').textContent = data.server_full_path;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Fetch markdown error:', e);
|
||||
@@ -289,8 +303,8 @@ class CurriculumStudio
|
||||
const btn = document.getElementById('btn_upload_pdf');
|
||||
const desc = document.getElementById('upload_status_desc');
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<span>⏳ جارٍ فك تشفير الكتاب بالذكاء الاصطناعي...</span>';
|
||||
desc.textContent = `جارٍ معالجة وتفصيص ملف [${file.name}] وبناء شجرة المناهج الحقيقية...`;
|
||||
btn.innerHTML = '<span>⏳ جارٍ فك تشفير وتفريغ الكتاب...</span>';
|
||||
desc.textContent = `جارٍ تفريغ ملف [${file.name}] إلى شجرة ملفات Markdown حقيقية على السيرفر...`;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('pdf_file', file);
|
||||
@@ -310,11 +324,12 @@ class CurriculumStudio
|
||||
document.getElementById('empty_selection_view').style.display = 'none';
|
||||
document.getElementById('active_lesson_view').style.display = 'block';
|
||||
document.getElementById('lesson_markdown_editor').value = data.active_md || '';
|
||||
document.getElementById('current_lesson_title_display').textContent = data.extracted_data?.units?.[0]?.lessons?.[0]?.title || 'الدرس المستخرج';
|
||||
document.getElementById('current_breadcrumb').textContent = `${data.extracted_data?.grade_name} ⟵ ${data.extracted_data?.subject_name}`;
|
||||
document.getElementById('current_lesson_title_display').textContent = data.active_title || 'الدرس المستخرج';
|
||||
document.getElementById('current_breadcrumb').textContent = data.active_breadcrumb || 'المسار التعليمي';
|
||||
document.getElementById('server_file_path_display').textContent = `${data.server_storage_dir}/${data.active_file}`;
|
||||
}
|
||||
|
||||
alert(`✅ ${data.message}`);
|
||||
alert(`✅ ${data.message}\n\nتم حفظ ملفات المنهاج على السيرفر في:\n${data.server_storage_dir}`);
|
||||
desc.textContent = `تم اعتماد المنهاج [${file.name}] بنجاح في قاعدة المعرفة الشجرية!`;
|
||||
} else {
|
||||
alert('⚠️ ' + (data.message || 'فشلت معالجة الملف'));
|
||||
@@ -324,7 +339,7 @@ class CurriculumStudio
|
||||
alert('حدث خطأ في الاتصال بالخادم أثناء رفع الملف.');
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<span>📤 رفع ملف المنهاج PDF الحقيقي</span>';
|
||||
btn.innerHTML = '<span>📤 رفع كتاب المنهاج PDF الحقيقي</span>';
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
@@ -341,7 +356,7 @@ class CurriculumStudio
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok && data.status === 'success') {
|
||||
alert('✅ تم حفظ واعتماد التعديلات بنجاح في المنهاج الرسمي!');
|
||||
alert(`✅ تم حفظ واعتماد التعديلات بنجاح في الملف:\n${data.server_full_path || currentFilePath}`);
|
||||
} else {
|
||||
alert('⚠️ فشل حفظ الملف');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user