Files
yogibook_aury_new/public/include/sidebar.php
T
2026-10-14 10:21:55 +02:00

409 lines
17 KiB
PHP

<?php
/**
* Sidebar - il menu dipende dalla VISTA attiva (SchoolContext::viewMode()):
* superadmin -> solo Piattaforma (per gestire una scuola si passa alla vista "school" dal selettore)
* school -> gestione della scuola (owner/admin), a gruppi richiudibili
* teacher -> classi, prenotazioni ed eventi
* student -> prenotazioni e ordini personali
* "Il mio account" è sempre presente.
*/
$__mode = SchoolContext::viewMode();
$__modes = SchoolContext::viewModes();
$__isSuper = SchoolContext::isSuperadmin();
$__isAdmin = SchoolContext::isSchoolAdmin();
$__isStaff = SchoolContext::isStaff();
$__home = SchoolContext::landingPage();
$__page = basename($_SERVER['PHP_SELF']);
// Logo della scuola corrente (se caricato), altrimenti logo standard
$__sc = SchoolContext::get();
$__logo = !empty($__sc['logo'])
? 'uploads/schools/' . (int) $__sc['idschool'] . '/' . rawurlencode($__sc['logo'])
: null;
if (empty($_SESSION['csrf_switch'])) {
$_SESSION['csrf_switch'] = bin2hex(random_bytes(16));
}
$__modeIcons = [
'superadmin' => 'bx bx-crown',
'school' => 'bx bxs-school',
'teacher' => 'bx bx-chalkboard',
'student' => 'bx bx-user',
];
// Avviso abbonamento YogiBook: solo nella vista scuola, per owner/admin
$__sub = null;
if ($__mode === 'school' && $__isAdmin && !empty($__sc['idschool'])) {
try {
require_once dirname(__DIR__) . '/class/PlatformBilling.php';
$__subSchool = PlatformBilling::school((int) $__sc['idschool']);
if ($__subSchool) {
$__st = PlatformBilling::state($__subSchool);
$__texts = [
'expiring' => ['warn', 'Abbonamento in scadenza', $__st['days'] === 0 ? 'Scade oggi' : 'Scade tra ' . $__st['days'] . ' gg'],
'trial' => ['info', 'Periodo di prova', 'Ancora ' . $__st['days'] . ' gg'],
'grace' => ['danger', 'Abbonamento scaduto', 'Rinnova entro ' . $__st['days'] . ' gg'],
'expired' => ['danger', 'Abbonamento scaduto', 'Rinnova per riattivarlo'],
'none' => ['info', 'Abbonamento non attivo', 'Scegli un piano'],
];
if (isset($__texts[$__st['code']])) {
$__sub = $__texts[$__st['code']];
}
}
} catch (Throwable $__ex) {
error_log('[sidebar] abbonamento: ' . $__ex->getMessage());
}
}
// Percorso "Primi passi" non ancora concluso: promemoria con l'avanzamento salvato
$__setup = null;
if ($__mode === 'school' && $__isAdmin && !empty($__sc['idschool'])) {
try {
if ((string) SchoolSettings::get('setup_completed_at', '') === '') {
$__ss = json_decode((string) SchoolSettings::get('setup_state', ''), true);
$__setup = is_array($__ss) && !empty($__ss['progress']) ? (string) $__ss['progress'] : '';
}
} catch (Throwable $__ex) {
error_log('[sidebar] primi passi: ' . $__ex->getMessage());
}
}
// Ordini su cui agire: da pagare + da propagare (contatore nel menu della scuola)
$__toPay = 0;
if ($__mode === 'school' && $__isAdmin && !empty($__sc['idschool'])) {
try {
require_once dirname(__DIR__) . '/class/ShopService.php';
$__toPay = ShopService::pendingCount((int) $__sc['idschool']);
} catch (Throwable $__ex) {
error_log('[sidebar] ordini: ' . $__ex->getMessage());
}
}
if (!function_exists('sb_item')) {
/** Voce singola. $also = altre pagine che la accendono (es. il form di modifica). */
function sb_item(string $href, string $icon, string $label, string $current, array $also = [], int $badge = 0): void
{
$on = ($href === $current || in_array($current, $also, true));
echo '<li class="' . ($on ? 'mm-active' : '') . '"><a href="' . $href . '" class="' . ($on ? 'active' : '') . '">'
. '<i class="' . $icon . ' icon nav-icon"></i>'
. '<span class="menu-item">' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '</span>'
. ($badge > 0 ? '<span class="badge rounded-pill bg-warning text-dark ms-1 sb-badge" title="Da pagare o da propagare">' . $badge . '</span>' : '')
. '</a></li>';
}
/**
* Gruppo richiudibile (metisMenu). Si apre da solo se contiene la pagina corrente.
* $items = [ [href, etichetta, [pagine collegate], contatore], ... ] (le voci null vengono saltate)
*/
function sb_group(string $icon, string $label, array $items, string $current): void
{
$items = array_values(array_filter($items));
if (!$items) {
return;
}
$open = false;
$badge = 0;
foreach ($items as $it) {
$badge += (int) ($it[3] ?? 0);
if ($it[0] === $current || in_array($current, $it[2] ?? [], true)) {
$open = true;
}
}
echo '<li class="' . ($open ? 'mm-active' : '') . '">'
. '<a href="javascript: void(0);" class="has-arrow" aria-expanded="' . ($open ? 'true' : 'false') . '">'
. '<i class="' . $icon . ' icon nav-icon"></i>'
. '<span class="menu-item">' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '</span>'
. ($badge > 0 ? '<span class="badge rounded-pill bg-warning text-dark ms-1 sb-badge">' . $badge . '</span>' : '')
. '</a>'
. '<ul class="sub-menu" aria-expanded="' . ($open ? 'true' : 'false') . '">';
foreach ($items as $it) {
$on = ($it[0] === $current || in_array($current, $it[2] ?? [], true));
echo '<li class="' . ($on ? 'mm-active' : '') . '"><a href="' . $it[0] . '" class="' . ($on ? 'active' : '') . '">'
. htmlspecialchars($it[1], ENT_QUOTES, 'UTF-8')
. (!empty($it[3]) ? ' <span class="badge rounded-pill bg-warning text-dark ms-1">' . (int) $it[3] . '</span>' : '')
. '</a></li>';
}
echo '</ul></li>';
}
}
?>
<!-- ========== Left Sidebar Start ========== -->
<style>
.view-switcher {
padding: 14px 16px 6px;
}
.view-switcher .vs-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .05em;
opacity: .6;
margin-bottom: 6px;
}
.view-switcher form {
display: flex;
gap: 4px;
background: rgba(0, 0, 0, .05);
border-radius: 10px;
padding: 4px;
margin: 0;
}
.view-switcher button {
flex: 1;
border: none;
background: transparent;
border-radius: 7px;
padding: 6px 4px;
font-size: 11px;
font-weight: 600;
color: inherit;
opacity: .7;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
line-height: 1.1;
}
.view-switcher button i {
font-size: 17px;
}
.view-switcher button:hover {
opacity: 1;
}
.view-switcher button.active {
background: var(--bs-primary, #2F7F84);
color: #fff;
opacity: 1;
cursor: default;
}
.view-switcher .vs-school {
font-size: 12px;
font-weight: 600;
margin-top: 8px;
opacity: .75;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
body[data-sidebar-size="sm"] .view-switcher,
body[data-sidebar-size="sm"] .sub-alert {
display: none;
}
.sub-alert {
display: flex;
gap: 10px;
align-items: center;
margin: 10px 16px 4px;
padding: 10px 12px;
border-radius: 10px;
text-decoration: none;
font-size: 12px;
line-height: 1.3;
border: 1px solid transparent;
}
.sub-alert i {
font-size: 18px;
flex-shrink: 0;
}
.sub-alert b {
display: block;
font-size: 12.5px;
}
.sub-alert.warn {
background: #FFF4E0;
color: #7a4a0b;
border-color: #f0d6a8;
}
.sub-alert.danger {
background: #FDECEA;
color: #8f2f24;
border-color: #f2c9c4;
}
.sub-alert.info {
background: #E6F4F5;
color: #1E4A4F;
border-color: #cfe5e6;
}
body[data-sidebar-size="sm"] .sb-badge {
display: none;
}
.sub-alert:hover {
filter: brightness(.97);
}
</style>
<div class="vertical-menu">
<!-- LOGO -->
<div class="navbar-brand-box">
<?php if ($__logo) : ?>
<a href="<?php echo $__home; ?>" class="logo logo-dark">
<span class="logo-sm"><img src="<?php echo $__logo; ?>" alt="" height="30" style="max-width:40px;object-fit:contain;"></span>
<span class="logo-lg"><img src="<?php echo $__logo; ?>" alt="" height="40" style="max-width:180px;object-fit:contain;"></span>
</a>
<a href="<?php echo $__home; ?>" class="logo logo-light">
<span class="logo-lg"><img src="<?php echo $__logo; ?>" alt="" height="40" style="max-width:180px;object-fit:contain;"></span>
<span class="logo-sm"><img src="<?php echo $__logo; ?>" alt="" height="26" style="max-width:40px;object-fit:contain;"></span>
</a>
<?php else : ?>
<a href="<?php echo $__home; ?>" class="logo logo-dark">
<span class="logo-sm"><img src="assets/images/logo-dark-sm.png" alt="" height="30"></span>
<span class="logo-lg"><img src="assets/images/logo-dark.png" alt="" height="32"></span>
</a>
<a href="<?php echo $__home; ?>" class="logo logo-light">
<span class="logo-lg"><img src="assets/images/logo-light.png" alt="" height="30"></span>
<span class="logo-sm"><img src="assets/images/logo-light-sm.png" alt="" height="26"></span>
</a>
<?php endif; ?>
</div>
<button type="button" class="btn btn-sm px-3 font-size-24 header-item waves-effect vertical-menu-btn">
<i class="bx bx-menu align-middle"></i>
</button>
<div data-simplebar class="sidebar-menu-scroll">
<?php if (count($__modes) > 1) : ?>
<!-- Selettore vista -->
<div class="view-switcher">
<div class="vs-label">Vista</div>
<form method="post" action="switchview.php">
<input type="hidden" name="token" value="<?php echo $_SESSION['csrf_switch']; ?>">
<?php foreach ($__modes as $__k => $__lbl) : ?>
<button type="submit" name="mode" value="<?php echo $__k; ?>"
class="<?php echo $__k === $__mode ? 'active' : ''; ?>"
<?php echo $__k === $__mode ? 'disabled' : ''; ?>
title="Vedi come <?php echo htmlspecialchars($__lbl, ENT_QUOTES, 'UTF-8'); ?>">
<i class="<?php echo $__modeIcons[$__k] ?? 'bx bx-show'; ?>"></i>
<?php echo htmlspecialchars($__lbl, ENT_QUOTES, 'UTF-8'); ?>
</button>
<?php endforeach; ?>
</form>
<?php if ($__mode !== 'superadmin') : ?>
<div class="vs-school" title="Scuola corrente">
<i class="bx bx-buildings"></i> <?php echo htmlspecialchars($__sc['name'], ENT_QUOTES, 'UTF-8'); ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($__setup !== null && $__page !== 'school_setup.php') : ?>
<!-- Promemoria Primi passi -->
<a href="school_setup.php" class="sub-alert info">
<i class="bx bx-rocket"></i>
<span><b>Primi passi<?php echo $__setup !== '' ? ' · ' . htmlspecialchars($__setup, ENT_QUOTES, 'UTF-8') : ''; ?></b>Configura e prova la tua scuola</span>
</a>
<?php endif; ?>
<?php if ($__sub && $__page !== 'subscription.php') : ?>
<!-- Avviso abbonamento -->
<a href="subscription.php" class="sub-alert <?php echo $__sub[0]; ?>">
<i class="bx <?php echo $__sub[0] === 'danger' ? 'bx-error-circle' : ($__sub[0] === 'warn' ? 'bx-time-five' : 'bx-info-circle'); ?>"></i>
<span><b><?php echo htmlspecialchars($__sub[1], ENT_QUOTES, 'UTF-8'); ?></b><?php echo htmlspecialchars($__sub[2], ENT_QUOTES, 'UTF-8'); ?> · Rinnova</span>
</a>
<?php endif; ?>
<!--- Sidemenu -->
<div id="sidebar-menu">
<ul class="metismenu list-unstyled" id="side-menu">
<?php if ($__mode === 'superadmin' && $__isSuper) : ?>
<!-- ============ PIATTAFORMA ============ -->
<li class="menu-title">Piattaforma</li>
<?php sb_item('sa-dashboard.php', 'bx bx-pulse', 'Panoramica', $__page); ?>
<?php sb_item('sa-schools.php', 'bx bx-buildings', 'Scuole', $__page); ?>
<?php sb_group('bx bx-wallet', 'Abbonamenti', [
['sa-subscriptions.php', 'Scuole e scadenze'],
['sa-orders.php', 'Ordini'],
['sa-plans.php', 'Piani'],
['sa-billing-settings.php', 'Impostazioni pagamenti'],
], $__page); ?>
<?php elseif ($__mode === 'school' && $__isAdmin) : ?>
<!-- ============ SCUOLA (owner / admin) ============ -->
<li class="menu-title">Scuola</li>
<?php sb_item('dashboard.php', 'bx bx-home-circle', 'Dashboard', $__page); ?>
<?php sb_group('bx bx-calendar', 'Classi', [
['adminpanel.php', 'Pannello classi'],
['pendingbookedclass.php', 'Da confermare / attesa'],
['admin-services.php', 'Servizi e orari'],
['dayoff.php', 'Giorni di chiusura'],
], $__page); ?>
<?php sb_group('bx bx-group', 'Allievi', [
['situationusers.php', 'Situazione allievi'],
['certificati.php', 'Certificati medici'],
['statistiche.php', 'Statistiche'],
], $__page); ?>
<?php sb_item('school_orders.php', 'bx bx-receipt', 'Ordini', $__page, ['orderbooklist.php', 'ordersummary.php'], $__toPay); ?>
<?php sb_group('bx bx-store-alt', 'Negozio', [
['products.php', 'Prodotti', ['product_form.php']],
['coupons.php', 'Coupon', ['coupon_form.php']],
['shop_preview.php', 'Anteprima negozio'],
], $__page); ?>
<?php sb_group('bx bx-calendar-star', 'Eventi', [
['events.php', 'Eventi', ['event_form.php', 'event_participants.php', 'event_reminder.php']],
['event_locations.php', 'Sedi'],
['event_options.php', 'Opzioni eventi'],
], $__page); ?>
<?php sb_group('bx bx-cog', 'Impostazioni', [
['school_setup.php', 'Primi passi'],
['optionsschool.php', 'Opzioni scuola'],
['package_rules.php', 'Regole pacchetti'],
['insegnanti.php', 'Insegnanti'],
['subscription.php', 'Abbonamento YogiBook'],
], $__page); ?>
<?php elseif ($__isStaff && $__mode !== 'student') : ?>
<!-- ============ INSEGNANTE ============ -->
<li class="menu-title">Classi</li>
<?php sb_item('adminpanel.php', 'bx bxs-school', 'Pannello classi', $__page); ?>
<?php sb_item('pendingbookedclass.php', 'bx bx-time-five', 'Da confermare / attesa', $__page); ?>
<?php sb_item('events.php', 'bx bx-calendar-star', 'Eventi', $__page, ['event_form.php', 'event_participants.php', 'event_reminder.php']); ?>
<?php else : ?>
<!-- ============ ALLIEVO ============ -->
<li class="menu-title">Le mie lezioni</li>
<?php sb_item('studentdashboard.php', 'bx bx-home-heart', 'Home', $__page); ?>
<?php sb_item('userpanel.php', 'bx bx-calendar-event', 'Prenotazioni', $__page); ?>
<?php sb_item('orders.php', 'bx bx-detail', 'I miei pacchetti', $__page, ['shop_order.php']); ?>
<?php sb_item('shop.php', 'bx bx-store-alt', 'Negozio', $__page, ['shop_checkout.php']); ?>
<?php endif; ?>
<!-- Account personale: sempre presente -->
<li class="menu-title">Account</li>
<?php sb_group('bx bx-user-circle', 'Il mio account', [
['userprofile.php', 'Profilo'],
$__mode === 'superadmin' ? null : ['userprofiledoc.php', 'Il mio certificato'],
['options.php', 'Preferenze'],
], $__page); ?>
</ul>
</div>
</div>
</div>
<!-- Left Sidebar End -->