39496-vm/admin.php
2026-04-07 18:26:56 +00:00

444 lines
33 KiB
PHP

<?php ob_start(); ?>
<?php
require_once __DIR__ . '/includes/app.php';
require_once __DIR__ . '/includes/auth.php';
require_login();
$page = $_GET['page'] ?? 'dashboard';
$action = $_GET['action'] ?? '';
// Handle Profile Update
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $page === 'profile') {
$name = $_POST['name'] ?? '';
$description = $_POST['description'] ?? '';
$logo_path = get_platform_profile()['logo_path'] ?? '';
$favicon_path = get_platform_profile()['favicon_path'] ?? '';
$upload_dir = __DIR__ . '/assets/images/uploads/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
if (!empty($_FILES['logo']['tmp_name'])) {
$filename = 'logo_' . time() . '_' . basename($_FILES['logo']['name']);
$target = $upload_dir . $filename;
if (move_uploaded_file($_FILES['logo']['tmp_name'], $target)) {
$logo_path = 'assets/images/uploads/' . $filename;
}
}
if (!empty($_FILES['favicon']['tmp_name'])) {
$filename = 'favicon_' . time() . '_' . basename($_FILES['favicon']['name']);
$target = $upload_dir . $filename;
if (move_uploaded_file($_FILES['favicon']['tmp_name'], $target)) {
$favicon_path = 'assets/images/uploads/' . $filename;
}
}
$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,
'ctr_no' => $ctr_no,
'telephone_no' => $telephone_no,
'email_id' => $email_id
]);
header('Location: ' . app_url('admin.php', ['page' => 'profile', 'saved' => 1]));
exit;
}
$metrics = subscription_metrics();
$recent = fetch_recent_subscriptions();
render_head(
t('Admin', 'الإدارة') . ' - ' . ucfirst($page),
t('Manage your learning platform.', 'إدارة منصة التعلم الخاصة بك.')
);
?>
<nav class="navbar navbar-expand-lg bg-white border-bottom sticky-top admin-navbar" style="z-index: 1040;">
<div class="container-fluid px-3 px-md-4">
<a class="navbar-brand fw-semibold d-flex align-items-center" href="<?= h(app_url('index.php')) ?>" target="_blank">
<?php $prof = get_platform_profile(); if (!empty($prof['logo_path'])): ?>
<img src="<?= h(asset_url($prof['logo_path'])) ?>" alt="Logo" style="height: 32px; margin-right: 8px; border-radius: 4px;">
<?php endif; ?>
<span style="color: var(--accent);"><?= h(app_name()) ?></span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#adminNavbar" aria-controls="adminNavbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="adminNavbar">
<ul class="navbar-nav mb-2 mb-lg-0 align-items-center gap-3">
<li class="nav-item">
<div class="btn-group btn-group-sm" role="group">
<a class="btn btn-outline-dark <?= current_lang() === 'en' ? 'active' : '' ?>" href="<?= h(page_lang_link('en')) ?>">EN</a>
<a class="btn btn-outline-dark <?= current_lang() === 'ar' ? 'active' : '' ?>" href="<?= h(page_lang_link('ar')) ?>">AR</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle d-flex align-items-center gap-2" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<div class="bg-light rounded-circle d-flex align-items-center justify-content-center" style="width: 32px; height: 32px; border: 1px solid var(--border);">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m8-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 1"/>
</svg>
</div>
<span class="fw-medium"><?= h(t('Admin', 'المدير')) ?></span>
</a>
<ul class="dropdown-menu dropdown-menu-end shadow-sm">
<li><a class="dropdown-item" href="<?= h(app_url('admin.php', ['page' => 'profile'])) ?>"><?= h(t('Platform Profile', 'ملف المنصة')) ?></a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="<?= h(app_url('index.php')) ?>"><?= h(t('Exit Admin', 'خروج من الإدارة')) ?></a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="d-flex flex-column flex-md-row" style="min-height: calc(100vh - 61px); overflow: hidden;">
<!-- Sidebar -->
<aside class="d-flex flex-column flex-shrink-0 p-3 bg-white border-end shadow-sm admin-sidebar">
<div class="fs-5 fw-bold mb-3 mt-2 px-2 text-secondary d-none d-md-block"><?= h(t('Admin Menu', 'قائمة الإدارة')) ?></div>
<ul class="nav nav-pills flex-row flex-md-column mb-auto gap-2 flex-wrap">
<li class="nav-item">
<a href="<?= h(app_url('admin.php', ['page' => 'dashboard'])) ?>" class="nav-link <?= $page === 'dashboard' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'dashboard' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-speedometer2" viewBox="0 0 16 16">
<path d="M8 4a.5.5 0 0 1 .5.5V6a.5.5 0 0 1-1 0V4.5A.5.5 0 0 1 8 4M3.732 5.732a.5.5 0 0 1 .707 0l.915.914a.5.5 0 1 1-.708.708l-.914-.915a.5.5 0 0 1 0-.707M2 10a.5.5 0 0 1 .5-.5h1.586a.5.5 0 0 1 0 1H2.5A.5.5 0 0 1 2 10m9.5 0a.5.5 0 0 1 .5-.5h1.5a.5.5 0 0 1 0 1H12a.5.5 0 0 1-.5-.5m.754-4.246a.389.389 0 0 0-.527-.02L7.547 9.31a.91.91 0 1 0 1.302 1.258l3.434-4.297a.389.389 0 0 0-.029-.518z"/>
<path fill-rule="evenodd" d="M0 10a8 8 0 1 1 15.547 2.661c-.442 1.253-1.845 1.602-2.932 1.25C11.309 13.488 9.475 13 8 13c-1.474 0-3.31.488-4.615.911-1.087.352-2.49.003-2.932-1.25A7.988 7.988 0 0 1 0 10m8-7a7 7 0 0 0-6.603 9.329c.203.575.923.876 1.68.63C4.397 12.533 6.358 12 8 12s3.604.532 4.923.96c.757.245 1.477-.056 1.68-.631A7 7 0 0 0 8 3"/>
</svg>
<?= h(t('Dashboard', 'لوحة القيادة')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'classes'])) ?>" class="nav-link <?= $page === 'classes' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'classes' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-diagram-3" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5zM8.5 5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5zM0 11.5A1.5 1.5 0 0 1 1.5 10h1A1.5 1.5 0 0 1 4 11.5v1A1.5 1.5 0 0 1 2.5 14h-1A1.5 1.5 0 0 1 0 12.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm4.5.5A1.5 1.5 0 0 1 7.5 10h1a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 8.5 14h-1A1.5 1.5 0 0 1 6 12.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm4.5.5a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"/>
</svg>
<?= h(t('Classes', 'الصفوف')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'subjects'])) ?>" class="nav-link <?= $page === 'subjects' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'subjects' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-book" viewBox="0 0 16 16">
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.814 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.814 8.985.936 8 1.783"/>
</svg>
<?= h(t('Subjects', 'المواد')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'courses'])) ?>" class="nav-link <?= $page === 'courses' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'courses' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-btn" viewBox="0 0 16 16">
<path d="M6.79 5.093A.5.5 0 0 0 6 5.5v5a.5.5 0 0 0 .79.407l3.5-2.5a.5.5 0 0 0 0-.814z"/>
<path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"/>
</svg>
<?= h(t('Courses', 'الدورات')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'plans'])) ?>" class="nav-link <?= $page === 'plans' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'plans' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tags" viewBox="0 0 16 16">
<path d="M3 2v4.586l7 7L14.586 9l-7-7zM2 2a1 1 0 0 1 1-1h4.586a1 1 0 0 1 .707.293l7 7a1 1 0 0 1 0 1.414l-4.586 4.586a1 1 0 0 1-1.414 0l-7-7A1 1 0 0 1 2 6.586z"/>
<path d="M5.5 5a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1m0 1a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M1 7.086a1 1 0 0 0 .293.707L8.75 15.25l-.043.043a1 1 0 0 1-1.414 0l-7-7A1 1 0 0 1 0 7.586V3a1 1 0 0 1 1-1z"/>
</svg>
<?= h(t('Plans', 'الخطط')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'students'])) ?>" class="nav-link <?= $page === 'students' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'students' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<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 4 0 .667.333 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>
<?= h(t('Students', 'الطلاب')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'teachers'])) ?>" class="nav-link <?= $page === 'teachers' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'teachers' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-video3" viewBox="0 0 16 16">
<path d="M14 9.5a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm-6 5.7c0 .8.8.8.8.8h6.4s.8 0 .8-.8-.8-3.2-4-3.2-4 2.4-4 3.2Z"/>
<path d="M2 2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h5.243c.122-.326.295-.668.526-1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v7.81c.353.23.656.496.91.783C15.965 12.022 16 11.531 16 11V4a2 2 0 0 0-2-2H2Z"/>
</svg>
<?= h(t('Teachers', 'المعلمون')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'assignments'])) ?>" class="nav-link <?= $page === 'assignments' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'assignments' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-journal-text" viewBox="0 0 16 16">
<path d="M5 10.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0-2a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5z"/>
<path d="M3 0h10a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-1h1v1a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v1H1V2a2 2 0 0 1 2-2z"/>
<path d="M1 5v-.5a.5.5 0 0 1 1 0V5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0V8h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1zm0 3v-.5a.5.5 0 0 1 1 0v.5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H1z"/>
</svg>
<?= h(t('Assignments', 'التعيينات')) ?>
</a>
</li>
<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', 'landing', 'users', 'roles']) ? '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', 'landing', 'users', 'roles']) ? '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 mb-1">
<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>
<li class="nav-item mb-1">
<a href="<?= h(app_url('admin.php', ['page' => 'landing'])) ?>" class="nav-link <?= $page === 'landing' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'landing' ? '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-layout-text-window-reverse" viewBox="0 0 16 16">
<path d="M13 6.5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h5a.5.5 0 0 0 .5-.5m0 3a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h5a.5.5 0 0 0 .5-.5m-.5 2.5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1 0-1z"/>
<path d="M14 0a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zM2 1a1 1 0 0 0-1 1v1h14V2a1 1 0 0 0-1-1zM1 4v10a1 1 0 0 0 1 1h2V4zm4 0v11h9a1 1 0 0 0 1-1V4z"/>
</svg>
<?= h(t('Landing Page', 'الصفحة الرئيسية')) ?>
</a>
</li>
<?php if (has_permission('users', 'view')): ?>
<li class="nav-item">
<a href="<?= h(app_url('admin.php', ['page' => 'users'])) ?>" class="nav-link <?= $page === 'users' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'users' ? '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-shield-lock" viewBox="0 0 16 16">
<path d="M5.338 1.59a61.44 61.44 0 0 0-2.837.856.481.481 0 0 0-.328.39c-.554 4.157.726 7.19 2.253 9.188a10.725 10.725 0 0 0 2.287 2.233c.346.244.652.42.893.533.12.057.218.095.293.118a.55.55 0 0 0 .101.025.615.615 0 0 0 .1-.025c.076-.023.174-.061.294-.118.24-.113.547-.29.893-.533a10.726 10.726 0 0 0 2.287-2.233c1.527-1.997 2.807-5.031 2.253-9.188a.48.48 0 0 0-.328-.39c-.651-.213-1.75-.56-2.837-.855C9.552 1.29 8.531 1.067 8 1.067c-.53 0-1.552.223-2.662.524zM5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.775 11.775 0 0 1-2.517 2.453 7.159 7.159 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7.158 7.158 0 0 1-1.048-.625 11.777 11.777 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 62.456 62.456 0 0 1 5.072.56z"/>
<path d="M9.5 6.5a1.5 1.5 0 0 1-1 1.415l.385 1.99a.5.5 0 0 1-.491.595h-.788a.5.5 0 0 1-.49-.595l.384-1.99a1.5 1.5 0 1 1 2-1.415z"/>
</svg>
<?= h(t('Platform Users', 'مستخدمي المنصة')) ?>
</a>
</li>
<?php if (has_permission('roles', 'view')): ?>
<li class="nav-item mb-1">
<a href="<?= h(app_url('admin.php', ['page' => 'roles'])) ?>" class="nav-link <?= $page === 'roles' ? 'active' : 'link-dark' ?> d-flex align-items-center gap-2" <?= $page === 'roles' ? '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-lines-fill" viewBox="0 0 16 16">
<path d="M6 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-5 6s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H1zM11 3.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5zm.5 2.5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4zm2 3a.5.5 0 0 0 0 1h2a.5.5 0 0 0 0-1h-2zm0 3a.5.5 0 0 0 0 1h2a.5.5 0 0 0 0-1h-2z"/>
</svg>
<?= h(t('Role Groups', 'مجموعات الصلاحيات')) ?>
</a>
</li>
<?php endif; ?>
<?php endif; ?>
</ul>
</div>
</li>
</ul>
</aside>
<!-- Content Area -->
<main class="flex-grow-1 d-flex flex-column" style="height: calc(100vh - 61px); overflow-y: auto;">
<div class="p-4 p-md-5 flex-grow-1">
<?php if ($page === 'dashboard'): ?>
<?php require_permission('dashboard', 'view'); ?>
<div class="section-header mb-4">
<div>
<span class="eyebrow"><?= h(t('Admin', 'الإدارة')) ?></span>
<h1 class="section-title mb-2"><?= h(t('Platform subscription overview', 'نظرة عامة على اشتراكات المنصة')) ?></h1>
<p class="text-secondary mb-0"><?= h(t('This first admin screen focuses on the subscription funnel that powers student access.', 'تركز شاشة الإدارة الأولى هذه على مسار الاشتراك الذي يغذي وصول الطلاب.')) ?></p>
</div>
</div>
<div class="row g-3 mb-4">
<div class="col-md-4"><div class="metric-card tall"><strong><?= h((string) $metrics['total']) ?></strong><span><?= h(t('total subscriptions', 'إجمالي الاشتراكات')) ?></span></div></div>
<div class="col-md-4"><div class="metric-card tall"><strong><?= h((string) $metrics['active']) ?></strong><span><?= h(t('active plans', 'خطط نشطة')) ?></span></div></div>
<div class="col-md-4"><div class="metric-card tall"><strong><?= h((string) $metrics['arabic']) ?></strong><span><?= h(t('Arabic preference', 'تفضيل العربية')) ?></span></div></div>
</div>
<div class="panel-card">
<div class="d-flex justify-content-between align-items-center mb-3">
<h2 class="h5 mb-0"><?= h(t('Latest subscriptions', 'أحدث الاشتراكات')) ?></h2>
</div>
<?php if (!$recent): ?>
<div class="empty-state-inline"><?= h(t('No subscriptions recorded yet.', 'لم يتم تسجيل أي اشتراكات بعد.')) ?></div>
<?php else: ?>
<div class="table-responsive">
<table class="table align-middle dashboard-table mb-0">
<thead>
<tr>
<th>#</th>
<th><?= h(t('Student', 'الطالب')) ?></th>
<th><?= h(t('Plan', 'الخطة')) ?></th>
<th><?= h(t('Language', 'اللغة')) ?></th>
<th><?= h(t('Payment', 'الدفع')) ?></th>
<th><?= h(t('Detail', 'التفاصيل')) ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($recent as $item): ?>
<?php $plan = get_plan($item['plan_key']) ?? get_plan('plus'); ?>
<tr>
<td><?= h((string) $item['id']) ?></td>
<td>
<div class="fw-semibold"><?= h($item['full_name']) ?></div>
<div class="small text-secondary"><?= h($item['email']) ?></div>
</td>
<td><?= h(plan_name($plan)) ?></td>
<td><?= h($item['preferred_language'] === 'ar' ? 'العربية' : 'English') ?></td>
<td><span class="<?= h(status_badge((string) $item['payment_status'])) ?>"><?= h((string) $item['payment_status']) ?></span></td>
<td><a class="btn btn-sm btn-outline-dark" href="<?= h(app_url('subscription.php', ['id' => (int) $item['id']])) ?>"><?= h(t('Open', 'فتح')) ?></a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
<?php elseif ($page === 'profile'): ?>
<?php if (get_logged_in_user()['role'] !== 'admin' || !empty(get_logged_in_user()['role_id'])) die('Access Denied'); ?>
<?php $prof = get_platform_profile(); ?>
<div class="section-header mb-4">
<div>
<span class="eyebrow"><?= h(t('Settings', 'الإعدادات')) ?></span>
<h1 class="section-title mb-2"><?= h(t('Platform Profile', 'ملف المنصة')) ?></h1>
<p class="text-secondary mb-0"><?= h(t('Update your platforms name, description, logo, and favicon.', 'قم بتحديث اسم منصتك ووصفها وشعارها والأيقونة المفضلة.')) ?></p>
</div>
</div>
<?php if (!empty($_GET['saved'])): ?>
<div class="alert alert-success"><?= h(t('Profile updated successfully.', 'تم تحديث الملف بنجاح.')) ?></div>
<?php endif; ?>
<div class="panel-card" style="max-width: 600px;">
<form method="post" enctype="multipart/form-data">
<div class="mb-3">
<label class="form-label"><?= h(t('Platform Name', 'اسم المنصة')) ?></label>
<input type="text" name="name" class="form-control" value="<?= h($prof['name'] ?? '') ?>" required>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Description', 'الوصف')) ?></label>
<textarea name="description" class="form-control" rows="3"><?= h($prof['description'] ?? '') ?></textarea>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Logo', 'الشعار')) ?></label>
<?php if (!empty($prof['logo_path'])): ?>
<div class="mb-2">
<img src="<?= h(asset_url($prof['logo_path'])) ?>" alt="Logo" style="height: 60px; border: 1px solid var(--border); border-radius: 8px; padding: 4px; background: #fff;">
</div>
<?php endif; ?>
<input type="file" name="logo" class="form-control" accept="image/*">
</div>
<div class="mb-4">
<label class="form-label"><?= h(t('Favicon', 'الأيقونة المفضلة')) ?></label>
<?php if (!empty($prof['favicon_path'])): ?>
<div class="mb-2">
<img src="<?= h(asset_url($prof['favicon_path'])) ?>" alt="Favicon" style="height: 32px; border: 1px solid var(--border); border-radius: 4px; padding: 2px; background: #fff;">
</div>
<?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 === 'plans'): ?>
<?php require_once __DIR__ . '/admin_plans.php'; ?>
<?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 === 'users'): ?>
<?php require_once __DIR__ . '/admin_users.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 elseif ($page === 'landing'): ?>
<?php require_once __DIR__ . '/admin_landing.php'; ?>
<?php elseif ($page === 'roles'): ?>
<?php require_once __DIR__ . '/admin_roles.php'; ?>
<?php else: ?>
<div class="section-header mb-4">
<div>
<h1 class="section-title mb-2"><?= h(ucfirst($page)) ?></h1>
</div>
</div>
<div class="panel-card">
<div class="empty-state-inline">
<?= h(t('This section is currently under construction. More admin features coming soon!', 'هذا القسم قيد الإنشاء حالياً. المزيد من ميزات الإدارة قريباً!')) ?>
</div>
</div>
<?php endif; ?>
</div>
<footer class="bg-white border-top py-3 mt-auto w-100">
<div class="container-fluid px-4 px-md-5 d-flex justify-content-between align-items-center small text-secondary">
<div>
&copy; <?= date('Y') ?> <?= h(app_name()) ?>. <?= h(t('All rights reserved.', 'جميع الحقوق محفوظة.')) ?>
</div>
<div>
<a href="<?= h(app_url('index.php')) ?>" class="text-decoration-none text-secondary"><?= h(t('View Site', 'عرض الموقع')) ?></a>
</div>
</div>
</footer>
</main>
</div>
<style>
.admin-sidebar {
width: 280px;
height: calc(100vh - 61px);
overflow-y: auto;
}
.admin-navbar {
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
@media (max-width: 767.98px) {
.admin-sidebar {
width: 100%;
height: auto;
border-right: none !important;
border-bottom: 1px solid var(--border);
}
}
</style>
<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>