Autosave: 20260407-180449
This commit is contained in:
parent
2346253cfd
commit
43c2d25666
73
admin.php
73
admin.php
@ -109,55 +109,78 @@ render_head(
|
||||
<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;"' : '' ?>>
|
||||
<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' ?>" <?= $page === 'classes' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
|
||||
<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' ?>" <?= $page === 'subjects' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
|
||||
<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' ?>" <?= $page === 'courses' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
|
||||
<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' ?>" <?= $page === 'plans' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
|
||||
<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>
|
||||
<?php if (get_logged_in_user()['role'] === 'admin'): ?>
|
||||
<li>
|
||||
<a href="<?= h(app_url('admin.php', ['page' => 'users'])) ?>" class="nav-link <?= $page === 'users' ? 'active' : 'link-dark' ?>" <?= $page === 'users' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
|
||||
<?= h(t('Platform Users', 'مستخدمي المنصة')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<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;"' : '' ?>>
|
||||
<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' ?>" <?= $page === 'teachers' ? 'style="background-color: var(--accent); color: white;"' : '' ?>>
|
||||
<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' ?>" <?= $page === 'assignments' ? 'style="background-color: var(--accent); color: white;"' : '' ?> >
|
||||
<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']) ? 'true' : 'false' ?>" aria-controls="settingsCollapse" style="font-size: 0.95rem; letter-spacing: 0.5px;">
|
||||
<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']) ? '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"/>
|
||||
@ -170,7 +193,7 @@ render_head(
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div class="collapse <?= in_array($page, ['profile', 'integrations', 'landing']) ? 'show' : '' ?>" id="settingsCollapse">
|
||||
<div class="collapse <?= in_array($page, ['profile', 'integrations', 'landing', 'users']) ? '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;"' : '' ?>>
|
||||
@ -181,16 +204,15 @@ render_head(
|
||||
<?= h(t('Platform Profile', 'ملف المنصة')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<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">
|
||||
<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"/>
|
||||
@ -199,6 +221,17 @@ render_head(
|
||||
<?= h(t('Landing Page', 'الصفحة الرئيسية')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php if (get_logged_in_user()['role'] === 'admin'): ?>
|
||||
<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 endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@ -607,6 +607,7 @@ if (!empty($prof['favicon_path'])):
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="<?= h(asset_url('assets/css/custom.css')) ?>">
|
||||
</head>
|
||||
<body class="app-shell <?= is_rtl() ? 'rtl' : 'ltr' ?>">
|
||||
|
||||
237
patch_admin.php
237
patch_admin.php
@ -1,237 +0,0 @@
|
||||
<?php
|
||||
$content = file_get_contents('admin_courses.php');
|
||||
|
||||
// 1. Add post actions
|
||||
$post_actions_orig = " if (\$post_action === 'edit' || \$post_action === 'add') {";
|
||||
$post_actions_new = <<<PHP
|
||||
if (\$post_action === 'close_all_registration') {
|
||||
db()->query("UPDATE courses SET registration_open = 0");
|
||||
header('Location: ' . app_url('admin.php', ['page' => 'courses']));
|
||||
exit;
|
||||
}
|
||||
if (\$post_action === 'open_all_registration') {
|
||||
db()->query("UPDATE courses SET registration_open = 1");
|
||||
header('Location: ' . app_url('admin.php', ['page' => 'courses']));
|
||||
exit;
|
||||
}
|
||||
if (\$post_action === 'reset_all_students') {
|
||||
db()->query("TRUNCATE TABLE course_students");
|
||||
header('Location: ' . app_url('admin.php', ['page' => 'courses']));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (\$post_action === 'edit' || \$post_action === 'add') {
|
||||
PHP;
|
||||
$content = str_replace($post_actions_orig, $post_actions_new, $content);
|
||||
|
||||
// 2. Add max_students and registration_open to post
|
||||
$vars_orig = <<<PHP
|
||||
$status = $_POST['status'] ?? 'active';
|
||||
$price = (float)($_POST['price'] ?? 0);
|
||||
PHP;
|
||||
$vars_new = <<<PHP
|
||||
$status = $_POST['status'] ?? 'active';
|
||||
$price = (float)($_POST['price'] ?? 0);
|
||||
$max_students = (isset($_POST['max_students']) && $_POST['max_students'] !== '') ? (int)$_POST['max_students'] : null;
|
||||
$registration_open = isset($_POST['registration_open']) ? 1 : 0;
|
||||
PHP;
|
||||
$content = str_replace($vars_orig, $vars_new, $content);
|
||||
|
||||
// 3. Update query edit
|
||||
$edit_orig = '$stmt = db()->prepare("UPDATE courses SET name_en=?, name_ar=?, description_en=?, description_ar=?, status=?, price=?, picture=? WHERE id=?");' . "\n" .
|
||||
' $stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $price, $picture, $post_id]);';
|
||||
$edit_new = '$stmt = db()->prepare("UPDATE courses SET name_en=?, name_ar=?, description_en=?, description_ar=?, status=?, price=?, picture=?, max_students=?, registration_open=? WHERE id=?");' . "\n" .
|
||||
' $stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $price, $picture, $max_students, $registration_open, $post_id]);';
|
||||
$content = str_replace($edit_orig, $edit_new, $content);
|
||||
|
||||
// 4. Update query add
|
||||
$add_orig = '$stmt = db()->prepare("INSERT INTO courses (name_en, name_ar, description_en, description_ar, status, price, picture) VALUES (?, ?, ?, ?, ?, ?, ?)");' . "\n" .
|
||||
' $stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $price, $picture]);';
|
||||
$add_new = '$stmt = db()->prepare("INSERT INTO courses (name_en, name_ar, description_en, description_ar, status, price, picture, max_students, registration_open) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");' . "\n" .
|
||||
' $stmt->execute([$name_en, $name_ar, $desc_en, $desc_ar, $status, $price, $picture, $max_students, $registration_open]);';
|
||||
$content = str_replace($add_orig, $add_new, $content);
|
||||
|
||||
// 5. Add bulk buttons
|
||||
$buttons_orig = <<<PHP
|
||||
<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">
|
||||
PHP;
|
||||
$buttons_new = <<<PHP
|
||||
<div>
|
||||
<h1 class="section-title mb-2"><?= h(t('Courses', 'الدورات')) ?></h1>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2 justify-content-end">
|
||||
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" class="m-0" onsubmit="return confirm('<?= h(t('Close registration for all courses?', 'هل أنت متأكد من إغلاق التسجيل لجميع الدورات؟')) ?>');">
|
||||
<input type="hidden" name="action" value="close_all_registration">
|
||||
<button type="submit" class="btn btn-outline-warning btn-sm"><?= h(t('Close All', 'إغلاق الكل')) ?></button>
|
||||
</form>
|
||||
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" class="m-0" onsubmit="return confirm('<?= h(t('Open registration for all courses?', 'هل أنت متأكد من فتح التسجيل لجميع الدورات؟')) ?>');">
|
||||
<input type="hidden" name="action" value="open_all_registration">
|
||||
<button type="submit" class="btn btn-outline-success btn-sm"><?= h(t('Open All', 'فتح الكل')) ?></button>
|
||||
</form>
|
||||
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'courses'])) ?>" class="m-0" onsubmit="return confirm('<?= h(t('Are you absolutely sure you want to remove ALL students from ALL courses to start a new batch?', 'هل أنت متأكد تماماً أنك تريد إزالة جميع الطلاب من جميع الدورات لبدء دفعة جديدة؟')) ?>');">
|
||||
<input type="hidden" name="action" value="reset_all_students">
|
||||
<button type="submit" class="btn btn-outline-danger btn-sm"><?= h(t('Reset Batch', 'إعادة ضبط الدفعة')) ?></button>
|
||||
</form>
|
||||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addCourseModal" style="background-color: var(--accent); border-color: var(--accent);">+ <?= h(t('Add Course', 'إضافة دورة')) ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-card mb-4">
|
||||
PHP;
|
||||
$content = str_replace($buttons_orig, $buttons_new, $content);
|
||||
|
||||
// 6. List view columns
|
||||
$th_orig = <<<PHP
|
||||
<th><?= h(t('Assigned', 'مخصص')) ?></th>
|
||||
<th class="text-end"><?= h(t('Actions', 'إجراءات')) ?></th>
|
||||
PHP;
|
||||
$th_new = <<<PHP
|
||||
<th><?= h(t('Assigned', 'مخصص')) ?></th>
|
||||
<th><?= h(t('Reg.', 'التسجيل')) ?></th>
|
||||
<th class="text-end"><?= h(t('Actions', 'إجراءات')) ?></th>
|
||||
PHP;
|
||||
$content = str_replace($th_orig, $th_new, $content);
|
||||
|
||||
$td_orig = <<<PHP
|
||||
<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', 'إدارة الطلاب')) ?>">
|
||||
PHP;
|
||||
$td_new = <<<PHP
|
||||
<td>
|
||||
<span class="badge bg-info text-dark"><?= $assigned_count ?></span>
|
||||
<?php if ($row['max_students']): ?>
|
||||
<span class="badge bg-secondary">/ <?= h($row['max_students']) ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-truncate" style="max-width: 200px;">
|
||||
<?= h(current_lang() === 'ar' ? $row['description_ar'] : $row['description_en']) ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($row['registration_open']): ?>
|
||||
<span class="badge bg-success"><?= h(t('Open', 'مفتوح')) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-danger"><?= h(t('Closed', 'مغلق')) ?></span>
|
||||
<?php endif; ?>
|
||||
</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', 'إدارة الطلاب')) ?>">
|
||||
PHP;
|
||||
$content = str_replace($td_orig, $td_new, $content);
|
||||
|
||||
// 7. Modals
|
||||
$edit_modal_orig = <<<PHP
|
||||
<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;
|
||||
$edit_modal_new = <<<PHP
|
||||
<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('Max Students', 'الحد الأقصى للطلاب')) ?></label>
|
||||
<input type="number" name="max_students" class="form-control" placeholder="<?= h(t('Empty = unlimited', 'فارغ = غير محدود')) ?>" value="<?= h($row['max_students']) ?>">
|
||||
</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;
|
||||
$content = str_replace($edit_modal_orig, $edit_modal_new, $content);
|
||||
|
||||
$edit_modal_orig2 = <<<PHP
|
||||
<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>
|
||||
PHP;
|
||||
$edit_modal_new2 = <<<PHP
|
||||
<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 class="col-12 mb-3">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" name="registration_open" id="regSwitch<?= $row['id'] ?>" value="1" <?= $row['registration_open'] ? 'checked' : '' ?>/>
|
||||
<label class="form-check-label" for="regSwitch<?= $row['id'] ?>"><?= h(t('Registration Open', 'التسجيل مفتوح')) ?></label>
|
||||
</div>
|
||||
</div>
|
||||
PHP;
|
||||
$content = str_replace($edit_modal_orig2, $edit_modal_new2, $content);
|
||||
|
||||
$add_modal_orig = <<<PHP
|
||||
<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/*">
|
||||
PHP;
|
||||
$add_modal_new = <<<PHP
|
||||
<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('Max Students', 'الحد الأقصى للطلاب')) ?></label>
|
||||
<input type="number" name="max_students" class="form-control" placeholder="<?= h(t('Empty = unlimited', 'فارغ = غير محدود')) ?>">
|
||||
</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;
|
||||
$content = str_replace($add_modal_orig, $add_modal_new, $content);
|
||||
|
||||
$add_modal_orig2 = <<<PHP
|
||||
<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>
|
||||
PHP;
|
||||
$add_modal_new2 = <<<PHP
|
||||
<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 class="col-12 mb-3">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" name="registration_open" id="regSwitchAdd" value="1" checked>
|
||||
<label class="form-check-label" for="regSwitchAdd"><?= h(t('Registration Open', 'التسجيل مفتوح')) ?></label>
|
||||
</div>
|
||||
</div>
|
||||
PHP;
|
||||
$content = str_replace($add_modal_orig2, $add_modal_new2, $content);
|
||||
|
||||
|
||||
file_put_contents('admin_courses.php', $content);
|
||||
echo "Done";
|
||||
?>
|
||||
187
patch_admin.py
187
patch_admin.py
@ -1,187 +0,0 @@
|
||||
import re
|
||||
import os
|
||||
|
||||
admin_landing_path = 'admin_landing.php'
|
||||
with open(admin_landing_path, 'r', encoding='utf-8') as f:
|
||||
admin_landing_content = f.read()
|
||||
|
||||
# Replace the save logic and the form rendering logic in admin_landing.php
|
||||
new_php_logic = """
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'save_landing') {
|
||||
$settings = $_POST['settings'] ?? [];
|
||||
|
||||
# Save text settings
|
||||
$stmt = $pdo->prepare("INSERT INTO landing_settings (setting_key, value_en, value_ar) VALUES (:key, :en, :ar) ON DUPLICATE KEY UPDATE value_en = :en, value_ar = :ar");
|
||||
foreach ($settings as $key => $values) {
|
||||
$stmt->execute([
|
||||
'key' => $key,
|
||||
'en' => $values['en'] ?? '',
|
||||
'ar' => $values['ar'] ?? ''
|
||||
]);
|
||||
}
|
||||
|
||||
# Save image settings
|
||||
$upload_dir = __DIR__ . '/assets/images/uploads/';
|
||||
if (!is_dir($upload_dir)) {
|
||||
mkdir($upload_dir, 0775, true);
|
||||
}
|
||||
|
||||
$sections = ['hero', 'courses', 'subjects', 'flow', 'plans'];
|
||||
foreach ($sections as $sec) {
|
||||
if (isset($_FILES['images']['error'][$sec]) && $_FILES['images']['error'][$sec] === UPLOAD_ERR_OK) {
|
||||
$filename = time() . '_' . basename($_FILES['images']['name'][$sec]);
|
||||
$target_file = $upload_dir . $filename;
|
||||
if (move_uploaded_file($_FILES['images']['tmp_name'][$sec], $target_file)) {
|
||||
$picture = 'assets/images/uploads/' . $filename;
|
||||
$stmt->execute([
|
||||
'key' => $sec . '_image',
|
||||
'en' => $picture,
|
||||
'ar' => $picture
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: ' . app_url('admin.php', ['page' => 'landing', 'saved' => 1]));
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $pdo->query("SELECT setting_key, value_en, value_ar FROM landing_settings");
|
||||
$all_settings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$settings = [];
|
||||
foreach ($all_settings as $row) {
|
||||
$settings[$row['setting_key']] = $row;
|
||||
}
|
||||
|
||||
$sections = [
|
||||
'hero' => [
|
||||
'label' => 'Hero Section / القسم الأول',
|
||||
'fields' => [
|
||||
'eyebrow' => ['label' => 'Eyebrow / النص الصغير', 'type' => 'text'],
|
||||
'title' => ['label' => 'Title / العنوان الرئيسي', 'type' => 'textarea'],
|
||||
'desc' => ['label' => 'Description / الوصف', 'type' => 'textarea'],
|
||||
]
|
||||
],
|
||||
'courses' => [
|
||||
'label' => 'Courses Section / قسم الدورات',
|
||||
'fields' => [
|
||||
'eyebrow' => ['label' => 'Eyebrow / النص الصغير', 'type' => 'text'],
|
||||
'title' => ['label' => 'Title / العنوان الرئيسي', 'type' => 'textarea'],
|
||||
]
|
||||
],
|
||||
'subjects' => [
|
||||
'label' => 'Subjects Section / قسم المواد',
|
||||
'fields' => [
|
||||
'eyebrow' => ['label' => 'Eyebrow / النص الصغير', 'type' => 'text'],
|
||||
'title' => ['label' => 'Title / العنوان الرئيسي', 'type' => 'textarea'],
|
||||
]
|
||||
],
|
||||
'flow' => [
|
||||
'label' => 'Delivery Flow Section / قسم مسار التسليم',
|
||||
'fields' => [
|
||||
'eyebrow' => ['label' => 'Eyebrow / النص الصغير', 'type' => 'text'],
|
||||
'title' => ['label' => 'Title / العنوان الرئيسي', 'type' => 'textarea'],
|
||||
]
|
||||
],
|
||||
'plans' => [
|
||||
'label' => 'Plans Section / قسم الخطط',
|
||||
'fields' => [
|
||||
'eyebrow' => ['label' => 'Eyebrow / النص الصغير', 'type' => 'text'],
|
||||
'title' => ['label' => 'Title / العنوان الرئيسي', 'type' => 'textarea'],
|
||||
]
|
||||
]
|
||||
];
|
||||
"""
|
||||
|
||||
new_html_form = """
|
||||
<div class="panel-card" style="max-width: 900px;">
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
<input type="hidden" name="action" value="save_landing">
|
||||
|
||||
<div class="accordion" id="sectionsAccordion">
|
||||
<?php foreach ($sections as $sec_key => $section): ?>
|
||||
<div class="accordion-item mb-3 border rounded">
|
||||
<h2 class="accordion-header" id="heading-<?= $sec_key ?>">
|
||||
<button class="accordion-button <?= $sec_key === 'hero' ? '' : 'collapsed' ?> bg-light fw-bold" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-<?= $sec_key ?>" aria-expanded="<?= $sec_key === 'hero' ? 'true' : 'false' ?>" aria-controls="collapse-<?= $sec_key ?>">
|
||||
<?= h($section['label']) ?>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapse-<?= $sec_key ?>" class="accordion-collapse collapse <?= $sec_key === 'hero' ? 'show' : '' ?>" aria-labelledby="heading-<?= $sec_key ?>" data-bs-parent="#sectionsAccordion">
|
||||
<div class="accordion-body">
|
||||
|
||||
<!-- Image Upload for Section -->
|
||||
<div class="mb-4 p-3 border rounded bg-white">
|
||||
<label class="form-label fw-bold"><?= h(t('Section Image', 'صورة القسم')) ?></label>
|
||||
<?php if (!empty($settings[$sec_key . '_image']['value_en'])): ?>
|
||||
<div class="mb-2">
|
||||
<img src="<?= h($settings[$sec_key . '_image']['value_en']) ?>" alt="Current Image" style="max-height: 100px; border-radius: 8px;">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<input type="file" class="form-control" name="images[<?= $sec_key ?>]" accept="image/*">
|
||||
<small class="text-muted"><?= h(t('Upload a new image to replace the current one.', 'قم برفع صورة جديدة لاستبدال الصورة الحالية.')) ?></small>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs mb-3" id="tab-<?= $sec_key ?>" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#<?= $sec_key ?>-en" type="button" role="tab">English</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#<?= $sec_key ?>-ar" type="button" role="tab">العربية</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="<?= $sec_key ?>-en" role="tabpanel">
|
||||
<?php foreach ($section['fields'] as $field_key => $field): ?>
|
||||
<?php $full_key = $sec_key . '_' . $field_key; ?>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold text-secondary"><?= h($field['label']) ?></label>
|
||||
<?php if ($field['type'] === 'textarea'): ?>
|
||||
<textarea class="form-control" name="settings[<?= $full_key ?>][en]" rows="2"><?= h($settings[$full_key]['value_en'] ?? '') ?></textarea>
|
||||
<?php else: ?>
|
||||
<input type="text" class="form-control" name="settings[<?= $full_key ?>][en]" value="<?= h($settings[$full_key]['value_en'] ?? '') ?>">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="<?= $sec_key ?>-ar" role="tabpanel" dir="rtl">
|
||||
<?php foreach ($section['fields'] as $field_key => $field): ?>
|
||||
<?php $full_key = $sec_key . '_' . $field_key; ?>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold text-secondary"><?= h($field['label']) ?></label>
|
||||
<?php if ($field['type'] === 'textarea'): ?>
|
||||
<textarea class="form-control" name="settings[<?= $full_key ?>][ar]" rows="2"><?= h($settings[$full_key]['value_ar'] ?? '') ?></textarea>
|
||||
<?php else: ?>
|
||||
<input type="text" class="form-control" name="settings[<?= $full_key ?>][ar]" value="<?= h($settings[$full_key]['value_ar'] ?? '') ?>">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-dark btn-lg px-4"><?= h(t('Save All Sections', 'حفظ كل الأقسام')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
"""
|
||||
|
||||
# Now replace the parts in admin_landing.php
|
||||
# 1. from `if ($_SERVER['REQUEST_METHOD']` to `$fields = [...];`
|
||||
php_pattern = re.compile(r"if \(\$_SERVER\[\'REQUEST_METHOD\'\].*?\];\s*", re.DOTALL)
|
||||
admin_landing_content = php_pattern.sub(new_php_logic, admin_landing_content)
|
||||
|
||||
# 2. from `<div class="panel-card"` to `</div>` at the end
|
||||
html_pattern = re.compile(r"<div class=\"panel-card\".*?</div>\s*$", re.DOTALL)
|
||||
admin_landing_content = html_pattern.sub(new_html_form, admin_landing_content)
|
||||
|
||||
with open(admin_landing_path, 'w', encoding='utf-8') as f:
|
||||
f.write(admin_landing_content)
|
||||
File diff suppressed because one or more lines are too long
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
$file = 'checkout.php';
|
||||
$content = file_get_contents($file);
|
||||
|
||||
$search1 = "'email' => trim((string) (\$_POST['email'] ?? '')),";
|
||||
$replace1 = $search1 . "\n 'password' => (string) (\$_POST['password'] ?? ''),";
|
||||
$content = str_replace($search1, $replace1, $content);
|
||||
|
||||
$search2 = "if (!filter_var(\$form['email'], FILTER_VALIDATE_EMAIL)) {";
|
||||
$replace2 = "if (empty(\$form['password']) || strlen(\$form['password']) < 6) {\n \$errors[] = t('Password must be at least 6 characters.', 'يجب أن تتكون كلمة المرور من 6 أحرف على الأقل.');\n }\n " . $search2;
|
||||
$content = str_replace($search2, $replace2, $content);
|
||||
|
||||
$search3 = "'email' => \$form['email'],";
|
||||
$replace3 = "'email' => \$form['email'],\n 'password' => password_hash(\$form['password'], PASSWORD_DEFAULT),";
|
||||
$content = str_replace($search3, $replace3, $content);
|
||||
|
||||
$search4 = '/<div class="col-md-6">\s*<label class="form-label" for="email">.*?<\/div>/s';
|
||||
$replace4 = '$0'."\n".' <div class="col-md-6">'."\n".' <label class="form-label" for="password"><?= h(t(\'Password\', \'كلمة المرور\')) ?></label>'."\n".' <input class="form-control" id="password" type="password" name="password" required>'."\n".' </div>';
|
||||
$content = preg_replace($search4, $replace4, $content);
|
||||
|
||||
file_put_contents($file, $content);
|
||||
echo "checkout.php patched\n";
|
||||
@ -1,34 +0,0 @@
|
||||
import sys
|
||||
|
||||
with open('checkout.php', 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
old_code = """if ($courseIdForView > 0) {
|
||||
$course = db()->query("SELECT * FROM courses WHERE id = $courseIdForView")->fetch();
|
||||
}"""
|
||||
|
||||
new_code = """if ($courseIdForView > 0) {
|
||||
$course = db()->query("SELECT * FROM courses WHERE id = $courseIdForView")->fetch();
|
||||
if ($course) {
|
||||
if (!$course['registration_open']) {
|
||||
$msg = current_lang() === 'ar' ? 'التسجيل في هذه الدورة/الدفعة مغلق حالياً.' : 'Registration for this course/batch is currently closed.';
|
||||
die("<div style='padding:2rem;text-align:center;font-family:sans-serif'><h1>" . $msg . "</h1><a href='index.php'>" . (current_lang() === 'ar' ? 'العودة' : 'Back') . "</a></div>");
|
||||
}
|
||||
if ($course['max_students'] > 0) {
|
||||
$enrolled = db()->query("SELECT COUNT(*) FROM course_students WHERE course_id = $courseIdForView")->fetchColumn();
|
||||
if ($enrolled >= $course['max_students']) {
|
||||
$msg = current_lang() === 'ar' ? 'لقد وصلت هذه الدورة إلى الحد الأقصى لعدد الطلاب.' : 'This course has reached its maximum capacity.';
|
||||
die("<div style='padding:2rem;text-align:center;font-family:sans-serif'><h1>" . $msg . "</h1><a href='index.php'>" . (current_lang() === 'ar' ? 'العودة' : 'Back') . "</a></div>");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Course not found');
|
||||
}
|
||||
}"""
|
||||
|
||||
content = content.replace(old_code, new_code)
|
||||
|
||||
with open('checkout.php', 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
print("Done")
|
||||
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/includes/app.php';
|
||||
|
||||
try {
|
||||
db()->exec("
|
||||
CREATE TABLE IF NOT EXISTS platform_profile (
|
||||
id INT PRIMARY KEY DEFAULT 1,
|
||||
name VARCHAR(255),
|
||||
description TEXT,
|
||||
logo_path VARCHAR(255),
|
||||
favicon_path VARCHAR(255)
|
||||
)
|
||||
");
|
||||
|
||||
$check = db()->query("SELECT COUNT(*) FROM platform_profile")->fetchColumn();
|
||||
if ($check == 0) {
|
||||
$stmt = db()->prepare("INSERT INTO platform_profile (id, name, description, logo_path, favicon_path) VALUES (1, :name, :desc, '', '')");
|
||||
$stmt->execute([
|
||||
'name' => 'LMS Platform',
|
||||
'desc' => 'Your trusted bilingual learning management system.'
|
||||
]);
|
||||
}
|
||||
echo "Platform profile DB patched.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Error: " . $e->getMessage();
|
||||
}
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/includes/app.php';
|
||||
|
||||
db()->exec("
|
||||
CREATE TABLE IF NOT EXISTS classes (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name_en VARCHAR(255) NOT NULL,
|
||||
name_ar VARCHAR(255) NOT NULL,
|
||||
description_en TEXT,
|
||||
description_ar TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
");
|
||||
|
||||
try {
|
||||
db()->exec("ALTER TABLE subjects ADD COLUMN class_id INT UNSIGNED DEFAULT NULL;");
|
||||
} catch (Exception $e) {
|
||||
// Column might exist
|
||||
}
|
||||
|
||||
echo "Database updated.\n";
|
||||
|
||||
161
patch_index.py
161
patch_index.py
@ -1,161 +0,0 @@
|
||||
with open('index.php', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 1. Hero Section
|
||||
# find the panel-card div and everything inside it up to </section>
|
||||
# It starts with:
|
||||
# <div class="col-lg-5">
|
||||
# <div class="panel-card">
|
||||
|
||||
old_hero_col = """ <div class="col-lg-5">
|
||||
<div class="panel-card">"""
|
||||
|
||||
new_hero_col = """ <div class="col-lg-5">
|
||||
<?php if ($hero_img = landing_setting('hero_image', '')): ?>
|
||||
<img src="<?= h($hero_img) ?>" class="img-fluid rounded shadow-lg w-100" style="object-fit: cover; max-height: 500px;" alt="Hero Image">
|
||||
<?php else: ?>
|
||||
<div class="panel-card">"""
|
||||
|
||||
content = content.replace(old_hero_col, new_hero_col)
|
||||
|
||||
old_hero_end = """ <a class="btn btn-outline-dark w-100 mt-3" href="<?= h(app_url('dashboard.php')) ?>"><?= h(t('Open student dashboard', 'افتح لوحة الطالب')) ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>"""
|
||||
|
||||
new_hero_end = """ <a class="btn btn-outline-dark w-100 mt-3" href="<?= h(app_url('dashboard.php')) ?>"><?= h(t('Open student dashboard', 'افتح لوحة الطالب')) ?></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>"""
|
||||
|
||||
content = content.replace(old_hero_end, new_hero_end)
|
||||
|
||||
|
||||
# 2. Courses Section
|
||||
old_courses = """ <div class="section-header">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('courses_eyebrow', 'Featured Courses', 'الدورات المميزة')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('courses_title', 'Enroll in specialized short courses designed to accelerate your skills.', 'سجل في دورات قصيرة متخصصة لتسريع تطوير مهاراتك.')) ?></h2>
|
||||
</div>
|
||||
</div>"""
|
||||
|
||||
new_courses = """ <?php if ($courses_img = landing_setting('courses_image', '')): ?>
|
||||
<div class="row align-items-center mb-4">
|
||||
<div class="col-lg-7">
|
||||
<span class="eyebrow"><?= h(landing_setting('courses_eyebrow', 'Featured Courses', 'الدورات المميزة')) ?></span>
|
||||
<h2 class="section-title mb-0"><?= h(landing_setting('courses_title', 'Enroll in specialized short courses designed to accelerate your skills.', 'سجل في دورات قصيرة متخصصة لتسريع تطوير مهاراتك.')) ?></h2>
|
||||
</div>
|
||||
<div class="col-lg-5 text-lg-end mt-3 mt-lg-0">
|
||||
<img src="<?= h($courses_img) ?>" class="img-fluid rounded shadow-sm" alt="Courses" style="max-height: 150px; object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="section-header">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('courses_eyebrow', 'Featured Courses', 'الدورات المميزة')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('courses_title', 'Enroll in specialized short courses designed to accelerate your skills.', 'سجل في دورات قصيرة متخصصة لتسريع تطوير مهاراتك.')) ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>"""
|
||||
content = content.replace(old_courses, new_courses)
|
||||
|
||||
|
||||
# 3. Subjects Section
|
||||
old_subjects = """ <div class="section-header">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('subjects_eyebrow', 'Featured subjects', 'المواد المميزة')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('subjects_title', 'Separate pages for catalog, detail, checkout, and dashboards.', 'صفحات منفصلة للكتالوج والتفاصيل والدفع ولوحات التحكم.')) ?></h2>
|
||||
</div>
|
||||
<a class="link-dark fw-semibold text-decoration-none" href="<?= h(app_url('catalog.php')) ?>"><?= h(t('See all subjects', 'عرض جميع المواد')) ?></a>
|
||||
</div>"""
|
||||
|
||||
new_subjects = """ <?php if ($subjects_img = landing_setting('subjects_image', '')): ?>
|
||||
<div class="row align-items-center mb-4">
|
||||
<div class="col-lg-7">
|
||||
<span class="eyebrow"><?= h(landing_setting('subjects_eyebrow', 'Featured subjects', 'المواد المميزة')) ?></span>
|
||||
<h2 class="section-title mb-2"><?= h(landing_setting('subjects_title', 'Separate pages for catalog, detail, checkout, and dashboards.', 'صفحات منفصلة للكتالوج والتفاصيل والدفع ولوحات التحكم.')) ?></h2>
|
||||
<a class="link-dark fw-semibold text-decoration-none" href="<?= h(app_url('catalog.php')) ?>"><?= h(t('See all subjects', 'عرض جميع المواد')) ?></a>
|
||||
</div>
|
||||
<div class="col-lg-5 text-lg-end mt-3 mt-lg-0">
|
||||
<img src="<?= h($subjects_img) ?>" class="img-fluid rounded shadow-sm" alt="Subjects" style="max-height: 150px; object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="section-header">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('subjects_eyebrow', 'Featured subjects', 'المواد المميزة')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('subjects_title', 'Separate pages for catalog, detail, checkout, and dashboards.', 'صفحات منفصلة للكتالوج والتفاصيل والدفع ولوحات التحكم.')) ?></h2>
|
||||
</div>
|
||||
<a class="link-dark fw-semibold text-decoration-none" href="<?= h(app_url('catalog.php')) ?>"><?= h(t('See all subjects', 'عرض جميع المواد')) ?></a>
|
||||
</div>
|
||||
<?php endif; ?>"""
|
||||
content = content.replace(old_subjects, new_subjects)
|
||||
|
||||
|
||||
# 4. Flow Section
|
||||
old_flow = """ <div class="section-header mb-4">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('flow_eyebrow', 'Delivery flow', 'مسار التسليم')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('flow_title', 'One thin slice from discovery to live access.', 'شريحة رشيقة من الاكتشاف حتى الوصول المباشر.')) ?></h2>
|
||||
</div>
|
||||
</div>"""
|
||||
|
||||
new_flow = """ <?php if ($flow_img = landing_setting('flow_image', '')): ?>
|
||||
<div class="row align-items-center mb-4">
|
||||
<div class="col-lg-7">
|
||||
<span class="eyebrow"><?= h(landing_setting('flow_eyebrow', 'Delivery flow', 'مسار التسليم')) ?></span>
|
||||
<h2 class="section-title mb-0"><?= h(landing_setting('flow_title', 'One thin slice from discovery to live access.', 'شريحة رشيقة من الاكتشاف حتى الوصول المباشر.')) ?></h2>
|
||||
</div>
|
||||
<div class="col-lg-5 text-lg-end mt-3 mt-lg-0">
|
||||
<img src="<?= h($flow_img) ?>" class="img-fluid rounded shadow-sm" alt="Delivery Flow" style="max-height: 150px; object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="section-header mb-4">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('flow_eyebrow', 'Delivery flow', 'مسار التسليم')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('flow_title', 'One thin slice from discovery to live access.', 'شريحة رشيقة من الاكتشاف حتى الوصول المباشر.')) ?></h2>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>"""
|
||||
content = content.replace(old_flow, new_flow)
|
||||
|
||||
|
||||
# 5. Plans Section
|
||||
old_plans = """ <div class="section-header mb-4">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('plans_eyebrow', 'Plans', 'الخطط')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('plans_title', 'Plan-based access for a shared marketplace.', 'وصول قائم على الخطط لمنصة مشتركة.')) ?></h2>
|
||||
</div>
|
||||
<a class="link-dark fw-semibold text-decoration-none" href="<?= h(app_url('pricing.php')) ?>"><?= h(t('Open pricing', 'افتح التسعير')) ?></a>
|
||||
</div>"""
|
||||
|
||||
new_plans = """ <?php if ($plans_img = landing_setting('plans_image', '')): ?>
|
||||
<div class="row align-items-center mb-4">
|
||||
<div class="col-lg-7">
|
||||
<span class="eyebrow"><?= h(landing_setting('plans_eyebrow', 'Plans', 'الخطط')) ?></span>
|
||||
<h2 class="section-title mb-2"><?= h(landing_setting('plans_title', 'Plan-based access for a shared marketplace.', 'وصول قائم على الخطط لمنصة مشتركة.')) ?></h2>
|
||||
<a class="link-dark fw-semibold text-decoration-none" href="<?= h(app_url('pricing.php')) ?>"><?= h(t('Open pricing', 'افتح التسعير')) ?></a>
|
||||
</div>
|
||||
<div class="col-lg-5 text-lg-end mt-3 mt-lg-0">
|
||||
<img src="<?= h($plans_img) ?>" class="img-fluid rounded shadow-sm" alt="Plans" style="max-height: 150px; object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="section-header mb-4">
|
||||
<div>
|
||||
<span class="eyebrow"><?= h(landing_setting('plans_eyebrow', 'Plans', 'الخطط')) ?></span>
|
||||
<h2 class="section-title"><?= h(landing_setting('plans_title', 'Plan-based access for a shared marketplace.', 'وصول قائم على الخطط لمنصة مشتركة.')) ?></h2>
|
||||
</div>
|
||||
<a class="link-dark fw-semibold text-decoration-none" href="<?= h(app_url('pricing.php')) ?>"><?= h(t('Open pricing', 'افتح التسعير')) ?></a>
|
||||
</div>
|
||||
<?php endif; ?>"""
|
||||
content = content.replace(old_plans, new_plans)
|
||||
|
||||
with open('index.php', 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
@ -1,15 +0,0 @@
|
||||
import re
|
||||
|
||||
with open("index.php", "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
# Pattern to remove the entire panel-card block
|
||||
pattern = r'<div class="panel-card">[\s\S]*?</div>\s*<\?php endif; \?>'
|
||||
replacement = '<?php endif; ?>'
|
||||
|
||||
new_content = re.sub(pattern, replacement, content)
|
||||
|
||||
with open("index.php", "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
|
||||
print("done")
|
||||
Loading…
x
Reference in New Issue
Block a user