fixed multi school account
This commit is contained in:
parent
70d01f160e
commit
67cc0742ff
@ -66,19 +66,18 @@ class LoginController extends Controller
|
||||
|
||||
// Validazione del campo school
|
||||
$schoolSlug = $request->input('school');
|
||||
|
||||
if ($schoolSlug) {
|
||||
$school = School::where('slug', $schoolSlug)->first();
|
||||
if (!$school) {
|
||||
return redirect()->to('login' . $to)
|
||||
->withErrors(['school' => trans('auth.school_not_found')]);
|
||||
}
|
||||
// Salva lo school_id nella sessione
|
||||
|
||||
if ($school) {
|
||||
// Se presente e valida → salva in sessione
|
||||
$request->session()->put('school_id', $school->id);
|
||||
} else {
|
||||
// Se il campo school è vuoto, possiamo gestire il caso di default
|
||||
return redirect()->to('login' . $to)
|
||||
->withErrors(['school' => trans('auth.school_required')]);
|
||||
}
|
||||
// ⚠️ se non esiste → NON blocchiamo il login
|
||||
}
|
||||
// ⚠️ se è vuota → NON facciamo nulla
|
||||
|
||||
|
||||
$credentials = $request->getCredentials();
|
||||
|
||||
@ -125,7 +124,7 @@ class LoginController extends Controller
|
||||
if ($user->hasRole('Admin')) {
|
||||
return redirect()->to('userarea/admin.php');
|
||||
} elseif ($user->hasRole('User')) {
|
||||
return redirect()->to('userarea/index.php');
|
||||
return redirect()->to('userarea/select_school.php');
|
||||
} elseif ($user->hasRole('teacher')) {
|
||||
return redirect()->to('userarea/teacher.php');
|
||||
} elseif ($user->hasRole('school_owner')) {
|
||||
@ -151,12 +150,48 @@ class LoginController extends Controller
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
*/
|
||||
public function logout(): RedirectResponse
|
||||
|
||||
|
||||
public function logout(Request $request): RedirectResponse
|
||||
{
|
||||
event(new LoggedOut);
|
||||
|
||||
// 1) Logout Laravel
|
||||
Auth::logout();
|
||||
|
||||
// 2) Pulisci + invalida session Laravel (NON solo forget)
|
||||
$request->session()->forget(['school_id', 'school_name', 'school_selected']);
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
// 3) Pulisci anche la session PHP nativa usata in userarea (PHPSESSID)
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
@session_start();
|
||||
}
|
||||
|
||||
unset(
|
||||
$_SESSION['school_id'],
|
||||
$_SESSION['school_name'],
|
||||
$_SESSION['school_selected']
|
||||
);
|
||||
|
||||
// Se vuoi essere ancora più “definitivo”, distruggi tutta la PHP session:
|
||||
$_SESSION = [];
|
||||
|
||||
if (ini_get('session.use_cookies')) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(
|
||||
session_name(),
|
||||
'',
|
||||
time() - 42000,
|
||||
$params['path'],
|
||||
$params['domain'],
|
||||
$params['secure'],
|
||||
$params['httponly']
|
||||
);
|
||||
}
|
||||
@session_destroy();
|
||||
|
||||
return redirect('login');
|
||||
}
|
||||
}
|
||||
|
||||
235
app/Http/Controllers/Web/Auth/select_school.php
Normal file
235
app/Http/Controllers/Web/Auth/select_school.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
session_start();
|
||||
include('include/headscript.php');
|
||||
|
||||
if (!isset($_SESSION['iduserlogin'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$iduserlogin = $_SESSION['iduserlogin'];
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
// === DATI UTENTE ===
|
||||
$stmt = $pdo->prepare("SELECT first_name, last_name, avatar FROM auth_users WHERE id = ?");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
$avatar = $user['avatar'] ? '../upload/users/' . $user['avatar'] : '../assets/images/default-avatar.png';
|
||||
$first_name = htmlspecialchars($user['first_name'] ?? '');
|
||||
|
||||
// === PROCESSA SELEZIONE SCUOLA (POST) ===
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['school_id'])) {
|
||||
$school_id = (int)$_POST['school_id'];
|
||||
|
||||
$stmt = $pdo->prepare("SELECT id, name, logo FROM schools WHERE id = ? AND status = 'active'");
|
||||
$stmt->execute([$school_id]);
|
||||
$school = $stmt->fetch();
|
||||
|
||||
if ($school) {
|
||||
// Iscrivi automaticamente se non era già iscritto
|
||||
$stmtCheck = $pdo->prepare("SELECT 1 FROM user_schools WHERE user_id = ? AND school_id = ?");
|
||||
$stmtCheck->execute([$iduserlogin, $school_id]);
|
||||
if (!$stmtCheck->fetch()) {
|
||||
$pdo->prepare("INSERT INTO user_schools (user_id, school_id, status) VALUES (?, ?, 'active')")
|
||||
->execute([$iduserlogin, $school_id]);
|
||||
}
|
||||
|
||||
// Imposta sessione
|
||||
$_SESSION['school_id'] = $school['id'];
|
||||
$_SESSION['school_name'] = $school['name'];
|
||||
|
||||
// Reindirizza alla dashboard finale
|
||||
header('Location: user_dashboard.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// === RECUPERA SCUOLE DELL'UTENTE ===
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT s.id, s.name, s.slug, s.logo, s.address_city
|
||||
FROM user_schools us
|
||||
JOIN schools s ON us.school_id = s.id
|
||||
WHERE us.user_id = ? AND us.status = 'active' AND s.status = 'active'
|
||||
ORDER BY s.name
|
||||
");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$userSchools = $stmt->fetchAll();
|
||||
|
||||
// Caso 1: ha esattamente 1 scuola → vai diretto
|
||||
if (count($userSchools) === 1) {
|
||||
$school = $userSchools[0];
|
||||
$_SESSION['school_id'] = $school['id'];
|
||||
$_SESSION['school_name'] = $school['name'];
|
||||
header('Location: user_dashboard.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Caso 2: ha più scuole → mostra selezione
|
||||
// Caso 3: nessuna scuola → mostra tutte le scuole pubbliche
|
||||
if (empty($userSchools)) {
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT id, name, slug, logo, address_city
|
||||
FROM schools
|
||||
WHERE status = 'active'
|
||||
ORDER BY name
|
||||
");
|
||||
$stmt->execute();
|
||||
$schools = $stmt->fetchAll();
|
||||
|
||||
$title = "Benvenuto! Scegli la tua scuola di yoga";
|
||||
$subtitle = "Seleziona la scuola dove vuoi prenotare le lezioni";
|
||||
} else {
|
||||
$schools = $userSchools;
|
||||
$title = "Ciao $first_name!";
|
||||
$subtitle = "Seleziona la scuola in cui vuoi entrare oggi";
|
||||
}
|
||||
?>
|
||||
|
||||
<!doctype html>
|
||||
<html lang="it">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Scegli la scuola - Yogiboook</title>
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<?php include('siteinfo.php'); ?>
|
||||
<style>
|
||||
:root {
|
||||
--pastel-blue: #94bacc;
|
||||
--pastel-green: #a3d9b1;
|
||||
--pastel-pink: #f8bbd0;
|
||||
--pastel-yellow: #fff8c4;
|
||||
}
|
||||
|
||||
.hero-header {
|
||||
background: linear-gradient(135deg, #94bacc, #a3d9b1);
|
||||
color: white;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.school-card {
|
||||
transition: all 0.3s ease;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.school-card:hover {
|
||||
transform: translateY(-10px);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
|
||||
border-color: var(--pastel-blue);
|
||||
}
|
||||
|
||||
.school-logo {
|
||||
height: 120px;
|
||||
object-fit: contain;
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.btn-select {
|
||||
background: linear-gradient(135deg, var(--pastel-blue), var(--pastel-green));
|
||||
border: none;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
border-radius: 15px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.btn-select:hover {
|
||||
transform: scale(1.05);
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<?php include('include/navbar.php'); ?>
|
||||
<?php include('include/topbar.php'); ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content" style="background: linear-gradient(to bottom, #f0f8ff, #f8f9fa); min-height: 100vh;">
|
||||
<div class="container-fluid px-4 pt-5">
|
||||
|
||||
<!-- Header Benvenuto -->
|
||||
<div class="card hero-header mb-5 shadow-lg">
|
||||
<div class="card-body text-center py-5">
|
||||
<h1 class="display-5 fw-bold mb-3"><?php echo $title; ?></h1>
|
||||
<p class="fs-5 opacity-90"><?php echo $subtitle; ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Griglia Scuole -->
|
||||
<?php if (empty($schools)): ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bx bx-building-house bx-lg text-muted"></i>
|
||||
<h4 class="mt-3 text-muted">Nessuna scuola disponibile al momento</h4>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<form method="POST" id="schoolForm">
|
||||
<?= csrf_field() ?> <!-- se usi CSRF, altrimenti rimuovi -->
|
||||
<div class="row g-4 justify-content-center">
|
||||
<?php foreach ($schools as $school): ?>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="school-card card h-100 shadow-sm" onclick="selectSchool(<?= $school['id'] ?>)">
|
||||
<div class="text-center">
|
||||
<?php
|
||||
$logoPath = !empty($school['logo']) && file_exists("photoschool/" . $school['logo'])
|
||||
? "photoschool/" . $school['logo']
|
||||
: null;
|
||||
?>
|
||||
<?php if ($logoPath): ?>
|
||||
<img src="<?= htmlspecialchars($logoPath) ?>"
|
||||
class="school-logo w-100"
|
||||
alt="<?= htmlspecialchars($school['name']) ?>">
|
||||
<?php else: ?>
|
||||
<div class="school-logo d-flex align-items-center justify-content-center">
|
||||
<i class="bx bx-building-house display-4 text-muted"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body text-center pb-4">
|
||||
<h5 class="card-title mb-2"><?= htmlspecialchars($school['name']) ?></h5>
|
||||
<?php if (!empty($school['address_city'])): ?>
|
||||
<p class="text-muted small mb-0">
|
||||
<i class="bx bx-map me-1"></i><?= htmlspecialchars($school['address_city']) ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-footer bg-transparent border-0 pt-0">
|
||||
<button type="submit" class="btn btn-select w-100 shadow-sm">
|
||||
<i class="bx bx-check me-2"></i>Seleziona questa scuola
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="radio" name="school_id" value="<?= $school['id'] ?>" id="school_<?= $school['id'] ?>" class="d-none" required>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include('include/footer.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
|
||||
<script>
|
||||
function selectSchool(id) {
|
||||
document.getElementById('school_' + id).checked = true;
|
||||
document.getElementById('schoolForm').submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -337,7 +337,7 @@ $cart_count = array_sum(array_column($_SESSION['cart'], 'quantity'));
|
||||
<li>
|
||||
<div class="dropdown-divider mb-0"></div>
|
||||
</li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="javascript:;"><i class="bx bx-log-out-circle"></i><span>Logout</span></a></li>
|
||||
<li><a class="dropdown-item d-flex align-items-center" href="../logout"><i class="bx bx-log-out-circle"></i><span>Logout</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@ -5,44 +5,52 @@ if (!isset($iduserlogin)) header('Location: login.php');
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
// Scuola corrente
|
||||
$school_id = session('school_id');
|
||||
if (!$school_id) die("Nessuna scuola selezionata");
|
||||
|
||||
// Dati utente
|
||||
$stmt = $pdo->prepare("SELECT first_name FROM auth_users WHERE id = ?");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
// === LEZIONI FUTURE DELL'UTENTE (prenotate) ===
|
||||
$stmt = $pdo->prepare("SELECT name, address_street, address_city, address_province FROM schools WHERE id = ?");
|
||||
$stmt->execute([$school_id]);
|
||||
$school = $stmt->fetch();
|
||||
|
||||
$currentMonth = $_GET['month'] ?? date('Y-m');
|
||||
$monthDate = DateTime::createFromFormat('Y-m', $currentMonth) ?: new DateTime();
|
||||
$prevMonth = (clone $monthDate)->modify('-1 month')->format('Y-m');
|
||||
$nextMonth = (clone $monthDate)->modify('+1 month')->format('Y-m');
|
||||
|
||||
setlocale(LC_TIME, 'it_IT.UTF-8', 'Italian');
|
||||
$monthName = ucfirst(utf8_encode(strftime('%B %Y', $monthDate->getTimestamp())));
|
||||
|
||||
$startOfMonth = $monthDate->format('Y-m-01');
|
||||
$endOfMonth = (clone $monthDate)->modify('first day of next month')->format('Y-m-d');
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT
|
||||
sb.id as booking_id,
|
||||
sb.booked_at,
|
||||
sb.status,
|
||||
cs.session_date,
|
||||
cs.start_time,
|
||||
cs.end_time,
|
||||
cs.room_name,
|
||||
c.name as class_name,
|
||||
ct.level,
|
||||
ct.day_of_week,
|
||||
t.first_name as teacher_name,
|
||||
o.id as order_id,
|
||||
o.available_entries,
|
||||
o.total_entries,
|
||||
o.available_recoveries
|
||||
FROM session_bookings sb
|
||||
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
LEFT JOIN teachers t ON cs.teacher_id = t.id
|
||||
JOIN orders o ON sb.order_id = o.id
|
||||
WHERE sb.user_id = ?
|
||||
AND cs.school_id = ?
|
||||
AND cs.session_date >= CURDATE()
|
||||
AND cs.session_date >= ?
|
||||
AND cs.session_date < ?
|
||||
ORDER BY cs.session_date ASC, cs.start_time ASC
|
||||
");
|
||||
$stmt->execute([$iduserlogin, $school_id]);
|
||||
$stmt->execute([$iduserlogin, $school_id, $startOfMonth, $endOfMonth]);
|
||||
$bookings = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
@ -52,51 +60,132 @@ $bookings = $stmt->fetchAll();
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Le mie lezioni - Yogiboook</title>
|
||||
<title>Le mie lezioni</title>
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<?php include('siteinfo.php'); ?>
|
||||
<style>
|
||||
:root {
|
||||
--pastel-blue: #94bacc;
|
||||
--pastel-green: #a3d9b1;
|
||||
--pastel-pink: #f8bbd0;
|
||||
.page-content {
|
||||
background: #f9fff9;
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.month-header {
|
||||
background: white;
|
||||
padding: 0.9rem 1rem;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.07);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
|
||||
.month-header h2 {
|
||||
font-size: 1.45rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.nav-arrow {
|
||||
font-size: 1.7rem;
|
||||
color: #10b981;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.lesson-card {
|
||||
background: white;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
border-left: 5px solid var(--pastel-blue);
|
||||
margin: 1rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.09);
|
||||
border-left: 6px solid #86efac;
|
||||
}
|
||||
|
||||
.lesson-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
|
||||
.date-header {
|
||||
background: #d1fae5;
|
||||
color: #065f46;
|
||||
padding: 1.4rem 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 0.4em 1em;
|
||||
border-radius: 50px;
|
||||
font-size: 0.85rem;
|
||||
.date-num {
|
||||
font-size: 2.7rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.date-day {
|
||||
font-size: 1.18rem;
|
||||
font-weight: 600;
|
||||
margin: 5px 0 0;
|
||||
}
|
||||
|
||||
.btn-reschedule {
|
||||
background: linear-gradient(45deg, #ff9a9e, #fad0c4);
|
||||
.lesson-body {
|
||||
padding: 1.4rem 1.3rem;
|
||||
}
|
||||
|
||||
.lesson-title {
|
||||
font-size: 1.38rem;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin: 0 0 0.8rem;
|
||||
}
|
||||
|
||||
.lesson-meta {
|
||||
font-size: 0.98rem;
|
||||
color: #444;
|
||||
margin: 0.5rem 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.lesson-meta i {
|
||||
width: 20px;
|
||||
color: #666;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.entries-badge {
|
||||
display: inline-block;
|
||||
background: #dbeafe;
|
||||
color: #1e40af;
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
font-size: 0.92rem;
|
||||
margin: 0.8rem 0;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
margin-top: 1.2rem;
|
||||
display: flex;
|
||||
gap: 0.8rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn-custom {
|
||||
flex: 1;
|
||||
min-width: 130px;
|
||||
padding: 0.85rem;
|
||||
border-radius: 14px;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary-custom {
|
||||
background: #10b981;
|
||||
color: white;
|
||||
border: none;
|
||||
color: white;
|
||||
border-radius: 25px;
|
||||
padding: 0.5rem 1.2rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
background: #e74c3c;
|
||||
color: white;
|
||||
border-radius: 25px;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.85rem;
|
||||
.btn-outline-custom {
|
||||
background: transparent;
|
||||
color: #10b981;
|
||||
border: 2px solid #10b981;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -107,96 +196,88 @@ $bookings = $stmt->fetchAll();
|
||||
<?php include('include/topbar.php'); ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content" style="background: linear-gradient(to bottom, #f8fdff, #f0f8ff);">
|
||||
<div class="page-content">
|
||||
|
||||
<div class="container-fluid px-4 pt-4">
|
||||
<div class="text-center mb-5">
|
||||
<h1 class="display-5 fw-bold text-primary">
|
||||
Le tue lezioni future
|
||||
</h1>
|
||||
<p class="lead text-muted">
|
||||
<?php echo $user['first_name']; ?>, ecco tutte le lezioni che hai prenotato
|
||||
</p>
|
||||
<div class="month-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<a href="?month=<?= $prevMonth ?>" class="nav-arrow">←</a>
|
||||
<h2><?= $monthName ?></h2>
|
||||
<a href="?month=<?= $nextMonth ?>" class="nav-arrow">→</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid px-0">
|
||||
|
||||
<?php if (empty($bookings)): ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bx bx-calendar-x bx-lg text-muted"></i>
|
||||
<h4 class="text-muted mt-4">Nessuna lezione prenotata</h4>
|
||||
<p class="text-muted">Quando acquisterai un carnet o un abbonamento, potrai prenotare qui le tue lezioni!</p>
|
||||
<a href="products.php" class="btn btn-primary btn-lg mt-3">Vai ai corsi</a>
|
||||
<div class="text-center py-5 px-3">
|
||||
<i class="bx bx-calendar-x" style="font-size:4.5rem;color:#e0e0e0;"></i>
|
||||
<h3 class="mt-4 text-secondary">Nessuna lezione prenotata</h3>
|
||||
<p class="text-muted">Le tue lezioni appariranno qui</p>
|
||||
<a href="products.php" class="btn btn-success btn-lg mt-3">Vedi i corsi</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="row g-4">
|
||||
<?php foreach ($bookings as $b): ?>
|
||||
<div class="col-lg-6 col-xl-4">
|
||||
<div class="card lesson-card h-100">
|
||||
<div class="card-body p-4">
|
||||
<!-- Data e ora -->
|
||||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||
<div>
|
||||
<h5 class="mb-1"><?php echo date('d', strtotime($b['session_date'])); ?></h5>
|
||||
<p class="text-muted mb-0"><?php echo ucfirst(strftime('%B %Y', strtotime($b['session_date']))); ?></p>
|
||||
<div class="lesson-card">
|
||||
<div class="date-header">
|
||||
<div class="date-num"><?= date('d', strtotime($b['session_date'])) ?></div>
|
||||
<div class="date-day">
|
||||
<?= ucfirst(utf8_encode(strftime('%A', strtotime($b['session_date'])))) ?>
|
||||
</div>
|
||||
<span class="status-badge <?php
|
||||
echo $b['status'] == 'booked' ? 'bg-success' : ($b['status'] == 'cancelled' ? 'bg-danger' : 'bg-warning');
|
||||
?>">
|
||||
<?php echo $b['status'] == 'booked' ? 'Prenotata' : ($b['status'] == 'cancelled' ? 'Annullata' : 'In attesa'); ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Dettagli lezione -->
|
||||
<h4 class="mb-2"><?php echo htmlspecialchars($b['class_name']); ?></h4>
|
||||
<p class="text-primary mb-2">
|
||||
<?php echo ucfirst($b['level'] ?? 'Tutti i livelli'); ?>
|
||||
<?php if ($b['day_of_week']): ?> • <?php echo ucfirst($b['day_of_week']); ?><?php endif; ?>
|
||||
</p>
|
||||
<div class="lesson-body">
|
||||
<h3 class="lesson-title">
|
||||
<?= htmlspecialchars($b['class_name']) ?>
|
||||
<?php if ($b['level']): ?> <small style="color:#666;">- <?= ucfirst($b['level']) ?></small><?php endif; ?>
|
||||
</h3>
|
||||
|
||||
<div class="mb-3">
|
||||
<p class="mb-1">
|
||||
<div class="lesson-meta">
|
||||
<i class="bx bx-time"></i>
|
||||
<?php echo date('H:i', strtotime($b['start_time'])); ?> - <?php echo date('H:i', strtotime($b['end_time'])); ?>
|
||||
</p>
|
||||
<?php if ($b['teacher_name']): ?>
|
||||
<p class="mb-1">
|
||||
<i class="bx bx-user"></i> Con <?php echo htmlspecialchars($b['teacher_name']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?= date('H:i', strtotime($b['start_time'])) ?> - <?= date('H:i', strtotime($b['end_time'])) ?>
|
||||
</div>
|
||||
|
||||
<!-- Ingressi rimanenti -->
|
||||
<div class="alert alert-light border mb-3 py-2">
|
||||
<small class="d-block">
|
||||
<strong>Ingressi:</strong>
|
||||
<span class="text-success"><?php echo $b['available_entries']; ?></span>/<?php echo $b['total_entries']; ?>
|
||||
<div class="lesson-meta">
|
||||
<i class="bx bx-home"></i>
|
||||
<?= htmlspecialchars($school['name']) ?>
|
||||
<?php if ($b['room_name']): ?> - <?= htmlspecialchars($b['room_name']) ?><?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="lesson-meta">
|
||||
<i class="bx bx-map"></i>
|
||||
<?= htmlspecialchars(trim($school['address_street'] . ', ' . $school['address_city'] . ' ' . $school['address_province'])) ?>
|
||||
</div>
|
||||
|
||||
<?php if ($b['available_entries'] > 0 || $b['available_recoveries'] > 0): ?>
|
||||
<div class="entries-badge">
|
||||
<?php if ($b['available_entries'] > 0): ?>
|
||||
Ingressi disponibili: <strong><?= $b['available_entries'] ?></strong>
|
||||
<?php endif; ?>
|
||||
<?php if ($b['available_recoveries'] > 0): ?>
|
||||
• <strong>Recuperi:</strong> <?php echo $b['available_recoveries']; ?>
|
||||
<?= $b['available_entries'] > 0 ? ' • ' : '' ?>
|
||||
Recuperi: <strong><?= $b['available_recoveries'] ?></strong>
|
||||
<?php endif; ?>
|
||||
</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Pulsanti azione -->
|
||||
<div class="d-flex gap-2">
|
||||
<?php if ($b['status'] == 'booked' && strtotime($b['session_date']) > time() + 86400): // più di 24h prima
|
||||
?>
|
||||
<button class="btn btn-reschedule" onclick="reschedule(<?php echo $b['booking_id']; ?>)">
|
||||
<?php if ($b['status'] == 'booked' && strtotime($b['session_date']) > time() + 86400): ?>
|
||||
<div class="action-buttons">
|
||||
<button class="btn-custom btn-primary-custom" onclick="reschedule(<?= $b['booking_id'] ?>)">
|
||||
Riprogramma
|
||||
</button>
|
||||
<button class="btn btn-cancel btn-sm" onclick="cancelBooking(<?php echo $b['booking_id']; ?>)">
|
||||
Annulla
|
||||
<button class="btn-custom btn-outline-custom" onclick="cancelBooking(<?= $b['booking_id'] ?>)">
|
||||
Cancella
|
||||
</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<button class="btn btn-secondary btn-sm" disabled>
|
||||
Non modificabile
|
||||
</button>
|
||||
<div class="text-muted small mt-3">
|
||||
Non modificabile (entro 24 ore)
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -205,52 +286,31 @@ $bookings = $stmt->fetchAll();
|
||||
</div>
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script>
|
||||
function reschedule(bookingId) {
|
||||
Swal.fire({
|
||||
title: 'Riprogrammare lezione?',
|
||||
text: "Vuoi scegliere un nuovo orario per questa lezione?",
|
||||
const reschedule = id => Swal.fire({
|
||||
title: 'Riprogrammare?',
|
||||
text: 'Scegli un nuovo orario',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Sì, riprogramma',
|
||||
cancelButtonText: 'Annulla'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'reschedule.php?booking=' + bookingId;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancelBooking(bookingId) {
|
||||
Swal.fire({
|
||||
confirmButtonText: 'Sì',
|
||||
cancelButtonText: 'No'
|
||||
}).then(r => r.isConfirmed && (location = 'reschedule.php?booking=' + id));
|
||||
const cancelBooking = id => Swal.fire({
|
||||
title: 'Annullare prenotazione?',
|
||||
text: "L'ingresso ti verrà restituito come recupero",
|
||||
text: 'Riceverai un recupero',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#e74c3c',
|
||||
confirmButtonColor: '#ef4444',
|
||||
confirmButtonText: 'Sì, annulla',
|
||||
cancelButtonText: 'No, tienila'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
fetch('cancel_booking.php', {
|
||||
cancelButtonText: 'No'
|
||||
}).then(r => r.isConfirmed && fetch('cancel_booking.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: 'booking_id=' + bookingId
|
||||
}).then(r => r.json()).then(data => {
|
||||
if (data.success) {
|
||||
Swal.fire('Annullata!', 'La lezione è stata annullata e hai ricevuto un recupero.', 'success')
|
||||
.then(() => location.reload());
|
||||
} else {
|
||||
Swal.fire('Errore', data.message, 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
body: 'booking_id=' + id
|
||||
}).then(r => r.json()).then(d => d.success ? Swal.fire('Annullata!', 'Hai un recupero', 'success').then(() => location.reload()) : Swal.fire('Errore', d.message, 'error')));
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
@ -932,6 +932,7 @@ $daily_sessions = $stmt->fetchAll();
|
||||
<?php echo $class['status'] === 'active' ? 'Attivo' : 'Inattivo'; ?>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-warning" data-bs-toggle="modal" data-bs-target="#editClassModal"
|
||||
onclick='fillEditModal(<?php echo json_encode([
|
||||
@ -981,6 +982,7 @@ $daily_sessions = $stmt->fetchAll();
|
||||
<th>Sala</th>
|
||||
<th>Insegnante</th>
|
||||
<th>Stato</th>
|
||||
<th>Prenotati</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -1117,12 +1119,35 @@ $daily_sessions = $stmt->fetchAll();
|
||||
}
|
||||
|
||||
// Recupera tutte le sessioni nell'intervallo
|
||||
// === NUOVA QUERY CON CONTEGGIO E LISTA PRENOTATI ===
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT cs.*,
|
||||
ct.level, ct.day_of_week, ct.start_time, ct.room_name, ct.teacher_id,
|
||||
SELECT
|
||||
cs.*,
|
||||
ct.level, ct.day_of_week, ct.start_time AS ct_start_time, ct.room_name, ct.teacher_id,
|
||||
c.name AS class_name, c.photo AS class_photo,
|
||||
ct.photo AS variation_photo,
|
||||
t.first_name AS teacher_first_name, t.last_name AS teacher_last_name
|
||||
t.first_name AS teacher_first_name, t.last_name AS teacher_last_name,
|
||||
|
||||
-- Contiamo gli studenti prenotati (solo booked, attended, rescheduled)
|
||||
(SELECT COUNT(*)
|
||||
FROM session_bookings sb
|
||||
WHERE sb.session_id = cs.id
|
||||
AND sb.status IN ('booked', 'attended', 'rescheduled')
|
||||
) AS booked_count,
|
||||
|
||||
-- Capacità massima (da class_sessions o da class_types se null)
|
||||
COALESCE(cs.max_capacity, ct.max_capacity, 0) AS effective_capacity,
|
||||
|
||||
-- Lista studenti prenotati (per il modale)
|
||||
(SELECT GROUP_CONCAT(
|
||||
CONCAT(au.first_name, ' ', au.last_name, '|', au.email, '|', COALESCE(au.phone, ''))
|
||||
SEPARATOR ';;;'
|
||||
)
|
||||
FROM session_bookings sb
|
||||
JOIN auth_users au ON sb.user_id = au.id
|
||||
WHERE sb.session_id = cs.id
|
||||
AND sb.status IN ('booked', 'attended', 'rescheduled')
|
||||
) AS booked_students
|
||||
FROM class_sessions cs
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
@ -1130,7 +1155,7 @@ $daily_sessions = $stmt->fetchAll();
|
||||
WHERE cs.session_date BETWEEN ? AND ?
|
||||
AND c.school_id = ?
|
||||
ORDER BY cs.session_date, cs.start_time
|
||||
");
|
||||
");
|
||||
$stmt->execute([$start_date, $end_date, $school_id]);
|
||||
$range_sessions = $stmt->fetchAll();
|
||||
?>
|
||||
@ -1158,6 +1183,7 @@ $daily_sessions = $stmt->fetchAll();
|
||||
<th>Sala</th>
|
||||
<th>Insegnante</th>
|
||||
<th>Stato</th>
|
||||
<th>Prenotati</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -1198,6 +1224,23 @@ $daily_sessions = $stmt->fetchAll();
|
||||
<?php echo $session['status'] === 'scheduled' ? 'Programmata' : ($session['status'] === 'completed' ? 'Completata' : 'Annullata'); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$booked = $session['booked_count'];
|
||||
$capacity = $session['effective_capacity'] > 0 ? $session['effective_capacity'] : '∞';
|
||||
$color = ($capacity !== '∞' && $booked >= $capacity) ? 'danger' : 'success';
|
||||
?>
|
||||
<button type="button" class="btn btn-sm btn-<?php echo $color; ?> position-relative"
|
||||
data-bs-toggle="modal" data-bs-target="#studentsModal-<?php echo $session['id']; ?>">
|
||||
<?php echo $booked; ?> / <?php echo $capacity; ?>
|
||||
<?php if ($booked > 0): ?>
|
||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-dark">
|
||||
<?php echo $booked; ?>
|
||||
<span class="visually-hidden">prenotati</span>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-warning" data-bs-toggle="modal" data-bs-target="#editSessionModal"
|
||||
onclick='fillEditSessionModal(<?php echo json_encode([
|
||||
@ -1863,6 +1906,57 @@ $daily_sessions = $stmt->fetchAll();
|
||||
white-space: normal;
|
||||
}
|
||||
</style>
|
||||
<?php foreach ($range_sessions as $session): ?>
|
||||
<?php if ($session['booked_count'] > 0): ?>
|
||||
<div class="modal fade" id="studentsModal-<?php echo $session['id']; ?>" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title">
|
||||
Prenotati - <?php echo htmlspecialchars($session['class_name']); ?>
|
||||
<?php echo ucfirst($session['level']); ?>
|
||||
del <?php echo date('d/m/Y', strtotime($session['session_date'])); ?>
|
||||
ore <?php echo substr($session['start_time'], 0, 5); ?>
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th>Email</th>
|
||||
<th>Telefono</th>
|
||||
<th>Stato</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$students = explode(';;;', $session['booked_students'] ?? '');
|
||||
foreach ($students as $s):
|
||||
if (empty(trim($s))) continue;
|
||||
list($name, $email, $phone) = explode('|', $s . '||');
|
||||
?>
|
||||
<tr>
|
||||
<td><strong><?php echo htmlspecialchars($name); ?></strong></td>
|
||||
<td><?php echo htmlspecialchars($email); ?></td>
|
||||
<td><?php echo htmlspecialchars($phone ?: '—'); ?></td>
|
||||
<td><span class="badge bg-success">Prenotato</span></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Chiudi</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;
|
||||
endforeach; ?>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
421
public/userarea/select_school.php
Normal file
421
public/userarea/select_school.php
Normal file
@ -0,0 +1,421 @@
|
||||
<?php
|
||||
session_start();
|
||||
include('include/headscript.php');
|
||||
|
||||
error_log("SELECT_SCHOOL HIT - user=" . ($_SESSION['iduserlogin'] ?? 'NOUSER') . " school=" . var_export($_SESSION['school_id'] ?? null, true));
|
||||
|
||||
// ----------------------------------------------------
|
||||
// SYNC school_id between Laravel session and PHP $_SESSION
|
||||
// ----------------------------------------------------
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// se Laravel ha school_id e PHP no → copio in PHP
|
||||
// if (!isset($_SESSION['school_id']) && function_exists('session') && session()->has('school_id')) {
|
||||
// $_SESSION['school_id'] = session('school_id');
|
||||
// if (session()->has('school_name')) {
|
||||
// $_SESSION['school_name'] = session('school_name');
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// se PHP ha school_id e Laravel no → copio in Laravel
|
||||
if (isset($_SESSION['school_id']) && function_exists('session') && !session()->has('school_id')) {
|
||||
session([
|
||||
'school_id' => $_SESSION['school_id'],
|
||||
'school_name' => $_SESSION['school_name'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| AUTH CHECK
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
if (!isset($_SESSION['iduserlogin'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SE SCHOOL GIÀ IN SESSIONE → VAI AVANTI
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
// Se ho già una school_id in sessione, vado avanti SOLO se l'utente ha 1 scuola sola.
|
||||
// Se ne ha >1, devo sempre mostrare la selezione.
|
||||
if (!empty($_SESSION['school_id'])) {
|
||||
// Non faccio redirect qui: lo decido DOPO aver caricato $userSchools
|
||||
// (vedi sotto, dopo la query delle scuole utente)
|
||||
}
|
||||
|
||||
|
||||
$iduserlogin = $_SESSION['iduserlogin'];
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DATI UTENTE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$stmt = $pdo->prepare("SELECT first_name, avatar FROM auth_users WHERE id = ?");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
$first_name = htmlspecialchars($user['first_name'] ?? '');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| POST → SELEZIONE SCUOLA
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['school_id'])) {
|
||||
$school_id = (int) $_POST['school_id'];
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT id, name
|
||||
FROM schools
|
||||
WHERE id = ? AND status = 'active'
|
||||
");
|
||||
$stmt->execute([$school_id]);
|
||||
$school = $stmt->fetch();
|
||||
|
||||
if ($school) {
|
||||
|
||||
// Iscrizione automatica se non esiste
|
||||
$check = $pdo->prepare("
|
||||
SELECT 1 FROM user_schools
|
||||
WHERE user_id = ? AND school_id = ?
|
||||
");
|
||||
$check->execute([$iduserlogin, $school_id]);
|
||||
|
||||
if (!$check->fetch()) {
|
||||
$pdo->prepare("
|
||||
INSERT INTO user_schools (user_id, school_id, status)
|
||||
VALUES (?, ?, 'active')
|
||||
")->execute([$iduserlogin, $school_id]);
|
||||
}
|
||||
|
||||
// Sessione
|
||||
$_SESSION['school_id'] = $school['id'];
|
||||
$_SESSION['school_name'] = $school['name'];
|
||||
$_SESSION['school_selected'] = 1;
|
||||
|
||||
|
||||
if (function_exists('session')) {
|
||||
session([
|
||||
'school_id' => $school['id'],
|
||||
'school_name' => $school['name'],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
header('Location: user_dashboard.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| RECUPERO SCUOLE UTENTE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT s.id, s.name, s.logo, s.address_city
|
||||
FROM user_schools us
|
||||
JOIN schools s ON us.school_id = s.id
|
||||
WHERE us.user_id = ?
|
||||
AND us.status = 'active'
|
||||
AND s.status = 'active'
|
||||
ORDER BY s.name
|
||||
");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$userSchools = $stmt->fetchAll();
|
||||
// --- VALIDAZIONE school_id: se non appartiene all'utente, la resetto ---
|
||||
$allowedIds = array_map(fn($r) => (int)$r['id'], $userSchools);
|
||||
|
||||
if (!empty($_SESSION['school_id']) && !in_array((int)$_SESSION['school_id'], $allowedIds, true)) {
|
||||
unset($_SESSION['school_id'], $_SESSION['school_name'], $_SESSION['school_selected']);
|
||||
if (function_exists('session')) {
|
||||
session()->forget('school_id');
|
||||
session()->forget('school_name');
|
||||
}
|
||||
}
|
||||
|
||||
// Caso 1: una sola scuola -> auto-select e vado in dashboard
|
||||
if (count($userSchools) === 1) {
|
||||
$_SESSION['school_id'] = (int)$userSchools[0]['id'];
|
||||
$_SESSION['school_name'] = $userSchools[0]['name'];
|
||||
$_SESSION['school_selected'] = 1;
|
||||
|
||||
if (function_exists('session')) {
|
||||
session([
|
||||
'school_id' => (int)$userSchools[0]['id'],
|
||||
'school_name' => $userSchools[0]['name'],
|
||||
]);
|
||||
}
|
||||
|
||||
header('Location: user_dashboard.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Caso 2: più scuole -> se school_id è presente MA non c'è selezione esplicita, mostro comunque la select
|
||||
// Se invece school_id + school_selected sono presenti, posso andare in dashboard
|
||||
if (count($userSchools) > 1 && !empty($_SESSION['school_id']) && !empty($_SESSION['school_selected'])) {
|
||||
header('Location: user_dashboard.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| CASO: NESSUNA SCUOLA → MOSTRA PUBBLICHE
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
if (empty($userSchools)) {
|
||||
$stmt = $pdo->query("
|
||||
SELECT id, name, logo, address_city
|
||||
FROM schools
|
||||
WHERE status = 'active'
|
||||
ORDER BY name
|
||||
");
|
||||
$schools = $stmt->fetchAll();
|
||||
|
||||
$title = "Benvenuto!";
|
||||
$subtitle = "Scegli la scuola dove vuoi prenotare le lezioni";
|
||||
} else {
|
||||
$schools = $userSchools;
|
||||
$title = "Ciao $first_name!";
|
||||
$subtitle = "Seleziona la scuola in cui entrare oggi";
|
||||
}
|
||||
?>
|
||||
|
||||
<!doctype html>
|
||||
<html lang="it">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Scegli la scuola - Yogiboook</title>
|
||||
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<?php include('siteinfo.php'); ?>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--pastel-blue: #94bacc;
|
||||
--pastel-green: #a3d9b1;
|
||||
--pastel-pink: #f8bbd0;
|
||||
--pastel-yellow: #fff8c4;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(to bottom, #f0f8ff, #f8f9fa);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.card-pastel {
|
||||
background: linear-gradient(135deg, #94bacc, #a3d9b1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.radius-20 {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.school-card {
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s ease;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.school-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 18px 45px rgba(0, 0, 0, 0.12);
|
||||
border-color: rgba(148, 186, 204, 0.9);
|
||||
}
|
||||
|
||||
.school-logo {
|
||||
height: 120px;
|
||||
object-fit: contain;
|
||||
background: #f8f9fa;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.btn-select {
|
||||
background: linear-gradient(135deg, var(--pastel-blue), var(--pastel-green));
|
||||
border: none;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
border-radius: 14px;
|
||||
padding: 12px 14px;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-select:hover {
|
||||
transform: scale(1.03);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.badge-soft {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0.35rem 0.75rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
FORCE FULL WIDTH WHEN SIDEBAR IS NOT INCLUDED
|
||||
========================================================= */
|
||||
.no-sidebar .page-wrapper,
|
||||
.no-sidebar .page-content {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.no-sidebar .topbar,
|
||||
.no-sidebar .header,
|
||||
.no-sidebar .navbar,
|
||||
.no-sidebar .topbar-nav {
|
||||
left: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.no-sidebar .wrapper {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.no-sidebar .sidebar-wrapper {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="no-sidebar">
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
<!-- niente navbar -->
|
||||
<?php include('include/topbar.php'); ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content" style="min-height: 100vh;">
|
||||
<div class="container-fluid px-4 pt-5 pb-5">
|
||||
|
||||
<!-- HERO -->
|
||||
<div class="card card-pastel radius-20 shadow-lg mb-5">
|
||||
<div class="card-body text-center py-5 position-relative">
|
||||
<div class="badge-soft mb-3">
|
||||
<i class="bx bx-buildings"></i>
|
||||
Selezione scuola
|
||||
</div>
|
||||
|
||||
<h1 class="display-6 fw-bold mb-2"><?= htmlspecialchars($title) ?></h1>
|
||||
<p class="fs-5 opacity-90 mb-0"><?= htmlspecialchars($subtitle) ?></p>
|
||||
|
||||
<div class="mt-4 text-white-50">
|
||||
<small>Utente: <strong class="text-white"><?= htmlspecialchars($first_name) ?></strong></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CONTENUTO -->
|
||||
<?php if (empty($schools)): ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bx bx-building-house bx-lg text-muted"></i>
|
||||
<h4 class="mt-3 text-muted">Nessuna scuola disponibile al momento</h4>
|
||||
<p class="text-muted mb-0">Riprova più tardi oppure contatta l’assistenza.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<form method="POST" id="schoolForm">
|
||||
<div class="row g-4 justify-content-center">
|
||||
|
||||
<?php foreach ($schools as $school): ?>
|
||||
<?php
|
||||
$sid = (int)$school['id'];
|
||||
$sname = $school['name'] ?? '';
|
||||
$scity = $school['address_city'] ?? '';
|
||||
|
||||
$logoPath = null;
|
||||
if (!empty($school['logo']) && file_exists("photoschool/" . $school['logo'])) {
|
||||
$logoPath = "photoschool/" . $school['logo'];
|
||||
}
|
||||
?>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card school-card h-100 shadow-sm" onclick="selectSchool(<?= $sid ?>)">
|
||||
|
||||
<div class="text-center">
|
||||
<?php if ($logoPath): ?>
|
||||
<img src="<?= htmlspecialchars($logoPath) ?>"
|
||||
class="school-logo w-100"
|
||||
alt="<?= htmlspecialchars($sname) ?>">
|
||||
<?php else: ?>
|
||||
<div class="school-logo d-flex align-items-center justify-content-center">
|
||||
<i class="bx bx-building-house display-4 text-muted"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="card-body text-center pb-4">
|
||||
<h5 class="card-title mb-2"><?= htmlspecialchars($sname) ?></h5>
|
||||
|
||||
<?php if (!empty($scity)): ?>
|
||||
<p class="text-muted small mb-0">
|
||||
<i class="bx bx-map me-1"></i><?= htmlspecialchars($scity) ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="card-footer bg-transparent border-0 pt-0 pb-4 px-4">
|
||||
<button type="submit" class="btn btn-select w-100 shadow-sm">
|
||||
<i class="bx bx-check me-2"></i>Seleziona questa scuola
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<input type="radio"
|
||||
name="school_id"
|
||||
value="<?= $sid ?>"
|
||||
id="school_<?= $sid ?>"
|
||||
class="d-none"
|
||||
required>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include('include/footer.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
|
||||
<script>
|
||||
function selectSchool(id) {
|
||||
const r = document.getElementById('school_' + id);
|
||||
if (r) r.checked = true;
|
||||
document.getElementById('schoolForm').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,6 +1,9 @@
|
||||
<?php
|
||||
session_start();
|
||||
include('include/headscript.php');
|
||||
|
||||
error_log("DASHBOARD HIT - user=" . ($_SESSION['iduserlogin'] ?? 'NOUSER') . " school=" . var_export($_SESSION['school_id'] ?? null, true));
|
||||
|
||||
if (!isset($iduserlogin)) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
@ -9,6 +12,87 @@ if (!isset($iduserlogin)) {
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 1) Carico le scuole attive dell'utente
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT s.id, s.name, s.logo
|
||||
FROM user_schools us
|
||||
JOIN schools s ON us.school_id = s.id
|
||||
WHERE us.user_id = ?
|
||||
AND us.status = 'active'
|
||||
AND s.status = 'active'
|
||||
ORDER BY s.name
|
||||
");
|
||||
$stmt->execute([(int)$iduserlogin]);
|
||||
$userSchools = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 2) Cambio scuola da modale (POST)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'change_school') {
|
||||
$newSchoolId = (int)($_POST['school_id'] ?? 0);
|
||||
|
||||
$allowedIds = array_map(fn($r) => (int)$r['id'], $userSchools);
|
||||
|
||||
if ($newSchoolId > 0 && in_array($newSchoolId, $allowedIds, true)) {
|
||||
// imposto sessione
|
||||
$_SESSION['school_id'] = $newSchoolId;
|
||||
|
||||
// imposto anche il nome (comodo per UI)
|
||||
foreach ($userSchools as $r) {
|
||||
if ((int)$r['id'] === $newSchoolId) {
|
||||
$_SESSION['school_name'] = $r['name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// flag: selezione esplicita
|
||||
$_SESSION['school_selected'] = 1;
|
||||
|
||||
header('Location: user_dashboard.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 3) Validazione school_id in sessione
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$allowedIds = array_map(fn($r) => (int)$r['id'], $userSchools);
|
||||
|
||||
// Se l'utente non ha scuole -> vai alla select (dove vedrà le pubbliche)
|
||||
if (count($userSchools) === 0) {
|
||||
header('Location: select_school.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Se school_id esiste ma NON appartiene all'utente -> reset
|
||||
if (!empty($_SESSION['school_id']) && !in_array((int)$_SESSION['school_id'], $allowedIds, true)) {
|
||||
unset($_SESSION['school_id'], $_SESSION['school_name'], $_SESSION['school_selected']);
|
||||
}
|
||||
|
||||
// Caso: una sola scuola -> auto-select (OK)
|
||||
if (count($userSchools) === 1 && empty($_SESSION['school_id'])) {
|
||||
$_SESSION['school_id'] = (int)$userSchools[0]['id'];
|
||||
$_SESSION['school_name'] = $userSchools[0]['name'];
|
||||
$_SESSION['school_selected'] = 1;
|
||||
}
|
||||
|
||||
// Caso: più scuole -> OBBLIGO selezione esplicita
|
||||
if (count($userSchools) > 1) {
|
||||
if (empty($_SESSION['school_id']) || empty($_SESSION['school_selected'])) {
|
||||
header('Location: select_school.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === DATI UTENTE ===
|
||||
$stmt = $pdo->prepare("SELECT first_name, last_name, email, avatar FROM auth_users WHERE id = ?");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
@ -16,7 +100,14 @@ $user = $stmt->fetch();
|
||||
$avatar = $user['avatar'] ? '../upload/users/' . $user['avatar'] : '../assets/images/default-avatar.png';
|
||||
|
||||
// === SCUOLA CORRENTE ===
|
||||
$school_id = session('school_id');
|
||||
$school_id = (int)($_SESSION['school_id'] ?? 0);
|
||||
|
||||
if ($school_id <= 0) {
|
||||
header('Location: select_school.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$school_name = 'Nessuna scuola selezionata';
|
||||
$school_logo_path = null; // niente default
|
||||
|
||||
@ -286,15 +377,56 @@ $active_orders = count(array_filter($orders, fn($o) => $o['status'] === 'complet
|
||||
<h5 class="modal-title">Scegli la scuola</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center py-5">
|
||||
<i class="bx bx-building-house bx-lg text-muted"></i>
|
||||
<h4 class="mt-3 text-muted">Le tue scuole</h4>
|
||||
<p class="text-muted">Qui compariranno tutte le scuole in cui sei iscritto</p>
|
||||
<div class="spinner-border text-primary mt-4" role="status">
|
||||
<span class="visually-hidden">Caricamento...</span>
|
||||
<div class="modal-body">
|
||||
<?php if (empty($userSchools)): ?>
|
||||
<div class="text-center text-muted py-4">
|
||||
Nessuna scuola associata.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="row g-3">
|
||||
<?php foreach ($userSchools as $s): ?>
|
||||
<?php
|
||||
$sid = (int)$s['id'];
|
||||
$sname = $s['name'];
|
||||
$logoPath = (!empty($s['logo']) && file_exists("photoschool/" . $s['logo']))
|
||||
? "photoschool/" . $s['logo']
|
||||
: null;
|
||||
$isCurrent = ($sid === (int)$school_id);
|
||||
?>
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center gap-3">
|
||||
<?php if ($logoPath): ?>
|
||||
<img src="<?= htmlspecialchars($logoPath) ?>" style="height:50px;width:auto;" class="rounded">
|
||||
<?php else: ?>
|
||||
<i class="bx bx-building-house bx-md text-muted"></i>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-bold"><?= htmlspecialchars($sname) ?></div>
|
||||
<?php if ($isCurrent): ?>
|
||||
<div class="text-success small">Selezionata</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!$isCurrent): ?>
|
||||
<form method="POST" class="m-0">
|
||||
<input type="hidden" name="action" value="change_school">
|
||||
<input type="hidden" name="school_id" value="<?= $sid ?>">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Seleziona
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@ -34,13 +34,11 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="school" class="sr-only">@lang('School')</label>
|
||||
<input type="text"
|
||||
<input type="hidden"
|
||||
name="school"
|
||||
id="school"
|
||||
class="form-control input-solid"
|
||||
placeholder="@lang('School')"
|
||||
value="{{ $school_slug ?? '' }}"
|
||||
{{ $school_slug ? 'readonly' : '' }}>
|
||||
value="{{ $school_slug ?? '' }}">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user