fix: 4 critical bugs — worker argv, student dashboard visibility, teacher onboarding flow, password validation
This commit is contained in:
@@ -73,9 +73,10 @@ class CurriculumController
|
||||
error_reporting(E_ALL);
|
||||
ob_start();
|
||||
|
||||
// Execute the script logic natively by setting argv
|
||||
$argv = ['curriculum_worker.php', $taskId];
|
||||
$_SERVER['argv'] = $argv;
|
||||
// CRITICAL: Set $GLOBALS['argv'] so the required worker script can access $argv[1]
|
||||
// (In a web request, $argv is empty — we must set it globally before requiring the worker)
|
||||
$GLOBALS['argv'] = ['curriculum_worker.php', $taskId];
|
||||
$_SERVER['argv'] = $GLOBALS['argv'];
|
||||
|
||||
require $scriptPath;
|
||||
|
||||
|
||||
@@ -637,7 +637,7 @@ class StudentPortal
|
||||
</div>
|
||||
|
||||
<!-- 2. STUDENT DASHBOARD (100% REAL DATABASE DATA) -->
|
||||
<div id="dashboard_container" style="width: 100%;">
|
||||
<div id="dashboard_container" style="width: 100%; display: none;">
|
||||
|
||||
<!-- Hero & Tawjihi Readiness Score -->
|
||||
<div class="dashboard-hero">
|
||||
@@ -1119,15 +1119,9 @@ class StudentPortal
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const token = localStorage.getItem('saqel_student_jwt');
|
||||
const cachedUser = localStorage.getItem('saqel_student_user');
|
||||
|
||||
if (token) {
|
||||
if (cachedUser) {
|
||||
try {
|
||||
const u = JSON.parse(cachedUser);
|
||||
renderDashboard(u);
|
||||
} catch (e) {}
|
||||
}
|
||||
// Always verify session with server — don't render from cache directly
|
||||
initWebSocket(token);
|
||||
await checkStudentSession(token);
|
||||
}
|
||||
|
||||
@@ -391,10 +391,8 @@ class TeacherPortal
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">تعيين كلمة المرور السرية <span style="color: #EF4444;">*</span></label>
|
||||
<input type="password" id="onboard_password" placeholder="8 خانات على الأقل" class="input-text">
|
||||
</div>
|
||||
|
||||
<!-- Password field removed: OTP-based auth, no password needed for initial setup -->
|
||||
|
||||
<button type="button" id="btn_complete_onboarding" onclick="handleCompleteOnboarding(event)" class="btn-primary">
|
||||
<span id="btn_onboard_text">حفظ وتفعيل لوحة التحكم 🚀</span>
|
||||
@@ -665,14 +663,9 @@ class TeacherPortal
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const token = localStorage.getItem('saqel_teacher_jwt');
|
||||
const cachedUser = localStorage.getItem('saqel_teacher_user');
|
||||
if (token) {
|
||||
if (cachedUser) {
|
||||
try {
|
||||
const u = JSON.parse(cachedUser);
|
||||
renderDashboard(u, { specialization: u.specialization || 'المعلم المعتمد' });
|
||||
} catch (e) {}
|
||||
}
|
||||
// Always verify session first — don't blindly render from cache
|
||||
// checkTeacherSession will render dashboard or show onboarding based on profile status
|
||||
initWebSocket(token);
|
||||
await checkTeacherSession(token);
|
||||
}
|
||||
@@ -1120,6 +1113,10 @@ class TeacherPortal
|
||||
}
|
||||
|
||||
function switchToOnboardingStep() {
|
||||
// Restore auth container, hide dashboard (renderDashboard may have hidden auth_container)
|
||||
document.getElementById('auth_container').style.display = 'block';
|
||||
document.getElementById('dashboard_container').style.display = 'none';
|
||||
// Show only onboarding step
|
||||
document.getElementById('step_phone_container').style.display = 'none';
|
||||
document.getElementById('step_otp_container').style.display = 'none';
|
||||
document.getElementById('step_onboarding_container').style.display = 'block';
|
||||
@@ -1217,21 +1214,14 @@ class TeacherPortal
|
||||
if (res.ok && data.status === 'success' && data.data?.token) {
|
||||
const token = data.data.token;
|
||||
const user = data.data.user;
|
||||
const profile = data.data.profile || {};
|
||||
localStorage.setItem('saqel_teacher_jwt', token);
|
||||
document.cookie = "saqel_teacher_jwt=" + token + "; path=/; max-age=2592000; SameSite=Lax";
|
||||
initWebSocket(token);
|
||||
|
||||
const isNewTeacher = user?.is_new || user?.full_name === 'معلم جديد' || user?.name === 'معلم جديد' || user?.name === 'الأستاذ المعتمد';
|
||||
if (isNewTeacher) {
|
||||
switchToOnboardingStep();
|
||||
} else {
|
||||
if (user) {
|
||||
localStorage.setItem('saqel_teacher_user', JSON.stringify({ ...user, ...profile }));
|
||||
}
|
||||
renderDashboard(user, profile);
|
||||
await checkTeacherSession(token);
|
||||
if (user) {
|
||||
localStorage.setItem('saqel_teacher_user', JSON.stringify(user));
|
||||
}
|
||||
initWebSocket(token);
|
||||
// Let checkTeacherSession decide: if profile is incomplete → onboarding, else → dashboard
|
||||
await checkTeacherSession(token);
|
||||
} else {
|
||||
showError(data.message || 'رمز التحقق غير صحيح');
|
||||
}
|
||||
@@ -1249,12 +1239,22 @@ class TeacherPortal
|
||||
const token = localStorage.getItem('saqel_teacher_jwt');
|
||||
const fullName = document.getElementById('onboard_fullname').value.trim();
|
||||
const spec = document.getElementById('onboard_specialization').value;
|
||||
const password = document.getElementById('onboard_password').value.trim();
|
||||
|
||||
if (!fullName || !password || password.length < 8) {
|
||||
showError('يرجى تعبئة كافة الحقول وكلمة مرور 8 خانات على الأقل');
|
||||
if (!fullName || fullName.length < 3) {
|
||||
showError('يرجى إدخال الاسم الكامل للمعلم');
|
||||
return;
|
||||
}
|
||||
if (!spec) {
|
||||
showError('يرجى تحديد التخصص والمادة');
|
||||
return;
|
||||
}
|
||||
|
||||
const onboardBtn = document.getElementById('btn_complete_onboarding');
|
||||
const onboardText = document.getElementById('btn_onboard_text');
|
||||
const onboardSpinner = document.getElementById('btn_onboard_spinner');
|
||||
onboardBtn.disabled = true;
|
||||
onboardText.style.display = 'none';
|
||||
onboardSpinner.style.display = 'inline-block';
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/teacher/profile/setup', {
|
||||
@@ -1263,16 +1263,23 @@ class TeacherPortal
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ' + token
|
||||
},
|
||||
body: JSON.stringify({ full_name: fullName, specialization: spec, password: password })
|
||||
body: JSON.stringify({ full_name: fullName, specialization: spec })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok && data.status === 'success') {
|
||||
const u = { full_name: fullName, specialization: spec };
|
||||
localStorage.setItem('saqel_teacher_user', JSON.stringify(u));
|
||||
renderDashboard(u, { specialization: spec });
|
||||
showLuxuryToast('أهلاً بك أستاذنا! 🎓', 'تم تفعيل ملفك الأكاديمي بنجاح.');
|
||||
} else {
|
||||
showError(data.message || 'فشل حفظ البيانات');
|
||||
}
|
||||
} catch (e) {
|
||||
showError('فشل حفظ الملف.');
|
||||
showError('تعذر الاتصال بالسيرفر. يرجى المحاولة مجدداً.');
|
||||
} finally {
|
||||
onboardBtn.disabled = false;
|
||||
onboardText.style.display = 'inline';
|
||||
onboardSpinner.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user