510 lines
20 KiB
PHP
510 lines
20 KiB
PHP
<?php
|
||
require_once('include/headscript.php');
|
||
require_once('include/csrf.php');
|
||
require_once(__DIR__ . '/class/SchoolSetup.php');
|
||
SchoolContext::requireSchoolAdmin();
|
||
|
||
/**
|
||
* SCUOLA - Primi passi: percorso guidato per configurare e provare la scuola.
|
||
* I passi si completano da soli quando i dati ci sono; alcuni si segnano a mano,
|
||
* i facoltativi si possono saltare. Alla fine l'owner chiude il percorso.
|
||
*/
|
||
function e($value): string
|
||
{
|
||
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
|
||
}
|
||
|
||
$sid = (int) $idschool;
|
||
|
||
/* ---------------------------------------------------------------- AZIONI */
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
yb_csrf_check();
|
||
$action = (string) ($_POST['action'] ?? '');
|
||
$key = preg_replace('/[^a-z_]/', '', (string) ($_POST['key'] ?? ''));
|
||
$state = SchoolSetup::state($sid);
|
||
$keys = array_column(SchoolSetup::steps($sid, (int) $iduserlogin), null, 'key');
|
||
|
||
if (isset($keys[$key])) {
|
||
if ($action === 'mark') {
|
||
$state['done'][$key] = date('Y-m-d');
|
||
unset($state['skip'][$key]);
|
||
} elseif ($action === 'unmark') {
|
||
unset($state['done'][$key]);
|
||
} elseif ($action === 'skip' && !$keys[$key]['required']) {
|
||
$state['skip'][$key] = date('Y-m-d');
|
||
} elseif ($action === 'unskip') {
|
||
unset($state['skip'][$key]);
|
||
}
|
||
SchoolSetup::saveState($sid, $state);
|
||
}
|
||
if ($action === 'complete') {
|
||
[,, $missing] = SchoolSetup::progress(SchoolSetup::steps($sid, (int) $iduserlogin));
|
||
if ($missing === 0) {
|
||
SchoolSettings::save(['setup_completed_at' => date('Y-m-d H:i:s')], $sid);
|
||
header('Location: school_setup.php?done=1');
|
||
exit();
|
||
}
|
||
}
|
||
if ($action === 'reopen') {
|
||
SchoolSettings::save(['setup_completed_at' => null], $sid);
|
||
}
|
||
header('Location: school_setup.php' . ($key !== '' ? '#step-' . $key : ''));
|
||
exit();
|
||
}
|
||
|
||
/* ------------------------------------------------------------------ DATI */
|
||
$steps = SchoolSetup::steps($sid, (int) $iduserlogin);
|
||
[$done, $total, $missing] = SchoolSetup::progress($steps);
|
||
$pct = $total ? (int) round($done / $total * 100) : 0;
|
||
$completedAt = (string) SchoolSettings::get('setup_completed_at', '');
|
||
|
||
// Avanzamento in cache per il promemoria in sidebar (scritto solo se cambia)
|
||
$state = SchoolSetup::state($sid);
|
||
if (($state['progress'] ?? '') !== $done . '/' . $total) {
|
||
$state['progress'] = $done . '/' . $total;
|
||
SchoolSetup::saveState($sid, $state);
|
||
}
|
||
|
||
$next = null;
|
||
foreach ($steps as $s) {
|
||
if (!$s['done'] && !$s['skipped']) {
|
||
$next = $s;
|
||
break;
|
||
}
|
||
}
|
||
$byPhase = [];
|
||
foreach ($steps as $i => $s) {
|
||
$s['n'] = $i + 1;
|
||
$byPhase[$s['phase']][] = $s;
|
||
}
|
||
?>
|
||
<!doctype html>
|
||
<html lang="it">
|
||
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>YogiBook - Primi passi</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
||
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
||
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
||
<link href="assets/css/app.min.css" id="app-style" rel="stylesheet" type="text/css" />
|
||
<link href="assets/css/yb-billing.css" rel="stylesheet" type="text/css" />
|
||
<style>
|
||
.su-wrap {
|
||
max-width: 920px;
|
||
}
|
||
|
||
.su-hero {
|
||
display: flex;
|
||
gap: 24px;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.su-ring {
|
||
--p: 0;
|
||
width: 112px;
|
||
height: 112px;
|
||
border-radius: 50%;
|
||
flex-shrink: 0;
|
||
display: grid;
|
||
place-items: center;
|
||
background: conic-gradient(#2F7F84 calc(var(--p) * 1%), #DBF6F9 0);
|
||
position: relative;
|
||
}
|
||
|
||
.su-ring::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 11px;
|
||
border-radius: 50%;
|
||
background: #fff;
|
||
}
|
||
|
||
.su-ring b {
|
||
position: relative;
|
||
font-size: 26px;
|
||
font-weight: 800;
|
||
color: #1E4A4F;
|
||
line-height: 1;
|
||
text-align: center;
|
||
}
|
||
|
||
.su-ring small {
|
||
display: block;
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
color: #6b7280;
|
||
margin-top: 3px;
|
||
}
|
||
|
||
.su-hero h1 {
|
||
font-size: 26px;
|
||
font-weight: 800;
|
||
color: #1E4A4F;
|
||
margin: 0 0 6px;
|
||
}
|
||
|
||
.su-hero p {
|
||
margin: 0;
|
||
color: #4b5563;
|
||
font-size: 15px;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.su-next {
|
||
border: 2px solid #6FBABE;
|
||
background: #F4FAFA;
|
||
border-radius: 16px;
|
||
padding: 18px 20px;
|
||
display: flex;
|
||
gap: 16px;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.su-next .k {
|
||
font-size: 12px;
|
||
font-weight: 800;
|
||
letter-spacing: .06em;
|
||
text-transform: uppercase;
|
||
color: #2F7F84;
|
||
}
|
||
|
||
.su-next .t {
|
||
font-size: 19px;
|
||
font-weight: 800;
|
||
color: #1E4A4F;
|
||
margin: 2px 0 4px;
|
||
}
|
||
|
||
.su-next .d {
|
||
font-size: 14px;
|
||
color: #374151;
|
||
max-width: 560px;
|
||
line-height: 1.45;
|
||
}
|
||
|
||
.su-phase {
|
||
margin-top: 26px;
|
||
}
|
||
|
||
.su-phase-head {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 10px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.su-phase-head h2 {
|
||
font-size: 15px;
|
||
font-weight: 800;
|
||
letter-spacing: .04em;
|
||
text-transform: uppercase;
|
||
color: #1E4A4F;
|
||
margin: 0;
|
||
}
|
||
|
||
.su-phase-head span {
|
||
color: #6b7280;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.su-step {
|
||
display: flex;
|
||
gap: 14px;
|
||
align-items: flex-start;
|
||
background: #fff;
|
||
border: 1px solid #e6ecec;
|
||
border-radius: 14px;
|
||
padding: 14px 16px;
|
||
margin-bottom: 10px;
|
||
scroll-margin-top: 90px;
|
||
}
|
||
|
||
.su-step.is-next {
|
||
border-color: #6FBABE;
|
||
box-shadow: 0 0 0 3px rgba(111, 186, 190, .18);
|
||
}
|
||
|
||
.su-dot {
|
||
width: 34px;
|
||
height: 34px;
|
||
border-radius: 50%;
|
||
flex-shrink: 0;
|
||
display: grid;
|
||
place-items: center;
|
||
font-weight: 800;
|
||
font-size: 14px;
|
||
background: #eef3f3;
|
||
color: #4b5563;
|
||
}
|
||
|
||
.su-step.done .su-dot {
|
||
background: #2F7F84;
|
||
color: #fff;
|
||
font-size: 20px;
|
||
box-shadow: 5px 0 0 #DBF6F9;
|
||
}
|
||
|
||
.su-step.skipped .su-dot {
|
||
background: #f3f4f6;
|
||
color: #9ca3af;
|
||
}
|
||
|
||
.su-body {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.su-title {
|
||
font-weight: 700;
|
||
color: #1f2937;
|
||
font-size: 15px;
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.su-step.done .su-title {
|
||
color: #1E4A4F;
|
||
}
|
||
|
||
.su-step.skipped .su-title {
|
||
color: #9ca3af;
|
||
text-decoration: line-through;
|
||
}
|
||
|
||
.su-tag {
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
padding: 1px 8px;
|
||
border-radius: 10px;
|
||
background: #eef0f3;
|
||
color: #4b5563;
|
||
}
|
||
|
||
.su-text {
|
||
font-size: 13.5px;
|
||
color: #4b5563;
|
||
line-height: 1.45;
|
||
margin-top: 3px;
|
||
}
|
||
|
||
.su-step.done .su-text {
|
||
display: none;
|
||
}
|
||
|
||
.su-detail {
|
||
font-size: 12.5px;
|
||
color: #2F7F84;
|
||
font-weight: 600;
|
||
margin-top: 3px;
|
||
}
|
||
|
||
.su-detail.warn {
|
||
color: #92560b;
|
||
}
|
||
|
||
.su-actions {
|
||
display: flex;
|
||
gap: 6px;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
}
|
||
|
||
.su-actions form {
|
||
margin: 0;
|
||
}
|
||
|
||
.su-link {
|
||
border: none;
|
||
background: none;
|
||
color: #6b7280;
|
||
font-size: 13px;
|
||
text-decoration: underline;
|
||
padding: 6px 4px;
|
||
min-height: 36px;
|
||
}
|
||
|
||
.su-link:hover {
|
||
color: #1E4A4F;
|
||
}
|
||
|
||
.su-finish {
|
||
text-align: center;
|
||
padding: 26px 16px;
|
||
}
|
||
|
||
.su-finish i {
|
||
font-size: 46px;
|
||
color: #2F7F84;
|
||
}
|
||
|
||
@media (max-width: 640px) {
|
||
.su-step {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.su-actions {
|
||
width: 100%;
|
||
justify-content: flex-start;
|
||
padding-left: 48px;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div id="layout-wrapper">
|
||
<header id="page-topbar" class="isvertical-topbar">
|
||
<div class="navbar-header">
|
||
<div class="d-flex">
|
||
<?php include('include/logoarea.php'); ?>
|
||
<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 class="page-title-box align-self-center d-none d-md-block">
|
||
<h4 class="page-title mb-0">Primi passi</h4>
|
||
</div>
|
||
</div>
|
||
<div class="d-flex">
|
||
<?php include('include/schoolswitcher.php'); ?><?php include('include/languageselection.php'); ?>
|
||
<?php include('include/profiletopbar.php'); ?>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
<?php include('include/sidebar.php'); ?>
|
||
<header class="ishorizontal-topbar">
|
||
<div class="navbar-header">
|
||
<div class="d-flex"></div>
|
||
</div>
|
||
<div class="topnav">
|
||
<div class="container-fluid">
|
||
<nav class="navbar navbar-light navbar-expand-lg topnav-menu"></nav>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="main-content">
|
||
<div class="page-content">
|
||
<div class="container-fluid">
|
||
<div class="su-wrap">
|
||
|
||
<?php if (isset($_GET['done'])) : ?>
|
||
<div class="alert alert-success">Configurazione completata. Il promemoria in alto nel menu non comparirà più: puoi tornare qui da Impostazioni → Primi passi.</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="card admin-card">
|
||
<div class="card-body">
|
||
<div class="su-hero">
|
||
<div class="su-ring" style="--p: <?php echo $pct; ?>;" role="img" aria-label="<?php echo $done; ?> passi su <?php echo $total; ?>">
|
||
<b><?php echo $done; ?>/<?php echo $total; ?><small>passi</small></b>
|
||
</div>
|
||
<div style="flex:1;min-width:240px;">
|
||
<h1><?php echo $completedAt ? 'La tua scuola è pronta' : 'Prepariamo la tua scuola'; ?></h1>
|
||
<p>
|
||
<?php if ($completedAt) : ?>
|
||
Percorso chiuso il <?php echo e(date('d/m/Y', strtotime($completedAt))); ?>. Puoi sempre ricontrollare i passi qui sotto.
|
||
<?php else : ?>
|
||
Segui i passi in ordine: ogni volta che inserisci i dati il passo si spunta da solo.
|
||
Alla fine fai una prova come allieva, così sai esattamente cosa vedranno.
|
||
<?php endif; ?>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if ($next && !$completedAt) : ?>
|
||
<div class="su-next mt-4">
|
||
<div>
|
||
<div class="k">Prossimo passo · <?php echo e(SchoolSetup::PHASES[$next['phase']][0]); ?></div>
|
||
<div class="t"><?php echo e($next['title']); ?></div>
|
||
<div class="d"><?php echo e($next['text']); ?></div>
|
||
</div>
|
||
<?php if ($next['url'] !== '') : ?>
|
||
<a href="<?php echo e($next['url']); ?>" class="btn btn-yb" style="min-height:46px;display:inline-flex;align-items:center;gap:6px;"><?php echo e($next['cta']); ?> <i class="bx bx-right-arrow-alt"></i></a>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php foreach (SchoolSetup::PHASES as $pk => [$pTitle, $pLead]) :
|
||
if (empty($byPhase[$pk])) continue; ?>
|
||
<section class="su-phase" aria-labelledby="ph-<?php echo $pk; ?>">
|
||
<div class="su-phase-head">
|
||
<h2 id="ph-<?php echo $pk; ?>"><?php echo e($pTitle); ?></h2>
|
||
<span><?php echo e($pLead); ?></span>
|
||
</div>
|
||
<?php foreach ($byPhase[$pk] as $s) :
|
||
$isNext = $next && $next['key'] === $s['key'] && !$completedAt;
|
||
$cls = $s['done'] ? 'done' : ($s['skipped'] ? 'skipped' : ''); ?>
|
||
<div class="su-step <?php echo $cls; ?> <?php echo $isNext ? 'is-next' : ''; ?>" id="step-<?php echo e($s['key']); ?>">
|
||
<div class="su-dot" aria-hidden="true"><?php echo $s['done'] ? '<i class="bx bx-check"></i>' : ($s['skipped'] ? '–' : $s['n']); ?></div>
|
||
<div class="su-body">
|
||
<div class="su-title">
|
||
<?php echo e($s['title']); ?>
|
||
<?php if (!$s['required']) : ?><span class="su-tag">facoltativo</span><?php endif; ?>
|
||
<?php if ($s['done'] && $s['manual'] && !$s['auto']) : ?><span class="su-tag">segnato a mano</span><?php endif; ?>
|
||
</div>
|
||
<div class="su-text"><?php echo e($s['text']); ?></div>
|
||
<?php if ($s['detail'] !== '') : ?>
|
||
<div class="su-detail <?php echo $s['done'] ? '' : 'warn'; ?>"><?php echo e($s['detail']); ?></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="su-actions">
|
||
<?php if ($s['url'] !== '') : ?>
|
||
<a href="<?php echo e($s['url']); ?>" class="btn-act <?php echo !$s['done'] && !$s['skipped'] ? 'ok' : ''; ?>"><?php echo $s['done'] ? 'Rivedi' : e($s['cta']); ?></a>
|
||
<?php endif; ?>
|
||
<?php if (!$s['done'] && !$s['skipped'] && $s['manual']) : ?>
|
||
<form method="post" action="school_setup.php"><?php echo yb_csrf_field(); ?><input type="hidden" name="action" value="mark"><input type="hidden" name="key" value="<?php echo e($s['key']); ?>"><button type="submit" class="btn-act"><i class="bx bx-check"></i> Fatto</button></form>
|
||
<?php endif; ?>
|
||
<?php if ($s['done'] && !$s['auto']) : ?>
|
||
<form method="post" action="school_setup.php"><?php echo yb_csrf_field(); ?><input type="hidden" name="action" value="unmark"><input type="hidden" name="key" value="<?php echo e($s['key']); ?>"><button type="submit" class="su-link">Non ancora</button></form>
|
||
<?php endif; ?>
|
||
<?php if (!$s['done'] && !$s['required'] && !$s['skipped']) : ?>
|
||
<form method="post" action="school_setup.php"><?php echo yb_csrf_field(); ?><input type="hidden" name="action" value="skip"><input type="hidden" name="key" value="<?php echo e($s['key']); ?>"><button type="submit" class="su-link">Salta</button></form>
|
||
<?php endif; ?>
|
||
<?php if ($s['skipped']) : ?>
|
||
<form method="post" action="school_setup.php"><?php echo yb_csrf_field(); ?><input type="hidden" name="action" value="unskip"><input type="hidden" name="key" value="<?php echo e($s['key']); ?>"><button type="submit" class="su-link">Ripristina</button></form>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</section>
|
||
<?php endforeach; ?>
|
||
|
||
<div class="card admin-card mt-4">
|
||
<div class="card-body su-finish">
|
||
<?php if ($completedAt) : ?>
|
||
<i class="bx bx-party"></i>
|
||
<h2 class="mt-2" style="font-size:20px;font-weight:800;color:#1E4A4F;">Configurazione completata</h2>
|
||
<form method="post" action="school_setup.php" class="mt-2"><?php echo yb_csrf_field(); ?><input type="hidden" name="action" value="reopen"><button type="submit" class="su-link">Riapri il percorso e mostra di nuovo il promemoria</button></form>
|
||
<?php elseif ($missing === 0) : ?>
|
||
<i class="bx bx-rocket"></i>
|
||
<h2 class="mt-2" style="font-size:20px;font-weight:800;color:#1E4A4F;">Tutto pronto!</h2>
|
||
<p class="text-muted">Hai completato tutti i passi necessari. Chiudi il percorso: il promemoria nel menu sparirà.</p>
|
||
<form method="post" action="school_setup.php"><?php echo yb_csrf_field(); ?><input type="hidden" name="action" value="complete"><button type="submit" class="btn btn-yb" style="min-height:48px;padding:0 26px;">Ho finito</button></form>
|
||
<?php else : ?>
|
||
<p class="mb-0 text-muted">Mancano <strong><?php echo $missing; ?></strong> <?php echo $missing === 1 ? 'passo necessario' : 'passi necessari'; ?>. I passi facoltativi puoi farli dopo o saltarli.</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<?php include('include/footer.php'); ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||
<script src="assets/libs/metismenujs/metismenujs.min.js"></script>
|
||
<script src="assets/libs/simplebar/simplebar.min.js"></script>
|
||
<script src="assets/libs/eva-icons/eva.min.js"></script>
|
||
<script src="assets/js/app.js"></script>
|
||
</body>
|
||
|
||
</html>
|