update buying courses

This commit is contained in:
Flatlogic Bot 2026-04-06 12:35:47 +00:00
parent 420d607cdd
commit 0798a850bb
17 changed files with 1016 additions and 137 deletions

View File

@ -34,12 +34,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $page === 'profile') {
}
}
$stmt = db()->prepare("UPDATE platform_profile SET name = :name, description = :description, logo_path = :logo, favicon_path = :favicon WHERE id = 1");
$ctr_no = $_POST['ctr_no'] ?? '';
$telephone_no = $_POST['telephone_no'] ?? '';
$email_id = $_POST['email_id'] ?? '';
$stmt = db()->prepare("UPDATE platform_profile SET name = :name, description = :description, logo_path = :logo, favicon_path = :favicon, ctr_no = :ctr_no, telephone_no = :telephone_no, email_id = :email_id WHERE id = 1");
$stmt->execute([
'name' => $name,
'description' => $description,
'logo' => $logo_path,
'favicon' => $favicon_path
'favicon' => $favicon_path,
'ctr_no' => $ctr_no,
'telephone_no' => $telephone_no,
'email_id' => $email_id
]);
header('Location: ' . app_url('admin.php', ['page' => 'profile', 'saved' => 1]));
@ -114,6 +121,11 @@ render_head(
<?= h(t('Subjects', 'المواد')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'courses'])) ?>" class="nav-link <?= $page === 'courses' ? 'active' : 'link-dark' ?>" <?= $page === 'courses' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
<?= h(t('Courses', 'الدورات')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'plans'])) ?>" class="nav-link <?= $page === 'plans' ? 'active' : 'link-dark' ?>" <?= $page === 'plans' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<?= h(t('Plans', 'الخطط')) ?>
@ -135,23 +147,42 @@ render_head(
</a>
</li>
<li class="nav-item w-100 mt-2 d-none d-md-block">
<div class="text-uppercase text-secondary fw-bold px-3 py-1" style="font-size: 0.75rem; letter-spacing: 0.5px;"><?= h(t('Settings', 'الإعدادات')) ?></div>
<li class="nav-item w-100 mt-3 border-top pt-3">
<a href="#settingsCollapse" data-bs-toggle="collapse" class="nav-link link-dark d-flex align-items-center justify-content-between text-secondary fw-bold px-3 py-2" aria-expanded="<?= in_array($page, ['profile', 'integrations']) ? 'true' : 'false' ?>" aria-controls="settingsCollapse" style="font-size: 0.95rem; letter-spacing: 0.5px;">
<div class="d-flex align-items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="bi bi-gear" viewBox="0 0 16 16">
<path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492M5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0"/>
<path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115z"/>
</svg>
<?= h(t('Settings', 'الإعدادات')) ?>
</div>
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708"/>
</svg>
</a>
<div class="collapse <?= in_array($page, ['profile', 'integrations']) ? 'show' : '' ?>" id="settingsCollapse">
<ul class="nav flex-column ms-3 mb-2">
<li class="nav-item mb-1 mt-2">
<a href="<?= h(app_url('admin.php', ['page' => 'profile'])) ?>" class="nav-link <?= $page === 'profile' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'profile' ? 'style="background-color: var(--accent); color: white; border-radius: 6px;"' : '' ?>>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-badge" viewBox="0 0 16 16">
<path d="M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
<path d="M4.5 0A2.5 2.5 0 0 0 2 2.5V14a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2.5A2.5 2.5 0 0 0 11.5 0zM3 2.5A1.5 1.5 0 0 1 4.5 1h7A1.5 1.5 0 0 1 13 2.5v10.795a4.2 4.2 0 0 0-.776-.492C11.392 12.387 10.063 12 8 12s-3.392.387-4.224.803a4.2 4.2 0 0 0-.776.492z"/>
</svg>
<?= h(t('Platform Profile', 'ملف المنصة')) ?>
</a>
</li>
<li class="nav-item">
<a href="<?= h(app_url('admin.php', ['page' => 'integrations'])) ?>" class="nav-link <?= $page === 'integrations' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'integrations' ? 'style="background-color: var(--accent); color: white; border-radius: 6px;"' : '' ?> >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plug" viewBox="0 0 16 16">
<path d="M6 0a.5.5 0 0 1 .5.5V3h3V.5a.5.5 0 0 1 1 0V3h1a.5.5 0 0 1 .5.5v3A3.5 3.5 0 0 1 8.5 10c-.002.434-.01.845-.04 1.22-.041.514-.126 1.003-.317 1.424a2.08 2.08 0 0 1-.97 1.028C6.725 13.9 6.169 14 5.5 14c-.998 0-1.61.33-1.974.718A1.92 1.92 0 0 0 3 16h2a.92.92 0 0 1 .328-.718c.364-.388.976-.718 1.974-.718 1.144 0 2.115-.256 2.872-.647a3.09 3.09 0 0 0 1.433-1.52c.28-.58.41-1.21.464-1.879A15 15 0 0 0 12 8.5V4h1a.5.5 0 0 1 .5.5V8a1 1 0 0 0 2 0V4.5A1.5 1.5 0 0 0 14 3h-1V.5a.5.5 0 0 1 1 0V3h.5A1.5 1.5 0 0 1 16 4.5v3A3.5 3.5 0 0 1 12.5 11v1.5a4.1 4.1 0 0 1-1.895 3.42c-.89.576-2.022.883-3.105.883H5.5a4.1 4.1 0 0 1-3.105-.883A4.1 4.1 0 0 1 .5 12.5V11A3.5 3.5 0 0 1 4 7.5v-3A1.5 1.5 0 0 1 5.5 3H6V.5A.5.5 0 0 1 6 0zM5 4v3.5A2.5 2.5 0 0 0 7.5 10h1A2.5 2.5 0 0 0 11 7.5V4H5z"/>
</svg>
<?= h(t('Integrations', 'التكاملات')) ?>
</a>
</li>
</ul>
</div>
</li>
<li class="nav-item">
<a href="<?= h(app_url('admin.php', ['page' => 'profile'])) ?>" class="nav-link <?= $page === 'profile' ? 'active' : 'link-dark' ?>" <?= $page === 'profile' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<?= h(t('Platform Profile', 'ملف المنصة')) ?>
</a>
</li>
<li class="nav-item w-100 mt-2 d-none d-md-block">
<div class="text-uppercase text-secondary fw-bold px-3 py-1" style="font-size: 0.75rem; letter-spacing: 0.5px;"><?= h(t('Integrations', 'التكاملات')) ?></div>
</li>
<li class="nav-item">
<a href="<?= h(app_url('admin.php', ['page' => 'integrations'])) ?>" class="nav-link <?= $page === 'integrations' ? 'active' : 'link-dark' ?>" <?= $page === 'integrations' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
<?= h(t('All Integrations', 'كل التكاملات')) ?>
</a>
</li>
</ul>
</aside>
@ -252,18 +283,41 @@ render_head(
<?php endif; ?>
<input type="file" name="favicon" class="form-control" accept="image/x-icon,image/png,image/jpeg,image/svg+xml">
</div>
<h5 class="mb-3 mt-4"><?= h(t('Contact Information', 'معلومات الاتصال')) ?></h5>
<div class="row g-3 mb-4">
<div class="col-md-6">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email_id" class="form-control" value="<?= h($prof['email_id'] ?? '') ?>">
</div>
<div class="col-md-6">
<label class="form-label"><?= h(t('Phone Number', 'رقم الهاتف')) ?></label>
<input type="text" name="telephone_no" class="form-control" value="<?= h($prof['telephone_no'] ?? '') ?>">
</div>
<div class="col-md-12">
<label class="form-label"><?= h(t('Commercial Registration No.', 'رقم السجل التجاري')) ?></label>
<input type="text" name="ctr_no" class="form-control" value="<?= h($prof['ctr_no'] ?? '') ?>">
</div>
</div>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);">
<?= h(t('Save Changes', 'حفظ التغييرات')) ?>
</button>
</form>
</div>
<?php elseif ($page === 'classes'): ?>
<?php elseif ($page === 'courses'): ?>
<?php require_once __DIR__ . '/admin_courses.php'; ?>
<?php elseif ($page === 'classes'): ?>
<?php require_once __DIR__ . '/admin_classes.php'; ?>
<?php elseif ($page === 'subjects'): ?>
<?php require_once __DIR__ . '/admin_subjects.php'; ?>
<?php elseif ($page === 'students'): ?>
<?php require_once __DIR__ . '/admin_students.php'; ?>
<?php elseif ($page === 'teachers'): ?>
<?php require_once __DIR__ . '/admin_teachers.php'; ?>
<?php elseif ($page === 'assignments'): ?>
<?php require_once __DIR__ . '/admin_assignments.php'; ?>
<?php elseif ($page === 'integrations'): ?>
<?php require_once __DIR__ . '/admin_integrations.php'; ?>
<?php else: ?>
@ -315,4 +369,4 @@ render_head(
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="<?= h(asset_url('assets/js/main.js')) ?>"></script>
</body>
</html>
</html>

View File

@ -23,13 +23,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name_ar = $_POST['name_ar'] ?? '';
$desc_en = $_POST['description_en'] ?? '';
$desc_ar = $_POST['description_ar'] ?? '';
$status = $_POST['status'] ?? 'active';
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("UPDATE classes SET name_en=?, name_ar=?, description_en=?, description_ar=? WHERE id=?");
$stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $post_id]);
$stmt = db()->prepare("UPDATE classes SET name_en=?, name_ar=?, description_en=?, description_ar=?, status=? WHERE id=?");
$stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $post_id]);
} else {
$stmt = db()->prepare("INSERT INTO classes (name_en, name_ar, description_en, description_ar) VALUES (?, ?, ?, ?)");
$stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar]);
$stmt = db()->prepare("INSERT INTO classes (name_en, name_ar, description_en, description_ar, status) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status]);
}
header('Location: ' . app_url('admin.php', ['page' => 'classes']));
exit;
@ -84,6 +85,7 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<tr>
<th>ID</th>
<th><?= h(t('Name', 'الاسم')) ?></th>
<th><?= h(t('Status', 'الحالة')) ?></th>
<th><?= h(t('Description', 'الوصف')) ?></th>
<th><?= h(t('Actions', 'إجراءات')) ?></th>
</tr>
@ -95,6 +97,13 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<td>
<div class="fw-semibold"><?= h(current_lang() === 'ar' ? $row['name_ar'] : $row['name_en']) ?></div>
</td>
<td>
<?php if (($row['status'] ?? 'active') === 'active'): ?>
<span class="badge bg-success"><?= h(t('Active', 'نشط')) ?></span>
<?php else: ?>
<span class="badge bg-secondary"><?= h(t('Inactive', 'غير نشط')) ?></span>
<?php endif; ?>
</td>
<td class="text-truncate" style="max-width: 200px;">
<?= h(current_lang() === 'ar' ? $row['description_ar'] : $row['description_en']) ?>
</td>
@ -120,6 +129,13 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'classes'])) ?>">
<input type="hidden" name="action" value="edit">
<input type="hidden" name="id" value="<?= $row['id'] ?>">
<div class="mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active" <?= ($row['status'] ?? 'active') === 'active' ? 'selected' : '' ?>><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive" <?= ($row['status'] ?? 'active') === 'inactive' ? 'selected' : '' ?>><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Name (EN)</label>
<input type="text" name="name_en" class="form-control" value="<?= h($row['name_en']) ?>" required>
@ -179,6 +195,13 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'classes'])) ?>">
<input type="hidden" name="action" value="add">
<div class="mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active"><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive"><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Name (EN)</label>
<input type="text" name="name_en" class="form-control" required>

365
admin_courses.php Normal file
View File

@ -0,0 +1,365 @@
<?php
// admin_courses.php
require_once __DIR__ . '/includes/app.php';
$action = $_GET['action'] ?? 'list';
$id = (int)($_GET['id'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$post_action = $_POST['action'] ?? $action;
$post_id = (int)($_POST['id'] ?? $id);
if ($post_action === 'delete' && $post_id > 0) {
$stmt = db()->prepare("DELETE FROM courses WHERE id = ?");
$stmt->execute([$post_id]);
header('Location: ' . app_url('admin.php', ['page' => 'courses']));
exit;
}
if ($post_action === 'edit' || $post_action === 'add') {
$name_en = $_POST['name_en'] ?? '';
$name_ar = $_POST['name_ar'] ?? '';
$desc_en = $_POST['description_en'] ?? '';
$desc_ar = $_POST['description_ar'] ?? '';
$status = $_POST['status'] ?? 'active';
$price = (float)($_POST['price'] ?? 0);
$picture = null;
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("SELECT picture FROM courses WHERE id = ?");
$stmt->execute([$post_id]);
$picture = $stmt->fetchColumn();
}
if (isset($_FILES['picture']) && $_FILES['picture']['error'] === UPLOAD_ERR_OK) {
$upload_dir = __DIR__ . '/assets/images/uploads/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0775, true);
}
$filename = time() . '_' . basename($_FILES['picture']['name']);
$target_file = $upload_dir . $filename;
if (move_uploaded_file($_FILES['picture']['tmp_name'], $target_file)) {
$picture = 'assets/images/uploads/' . $filename;
}
}
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("UPDATE courses SET name_en=?, name_ar=?, description_en=?, description_ar=?, status=?, price=?, picture=? WHERE id=?");
$stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $price, $picture, $post_id]);
} else {
$stmt = db()->prepare("INSERT INTO courses (name_en, name_ar, description_en, description_ar, status, price, picture) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $price, $picture]);
}
header('Location: ' . app_url('admin.php', ['page' => 'courses']));
exit;
}
if ($post_action === 'manage_students') {
$course_id = (int)$_POST['course_id'];
$student_ids = $_POST['student_ids'] ?? [];
db()->prepare("DELETE FROM course_students WHERE course_id=?")->execute([$course_id]);
$insert_stmt = db()->prepare("INSERT INTO course_students (course_id, student_id) VALUES (?, ?)");
foreach ($student_ids as $sid) {
$insert_stmt->execute([$course_id, (int)$sid]);
}
header('Location: ' . app_url('admin.php', ['page' => 'courses']));
exit;
}
}
// Fetch all students for assignment mapping
$all_students_stmt = db()->query("SELECT id, full_name, email FROM student_subscriptions ORDER BY full_name ASC");
$all_students = $all_students_stmt->fetchAll(PDO::FETCH_ASSOC);
$course_students_stmt = db()->query("SELECT course_id, student_id FROM course_students");
$all_course_students = $course_students_stmt->fetchAll(PDO::FETCH_ASSOC);
$course_students_map = [];
foreach ($all_course_students as $cs) {
$course_students_map[$cs['course_id']][] = $cs['student_id'];
}
// list view
$search = $_GET['search'] ?? '';
$page_num = max(1, (int)($_GET['p'] ?? 1));
$limit = 10;
$offset = ($page_num - 1) * $limit;
$where = "";
$params = [];
if ($search !== '') {
$where = "WHERE name_en LIKE ? OR name_ar LIKE ?";
$params[] = "%$search%";
$params[] = "%$search%";
}
$total_stmt = db()->prepare("SELECT COUNT(*) FROM courses $where");
$total_stmt->execute($params);
$total = $total_stmt->fetchColumn();
$pages = ceil($total / $limit);
$stmt = db()->prepare("SELECT * FROM courses $where ORDER BY id DESC LIMIT $limit OFFSET $offset");
$stmt->execute($params);
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<div class="section-header mb-4 d-flex justify-content-between align-items-center">
<div>
<h1 class="section-title mb-2"><?= h(t('Courses', 'الدورات')) ?></h1>
</div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addCourseModal" style="background-color: var(--accent); border-color: var(--accent);">+ <?= h(t('Add Course', 'إضافة دورة')) ?></button>
</div>
<div class="panel-card mb-4">
<form method="get" class="d-flex gap-2 align-items-center">
<input type="hidden" name="page" value="courses">
<input type="text" name="search" class="form-control w-auto" placeholder="<?= h(t('Search...', 'بحث...')) ?>" value="<?= h($search) ?>">
<button type="submit" class="btn btn-outline-secondary"><?= h(t('Filter', 'تصفية')) ?></button>
<?php if ($search): ?>
<a href="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" class="btn btn-link text-secondary text-decoration-none"><?= h(t('Clear', 'مسح')) ?></a>
<?php endif; ?>
</form>
</div>
<div class="panel-card">
<div class="table-responsive">
<table class="table align-middle dashboard-table mb-0">
<thead>
<tr>
<th>ID</th>
<th><?= h(t('Name', 'الاسم')) ?></th>
<th><?= h(t('Price', 'السعر')) ?></th>
<th><?= h(t('Status', 'الحالة')) ?></th>
<th><?= h(t('Students', 'الطلاب')) ?></th>
<th><?= h(t('Description', 'الوصف')) ?></th>
<th><?= h(t('Actions', 'إجراءات')) ?></th>
</tr>
</thead>
<tbody>
<?php foreach($items as $row):
$assigned_count = count($course_students_map[$row['id']] ?? []);
?>
<tr>
<td><?= h((string)$row['id']) ?></td>
<td>
<div class="d-flex align-items-center gap-3">
<?php if(!empty($row['picture'])): ?>
<img src="<?= h($row['picture']) ?>" alt="" class="rounded" style="width: 40px; height: 40px; object-fit: cover;">
<?php else: ?>
<div class="rounded bg-secondary text-white d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<svg width="20" height="20" fill="currentColor" viewBox="0 0 16 16"><path d="M4 0h5.293A1 1 0 0 1 10 .293L13.707 4a1 1 0 0 1 .293.707V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm5.5 1.5v2a1 1 0 0 0 1 1h2l-3-3z"/></svg>
</div>
<?php endif; ?>
<div class="fw-semibold"><?= h(current_lang() === 'ar' ? $row['name_ar'] : $row['name_en']) ?></div>
</div>
</td>
<td>
<span class="badge bg-light text-dark border"><?= h(number_format($row['price'] ?? 0, 2)) ?></span>
</td>
<td>
<?php if (($row['status'] ?? 'active') === 'active'): ?>
<span class="badge bg-success"><?= h(t('Active', 'نشط')) ?></span>
<?php else: ?>
<span class="badge bg-secondary"><?= h(t('Inactive', 'غير نشط')) ?></span>
<?php endif; ?>
</td>
<td>
<span class="badge bg-info text-dark"><?= $assigned_count ?></span>
</td>
<td class="text-truncate" style="max-width: 200px;">
<?= h(current_lang() === 'ar' ? $row['description_ar'] : $row['description_en']) ?>
</td>
<td>
<button type="button" class="btn btn-sm btn-outline-info" data-bs-toggle="modal" data-bs-target="#manageStudentsModal<?= $row['id'] ?>" title="<?= h(t('Manage Students', 'إدارة الطلاب')) ?>">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-people" viewBox="0 0 16 16">
<path d="M15 14s1 0 1-1-1-4-5-4-5 3-5 4 1 1 1 1zm-7.978-1L7 12.996c.001-.264.167-1.03.76-1.72C8.312 10.629 9.282 10 11 10c1.717 0 2.687.63 3.24 1.276.593.69.758 1.457.76 1.72l-.008.002-.014.002zM11 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4m3-2a3 3 0 1 1-6 0 3 3 0 0 1 6 0M6.936 9.28a6 6 0 0 0-1.23-.247A7 7 0 0 0 5 9c-4 0-5 3-5 4q0 1 1 1h4.216A2.24 2.24 0 0 1 5 13c0-1.01.377-2.042 1.09-2.904.243-.294.526-.569.846-.816M4.92 10A5.5 5.5 0 0 0 4 13H1c0-.26.164-1.03.76-1.724.545-.636 1.492-1.256 3.16-1.275ZM1.5 5.5a3 3 0 1 1 6 0 3 3 0 0 1-6 0m3-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4"/>
</svg>
</button>
<button type="button" class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#editCourseModal<?= $row['id'] ?>" title="<?= h(t('Edit', 'تعديل')) ?>">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/></svg>
</button>
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses', 'action'=>'delete', 'id'=>$row['id']])) ?>" class="d-inline" onsubmit="return confirm('<?= h(t('Are you sure?', 'هل أنت متأكد؟')) ?>');">
<button type="submit" class="btn btn-sm btn-outline-danger" title="<?= h(t('Delete', 'حذف')) ?>"><svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/><path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/></svg></button>
</form>
</td>
</tr>
<!-- Manage Students Modal for Row <?= $row['id'] ?> -->
<div class="modal fade" id="manageStudentsModal<?= $row['id'] ?>" tabindex="-1" aria-labelledby="manageStudentsModalLabel<?= $row['id'] ?>" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content border-0 shadow">
<div class="modal-header border-0 bg-dark-blue">
<h5 class="modal-title section-title" id="manageStudentsModalLabel<?= $row['id'] ?>">
<?= h(t('Manage Students', 'إدارة الطلاب')) ?> - <?= h(current_lang() === 'ar' ? $row['name_ar'] : $row['name_en']) ?>
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="manage_students">
<input type="hidden" name="course_id" value="<?= $row['id'] ?>">
<div class="mb-3">
<label class="form-label"><?= h(t('Select Students', 'اختر الطلاب')) ?></label>
<div class="list-group">
<?php
$assigned_to_this = $course_students_map[$row['id']] ?? [];
foreach ($all_students as $student):
$is_assigned = in_array($student['id'], $assigned_to_this);
?>
<label class="list-group-item d-flex gap-2 align-items-center">
<input class="form-check-input flex-shrink-0" type="checkbox" name="student_ids[]" value="<?= h($student['id']) ?>" <?= $is_assigned ? 'checked' : '' ?>>
<span>
<?= h($student['full_name']) ?>
<small class="d-block text-muted"><?= h($student['email']) ?></small>
</span>
</label>
<?php endforeach; ?>
<?php if(empty($all_students)): ?>
<div class="text-muted"><?= h(t('No students available.', 'لا يوجد طلاب متاحين.')) ?></div>
<?php endif; ?>
</div>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"><?= h(t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);"><?= h(t('Save Assignments', 'حفظ التعيينات')) ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Edit Modal for Row <?= $row['id'] ?> -->
<div class="modal fade" id="editCourseModal<?= $row['id'] ?>" tabindex="-1" aria-labelledby="editCourseModalLabel<?= $row['id'] ?>" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header border-0 bg-dark-blue">
<h5 class="modal-title section-title" id="editCourseModalLabel<?= $row['id'] ?>"><?= h(t('Edit Course', 'تعديل الدورة')) ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="edit">
<input type="hidden" name="id" value="<?= $row['id'] ?>">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Name (EN)</label>
<input type="text" name="name_en" class="form-control" value="<?= h($row['name_en']) ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Name (AR)</label>
<input type="text" name="name_ar" class="form-control" value="<?= h($row['name_ar']) ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Description (EN)</label>
<textarea name="description_en" class="form-control"><?= h($row['description_en']) ?></textarea>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Description (AR)</label>
<textarea name="description_ar" class="form-control"><?= h($row['description_ar']) ?></textarea>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Price', 'السعر')) ?></label>
<input type="number" step="0.01" name="price" class="form-control" value="<?= h($row['price'] ?? 0) ?>">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Picture', 'صورة')) ?></label>
<input type="file" name="picture" class="form-control" accept="image/*">
<?php if(!empty($row['picture'])): ?>
<div class="mt-2"><img src="<?= h($row['picture']) ?>" alt="Course Image" class="img-thumbnail" style="max-height: 50px;"></div>
<?php endif; ?>
</div>
<div class="col-12 mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active" <?= ($row['status'] ?? 'active') === 'active' ? 'selected' : '' ?>><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive" <?= ($row['status'] ?? 'active') === 'inactive' ? 'selected' : '' ?>><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"><?= h(t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);"><?= h(t('Save Changes', 'حفظ التغييرات')) ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- End Edit Modal -->
<?php endforeach; ?>
<?php if(!$items): ?>
<tr><td colspan="6" class="text-center text-secondary py-3"><?= h(t('No courses found.', 'لا توجد دورات.')) ?></td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<?php if ($pages > 1): ?>
<nav class="mt-4">
<ul class="pagination justify-content-center">
<?php for($i=1; $i<=$pages; $i++): ?>
<li class="page-item <?= $i === $page_num ? 'active' : '' ?>">
<a class="page-link" href="<?= h(app_url('admin.php', ['page'=>'courses', 'p'=>$i, 'search'=>$search])) ?>"><?= $i ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
<?php endif; ?>
<!-- Add Course Modal -->
<div class="modal fade" id="addCourseModal" tabindex="-1" aria-labelledby="addCourseModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header border-0 bg-dark-blue">
<h5 class="modal-title section-title" id="addCourseModalLabel"><?= h(t('Add Course', 'إضافة دورة')) ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="add">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Name (EN)</label>
<input type="text" name="name_en" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Name (AR)</label>
<input type="text" name="name_ar" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Description (EN)</label>
<textarea name="description_en" class="form-control"></textarea>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Description (AR)</label>
<textarea name="description_ar" class="form-control"></textarea>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Price', 'السعر')) ?></label>
<input type="number" step="0.01" name="price" class="form-control" value="0.00">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Picture', 'صورة')) ?></label>
<input type="file" name="picture" class="form-control" accept="image/*">
</div>
<div class="col-12 mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active"><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive"><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"><?= h(t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);"><?= h(t('Save', 'حفظ')) ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- End Add Modal -->

327
admin_students.php Normal file
View File

@ -0,0 +1,327 @@
<?php
// admin_students.php
require_once __DIR__ . '/includes/app.php';
$action = $_GET['action'] ?? 'list';
$id = (int)($_GET['id'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$post_action = $_POST['action'] ?? $action;
$post_id = (int)($_POST['id'] ?? $id);
if ($post_action === 'delete' && $post_id > 0) {
$stmt = db()->prepare("DELETE FROM student_subscriptions WHERE id = ?");
$stmt->execute([$post_id]);
header('Location: ' . app_url('admin.php', ['page' => 'students']));
exit;
}
if ($post_action === 'edit' || $post_action === 'add') {
$full_name = $_POST['full_name'] ?? '';
$email = $_POST['email'] ?? '';
$whatsapp = $_POST['whatsapp'] ?? '';
$plan_key = $_POST['plan_key'] ?? '';
$payment_status = $_POST['payment_status'] ?? 'active';
$status = $_POST['status'] ?? 'active';
$civil_id = $_POST['civil_id'] ?? '';
$picture = null;
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("SELECT picture FROM student_subscriptions WHERE id = ?");
$stmt->execute([$post_id]);
$picture = $stmt->fetchColumn();
}
if (isset($_FILES['picture']) && $_FILES['picture']['error'] === UPLOAD_ERR_OK) {
$upload_dir = __DIR__ . '/assets/images/uploads/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0775, true);
}
$filename = time() . '_' . basename($_FILES['picture']['name']);
$target_file = $upload_dir . $filename;
if (move_uploaded_file($_FILES['picture']['tmp_name'], $target_file)) {
$picture = 'assets/images/uploads/' . $filename;
}
}
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("UPDATE student_subscriptions SET full_name=?, email=?, whatsapp=?, plan_key=?, payment_status=?, status=?, civil_id=?, picture=? WHERE id=?");
$stmt->execute([$full_name, $email, $whatsapp, $plan_key, $payment_status, $status, $civil_id, $picture, $post_id]);
} else {
$stmt = db()->prepare("INSERT INTO student_subscriptions (full_name, email, whatsapp, plan_key, payment_status, status, civil_id, picture) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$full_name, $email, $whatsapp, $plan_key, $payment_status, $status, $civil_id, $picture]);
}
header('Location: ' . app_url('admin.php', ['page' => 'students']));
exit;
}
}
// list view
$search = $_GET['search'] ?? '';
$page_num = max(1, (int)($_GET['p'] ?? 1));
$limit = 10;
$offset = ($page_num - 1) * $limit;
$where = "";
$params = [];
if ($search) {
$where = "WHERE full_name LIKE ? OR email LIKE ? OR whatsapp LIKE ?";
$params = ["%$search%", "%$search%", "%$search%"];
}
$count_stmt = db()->prepare("SELECT COUNT(*) FROM student_subscriptions $where");
$count_stmt->execute($params);
$total_items = $count_stmt->fetchColumn();
$total_pages = ceil($total_items / $limit);
$stmt = db()->prepare("SELECT * FROM student_subscriptions $where ORDER BY id DESC LIMIT $limit OFFSET $offset");
$stmt->execute($params);
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<div class="section-header mb-4 d-flex justify-content-between align-items-center">
<div>
<span class="eyebrow"><?= h(t('Admin', 'الإدارة')) ?></span>
<h1 class="section-title mb-0"><?= h(t('Students', 'الطلاب')) ?></h1>
</div>
<button type="button" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);" data-bs-toggle="modal" data-bs-target="#addStudentModal">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16" class="me-1"><path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/></svg>
<?= h(t('Add Student', 'إضافة طالب')) ?>
</button>
</div>
<div class="panel-card mb-4">
<form method="get" class="d-flex gap-2 align-items-center">
<input type="hidden" name="page" value="students">
<input type="text" name="search" class="form-control w-auto" placeholder="<?= h(t('Search...', 'بحث...')) ?>" value="<?= h($search) ?>">
<button type="submit" class="btn btn-outline-secondary"><?= h(t('Filter', 'تصفية')) ?></button>
<?php if ($search): ?>
<a href="<?= h(app_url('admin.php', ['page'=>'students'])) ?>" class="btn btn-link text-secondary text-decoration-none"><?= h(t('Clear', 'مسح')) ?></a>
<?php endif; ?>
</form>
</div>
<div class="panel-card">
<div class="table-responsive">
<table class="table align-middle dashboard-table mb-0">
<thead>
<tr>
<th><?= h(t('Name', 'الاسم')) ?></th>
<th><?= h(t('Status', 'الحالة')) ?></th>
<th><?= h(t('Email', 'البريد الإلكتروني')) ?></th>
<th><?= h(t('WhatsApp', 'واتساب')) ?></th>
<th><?= h(t('Plan', 'الخطة')) ?></th>
<th><?= h(t('Payment', 'الدفع')) ?></th>
<th><?= h(t('Actions', 'إجراءات')) ?></th>
</tr>
</thead>
<tbody>
<?php foreach($items as $row): ?>
<tr>
<td>
<div class="fw-semibold"><?= h($row['full_name']) ?></div>
</td>
<td>
<?php if (($row['status'] ?? 'active') === 'active'): ?>
<span class="badge bg-success"><?= h(t('Active', 'نشط')) ?></span>
<?php else: ?>
<span class="badge bg-secondary"><?= h(t('Inactive', 'غير نشط')) ?></span>
<?php endif; ?>
</td>
<td><?= h($row['email']) ?></td>
<td><?= h($row['whatsapp']) ?></td>
<td><?= h($row['plan_key']) ?></td>
<td>
<?php if (($row['payment_status'] ?? '') === 'active'): ?>
<span class="badge bg-success"><?= h(t('Active', 'نشط')) ?></span>
<?php else: ?>
<span class="badge bg-warning text-dark"><?= h($row['payment_status']) ?></span>
<?php endif; ?>
</td>
<td>
<button type="button" class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#editStudentModal<?= $row['id'] ?>" title="<?= h(t('Edit', 'تعديل')) ?>">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/></svg>
</button>
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'students', 'action'=>'delete', 'id'=>$row['id']])) ?>" class="d-inline" onsubmit="return confirm('<?= h(t('Are you sure?', 'هل أنت متأكد؟')) ?>');">
<button type="submit" class="btn btn-sm btn-outline-danger" title="<?= h(t('Delete', 'حذف')) ?>">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/><path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/></svg>
</button>
</form>
</td>
</tr>
<!-- Edit Modal -->
<div class="modal fade" id="editStudentModal<?= $row['id'] ?>" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header border-bottom-0 pb-3" style="background-color: var(--bs-light);">
<div class="d-flex align-items-center gap-3">
<?php if (!empty($row['picture'])): ?>
<img src="<?= h($row['picture']) ?>" alt="Picture" class="rounded-circle border" style="width: 48px; height: 48px; object-fit: cover;">
<?php else: ?>
<div class="rounded-circle bg-secondary text-white d-flex align-items-center justify-content-center" style="width: 48px; height: 48px;">
<svg width="24" height="24" fill="currentColor" viewBox="0 0 16 16"><path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/></svg>
</div>
<?php endif; ?>
<div>
<h5 class="modal-title fw-bold mb-0"><?= h(t('Edit Student', 'تعديل الطالب')) ?></h5>
<div class="text-muted small fw-semibold mt-1"><?= h($row['full_name']) ?></div>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'students'])) ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="edit">
<input type="hidden" name="id" value="<?= $row['id'] ?>">
<!-- Name Bar with Background -->
<div class="mb-3 p-3 bg-light rounded border">
<label class="form-label fw-bold"><?= h(t('Name', 'الاسم')) ?></label>
<input type="text" name="full_name" class="form-control" value="<?= h($row['full_name']) ?>" required>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Civil ID', 'الرقم المدني')) ?></label>
<input type="text" name="civil_id" class="form-control" value="<?= h($row['civil_id'] ?? '') ?>">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Picture', 'الصورة')) ?></label>
<input type="file" name="picture" class="form-control" accept="image/*">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email" class="form-control" value="<?= h($row['email']) ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('WhatsApp', 'واتساب')) ?></label>
<input type="text" name="whatsapp" class="form-control" value="<?= h($row['whatsapp']) ?>">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Plan Key', 'الخطة')) ?></label>
<input type="text" name="plan_key" class="form-control" value="<?= h($row['plan_key']) ?>">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Payment Status', 'حالة الدفع')) ?></label>
<input type="text" name="payment_status" class="form-control" value="<?= h($row['payment_status']) ?>">
</div>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active" <?= ($row['status'] ?? 'active') === 'active' ? 'selected' : '' ?>><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive" <?= ($row['status'] ?? 'active') === 'inactive' ? 'selected' : '' ?>><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"><?= h(t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);"><?= h(t('Save Changes', 'حفظ التغييرات')) ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<?php if(empty($items)): ?>
<tr>
<td colspan="7" class="text-center py-4 text-secondary">
<?= h(t('No students found.', 'لم يتم العثور على طلاب.')) ?>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<?php if($total_pages > 1): ?>
<nav class="mt-4">
<ul class="pagination justify-content-center">
<?php for($i=1; $i<=$total_pages; $i++): ?>
<li class="page-item <?= $i === $page_num ? 'active' : '' ?>">
<a class="page-link" href="<?= h(app_url('admin.php', ['page'=>'students', 'p'=>$i, 'search'=>$search])) ?>"><?= $i ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
<?php endif; ?>
<!-- Add Modal -->
<div class="modal fade" id="addStudentModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header border-bottom-0 pb-3" style="background-color: var(--bs-light);">
<h5 class="modal-title fw-bold"><?= h(t('Add Student', 'إضافة طالب')) ?></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'students'])) ?>" enctype="multipart/form-data">
<input type="hidden" name="action" value="add">
<!-- Name Bar with Background -->
<div class="mb-3 p-3 bg-light rounded border">
<label class="form-label fw-bold"><?= h(t('Name', 'الاسم')) ?></label>
<input type="text" name="full_name" class="form-control" required>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Civil ID', 'الرقم المدني')) ?></label>
<input type="text" name="civil_id" class="form-control">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Picture', 'الصورة')) ?></label>
<input type="file" name="picture" class="form-control" accept="image/*">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('WhatsApp', 'واتساب')) ?></label>
<input type="text" name="whatsapp" class="form-control">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Plan Key', 'الخطة')) ?></label>
<input type="text" name="plan_key" class="form-control">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Payment Status', 'حالة الدفع')) ?></label>
<input type="text" name="payment_status" class="form-control" value="active">
</div>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active"><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive"><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"><?= h(t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);"><?= h(t('Save', 'حفظ')) ?></button>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@ -26,17 +26,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title_ar = $_POST['title_ar'] ?? '';
$summary_en = $_POST['summary_en'] ?? '';
$summary_ar = $_POST['summary_ar'] ?? '';
$status = $_POST['status'] ?? 'active';
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("UPDATE subjects SET class_id=?, title_en=?, title_ar=?, summary_en=?, summary_ar=? WHERE id=?");
$stmt->execute([$class_id, $title_en, $title_ar, $summary_en, $summary_ar, $post_id]);
$stmt = db()->prepare("UPDATE subjects SET class_id=?, title_en=?, title_ar=?, summary_en=?, summary_ar=?, status=? WHERE id=?");
$stmt->execute([$class_id, $title_en, $title_ar, $summary_en, $summary_ar, $status, $post_id]);
} else {
$slug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $title_en)));
if (empty($slug)) $slug = 'subject';
$slug .= '-' . substr(md5(uniqid()), 0, 5);
$stmt = db()->prepare("INSERT INTO subjects (slug, class_id, title_en, title_ar, summary_en, summary_ar) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$slug, $class_id, $title_en, $title_ar, $summary_en, $summary_ar]);
$stmt = db()->prepare("INSERT INTO subjects (slug, class_id, title_en, title_ar, summary_en, summary_ar, status) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$slug, $class_id, $title_en, $title_ar, $summary_en, $summary_ar, $status]);
}
header('Location: ' . app_url('admin.php', ['page' => 'subjects']));
exit;
@ -120,6 +121,7 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<tr>
<th>ID</th>
<th><?= h(t('Subject Name', 'اسم المادة')) ?></th>
<th><?= h(t('Status', 'الحالة')) ?></th>
<th><?= h(t('Details', 'تفاصيل')) ?></th>
<th><?= h(t('Class', 'الصف')) ?></th>
<th><?= h(t('Actions', 'إجراءات')) ?></th>

View File

@ -21,6 +21,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$phone = $_POST['phone'] ?? '';
$bio = $_POST['bio'] ?? '';
$status = $_POST['status'] ?? 'active';
$raw_password = $_POST['password'] ?? '';
$photo_path = '';
$existing_password = '';
@ -60,11 +61,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
if ($post_action === 'edit' && $post_id > 0) {
$stmt = db()->prepare("UPDATE teachers SET name=?, email=?, phone=?, bio=?, photo_path=?, password=? WHERE id=?");
$stmt->execute([$name, $email, $phone, $bio, $photo_path, $final_password, $post_id]);
$stmt = db()->prepare("UPDATE teachers SET name=?, email=?, phone=?, bio=?, photo_path=?, password=?, status=? WHERE id=?");
$stmt->execute([$name, $email, $phone, $bio, $photo_path, $final_password, $status, $post_id]);
} else {
$stmt = db()->prepare("INSERT INTO teachers (name, email, phone, bio, photo_path, password) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $email, $phone, $bio, $photo_path, $final_password]);
$stmt = db()->prepare("INSERT INTO teachers (name, email, phone, bio, photo_path, password, status) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $email, $phone, $bio, $photo_path, $final_password, $status]);
}
header('Location: ' . app_url('admin.php', ['page' => 'teachers']));
exit;
@ -120,6 +121,7 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<tr>
<th><?= h(t('Photo', 'الصورة')) ?></th>
<th><?= h(t('Name', 'الاسم')) ?></th>
<th><?= h(t('Status', 'الحالة')) ?></th>
<th><?= h(t('Contact', 'جهة الاتصال')) ?></th>
<th><?= h(t('Actions', 'إجراءات')) ?></th>
</tr>
@ -139,6 +141,13 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<td>
<div class="fw-semibold"><?= h($row['name']) ?></div>
</td>
<td>
<?php if (isset($row['status']) && $row['status'] === 'inactive'): ?>
<span class="badge bg-secondary"><?= h(t('Inactive', 'غير نشط')) ?></span>
<?php else: ?>
<span class="badge bg-success"><?= h(t('Active', 'نشط')) ?></span>
<?php endif; ?>
</td>
<td>
<?php if (!empty($row['email'])): ?><div><small><?= h($row['email']) ?></small></div><?php endif; ?>
<?php if (!empty($row['phone'])): ?><div><small><?= h($row['phone']) ?></small></div><?php endif; ?>
@ -168,37 +177,46 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<input type="hidden" name="action" value="edit">
<input type="hidden" name="id" value="<?= $row['id'] ?>">
<div class="mb-3">
<label class="form-label"><?= h(t('Name', 'الاسم')) ?></label>
<input type="text" name="name" class="form-control" value="<?= h($row['name']) ?>" required>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email" class="form-control" value="<?= h($row['email'] ?? '') ?>">
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Phone', 'رقم الهاتف')) ?></label>
<input type="tel" name="phone" class="form-control" value="<?= h($row['phone'] ?? '') ?>" dir="ltr">
</div>
<div class="mb-3">
<label class="form-label">
<?= h(t('Password', 'كلمة المرور')) ?>
<small class="text-muted">(<?= h(t('Leave blank to keep current', 'اتركه فارغاً للاحتفاظ بكلمة المرور الحالية')) ?>)</small>
</label>
<input type="password" name="password" class="form-control" autocomplete="new-password">
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Bio', 'نبذة')) ?></label>
<textarea name="bio" class="form-control" rows="4"><?= h($row['bio'] ?? '') ?></textarea>
</div>
<div class="mb-4">
<label class="form-label"><?= h(t('Photo', 'الصورة')) ?></label>
<?php if (!empty($row['photo_path'])): ?>
<div class="mb-2">
<img src="<?= h(asset_url($row['photo_path'])) ?>" alt="Photo" style="height: 60px; border-radius: 4px; object-fit: cover;">
</div>
<?php endif; ?>
<input type="file" name="photo" class="form-control" accept="image/*">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Name', 'الاسم')) ?></label>
<input type="text" name="name" class="form-control" value="<?= h($row['name']) ?>" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email" class="form-control" value="<?= h($row['email'] ?? '') ?>">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Phone', 'رقم الهاتف')) ?></label>
<input type="tel" name="phone" class="form-control" value="<?= h($row['phone'] ?? '') ?>" dir="ltr">
</div>
<div class="col-md-6 mb-3">
<label class="form-label">
<?= h(t('Password', 'كلمة المرور')) ?>
<small class="text-muted">(<?= h(t('Leave blank', 'اتركه فارغاً')) ?>)</small>
</label>
<input type="password" name="password" class="form-control" autocomplete="new-password">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Photo', 'الصورة')) ?></label>
<input type="file" name="photo" class="form-control" accept="image/*">
<?php if (!empty($row['photo_path'])): ?>
<div class="mt-2">
<img src="<?= h(asset_url($row['photo_path'])) ?>" alt="Photo" style="height: 40px; border-radius: 4px; object-fit: cover;">
</div>
<?php endif; ?>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active" <?= (isset($row['status']) && $row['status'] === 'active') ? 'selected' : '' ?>><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive" <?= (isset($row['status']) && $row['status'] === 'inactive') ? 'selected' : '' ?>><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
<div class="col-md-12 mb-3">
<label class="form-label"><?= h(t('Bio', 'نبذة')) ?></label>
<textarea name="bio" class="form-control" rows="3"><?= h($row['bio'] ?? '') ?></textarea>
</div>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">
@ -214,7 +232,7 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<?php endforeach; ?>
<?php if(!$items): ?>
<tr><td colspan="4" class="text-center text-secondary py-3"><?= h(t('No teachers found.', 'لا يوجد معلمون.')) ?></td></tr>
<tr><td colspan="5" class="text-center text-secondary py-3"><?= h(t('No teachers found.', 'لا يوجد معلمون.')) ?></td></tr>
<?php endif; ?>
</tbody>
</table>
@ -245,29 +263,38 @@ $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
<form method="post" enctype="multipart/form-data" action="<?= h(app_url('admin.php', ['page'=>'teachers'])) ?>">
<input type="hidden" name="action" value="add">
<div class="mb-3">
<label class="form-label"><?= h(t('Name', 'الاسم')) ?></label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email" class="form-control">
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Phone', 'رقم الهاتف')) ?></label>
<input type="tel" name="phone" class="form-control" dir="ltr">
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Password', 'كلمة المرور')) ?></label>
<input type="password" name="password" class="form-control" autocomplete="new-password" required>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Bio', 'نبذة')) ?></label>
<textarea name="bio" class="form-control" rows="4"></textarea>
</div>
<div class="mb-4">
<label class="form-label"><?= h(t('Photo', 'الصورة')) ?></label>
<input type="file" name="photo" class="form-control" accept="image/*">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Name', 'الاسم')) ?></label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Email', 'البريد الإلكتروني')) ?></label>
<input type="email" name="email" class="form-control">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Phone', 'رقم الهاتف')) ?></label>
<input type="tel" name="phone" class="form-control" dir="ltr">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Password', 'كلمة المرور')) ?></label>
<input type="password" name="password" class="form-control" autocomplete="new-password" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Photo', 'الصورة')) ?></label>
<input type="file" name="photo" class="form-control" accept="image/*">
</div>
<div class="col-md-6 mb-3">
<label class="form-label"><?= h(t('Status', 'الحالة')) ?></label>
<select name="status" class="form-select">
<option value="active" selected><?= h(t('Active', 'نشط')) ?></option>
<option value="inactive"><?= h(t('Inactive', 'غير نشط')) ?></option>
</select>
</div>
<div class="col-md-12 mb-3">
<label class="form-label"><?= h(t('Bio', 'نبذة')) ?></label>
<textarea name="bio" class="form-control" rows="3"></textarea>
</div>
</div>
<div class="d-flex justify-content-end gap-2 mt-4">

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400" viewBox="0 0 600 400"><rect width="100%" height="100%" fill="#4e73df"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="sans-serif" font-size="24" fill="#ffffff">Introduction to Web Development</text></svg>

After

Width:  |  Height:  |  Size: 305 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400" viewBox="0 0 600 400"><rect width="100%" height="100%" fill="#1cc88a"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="sans-serif" font-size="24" fill="#ffffff">Advanced Python Programming</text></svg>

After

Width:  |  Height:  |  Size: 301 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400" viewBox="0 0 600 400"><rect width="100%" height="100%" fill="#f6c23e"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="sans-serif" font-size="24" fill="#ffffff">Digital Marketing Masterclass</text></svg>

After

Width:  |  Height:  |  Size: 303 B

View File

@ -5,6 +5,11 @@ $planKey = (string) ($_GET['plan'] ?? $_POST['plan_key'] ?? 'plus');
$plan = get_plan($planKey) ?? get_plan('plus');
$cycle = (string) ($_GET['cycle'] ?? $_POST['billing_cycle'] ?? 'monthly');
$cycle = in_array($cycle, ['monthly', 'yearly'], true) ? $cycle : 'monthly';
$courseIdForView = (int) ($_GET['course_id'] ?? $_POST['course_id'] ?? 0);
$course = null;
if ($courseIdForView > 0) {
$course = db()->query("SELECT * FROM courses WHERE id = $courseIdForView")->fetch();
}
$errors = [];
$form = [
'full_name' => trim((string) ($_POST['full_name'] ?? '')),
@ -46,6 +51,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
]);
$_SESSION['subscription_id'] = $id;
$_SESSION['student_email'] = $form['email'];
$courseId = (int) ($_GET['course_id'] ?? $_POST['course_id'] ?? 0);
if ($courseId > 0) {
try {
$stmt = db()->prepare('INSERT IGNORE INTO course_students (course_id, student_id) VALUES (?, ?)');
$stmt->execute([$courseId, $id]);
} catch (Exception $e) {}
}
header('Location: ' . app_url('subscription.php', ['id' => $id, 'created' => 1]));
exit;
}
@ -76,6 +89,9 @@ render_nav('pricing.php');
<?php endif; ?>
<form method="post" class="row g-3">
<input type="hidden" name="plan_key" value="<?= h($plan['key']) ?>">
<?php if (isset($_GET['course_id']) || isset($_POST['course_id'])): ?>
<input type="hidden" name="course_id" value="<?= h($_GET['course_id'] ?? $_POST['course_id'] ?? 0) ?>">
<?php endif; ?>
<div class="col-md-6">
<label class="form-label" for="full_name"><?= h(t('Full name', 'الاسم الكامل')) ?></label>
<input class="form-control" id="full_name" name="full_name" required value="<?= h($form['full_name']) ?>">
@ -95,13 +111,17 @@ render_nav('pricing.php');
<option value="ar" <?= $form['preferred_language'] === 'ar' ? 'selected' : '' ?>>العربية</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label" for="billing_cycle"><?= h(t('Billing', 'الدفع الدوري')) ?></label>
<select class="form-select" id="billing_cycle" name="billing_cycle">
<option value="monthly" <?= $form['billing_cycle'] === 'monthly' ? 'selected' : '' ?>><?= h(t('Monthly', 'شهري')) ?></option>
<option value="yearly" <?= $form['billing_cycle'] === 'yearly' ? 'selected' : '' ?>><?= h(t('Yearly', 'سنوي')) ?></option>
</select>
</div>
<?php if ($course): ?>
<input type="hidden" name="billing_cycle" value="monthly">
<?php else: ?>
<div class="col-md-3">
<label class="form-label" for="billing_cycle"><?= h(t('Billing', 'الدفع الدوري')) ?></label>
<select class="form-select" id="billing_cycle" name="billing_cycle">
<option value="monthly" <?= $form['billing_cycle'] === 'monthly' ? 'selected' : '' ?>><?= h(t('Monthly', 'شهري')) ?></option>
<option value="yearly" <?= $form['billing_cycle'] === 'yearly' ? 'selected' : '' ?>><?= h(t('Yearly', 'سنوي')) ?></option>
</select>
</div>
<?php endif; ?>
<div class="col-12">
<div class="form-check border rounded-3 p-3">
<input class="form-check-input" type="checkbox" id="wablas_opt_in" name="wablas_opt_in" value="1" <?= $form['wablas_opt_in'] ? 'checked' : '' ?>>
@ -122,13 +142,30 @@ render_nav('pricing.php');
<div class="d-flex justify-content-between align-items-start mb-3">
<div>
<span class="eyebrow"><?= h(t('Order summary', 'ملخص الطلب')) ?></span>
<h2 class="h5 mb-1"><?= h(plan_name($plan)) ?></h2>
<p class="small text-secondary mb-0"><?= h(t('Single-platform access', 'وصول إلى منصة موحدة')) ?></p>
<?php if ($course): ?>
<h2 class="h5 mb-1"><?= h(current_lang() === 'ar' ? $course['name_ar'] : $course['name_en']) ?></h2>
<p class="small text-secondary mb-0"><?= h(t('Short course enrollment', 'تسجيل في دورة قصيرة')) ?></p>
<?php else: ?>
<h2 class="h5 mb-1"><?= h(plan_name($plan)) ?></h2>
<p class="small text-secondary mb-0"><?= h(t('Single-platform access', 'وصول إلى منصة موحدة')) ?></p>
<?php endif; ?>
</div>
<span class="badge bg-dark-subtle text-dark-emphasis border"><?= h(t('Step 1 MVP', 'النسخة الأولى')) ?></span>
</div>
<div class="summary-row"><span><?= h(t('Billing cycle', 'دورة الدفع')) ?></span><strong><?= h($cycle === 'yearly' ? t('Yearly', 'سنوي') : t('Monthly', 'شهري')) ?></strong></div>
<div class="summary-row"><span><?= h(t('Price', 'السعر')) ?></span><strong data-cycle-price><?= h(price_label($plan, $cycle)) ?></strong></div>
<div class="summary-row"><span><?= h(t('Billing cycle', 'دورة الدفع')) ?></span><strong>
<?php if ($course): ?>
<?= h(t('One-time', 'لمرة واحدة')) ?>
<?php else: ?>
<?= h($cycle === 'yearly' ? t('Yearly', 'سنوي') : t('Monthly', 'شهري')) ?>
<?php endif; ?>
</strong></div>
<div class="summary-row"><span><?= h(t('Price', 'السعر')) ?></span><strong data-cycle-price>
<?php if ($course): ?>
<?= h('$' . number_format($course['price'], 2)) ?>
<?php else: ?>
<?= h(price_label($plan, $cycle)) ?>
<?php endif; ?>
</strong></div>
<div class="summary-row"><span><?= h(t('Gateway', 'البوابة')) ?></span><strong>Thawani</strong></div>
<div class="summary-row"><span><?= h(t('Notifications', 'الإشعارات')) ?></span><strong>Wablas</strong></div>
<div class="summary-row"><span><?= h(t('Live rooms', 'الغرف المباشرة')) ?></span><strong>Google Meet</strong></div>

View File

@ -256,12 +256,50 @@ function ensure_catalog_tables(): void
function subjects_catalog(): array
{
ensure_catalog_tables();
$stmt = db()->query('SELECT * FROM subjects');
$stmt = db()->query("SELECT s.* FROM subjects s LEFT JOIN classes c ON s.class_id = c.id WHERE s.status = 'active' AND (s.class_id IS NULL OR s.class_id = 0 OR c.status = 'active')");
$rows = $stmt->fetchAll();
$result = [];
foreach ($rows as $row) {
$row['modules_en'] = json_decode($row['modules_en'], true) ?: [];
$row['modules_ar'] = json_decode($row['modules_ar'], true) ?: [];
$row['modules_en'] = json_decode($row['modules_en'] ?? '[]', true) ?: [];
$row['modules_ar'] = json_decode($row['modules_ar'] ?? '[]', true) ?: [];
$class_id = (int)$row['class_id'];
$subject_id = (int)$row['id'];
// Dynamically fetch active assigned teacher
$teacher_stmt = db()->prepare(
"SELECT t.name
FROM teacher_assignments ta
JOIN teachers t ON ta.teacher_id = t.id
WHERE t.status = 'active'
AND ta.class_id = ?
AND (ta.subject_id = ? OR ta.subject_id = 0)
LIMIT 1"
);
$teacher_stmt->execute([$class_id, $subject_id]);
$teacher_name = $teacher_stmt->fetchColumn();
if ($teacher_name) {
$row['teacher_en'] = $teacher_name;
$row['teacher_ar'] = $teacher_name;
} else {
// Check if there is an inactive teacher assigned. If so, override with empty or "No Teacher".
$inactive_stmt = db()->prepare(
"SELECT t.name
FROM teacher_assignments ta
JOIN teachers t ON ta.teacher_id = t.id
WHERE t.status = 'inactive'
AND ta.class_id = ?
AND (ta.subject_id = ? OR ta.subject_id = 0)
LIMIT 1"
);
$inactive_stmt->execute([$class_id, $subject_id]);
if ($inactive_stmt->fetchColumn()) {
$row['teacher_en'] = 'No Active Teacher';
$row['teacher_ar'] = 'لا يوجد معلم نشط';
}
}
$result[$row['slug']] = $row;
}
return $result;
@ -275,8 +313,8 @@ function plans_catalog(): array
$result = [];
foreach ($rows as $row) {
$row['key'] = $row['plan_key'];
$row['features_en'] = json_decode($row['features_en'], true) ?: [];
$row['features_ar'] = json_decode($row['features_ar'], true) ?: [];
$row['features_en'] = json_decode($row['features_en'] ?? '[]', true) ?: [];
$row['features_ar'] = json_decode($row['features_ar'] ?? '[]', true) ?: [];
$result[$row['key']] = $row;
}
return $result;

View File

@ -7,8 +7,9 @@ render_head(
);
render_nav('index.php');
$subjects = subjects_catalog();
$courses = db()->query("SELECT * FROM courses WHERE status = 'active' ORDER BY created_at DESC LIMIT 3")->fetchAll();
$plans = plans_catalog();
$metrics = ['subjects' => count($subjects), 'teachers' => 12, 'live' => 18];
$metrics = ['subjects' => count($subjects), 'teachers' => db()->query("SELECT COUNT(*) FROM teachers WHERE status = 'active'")->fetchColumn(), 'live' => 18];
?>
<main>
<section class="hero-section border-bottom">
@ -70,7 +71,41 @@ $metrics = ['subjects' => count($subjects), 'teachers' => 12, 'live' => 18];
</div>
</section>
<section class="py-5 border-bottom bg-white">
<section class="py-5 border-bottom bg-light">
<div class="container">
<div class="section-header">
<div>
<span class="eyebrow"><?= h(t('Featured Courses', 'الدورات المميزة')) ?></span>
<h2 class="section-title"><?= h(t('Enroll in specialized short courses designed to accelerate your skills.', 'سجل في دورات قصيرة متخصصة لتسريع تطوير مهاراتك.')) ?></h2>
</div>
</div>
<div class="row g-4 mt-3">
<?php foreach ($courses as $course): ?>
<div class="col-lg-4">
<article class="card h-100 border-0 shadow-sm overflow-hidden" style="border-radius: 1rem;">
<?php if (!empty($course['picture'])): ?>
<img src="<?= h($course['picture']) ?>" class="card-img-top" alt="<?= h(current_lang() === 'ar' ? $course['name_ar'] : $course['name_en']) ?>" style="height: 200px; object-fit: cover;">
<?php else: ?>
<div class="card-img-top bg-secondary" style="height: 200px;"></div>
<?php endif; ?>
<div class="card-body d-flex flex-column p-4">
<div class="d-flex justify-content-between align-items-start mb-3">
<h3 class="h5 mb-0 fw-bold"><?= h(current_lang() === 'ar' ? $course['name_ar'] : $course['name_en']) ?></h3>
<span class="badge bg-primary text-white rounded-pill fs-6 px-3 py-2"><?= h('$' . number_format($course['price'], 2)) ?></span>
</div>
<p class="text-secondary mb-4 flex-grow-1"><?= h(current_lang() === 'ar' ? $course['description_ar'] : $course['description_en']) ?></p>
<div class="d-grid mt-auto">
<a class="btn btn-dark" href="<?= h(app_url('checkout.php', ['course_id' => $course['id']])) ?>"><?= h(t('Enroll Now', 'سجل الآن')) ?></a>
</div>
</div>
</article>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<section class="py-5 border-bottom bg-white">
<div class="container">
<div class="section-header">
<div>

View File

@ -1,12 +0,0 @@
<?php
$content = file_get_contents('admin.php');
$injection = <<<HTML
<?php elseif ($page === 'classes'): ?>
<?php require_once __DIR__ . '/admin_classes.php'; ?>
<?php elseif ($page === 'subjects'): ?>
<?php require_once __DIR__ . '/admin_subjects.php'; ?>
HTML;
$content = str_replace('<?php else: ?>', $injection . "\n <?php else: "), $content);
file_put_contents('admin.php', $content);
echo "Injected.\n";

View File

@ -1,20 +0,0 @@
<?php
$content = file_get_contents('admin.php');
$new_nav_item = <<<HTML
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'classes'])) ?>" class="nav-link <?= \$page === 'classes' ? 'active' : 'link-dark' ?>" <?= \$page === 'classes' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
<?= h(t('Classes', 'الصفوف')) ?>
</a>
</li>
HTML;
$content = str_replace(
'<li>\n <a href="<?= h(app_url(\'admin.php\', [\'page\' => \'subjects\']))',
$new_nav_item . "\n " . '<li>\n <a href="<?= h(app_url(\'admin.php\', [\'page\' => \'subjects\']))',
$content
);
file_put_contents('admin.php', $content);
echo "Nav patched.\n";