39496-vm/admin.php
2026-04-06 05:37:02 +00:00

319 lines
17 KiB
PHP

<?php ob_start(); ?>
<?php
require_once __DIR__ . '/includes/app.php';
$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;
}
}
$stmt = db()->prepare("UPDATE platform_profile SET name = :name, description = :description, logo_path = :logo, favicon_path = :favicon WHERE id = 1");
$stmt->execute([
'name' => $name,
'description' => $description,
'logo' => $logo_path,
'favicon' => $favicon_path
]);
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' ?>" <?= $page === 'dashboard' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<?= h(t('Dashboard', 'لوحة القيادة')) ?>
</a>
</li>
<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>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'subjects'])) ?>" class="nav-link <?= $page === 'subjects' ? 'active' : 'link-dark' ?>" <?= $page === 'subjects' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<?= h(t('Subjects', 'المواد')) ?>
</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', 'الخطط')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'students'])) ?>" class="nav-link <?= $page === 'students' ? 'active' : 'link-dark' ?>" <?= $page === 'students' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<?= h(t('Students', 'الطلاب')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'teachers'])) ?>" class="nav-link <?= $page === 'teachers' ? 'active' : 'link-dark' ?>" <?= $page === 'teachers' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
<?= h(t('Teachers', 'المعلمون')) ?>
</a>
</li>
<li>
<a href="<?= h(app_url('admin.php', ['page' => 'assignments'])) ?>" class="nav-link <?= $page === 'assignments' ? 'active' : 'link-dark' ?>" <?= $page === 'assignments' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
<?= h(t('Assignments', 'التعيينات')) ?>
</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>
<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>
<!-- 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'): ?>
<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 $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>
<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 require_once __DIR__ . '/admin_classes.php'; ?>
<?php elseif ($page === 'subjects'): ?>
<?php require_once __DIR__ . '/admin_subjects.php'; ?>
<?php elseif ($page === 'teachers'): ?>
<?php require_once __DIR__ . '/admin_teachers.php'; ?>
<?php elseif ($page === 'integrations'): ?>
<?php require_once __DIR__ . '/admin_integrations.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>