feat: Implement Socratic Step-by-Step Problem Lab with 60s locked struggle timer and progressive step disclosure scaffolding

This commit is contained in:
Hamza-Ayed
2026-08-28 02:00:56 +03:00
parent 4d01962cf8
commit a99ff9a184
+299 -1
View File
@@ -593,6 +593,7 @@ class StudentPortal
<!-- Tabs Navigation -->
<div class="tabs-nav">
<button class="tab-btn active" id="tab_btn_lessons" onclick="switchStudentTab('lessons')">🎬 الحصص ومشغل الفيديو السقراطي</button>
<button class="tab-btn" id="tab_btn_steplab" onclick="switchStudentTab('steplab')">🧪 مختبر التفكير السقراطي (حل خطوة بخطوة)</button>
<button class="tab-btn" id="tab_btn_chat" onclick="switchStudentTab('chat')">💬 اسأل الأستاذ حمزة الغويري (Workerman 0ms)</button>
<button class="tab-btn" id="tab_btn_exams" onclick="switchStudentTab('exams')">📝 الامتحانات وهرمية التقييم المعرفي</button>
</div>
@@ -741,6 +742,155 @@ class StudentPortal
</div>
</div>
<!-- TAB 4: Socratic Step-by-Step Problem Lab -->
<div id="tab_steplab_content" class="studio-card" style="display: none;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 12px;">
<div>
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 4px;">
<span style="font-size: 11px; font-weight: 800; background: rgba(0,245,212,0.12); color: var(--accent-cyan); padding: 3px 10px; border-radius: 6px;">منهجية التفكير الإنتاجي 🧠</span>
<span style="font-size: 11px; font-weight: 800; background: rgba(245,158,11,0.12); color: var(--accent-gold); padding: 3px 10px; border-radius: 6px;">قدرات عليا وزارية 2008</span>
</div>
<h3 style="font-size: 18px; font-weight: 900;">مختبر التفكير السقراطي والحل المتدرج خطوة بخطوة 🧪</h3>
<p style="font-size: 12px; color: var(--text-muted); margin-top: 4px;">واجه المسألة باستقلالية: نافذة تفكير مغلقة 60 ثانية، ثم كشف متدرج للخطوات حسب معايير التصحيح الوزاري.</p>
</div>
<!-- Problem Selector Pills -->
<div style="display: flex; gap: 8px; flex-wrap: wrap;">
<button type="button" onclick="loadStepLabProblem(0)" id="btn_prob_0" class="btn-primary" style="width: auto; padding: 6px 14px; font-size: 12px; background: linear-gradient(135deg, #0284C7, #0369A1);">مسألة 1: المخروط المائي 💧</button>
<button type="button" onclick="loadStepLabProblem(1)" id="btn_prob_1" class="btn-primary" style="width: auto; padding: 6px 14px; font-size: 12px; background: rgba(255,255,255,0.06); border: 1px solid var(--border);">مسألة 2: انزلاق السلم 🪜</button>
<button type="button" onclick="loadStepLabProblem(2)" id="btn_prob_2" class="btn-primary" style="width: auto; padding: 6px 14px; font-size: 12px; background: rgba(255,255,255,0.06); border: 1px solid var(--border);">مسألة 3: حركة المقذوفات 🎯</button>
</div>
</div>
<!-- Problem Card -->
<div style="background: rgba(11, 19, 43, 0.85); border: 1px solid rgba(56, 189, 248, 0.3); border-radius: 18px; padding: 24px; margin-bottom: 24px; box-shadow: 0 10px 30px rgba(0,0,0,0.4);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
<span style="font-size: 13px; font-weight: 800; color: var(--accent-gold);" id="steplab_prob_topic">الرياضيات العلمي — المعدلات المرتبطة بالزمن (توجيهي 2008)</span>
<span style="font-size: 11px; color: var(--text-muted);">المصدر: توماس كالكولوس + بنك التميز الوزاري</span>
</div>
<h4 style="font-size: 16px; font-weight: 700; line-height: 1.8; color: #FFFFFF; margin-bottom: 16px;" id="steplab_prob_text">
خزان ماء على شكل مخروط دائري قائم مقلوب، رأسه إلى أسفل وقاعدته أفقية، نصف قطر قاعدته 2 متر وارتفاعه 6 أمتار. يُصب فيه الماء بمعدل ثابت (0.5 م³/دقيقة). جد معدل ارتفاع منسوب الماء في الخزان عندما يكون عمق الماء 3 أمتار.
</h4>
<!-- 1. LOCKED THINKING / STRUGGLE WINDOW (60s Timer) -->
<div id="steplab_struggle_box" style="background: rgba(0,0,0,0.5); border: 2px dashed rgba(245, 158, 11, 0.5); border-radius: 16px; padding: 20px; text-align: center; margin-top: 16px;">
<div style="font-size: 32px; margin-bottom: 6px;">⏳</div>
<h5 style="font-size: 15px; font-weight: 800; color: var(--accent-gold); margin-bottom: 4px;">نافذة التفكير الحر والتجربة المستقلة (الحل مقفل)</h5>
<p style="font-size: 12.5px; color: var(--text-muted); max-width: 520px; margin: 0 auto 14px auto;">
امسك ورقة وقلم وابدأ برسم المخطط وتفريغ المعطيات. لا يُسمح بكشف خطوات الحل حتى انتهاء المؤقت لتدريب عقلك على التوليد الذاتي للفكرة.
</p>
<div style="display: inline-flex; align-items: center; gap: 10px; background: rgba(245, 158, 11, 0.15); border: 1px solid rgba(245, 158, 11, 0.4); padding: 8px 24px; border-radius: 980px; font-family: monospace; font-size: 20px; font-weight: 900; color: var(--accent-gold);" id="steplab_timer_display">
00:60
</div>
<div style="margin-top: 14px;">
<button type="button" onclick="skipStruggleTimer()" style="background: none; border: none; color: var(--text-muted); font-size: 11.5px; text-decoration: underline; cursor: pointer;">
أنا جاهز وكتبت خطوتي الأولى (بدء الكشف المتدرج ↵)
</button>
</div>
</div>
<!-- 2. PROGRESSIVE STEP-BY-STEP LADDER (Revealed after timer) -->
<div id="steplab_steps_ladder" style="display: none; margin-top: 24px; display: flex; flex-direction: column; gap: 14px;">
<!-- STEP 1 -->
<div class="steplab-card" id="step_card_1" style="background: rgba(15, 23, 42, 0.85); border: 1px solid var(--border); border-radius: 16px; padding: 18px; transition: all 0.3s ease;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10px;">
<span style="font-size: 12px; font-weight: 800; background: #0284C7; color: #FFF; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;">1</span>
<span style="font-size: 14px; font-weight: 800;">الخطوة الأولى: تفريغ المعطيات والرسم التخطيطي</span>
</div>
<button type="button" id="btn_reveal_step_1" onclick="revealStep(1)" class="btn-primary" style="width: auto; padding: 6px 16px; font-size: 12px;">كشف تفاصيل الخطوة 💡</button>
</div>
<div id="step_body_1" style="display: none; margin-top: 14px; border-top: 1px solid rgba(255,255,255,0.08); padding-top: 14px;">
<div style="font-size: 13px; line-height: 1.7; color: #F1F5F9;" id="step_content_1">
• نصف قطر المخروط الكامل: R = 2 m ، الارتفاع الكامل: H = 6 m.<br>
• معدل تدفق الحجم: dV/dt = +0.5 m³/min (إشارة موجبة لأن الحجم يزداد).<br>
• اللحظة الزمنية المطلوبة: عندما يكون عمق الماء h = 3 m.<br>
• المطلوب إيجاده: معدل تغير الارتفاع (dh/dt) = ؟
</div>
<div style="margin-top: 12px; display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--text-muted);">
<span>هل طابقت خطوتك الأولى؟</span>
<button type="button" onclick="verifyStep(1, true)" style="background: rgba(16,185,129,0.2); border: 1px solid #10B981; color: #34D399; padding: 3px 12px; border-radius: 6px; cursor: pointer; font-weight: 700;">نعم ✓</button>
<button type="button" onclick="verifyStep(1, false)" style="background: rgba(239,68,68,0.2); border: 1px solid #EF4444; color: #F87171; padding: 3px 12px; border-radius: 6px; cursor: pointer; font-weight: 700;">تعثرت هنا ✗</button>
</div>
</div>
</div>
<!-- STEP 2 -->
<div class="steplab-card" id="step_card_2" style="background: rgba(15, 23, 42, 0.85); border: 1px solid var(--border); border-radius: 16px; padding: 18px; opacity: 0.5;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10px;">
<span style="font-size: 12px; font-weight: 800; background: #475569; color: #FFF; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;">2</span>
<span style="font-size: 14px; font-weight: 800;">الخطوة الثانية: كتابة العلاقة الأساسية والعلاقة المساعدة (تشابه المثلثات)</span>
</div>
<button type="button" id="btn_reveal_step_2" disabled onclick="revealStep(2)" class="btn-primary" style="width: auto; padding: 6px 16px; font-size: 12px;">كشف الخطوة 2 📐</button>
</div>
<div id="step_body_2" style="display: none; margin-top: 14px; border-top: 1px solid rgba(255,255,255,0.08); padding-top: 14px;">
<div style="font-size: 13px; line-height: 1.7; color: #F1F5F9;" id="step_content_2">
1. قانون حجم المخروط المائي: V = (1/3) * π * r² * h.<br>
2. العلاقة المساعدة من تشابه مقطع المثلثين: r / h = 2 / 6 = 1 / 3 ⟹ r = (1/3) * h.<br>
3. التخلص من المتغير r لأن المطلوب هو dh/dt: V = (1/3) * π * ((1/3)*h)² * h = (π / 27) * h³.
</div>
<div style="margin-top: 12px; display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--text-muted);">
<span>هل طابقت خطوتك الثانية؟</span>
<button type="button" onclick="verifyStep(2, true)" style="background: rgba(16,185,129,0.2); border: 1px solid #10B981; color: #34D399; padding: 3px 12px; border-radius: 6px; cursor: pointer; font-weight: 700;">نعم ✓</button>
<button type="button" onclick="verifyStep(2, false)" style="background: rgba(239,68,68,0.2); border: 1px solid #EF4444; color: #F87171; padding: 3px 12px; border-radius: 6px; cursor: pointer; font-weight: 700;">تعثرت هنا ✗</button>
</div>
</div>
</div>
<!-- STEP 3 -->
<div class="steplab-card" id="step_card_3" style="background: rgba(15, 23, 42, 0.85); border: 1px solid var(--border); border-radius: 16px; padding: 18px; opacity: 0.5;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10px;">
<span style="font-size: 12px; font-weight: 800; background: #475569; color: #FFF; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;">3</span>
<span style="font-size: 14px; font-weight: 800;">الخطوة الثالثة: الاشتقاق الضمني بالنسبة للزمن t</span>
</div>
<button type="button" id="btn_reveal_step_3" disabled onclick="revealStep(3)" class="btn-primary" style="width: auto; padding: 6px 16px; font-size: 12px;">كشف الخطوة 3 ⚡</button>
</div>
<div id="step_body_3" style="display: none; margin-top: 14px; border-top: 1px solid rgba(255,255,255,0.08); padding-top: 14px;">
<div style="font-size: 13px; line-height: 1.7; color: #F1F5F9;" id="step_content_3">
باشتقاق طرفي المعادلة [V = (π/27) * h³] بالنسبة للزمن t:<br>
• dV/dt = (π / 27) * 3h² * (dh/dt)<br>
• dV/dt = (π / 9) * h² * (dh/dt)
</div>
<div style="margin-top: 12px; display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--text-muted);">
<span>هل طابقت خطوتك الثالثة؟</span>
<button type="button" onclick="verifyStep(3, true)" style="background: rgba(16,185,129,0.2); border: 1px solid #10B981; color: #34D399; padding: 3px 12px; border-radius: 6px; cursor: pointer; font-weight: 700;">نعم ✓</button>
<button type="button" onclick="verifyStep(3, false)" style="background: rgba(239,68,68,0.2); border: 1px solid #EF4444; color: #F87171; padding: 3px 12px; border-radius: 6px; cursor: pointer; font-weight: 700;">تعثرت هنا ✗</button>
</div>
</div>
</div>
<!-- STEP 4 -->
<div class="steplab-card" id="step_card_4" style="background: rgba(15, 23, 42, 0.85); border: 1px solid var(--border); border-radius: 16px; padding: 18px; opacity: 0.5;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10px;">
<span style="font-size: 12px; font-weight: 800; background: #475569; color: #FFF; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;">4</span>
<span style="font-size: 14px; font-weight: 800;">الخطوة الرابعة: التعويض العددي باللحظة الزمنية واستخراج الناتج النهائي</span>
</div>
<button type="button" id="btn_reveal_step_4" disabled onclick="revealStep(4)" class="btn-primary" style="width: auto; padding: 6px 16px; font-size: 12px;">كشف الناتج النهائي 🎯</button>
</div>
<div id="step_body_4" style="display: none; margin-top: 14px; border-top: 1px solid rgba(255,255,255,0.08); padding-top: 14px;">
<div style="font-size: 13px; line-height: 1.7; color: #F1F5F9;" id="step_content_4">
بالتعويض بالقيم [dV/dt = 0.5] و [h = 3 m]:<br>
• 0.5 = (π / 9) * (3)² * (dh/dt)<br>
• 0.5 = (π / 9) * 9 * (dh/dt)<br>
• 0.5 = π * (dh/dt)<br>
• <strong style="color: var(--accent-cyan); font-size: 15px;">dh/dt = 0.5 / π = 1 / (2π) m/min ≈ 0.159 m/min</strong>
</div>
<div style="margin-top: 12px; padding: 10px; background: rgba(0,245,212,0.1); border: 1px solid rgba(0,245,212,0.3); border-radius: 8px; color: var(--accent-cyan); font-size: 12px; font-weight: 700;">
🎉 أحسنت! هكذا تكتمل العلامة الكاملة للمسألة في الامتحان الوزاري خطوة بخطوة.
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Dynamic DRM Watermark -->
<div class="watermark-anim">
<span id="drm_watermark_text">SAQEL-DRM • 079XXXXXXX</span>
@@ -1216,16 +1366,164 @@ class StudentPortal
let activeTeacherId = null;
// ==========================================
// Socratic Step-by-Step Lab Engine
// ==========================================
let stepLabTimerInterval = null;
let stepLabRemainingSeconds = 60;
let currentStepLabIdx = 0;
const stepLabProblems = [
{
topic: "الرياضيات العلمي — المعدلات المرتبطة بالزمن (توجيهي 2008)",
source: "المصدر: توماس كالكولوس + بنك التميز الوزاري",
text: "خزان ماء على شكل مخروط دائري قائم مقلوب، رأسه إلى أسفل وقاعدته أفقية، نصف قطر قاعدته 2 متر وارتفاعه 6 أمتار. يُصب فيه الماء بمعدل ثابت (0.5 م³/دقيقة). جد معدل ارتفاع منسوب الماء في الخزان عندما يكون عمق الماء 3 أمتار.",
steps: [
"• نصف قطر المخروط الكامل: R = 2 m ، الارتفاع الكامل: H = 6 m.<br>• معدل تدفق الحجم: dV/dt = +0.5 m³/min (إشارة موجبة لأن الحجم يزداد).<br>• اللحظة الزمنية المطلوبة: عندما يكون عمق الماء h = 3 m.<br>• المطلوب إيجاده: معدل تغير الارتفاع (dh/dt) = ؟",
"1. قانون حجم المخروط المائي: V = (1/3) * π * r² * h.<br>2. العلاقة المساعدة من تشابه مقطع المثلثين: r / h = 2 / 6 = 1 / 3 ⟹ r = (1/3) * h.<br>3. التخلص من المتغير r لأن المطلوب هو dh/dt: V = (1/3) * π * ((1/3)*h)² * h = (π / 27) * h³.",
"باشتقاق طرفي المعادلة [V = (π/27) * h³] بالنسبة للزمن t:<br>• dV/dt = (π / 27) * 3h² * (dh/dt)<br>• dV/dt = (π / 9) * h² * (dh/dt)",
"بالتعويض بالقيم [dV/dt = 0.5] و [h = 3 m]:<br>• 0.5 = (π / 9) * (3)² * (dh/dt)<br>• 0.5 = (π / 9) * 9 * (dh/dt)<br>• 0.5 = π * (dh/dt)<br>• <strong style=\"color: var(--accent-cyan); font-size: 15px;\">dh/dt = 0.5 / π = 1 / (2π) m/min ≈ 0.159 m/min</strong>"
]
},
{
topic: "الرياضيات العلمي — تطبيقات التفاضل وهندسة الحركة",
source: "المصدر: ستيوارت كالكولوس + أسئلة قدرات عليا وزارية",
text: "سلّم طوله 5 أمتار يستند بطرفه العلوي على حائط رأسي وبطرفه السفلي على أرض أفقية. إذا بدأ الطرف السفلي ينزلق مبتعداً عن الحائط بمعدل (2 م/ث). جد سرعة انزلاق الطرف العلوي للسلّم عندما يكون الطرف السفلي على بُعد 3 أمتار من الحائط.",
steps: [
"• طول السلّم ثابت (الوتر): L = 5 m.<br>• بعد الطرف السفلي عن الحائط: x = 3 m ، ومعدل انزلاقه: dx/dt = +2 m/s.<br>• بعد الطرف العلوي عن الأرض: y (متغير يتناقص).<br>• المطلوب: معدل انزلاق الطرف العلوي (dy/dt) = ؟",
"1. العلاقة الأساسية من مبرهنة فيثاغورس: x² + y² = 5² = 25.<br>2. إيجاد قيمة y عند اللحظة المطلوبة (x = 3): (3)² + y² = 25 ⟹ y² = 16 ⟹ y = 4 m.",
"باشتقاق العلاقة [x² + y² = 25] ضمنياً بالنسبة للزمن t:<br>• 2x * (dx/dt) + 2y * (dy/dt) = 0<br>• x * (dx/dt) + y * (dy/dt) = 0",
"بالتعويض بالقيم [x = 3, dx/dt = 2, y = 4]:<br>• (3)(2) + 4(dy/dt) = 0<br>• 6 + 4(dy/dt) = 0<br>• <strong style=\"color: var(--accent-cyan); font-size: 15px;\">dy/dt = -6 / 4 = -1.5 m/s</strong> (الإشارة السالبة تعني أن الطرف العلوي ينزلق للأسفل بمعدل 1.5 م/ث)."
]
},
{
topic: "الفيزياء العلمي — المقذوفات والحركة في بعدين",
source: "المصدر: فيزياء سيرويه + معايير التميز الوزاري",
text: "أُطلقت قذيفة من قمة برج ارتفاعه 45 متراً بسرعة ابتدائية 50 م/ث وبزاوية 30° فوق الأفق. بافتراض تسارع الجاذبية g = 10 m/s² وإهمال مقاومة الهواء، جد أقصى ارتفاع تصل إليه القذيفة عن سطح الأرض، والزمن الكلي للوصول إلى الأرض.",
steps: [
"• السرعة الابتدائية: v0 = 50 m/s ، زاوية الإطلاق: θ = 30°.<br>• المركبة الأفقية للسرعة: v0x = 50 * cos(30°) = 25√3 m/s (ثابتة).<br>• المركبة الرأسية الابتدائية: v0y = 50 * sin(30°) = 25 m/s.<br>• الارتفاع الابتدائي: y0 = 45 m.",
"1. عند أقصى ارتفاع تكون السرعة الرأسية vy = 0.<br>2. معادلة الحركة: vy² = v0y² - 2g(h_max - y0)<br>3. 0 = (25)² - 2(10)(Δy) ⟹ 20(Δy) = 625 ⟹ Δy = 31.25 m.",
"أقصى ارتفاع كلي عن سطح الأرض:<br>• H_total = y0 + Δy = 45 + 31.25 = <strong style=\"color: var(--accent-gold);\">76.25 متراً</strong>.",
"لحساب زمن الوصول للأرض نطبق معادلة الإزاحة الرأسية [y - y0 = v0y*t - 0.5g*t²]:<br>• -45 = 25t - 5t² ⟹ 5t² - 25t - 45 = 0 ⟹ t² - 5t - 9 = 0<br>• بالمعادلة التربيعية: <strong style=\"color: var(--accent-cyan); font-size: 15px;\">t ≈ 6.41 ثانية</strong>."
]
}
];
function loadStepLabProblem(idx) {
currentStepLabIdx = idx;
const prob = stepLabProblems[idx];
document.getElementById('steplab_prob_topic').textContent = prob.topic;
document.getElementById('steplab_prob_text').innerHTML = prob.text;
// Reset buttons styling
[0, 1, 2].forEach(i => {
const b = document.getElementById(`btn_prob_${i}`);
if (b) {
if (i === idx) {
b.style.background = 'linear-gradient(135deg, #0284C7, #0369A1)';
b.style.border = 'none';
} else {
b.style.background = 'rgba(255,255,255,0.06)';
b.style.border = '1px solid var(--border)';
}
}
});
// Populate step contents
for (let s = 1; s <= 4; s++) {
const el = document.getElementById(`step_content_${s}`);
if (el) el.innerHTML = prob.steps[s - 1];
const card = document.getElementById(`step_card_${s}`);
const body = document.getElementById(`step_body_${s}`);
const btn = document.getElementById(`btn_reveal_step_${s}`);
if (body) body.style.display = 'none';
if (card) card.style.opacity = (s === 1) ? '1' : '0.5';
if (btn) {
btn.disabled = (s !== 1);
btn.textContent = (s === 1) ? 'كشف تفاصيل الخطوة 💡' : `كشف الخطوة ${s}`;
}
}
// Start struggle timer
startStruggleTimer();
}
function startStruggleTimer() {
clearInterval(stepLabTimerInterval);
stepLabRemainingSeconds = 60;
const box = document.getElementById('steplab_struggle_box');
const ladder = document.getElementById('steplab_steps_ladder');
const display = document.getElementById('steplab_timer_display');
box.style.display = 'block';
ladder.style.display = 'none';
display.textContent = '00:60';
stepLabTimerInterval = setInterval(() => {
stepLabRemainingSeconds--;
const s = stepLabRemainingSeconds.toString().padStart(2, '0');
display.textContent = `00:${s}`;
if (stepLabRemainingSeconds <= 0) {
clearInterval(stepLabTimerInterval);
unlockStepsLadder();
}
}, 1000);
}
function skipStruggleTimer() {
clearInterval(stepLabTimerInterval);
unlockStepsLadder();
}
function unlockStepsLadder() {
document.getElementById('steplab_struggle_box').style.display = 'none';
document.getElementById('steplab_steps_ladder').style.display = 'flex';
playChimeNotification();
showLuxuryToast('انتهت فترة التفكير 💡', 'يمكنك الآن كشف خطوات الحل خطوة بخطوة.');
}
function revealStep(stepNum) {
const body = document.getElementById(`step_body_${stepNum}`);
const btn = document.getElementById(`btn_reveal_step_${stepNum}`);
if (body) body.style.display = 'block';
if (btn) {
btn.style.display = 'none';
}
// Unlock next step card
const nextStep = stepNum + 1;
const nextCard = document.getElementById(`step_card_${nextStep}`);
const nextBtn = document.getElementById(`btn_reveal_step_${nextStep}`);
if (nextCard) nextCard.style.opacity = '1';
if (nextBtn) nextBtn.disabled = false;
}
function verifyStep(stepNum, isSuccess) {
if (isSuccess) {
showLuxuryToast('إنجاز ممتاز ✓', `أتقنت الخطوة ${stepNum} بنجاح!`);
playChimeNotification();
} else {
showLuxuryToast('نقطة تعلم 💡', `راجع تفاصيل الخطوة ${stepNum} لتثبيت الفهم.`);
}
}
function switchStudentTab(tab) {
document.getElementById('tab_lessons_content').style.display = (tab === 'lessons') ? 'block' : 'none';
document.getElementById('tab_steplab_content').style.display = (tab === 'steplab') ? 'block' : 'none';
document.getElementById('tab_chat_content').style.display = (tab === 'chat') ? 'block' : 'none';
document.getElementById('tab_exams_content').style.display = (tab === 'exams') ? 'block' : 'none';
document.getElementById('tab_btn_lessons').className = (tab === 'lessons') ? 'tab-btn active' : 'tab-btn';
document.getElementById('tab_btn_steplab').className = (tab === 'steplab') ? 'tab-btn active' : 'tab-btn';
document.getElementById('tab_btn_chat').className = (tab === 'chat') ? 'tab-btn active' : 'tab-btn';
document.getElementById('tab_btn_exams').className = (tab === 'exams') ? 'tab-btn active' : 'tab-btn';
if (tab === 'chat') {
if (tab === 'steplab') {
loadStepLabProblem(currentStepLabIdx);
} else if (tab === 'chat') {
loadStudentChat();
}
}