From c40ef2f75429a8d19beed72fb395faee379515f2 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 6 Apr 2026 13:49:07 +0000 Subject: [PATCH] live lessons --- dashboard.php | 123 ++++++++++++++++++---------------- live_lesson.php | 172 ++++++++++++++++++++++++++++++++++++++++++++++++ teacher.php | 145 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 383 insertions(+), 57 deletions(-) create mode 100644 live_lesson.php diff --git a/dashboard.php b/dashboard.php index 742b785..a395f93 100644 --- a/dashboard.php +++ b/dashboard.php @@ -2,9 +2,24 @@ require_once __DIR__ . '/includes/app.php'; $subscription = current_subscription(); $history = []; +$enrolled_courses = []; +$db = db(); + if ($subscription) { $history = fetch_subscriptions_by_email((string) $subscription['email']); + + // Fetch enrolled courses for this student + $student_id = (int) $subscription['id']; + $stmt = $db->prepare(" + SELECT c.* + FROM courses c + JOIN course_students cs ON c.id = cs.course_id + WHERE cs.student_id = ? AND c.status = 'active' + "); + $stmt->execute([$student_id]); + $enrolled_courses = $stmt->fetchAll(PDO::FETCH_ASSOC); } + render_head( t('Student dashboard', 'لوحة الطالب'), t('Review the active subscription, upcoming live classes, and access to subject detail pages.', 'راجع الاشتراك النشط والفصول المباشرة القادمة والوصول إلى صفحات تفاصيل المواد.') @@ -20,7 +35,7 @@ render_nav('dashboard.php');

- +
@@ -30,86 +45,80 @@ render_nav('dashboard.php');
- +

-

+

-
+ +

- = 999 ? 4 : $plan['subjects_limit']); ?> - + 0 ? round(($completed / $totalModules) * 100) : 0; + // Fetch next or current live lesson + $live_stmt = $db->prepare(" + SELECT * + FROM course_live_lessons + WHERE course_id = ? AND status != 'ended' + ORDER BY scheduled_at ASC + LIMIT 1 + "); + $live_stmt->execute([$course['id']]); + $next_lesson = $live_stmt->fetch(PDO::FETCH_ASSOC); ?>
-
+
+ + +
-

-

-
- -
-
-

%

-
-
+

-

-
- - -
+ + +
+

+ + LIVE + + + + +

+

+ + + + + + +
+ +

+
+ + +
+
+
+
-
-
-

- -
-
- - - - - - - - - - - - - - - - - - - - -
-
-
+
diff --git a/live_lesson.php b/live_lesson.php new file mode 100644 index 0000000..5f35509 --- /dev/null +++ b/live_lesson.php @@ -0,0 +1,172 @@ +prepare(" + SELECT l.*, c.name_en, c.name_ar, c.teacher_id + FROM course_live_lessons l + JOIN courses c ON l.course_id = c.id + WHERE l.id = ? +"); +$stmt->execute([$lesson_id]); +$lesson = $stmt->fetch(PDO::FETCH_ASSOC); + +if (!$lesson) { + die("Lesson not found."); +} + +// Check role +$is_teacher = false; +$is_student = false; + +// Mock student and teacher IDs for the prototype based on current session +// In reality, this would be based on logged-in user session +$current_teacher_id = 1; // Used in teacher.php +$current_student_id = 1; // Assuming we use 1 for student preview too + +if (isset($_GET['as']) && $_GET['as'] === 'teacher') { + if ($lesson['teacher_id'] == $current_teacher_id) { + $is_teacher = true; + } +} else { + // Basic check if student is in course + $is_student = true; +} + +if (!$is_teacher && !$is_student) { + die("Unauthorized access."); +} + +// Ensure lesson status logic +if ($is_teacher && isset($_GET['start'])) { + if ($lesson['status'] === 'scheduled') { + $db->prepare("UPDATE course_live_lessons SET status = 'live' WHERE id = ?")->execute([$lesson_id]); + $lesson['status'] = 'live'; + } +} + +if ($is_teacher && isset($_GET['end'])) { + if ($lesson['status'] === 'live') { + $db->prepare("UPDATE course_live_lessons SET status = 'ended' WHERE id = ?")->execute([$lesson_id]); + $lesson['status'] = 'ended'; + } +} + +$room_name = $lesson['room_name']; +$user_display_name = $is_teacher ? 'Teacher' : 'Student'; + +render_head( + t('Live Lesson: ', 'درس مباشر: ') . t($lesson['title'], $lesson['title']), + t('Join the live streaming lesson.', 'انضم إلى بث الدرس المباشر.') +); + +// We won't render normal nav here to maximize screen space for the lesson, or we render a simplified one +?> + + +
+
+

+ LIVE + - +

+
+
+ + + + + Ended + + + + + +
+
+ + +
+
+

+

+ + + + + +
+
+ +
+
+

+

+
+
+ + +
+ + + + + \ No newline at end of file diff --git a/teacher.php b/teacher.php index 58f9253..7f16fc7 100644 --- a/teacher.php +++ b/teacher.php @@ -41,6 +41,37 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { exit; } + if ($post_action === 'add_live' || $post_action === 'edit_live') { + $c_id = (int)$_POST['course_id']; + $live_id = (int)($_POST['live_id'] ?? 0); + $title = $_POST['title'] ?? ''; + $scheduled_at = $_POST['scheduled_at'] ?? ''; + + if (owns_course($db, $c_id, $teacher_id)) { + if ($post_action === 'add_live') { + $room_name = 'room_' . substr(md5(uniqid()), 0, 10); + $stmt = $db->prepare("INSERT INTO course_live_lessons (course_id, title, scheduled_at, room_name) VALUES (?, ?, ?, ?)"); + $stmt->execute([$c_id, $title, $scheduled_at, $room_name]); + } else if ($post_action === 'edit_live' && $live_id > 0) { + $stmt = $db->prepare("UPDATE course_live_lessons SET title = ?, scheduled_at = ? WHERE id = ? AND course_id = ?"); + $stmt->execute([$title, $scheduled_at, $live_id, $c_id]); + } + } + header("Location: " . app_url('teacher.php', ['action' => 'live', 'course_id' => $c_id])); + exit; + } + + if ($post_action === 'delete_live') { + $c_id = (int)$_POST['course_id']; + $live_id = (int)$_POST['live_id']; + if (owns_course($db, $c_id, $teacher_id)) { + $stmt = $db->prepare("DELETE FROM course_live_lessons WHERE id = ? AND course_id = ?"); + $stmt->execute([$live_id, $c_id]); + } + header("Location: " . app_url('teacher.php', ['action' => 'live', 'course_id' => $c_id])); + exit; + } + if ($post_action === 'delete_activity') { $c_id = (int)$_POST['course_id']; $act_id = (int)$_POST['activity_id']; @@ -284,6 +315,120 @@ render_nav('teacher.php'); } + 0): ?> + prepare("SELECT * FROM course_live_lessons WHERE course_id = ? ORDER BY scheduled_at ASC"); + $stmt->execute([$course_id]); + $lessons = $stmt->fetchAll(PDO::FETCH_ASSOC); + ?> +
+

-

+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+ + + + + + +
+ + + + +
+
+
+
+
+ + + + + 0 && $activity_id > 0): ?>