user_id; $user = Database::selectOne("SELECT id, uuid, full_name, role, status FROM users WHERE id = ? LIMIT 1", [$userId]); if (!$user) { $response->status(404)->json(['status' => 'error', 'message' => 'المعلم غير موجود']); return; } $profile = Database::selectOne("SELECT * FROM teacher_profiles WHERE user_id = ? LIMIT 1", [$userId]); $rawName = (string)($user['full_name'] ?? ''); $decryptedName = Security::decrypt($rawName) ?: $rawName; if (empty($decryptedName)) { $decryptedName = 'معلم جديد'; } $isComplete = !empty($profile) && !empty($profile['specialization']); $response->json([ 'status' => 'success', 'is_completed' => $isComplete, 'user' => [ 'uuid' => $user['uuid'], 'full_name' => $decryptedName, 'role' => $user['role'], 'status' => $user['status'], ], 'profile' => $profile ?: null ]); } /** * Complete or Update Teacher Onboarding Profile (Password, Name, Bio, Grades, Subjects) * POST /api/teacher/profile/setup */ public function setupProfile(Request $request, Response $response): void { $userId = $request->user_id; $body = $request->getBody(); $validator = new Validator(); $isValid = $validator->validate($body, [ 'full_name' => 'required', 'specialization' => 'required', 'password' => 'required|min:8', ]); if (!$isValid) { $response->status(400)->json([ 'status' => 'error', 'message' => 'بيانات الملف الشخصي غير مكتملة أو كلمة المرور قصيرة (أقل من 8 خانات)', 'errors' => $validator->getErrors() ]); return; } $fullName = trim((string)$body['full_name']); $specialization = trim((string)$body['specialization']); $bio = trim((string)($body['bio'] ?? '')); $gradeLevels = is_array($body['grade_levels'] ?? null) ? implode(',', $body['grade_levels']) : (string)($body['grade_levels'] ?? 'tawjihi_2008'); $passwordHash = Security::hashPassword((string)$body['password']); // 1. Update User table $encryptedName = Security::encrypt($fullName); Database::query( "UPDATE users SET full_name = ?, password_hash = ?, grade_level = ?, status = 'active' WHERE id = ?", [$encryptedName, $passwordHash, $gradeLevels, $userId] ); // 2. Upsert Teacher Profile $existingProfile = Database::selectOne("SELECT id FROM teacher_profiles WHERE user_id = ? LIMIT 1", [$userId]); if ($existingProfile) { Database::query( "UPDATE teacher_profiles SET bio = ?, specialization = ? WHERE user_id = ?", [$bio, $specialization, $userId] ); } else { Database::insert( "INSERT INTO teacher_profiles (user_id, bio, specialization, revenue_share_pct, contract_type) VALUES (?, ?, ?, 50.00, 'exclusive')", [$userId, $bio, $specialization] ); } $response->json([ 'status' => 'success', 'message' => 'تم توثيق بيانات المعلم وإعداد كلمة المرور بنجاح!', 'data' => [ 'full_name' => $fullName, 'specialization' => $specialization, 'grade_levels' => $gradeLevels ] ]); } /** * Teacher Dashboard Statistics * GET /api/teacher/dashboard */ public function getDashboard(Request $request, Response $response): void { $userId = $request->user_id; // Total Courses $coursesCount = (int)Database::selectOne("SELECT COUNT(*) as total FROM courses WHERE teacher_id = ?", [$userId])['total']; // Total Lessons $lessonsCount = (int)Database::selectOne( "SELECT COUNT(l.id) as total FROM lessons l JOIN courses c ON l.course_id = c.id WHERE c.teacher_id = ?", [$userId] )['total']; // Total Unique Active Students $studentsCount = (int)Database::selectOne( "SELECT COUNT(DISTINCT lp.user_id) as total FROM lesson_progress lp JOIN lessons l ON lp.lesson_id = l.id JOIN courses c ON l.course_id = c.id WHERE c.teacher_id = ?", [$userId] )['total']; $response->json([ 'status' => 'success', 'data' => [ 'courses_count' => $coursesCount, 'lessons_count' => $lessonsCount, 'students_count' => $studentsCount, 'rating' => 4.9, 'completion_avg' => 87.5 ] ]); } /** * List Teacher's Courses * GET /api/teacher/courses */ public function getCourses(Request $request, Response $response): void { $userId = $request->user_id; $courses = Database::select( "SELECT c.id, c.uuid, c.title, c.description, c.semester, c.price_jod, c.is_published, c.created_at, COUNT(l.id) as lessons_total FROM courses c LEFT JOIN lessons l ON l.course_id = c.id WHERE c.teacher_id = ? GROUP BY c.id ORDER BY c.id DESC", [$userId] ); $response->json([ 'status' => 'success', 'data' => $courses ]); } /** * Add New Course * POST /api/teacher/courses */ public function addCourse(Request $request, Response $response): void { $body = $request->getBody(); $title = trim((string)($body['title'] ?? '')); $description = trim((string)($body['description'] ?? '')); $subjectId = (int)($body['subject_id'] ?? 1); $semester = (string)($body['semester'] ?? 'first'); $price = (float)($body['price_jod'] ?? 35.00); if (empty($title)) { $response->status(400)->json([ 'status' => 'error', 'message' => 'عنوان الدورة مطلوب' ]); return; } $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); $courseId = Database::insert( "INSERT INTO courses (uuid, subject_id, teacher_id, title, description, semester, price_jod, is_published) VALUES (?, ?, ?, ?, ?, ?, ?, 1)", [$uuid, $subjectId, $request->user_id, $title, $description, $semester, $price] ); $response->status(201)->json([ 'status' => 'success', 'message' => 'تم إنشاء الدورة بنجاح', 'data' => [ 'course_id' => $courseId, 'uuid' => $uuid ] ]); } /** * Add New Lesson to Course * POST /api/teacher/lessons */ public function addLesson(Request $request, Response $response): void { $body = $request->getBody(); $courseId = (int)($body['course_id'] ?? 0); $title = trim((string)($body['title'] ?? '')); $bunnyVideoId = trim((string)($body['bunny_video_id'] ?? '')); $duration = (int)($body['duration_seconds'] ?? 0); $sequenceOrder = (int)($body['sequence_order'] ?? 1); if (!$courseId || empty($title) || empty($bunnyVideoId)) { $response->status(400)->json([ 'status' => 'error', 'message' => 'معرف الدورة، عنوان الدرس، ومعرف فيديو Bunny مطلوبين' ]); return; } // Verify Course Ownership $course = Database::selectOne("SELECT id, teacher_id FROM courses WHERE id = ? LIMIT 1", [$courseId]); if (!$course || ($course['teacher_id'] != $request->user_id && $request->role !== 'super_admin')) { $response->status(403)->json([ 'status' => 'error', 'message' => 'غير مصرح: لا تملك هذه الدورة' ]); return; } $lessonId = Database::insert( "INSERT INTO lessons (course_id, title, sequence_order, bunny_video_id, duration_seconds, is_free_preview) VALUES (?, ?, ?, ?, ?, 0)", [$courseId, $title, $sequenceOrder, $bunnyVideoId, $duration] ); $response->status(201)->json([ 'status' => 'success', 'message' => 'تمت إضافة الدرس بنجاح', 'data' => [ 'lesson_id' => $lessonId ] ]); } }