added statistic and remove froms school
This commit is contained in:
parent
39fb15c649
commit
f911b82716
51
public/userarea/cancel_booking.php
Normal file
51
public/userarea/cancel_booking.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!isset($_SESSION['iduserlogin'])) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Non autorizzato']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
$booking_id = (int)($_POST['booking_id'] ?? 0);
|
||||||
|
$user_id = (int)$_SESSION['iduserlogin'];
|
||||||
|
|
||||||
|
if ($booking_id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID prenotazione non valido']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica che la prenotazione appartenga all'utente e sia cancellabile
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT sb.id
|
||||||
|
FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.id = ?
|
||||||
|
AND sb.user_id = ?
|
||||||
|
AND sb.status = 'booked'
|
||||||
|
AND cs.session_date > DATE_ADD(NOW(), INTERVAL 24 HOUR)
|
||||||
|
");
|
||||||
|
$stmt->execute([$booking_id, $user_id]);
|
||||||
|
if (!$stmt->fetch()) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Prenotazione non trovata, non tua, già annullata o non più cancellabile (entro 24 ore)']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiorna status a 'cancelled'
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE session_bookings
|
||||||
|
SET status = 'cancelled',
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
$success = $stmt->execute([$booking_id]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => $success,
|
||||||
|
'message' => $success ? 'Prenotazione annullata con successo' : 'Errore durante l\'aggiornamento'
|
||||||
|
]);
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -50,10 +50,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['certificate']) && $_
|
|||||||
(user_id, filename, stored_path, document_name, expiry_date, notes, uploaded_at)
|
(user_id, filename, stored_path, document_name, expiry_date, notes, uploaded_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, NOW())
|
VALUES (?, ?, ?, ?, ?, ?, NOW())
|
||||||
");
|
");
|
||||||
|
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
$iduserlogin,
|
$iduserlogin,
|
||||||
$file['name'],
|
$file['name'],
|
||||||
'certificate/' . $new_filename,
|
'userarea/certificate/' . $new_filename, // ← solo questo
|
||||||
$document_name,
|
$document_name,
|
||||||
$expiry_date,
|
$expiry_date,
|
||||||
$notes
|
$notes
|
||||||
@ -151,6 +152,21 @@ $user = $stmt->fetch();
|
|||||||
.file-link:hover {
|
.file-link:hover {
|
||||||
color: #0056b3;
|
color: #0056b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Riga rosa tenue per scaduti */
|
||||||
|
tr.expired-row {
|
||||||
|
background-color: #ffebee !important;
|
||||||
|
/* rosa molto chiaro / rosso tenue */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badge scaduto */
|
||||||
|
.badge-expired {
|
||||||
|
background-color: #dc3545;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 0.4em 0.8em;
|
||||||
|
border-radius: 50px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -238,10 +254,11 @@ $user = $stmt->fetch();
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($certificates as $cert):
|
<?php foreach ($certificates as $cert):
|
||||||
$file_url = '../' . $cert['stored_path'];
|
$file_url = '/' . $cert['stored_path']; // usa percorso root-relative come consigliato prima
|
||||||
$expired = $cert['expiry_date'] && strtotime($cert['expiry_date']) < time();
|
$expired = $cert['expiry_date'] && strtotime($cert['expiry_date']) < time();
|
||||||
|
$row_class = $expired ? 'expired-row' : '';
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr class="<?= $row_class ?>">
|
||||||
<td><?= date('d/m/Y H:i', strtotime($cert['uploaded_at'])) ?></td>
|
<td><?= date('d/m/Y H:i', strtotime($cert['uploaded_at'])) ?></td>
|
||||||
<td>
|
<td>
|
||||||
<a href="<?= htmlspecialchars($file_url) ?>" target="_blank" class="file-link">
|
<a href="<?= htmlspecialchars($file_url) ?>" target="_blank" class="file-link">
|
||||||
@ -252,7 +269,9 @@ $user = $stmt->fetch();
|
|||||||
</td>
|
</td>
|
||||||
<td class="<?= $expired ? 'expired' : '' ?>">
|
<td class="<?= $expired ? 'expired' : '' ?>">
|
||||||
<?= $cert['expiry_date'] ? date('d/m/Y', strtotime($cert['expiry_date'])) : '—' ?>
|
<?= $cert['expiry_date'] ? date('d/m/Y', strtotime($cert['expiry_date'])) : '—' ?>
|
||||||
<?= $expired ? '<br><small>SCADUTO</small>' : '' ?>
|
<?php if ($expired): ?>
|
||||||
|
<span class="badge-expired ms-2">SCADUTO</span>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td><?= $cert['notes'] ? nl2br(htmlspecialchars(substr($cert['notes'], 0, 100))) . (strlen($cert['notes']) > 100 ? '...' : '') : '—' ?></td>
|
<td><?= $cert['notes'] ? nl2br(htmlspecialchars(substr($cert['notes'], 0, 100))) . (strlen($cert['notes']) > 100 ? '...' : '') : '—' ?></td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
|
|||||||
@ -46,12 +46,26 @@ $stmt = $pdo->prepare("
|
|||||||
JOIN orders o ON sb.order_id = o.id
|
JOIN orders o ON sb.order_id = o.id
|
||||||
WHERE sb.user_id = ?
|
WHERE sb.user_id = ?
|
||||||
AND cs.school_id = ?
|
AND cs.school_id = ?
|
||||||
|
AND sb.status = 'booked'
|
||||||
AND cs.session_date >= ?
|
AND cs.session_date >= ?
|
||||||
AND cs.session_date < ?
|
AND cs.session_date < ?
|
||||||
ORDER BY cs.session_date ASC, cs.start_time ASC
|
ORDER BY cs.session_date ASC, cs.start_time ASC
|
||||||
");
|
");
|
||||||
$stmt->execute([$iduserlogin, $school_id, $startOfMonth, $endOfMonth]);
|
$stmt->execute([$iduserlogin, $school_id, $startOfMonth, $endOfMonth]);
|
||||||
$bookings = $stmt->fetchAll();
|
$bookings = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// === CONTROLLA CERTIFICATI VALIDI ===
|
||||||
|
$stmt_cert = $pdo->prepare("
|
||||||
|
SELECT COUNT(*) AS valid_count
|
||||||
|
FROM user_medical_certificates
|
||||||
|
WHERE user_id = ?
|
||||||
|
AND expiry_date IS NOT NULL
|
||||||
|
AND expiry_date >= CURDATE()
|
||||||
|
AND is_valid = 1
|
||||||
|
");
|
||||||
|
$stmt_cert->execute([$iduserlogin]);
|
||||||
|
$cert_result = $stmt_cert->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$has_valid_cert = ($cert_result['valid_count'] > 0);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
@ -207,7 +221,16 @@ $bookings = $stmt->fetchAll();
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container-fluid px-0">
|
<div class="container-fluid px-0">
|
||||||
|
<?php if (!$has_valid_cert): ?>
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show mb-4 shadow" role="alert">
|
||||||
|
<strong>Attenzione!</strong> Non hai un certificato medico valido caricato.
|
||||||
|
<br>Ti potrebbe essere vietato l'accesso alle lezioni/pratiche.
|
||||||
|
<a href="my_certificates.php" class="alert-link fw-bold ms-2">
|
||||||
|
Caricalo subito qui →
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
<?php if (empty($bookings)): ?>
|
<?php if (empty($bookings)): ?>
|
||||||
<div class="text-center py-5 px-3">
|
<div class="text-center py-5 px-3">
|
||||||
<i class="bx bx-calendar-x" style="font-size:4.5rem;color:#e0e0e0;"></i>
|
<i class="bx bx-calendar-x" style="font-size:4.5rem;color:#e0e0e0;"></i>
|
||||||
@ -264,7 +287,7 @@ $bookings = $stmt->fetchAll();
|
|||||||
<button class="btn-custom btn-primary-custom" onclick="reschedule(<?= $b['booking_id'] ?>)">
|
<button class="btn-custom btn-primary-custom" onclick="reschedule(<?= $b['booking_id'] ?>)">
|
||||||
Riprogramma
|
Riprogramma
|
||||||
</button>
|
</button>
|
||||||
<button class="btn-custom btn-outline-custom" onclick="cancelBooking(<?= $b['booking_id'] ?>)">
|
<button class="btn-custom btn-outline-custom" onclick="confirmCancel(<?= $b['booking_id'] ?>)">
|
||||||
Cancella
|
Cancella
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -288,29 +311,52 @@ $bookings = $stmt->fetchAll();
|
|||||||
<?php include('jsinclude.php'); ?>
|
<?php include('jsinclude.php'); ?>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
<script>
|
<script>
|
||||||
const reschedule = id => Swal.fire({
|
const confirmCancel = id => {
|
||||||
title: 'Riprogrammare?',
|
Swal.fire({
|
||||||
text: 'Scegli un nuovo orario',
|
title: 'Annullare questa prenotazione?',
|
||||||
icon: 'question',
|
html: 'Cancellando la lezione:<br>' +
|
||||||
showCancelButton: true,
|
'<ul style="text-align:left; margin:15px 0 0 20px; font-size:0.95rem;">' +
|
||||||
confirmButtonText: 'Sì',
|
'<li>Il ticket/ingresso resterà disponibile nella tua area utente</li>' +
|
||||||
cancelButtonText: 'No'
|
'<li>Potrai riprogrammarlo su un\'altra data (se non hai superato il limite di recuperi o la scadenza del pacchetto)</li>' +
|
||||||
}).then(r => r.isConfirmed && (location = 'reschedule.php?booking=' + id));
|
'<li>L\'annullamento è irreversibile</li>' +
|
||||||
const cancelBooking = id => Swal.fire({
|
'</ul>',
|
||||||
title: 'Annullare prenotazione?',
|
|
||||||
text: 'Riceverai un recupero',
|
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#ef4444',
|
confirmButtonColor: '#ef4444',
|
||||||
confirmButtonText: 'Sì, annulla',
|
cancelButtonColor: '#6c757d',
|
||||||
cancelButtonText: 'No'
|
confirmButtonText: 'Sì, annulla la lezione',
|
||||||
}).then(r => r.isConfirmed && fetch('cancel_booking.php', {
|
cancelButtonText: 'No, mantienila',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
fetch('cancel_booking.php', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
},
|
},
|
||||||
body: 'booking_id=' + id
|
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')));
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Prenotazione annullata!',
|
||||||
|
text: 'Il tuo ingresso è tornato disponibile per un recupero/riprogrammazione.',
|
||||||
|
icon: 'success',
|
||||||
|
timer: 2500
|
||||||
|
}).then(() => {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire('Errore', data.message || 'Impossibile annullare la prenotazione.', 'error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Swal.fire('Errore di connessione', 'Impossibile comunicare con il server.', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
59
public/userarea/remove_school.php
Normal file
59
public/userarea/remove_school.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
include('include/headscript.php'); // ← adatta il path se necessario (da userarea/ sale di due livelli)
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!isset($_SESSION['iduserlogin'])) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Non autorizzato']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
$school_id = (int)($_POST['school_id'] ?? 0);
|
||||||
|
$user_id = (int)$_SESSION['iduserlogin'];
|
||||||
|
|
||||||
|
if ($school_id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Scuola non valida']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica iscrizione attiva
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT id FROM user_schools
|
||||||
|
WHERE user_id = ? AND school_id = ? AND status = 'active'
|
||||||
|
");
|
||||||
|
$stmt->execute([$user_id, $school_id]);
|
||||||
|
if (!$stmt->fetch()) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Non sei iscritto a questa scuola']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft-delete: imposta status = 'inactive'
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE user_schools
|
||||||
|
SET status = 'inactive', updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE user_id = ? AND school_id = ?
|
||||||
|
");
|
||||||
|
$stmt->execute([$user_id, $school_id]);
|
||||||
|
|
||||||
|
// Opzionale: resetta scuola corrente in sessione
|
||||||
|
if (isset($_SESSION['school_id']) && $_SESSION['school_id'] == $school_id) {
|
||||||
|
unset($_SESSION['school_id'], $_SESSION['school_name'], $_SESSION['school_selected']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Opzionale) cancella dati associati - commenta se NON vuoi eliminare
|
||||||
|
// Esempio cancellazione prenotazioni:
|
||||||
|
$pdo->prepare("
|
||||||
|
DELETE sb FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.user_id = ? AND cs.school_id = ?
|
||||||
|
")->execute([$user_id, $school_id]);
|
||||||
|
|
||||||
|
// Esempio cancellazione ordini:
|
||||||
|
$pdo->prepare("DELETE FROM orders WHERE user_id = ? AND school_id = ?")
|
||||||
|
->execute([$user_id, $school_id]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
@ -126,8 +126,18 @@ if ($school_id) {
|
|||||||
|
|
||||||
if ($school) {
|
if ($school) {
|
||||||
$school_name = $school['name'];
|
$school_name = $school['name'];
|
||||||
if (!empty($school['logo']) && file_exists("photoschool/" . $school['logo'])) {
|
$logoRaw = trim($school['logo'] ?? '');
|
||||||
$school_logo_path = "photoschool/" . $school['logo'];
|
if (!empty($logoRaw)) {
|
||||||
|
// Percorso fisico per verificare esistenza
|
||||||
|
$physicalPath = __DIR__ . '/../' . $logoRaw; // da userarea/ sale a public/ + photoschool/...
|
||||||
|
|
||||||
|
if (file_exists($physicalPath)) {
|
||||||
|
// Percorso web corretto (root-relative)
|
||||||
|
$school_logo_path = '/' . $logoRaw;
|
||||||
|
} else {
|
||||||
|
// Debug: scrivi nel log se il file non esiste
|
||||||
|
error_log("LOGO SCUOLA NON TROVATO - school_id: $school_id | path fisico: $physicalPath");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +157,54 @@ $stmt = $pdo->prepare("
|
|||||||
$stmt->execute([$iduserlogin, $school_id]);
|
$stmt->execute([$iduserlogin, $school_id]);
|
||||||
$orders = $stmt->fetchAll();
|
$orders = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// 1. Lezioni acquistate totali (somma total_entries da ordini completati)
|
||||||
|
$stmt_total_lessons = $pdo->prepare("
|
||||||
|
SELECT COALESCE(SUM(total_entries), 0) AS total_lessons
|
||||||
|
FROM orders
|
||||||
|
WHERE user_id = ? AND school_id = ? AND status = 'completed'
|
||||||
|
");
|
||||||
|
$stmt_total_lessons->execute([$iduserlogin, $school_id]);
|
||||||
|
$total_lessons = $stmt_total_lessons->fetchColumn() ?: 0;
|
||||||
|
|
||||||
|
// 2. Lezioni da praticare (booked + data futura)
|
||||||
|
$stmt_to_practice = $pdo->prepare("
|
||||||
|
SELECT COUNT(sb.id) AS to_practice
|
||||||
|
FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.user_id = ?
|
||||||
|
AND cs.school_id = ?
|
||||||
|
AND sb.status = 'booked'
|
||||||
|
AND cs.session_date >= CURDATE()
|
||||||
|
");
|
||||||
|
$stmt_to_practice->execute([$iduserlogin, $school_id]);
|
||||||
|
$to_practice = $stmt_to_practice->fetchColumn() ?: 0;
|
||||||
|
|
||||||
|
// 3. Lezioni perse (missed + data passata)
|
||||||
|
$stmt_missed = $pdo->prepare("
|
||||||
|
SELECT COUNT(sb.id) AS missed
|
||||||
|
FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.user_id = ?
|
||||||
|
AND cs.school_id = ?
|
||||||
|
AND sb.status = 'missed'
|
||||||
|
AND cs.session_date < CURDATE()
|
||||||
|
");
|
||||||
|
$stmt_missed->execute([$iduserlogin, $school_id]);
|
||||||
|
$missed = $stmt_missed->fetchColumn() ?: 0;
|
||||||
|
|
||||||
|
// === CONTROLLA CERTIFICATI VALIDI ===
|
||||||
|
$stmt_cert = $pdo->prepare("
|
||||||
|
SELECT COUNT(*) AS valid_count
|
||||||
|
FROM user_medical_certificates
|
||||||
|
WHERE user_id = ?
|
||||||
|
AND expiry_date IS NOT NULL
|
||||||
|
AND expiry_date >= CURDATE()
|
||||||
|
AND is_valid = 1
|
||||||
|
");
|
||||||
|
$stmt_cert->execute([$iduserlogin]);
|
||||||
|
$cert_result = $stmt_cert->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$has_valid_cert = ($cert_result['valid_count'] > 0);
|
||||||
|
|
||||||
// === STATISTICHE RAPIDE ===
|
// === STATISTICHE RAPIDE ===
|
||||||
$total_spent = array_sum(array_column($orders, 'price'));
|
$total_spent = array_sum(array_column($orders, 'price'));
|
||||||
$total_entries = array_sum(array_column($orders, 'total_entries'));
|
$total_entries = array_sum(array_column($orders, 'total_entries'));
|
||||||
@ -228,8 +286,9 @@ $active_orders = count(array_filter($orders, fn($o) => $o['status'] === 'complet
|
|||||||
<div class="card-body text-center py-5">
|
<div class="card-body text-center py-5">
|
||||||
|
|
||||||
<!-- Logo solo se esiste -->
|
<!-- Logo solo se esiste -->
|
||||||
<?php if ($school_logo_path): ?>
|
<?php
|
||||||
<img src="<?php echo htmlspecialchars($school_logo_path); ?>"
|
if ($logoRaw): ?>
|
||||||
|
<img src="<?php echo htmlspecialchars($logoRaw); ?>"
|
||||||
alt="Logo <?php echo htmlspecialchars($school_name); ?>"
|
alt="Logo <?php echo htmlspecialchars($school_name); ?>"
|
||||||
class="mb-4 rounded-3 shadow"
|
class="mb-4 rounded-3 shadow"
|
||||||
style="height: 90px; object-fit: contain;">
|
style="height: 90px; object-fit: contain;">
|
||||||
@ -256,42 +315,53 @@ $active_orders = count(array_filter($orders, fn($o) => $o['status'] === 'complet
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PROFILO + STATISTICHE -->
|
<?php if (!$has_valid_cert): ?>
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show mb-4 shadow" role="alert">
|
||||||
|
<strong>Attenzione!</strong> Non hai un certificato medico valido caricato.
|
||||||
|
<br>Ti potrebbe essere vietato l'accesso alle lezioni/pratiche.
|
||||||
|
<a href="my_certificates.php" class="alert-link fw-bold ms-2">
|
||||||
|
Caricalo subito qui →
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<!-- STATISTICHE PASTELLO - NUOVA VERSIONE -->
|
||||||
<div class="row g-4 mb-5">
|
<div class="row g-4 mb-5">
|
||||||
<div class="col-lg-4">
|
<!-- Box 1: Lezioni acquistate totali -->
|
||||||
<div class="card stat-card text-center h-100">
|
<div class="col-md-3">
|
||||||
<div class="card-body">
|
<div class="card stat-card text-center h-100" style="background: linear-gradient(135deg, #d1fae5, #a7f3d0);">
|
||||||
<img src="<?php echo $avatar; ?>" alt="Avatar" class="rounded-circle avatar-circle mb-3">
|
<div class="card-body py-4">
|
||||||
<h5><?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?></h5>
|
<h3 class="fw-bold text-success mb-1"><?= number_format($total_lessons) ?></h3>
|
||||||
<p class="text-muted"><?php echo htmlspecialchars($user['email']); ?></p>
|
<p class="text-dark mb-0">Lezioni acquistate totali</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-8">
|
|
||||||
<div class="row g-4">
|
<!-- Box 2: Lezioni da praticare -->
|
||||||
<div class="col-md-4">
|
<div class="col-md-3">
|
||||||
<div class="card stat-card text-center h-100">
|
<div class="card stat-card text-center h-100" style="background: linear-gradient(135deg, #dbeafe, #bfdbfe);">
|
||||||
<div class="card-body">
|
<div class="card-body py-4">
|
||||||
<h3 class="text-primary fw-bold"><?php echo count($orders); ?></h3>
|
<h3 class="fw-bold text-primary mb-1"><?= number_format($to_practice) ?></h3>
|
||||||
<p class="mb-0">Ordini totali</p>
|
<p class="text-dark mb-0">Lezioni da praticare</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card stat-card text-center h-100">
|
<!-- Box 3: Lezioni perse -->
|
||||||
<div class="card-body">
|
<div class="col-md-3">
|
||||||
<h3 class="text-success fw-bold">€<?php echo number_format($total_spent, 2); ?></h3>
|
<div class="card stat-card text-center h-100" style="background: linear-gradient(135deg, #fee2e2, #fecaca);">
|
||||||
<p class="mb-0">Speso in totale</p>
|
<div class="card-body py-4">
|
||||||
|
<h3 class="fw-bold text-danger mb-1"><?= number_format($missed) ?></h3>
|
||||||
|
<p class="text-dark mb-0">Lezioni perse</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card stat-card text-center h-100">
|
<!-- Box 4: Vuoto (pronto per futuro) -->
|
||||||
<div class="card-body">
|
<div class="col-md-3">
|
||||||
<h3 class="text-info fw-bold"><?php echo $available_entries; ?></h3>
|
<div class="card stat-card text-center h-100" style="background: linear-gradient(135deg, #fef3c7, #fde68a);">
|
||||||
<p class="mb-0">Ingressi disponibili</p>
|
<div class="card-body py-4 d-flex align-items-center justify-content-center">
|
||||||
</div>
|
<p class="text-muted mb-0 fst-italic">Prossimamente...</p>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -370,6 +440,18 @@ $active_orders = count(array_filter($orders, fn($o) => $o['status'] === 'complet
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- PULSANTE RIMUOVI SCUOLA (in fondo, evidente) -->
|
||||||
|
<!-- Link discreto per rimuoversi dalla scuola (in fondo a destra) -->
|
||||||
|
<div class="text-end mt-5 mb-5 pe-4">
|
||||||
|
<a href="#" class="text-danger small text-decoration-none"
|
||||||
|
onclick="confirmRemoveSchool(<?= $school_id ?>, '<?= addslashes(htmlspecialchars($school_name)) ?>'); return false;">
|
||||||
|
<i class="bx bx-log-out bx-sm me-1"></i>
|
||||||
|
Rimuovimi da questa scuola
|
||||||
|
</a>
|
||||||
|
<p class="text-muted fst-italic small mt-1" style="font-size:0.8rem;">
|
||||||
|
(azione irreversibile: perderai lezioni, crediti e storico associato)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -377,6 +459,57 @@ $active_orders = count(array_filter($orders, fn($o) => $o['status'] === 'complet
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php include('jsinclude.php'); ?>
|
<?php include('jsinclude.php'); ?>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
<script>
|
||||||
|
const confirmRemoveSchool = (schoolId, schoolName) => {
|
||||||
|
Swal.fire({
|
||||||
|
title: `Abbandonare ${schoolName}?`,
|
||||||
|
html: `Stai per rimuoverti completamente da <strong>${schoolName}</strong>.<br><br>` +
|
||||||
|
`<strong class="text-danger">Attenzione:</strong> perderai irreversibilmente:<br>` +
|
||||||
|
`<ul style="text-align:left; margin:15px 0 0 30px; font-size:0.95rem;">` +
|
||||||
|
`<li>Tutte le tue lezioni prenotate</li>` +
|
||||||
|
`<li>Crediti, ingressi e recuperi residui</li>` +
|
||||||
|
`<li>Storico ordini e archivio personale legato a questa scuola</li>` +
|
||||||
|
`</ul><br>` +
|
||||||
|
`Questa azione <u>non può essere annullata</u>.`,
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#d33',
|
||||||
|
cancelButtonColor: '#3085d6',
|
||||||
|
confirmButtonText: 'Sì, rimuovimi definitivamente',
|
||||||
|
cancelButtonText: 'No, mantienimi iscritto',
|
||||||
|
reverseButtons: true
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
fetch('remove_school.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
body: 'school_id=' + schoolId
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Rimozione completata',
|
||||||
|
text: `Non fai più parte di ${schoolName}.`,
|
||||||
|
icon: 'success',
|
||||||
|
timer: 3000
|
||||||
|
}).then(() => {
|
||||||
|
location.reload(); // o redirect a select_school.php
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire('Errore', data.message || 'Impossibile rimuoverti dalla scuola.', 'error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
Swal.fire('Errore', 'Problema di connessione con il server.', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<!-- Modal Cambia Scuola -->
|
<!-- Modal Cambia Scuola -->
|
||||||
<div class="modal fade" id="changeSchoolModal" tabindex="-1">
|
<div class="modal fade" id="changeSchoolModal" tabindex="-1">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user