future lessons
This commit is contained in:
parent
67cc0742ff
commit
b592be5831
16
.env
16
.env
@ -23,13 +23,13 @@ REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=mail
|
||||
MAIL_FROM_NAME=Vanguard
|
||||
MAIL_FROM_ADDRESS=vanguard@test.dev
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_NAME=YogaSoul
|
||||
MAIL_FROM_ADDRESS=info@yogasoul.it
|
||||
MAIL_HOST=mail.yogasoul.it
|
||||
MAIL_PORT=465
|
||||
MAIL_USERNAME=info@yogasoul.it
|
||||
MAIL_PASSWORD=!Testolina88
|
||||
MAIL_ENCRYPTION=ssl
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
@ -38,3 +38,5 @@ PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
EXPOSE_API=true
|
||||
35
public/api/_bootstrap.php
Normal file
35
public/api/_bootstrap.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// ==============================
|
||||
// PATH BASE
|
||||
// ==============================
|
||||
$BASE_PATH = dirname(__DIR__) . '/userarea';
|
||||
|
||||
// ==============================
|
||||
// DB
|
||||
// ==============================
|
||||
require_once $BASE_PATH . '/class/db-functions.php';
|
||||
$db = DBHandlerSelect::getInstance()->getConnection();
|
||||
|
||||
// ==============================
|
||||
// AUTH VANGUARD
|
||||
// ==============================
|
||||
require_once $BASE_PATH . '/../../extra/auth.php';
|
||||
|
||||
// ==============================
|
||||
// AUTH API (TOKEN)
|
||||
// ==============================
|
||||
$user = Auth::guard('api')->user();
|
||||
|
||||
if (!$user) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Unauthorized']);
|
||||
exit;
|
||||
}
|
||||
68
public/api/my-lessons.php
Normal file
68
public/api/my-lessons.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/_bootstrap.php';
|
||||
|
||||
// ==============================
|
||||
// PARAMETRI
|
||||
// ==============================
|
||||
$month = $_GET['month'] ?? date('Y-m');
|
||||
$monthDate = DateTime::createFromFormat('Y-m', $month) ?: new DateTime();
|
||||
|
||||
$startOfMonth = $monthDate->format('Y-m-01');
|
||||
$endOfMonth = (clone $monthDate)->modify('+1 month')->format('Y-m-d');
|
||||
|
||||
// ==============================
|
||||
// DATI UTENTE
|
||||
// ==============================
|
||||
$userId = $user->id;
|
||||
$schoolId = $user->school_id ?? null;
|
||||
|
||||
if (!$schoolId) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'No school selected']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// QUERY (IDENTICA ALLA WEB)
|
||||
// ==============================
|
||||
$stmt = $db->prepare("
|
||||
SELECT
|
||||
sb.id AS booking_id,
|
||||
sb.status,
|
||||
cs.session_date,
|
||||
cs.start_time,
|
||||
cs.end_time,
|
||||
cs.room_name,
|
||||
c.name AS class_name,
|
||||
ct.level,
|
||||
o.available_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
|
||||
JOIN orders o ON sb.order_id = o.id
|
||||
WHERE sb.user_id = ?
|
||||
AND cs.school_id = ?
|
||||
AND cs.session_date >= ?
|
||||
AND cs.session_date < ?
|
||||
ORDER BY cs.session_date ASC, cs.start_time ASC
|
||||
");
|
||||
|
||||
$stmt->execute([
|
||||
$userId,
|
||||
$schoolId,
|
||||
$startOfMonth,
|
||||
$endOfMonth
|
||||
]);
|
||||
|
||||
$lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// ==============================
|
||||
// OUTPUT
|
||||
// ==============================
|
||||
echo json_encode([
|
||||
'month' => $month,
|
||||
'count' => count($lessons),
|
||||
'lessons' => $lessons
|
||||
]);
|
||||
@ -5,9 +5,9 @@ use PHPMailer\PHPMailer\Exception;
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
// Carica le variabili di ambiente
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Assicurati che PHPMailer e Dotenv siano installati con Composer
|
||||
require_once dirname(__DIR__, 3) . '/vendor/autoload.php'; // Assicurati che PHPMailer e Dotenv siano installati con Composer
|
||||
|
||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__, 2)); // Se la cartella `class` è a 2 livelli sopra la root
|
||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__, 3)); // Se la cartella `class` è a 2 livelli sopra la root
|
||||
$dotenv->load();
|
||||
|
||||
function sendEmail($to, $subject, $body, $attachments = [], $cc = [], $bcc = [])
|
||||
|
||||
543
public/userarea/future_sessions.php
Normal file
543
public/userarea/future_sessions.php
Normal file
@ -0,0 +1,543 @@
|
||||
<?php
|
||||
// future_sessions.php - VERSIONE COMPLETA E DEFINITIVA
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include('include/headscript.php');
|
||||
include(dirname(__DIR__) . '/userarea/class/mailer.php'); // Il tuo PHPMailer
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
if (!isset($iduserlogin)) {
|
||||
die("Errore: ID utente non definito.");
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("SELECT id, name, logo FROM schools WHERE owner_id = ?");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$school = $stmt->fetch();
|
||||
if (!$school) {
|
||||
die("Errore: Nessuna scuola trovata.");
|
||||
}
|
||||
$school_id = $school['id'];
|
||||
$school_name = $school['name'];
|
||||
|
||||
// === GESTIONE AZIONI ===
|
||||
$feedback = '';
|
||||
$showEmailModal = false;
|
||||
$emailData = null;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
// Cancellazione lezione
|
||||
if ($action === 'delete_session') {
|
||||
$session_id = (int)($_POST['session_id'] ?? 0);
|
||||
$send_email = !empty($_POST['send_email']);
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT cs.id, cs.session_date, cs.start_time, cs.end_time,
|
||||
c.name AS class_name, ct.level
|
||||
FROM class_sessions cs
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
WHERE cs.id = ? AND c.school_id = ?
|
||||
");
|
||||
$stmt->execute([$session_id, $school_id]);
|
||||
$session = $stmt->fetch();
|
||||
|
||||
if ($session) {
|
||||
$recipients = [];
|
||||
if ($send_email) {
|
||||
$stmt2 = $pdo->prepare("
|
||||
SELECT au.email, au.first_name
|
||||
FROM session_bookings sb
|
||||
JOIN auth_users au ON sb.user_id = au.id
|
||||
WHERE sb.session_id = ? AND sb.status IN ('booked','attended','rescheduled')
|
||||
");
|
||||
$stmt2->execute([$session_id]);
|
||||
$recipients = $stmt2->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Se devo inviare email e ci sono destinatari -> apro modale (NON cancello ancora)
|
||||
if ($send_email && !empty($recipients)) {
|
||||
$showEmailModal = true;
|
||||
$emailData = [
|
||||
'session_id' => $session_id,
|
||||
'class_name' => $session['class_name'],
|
||||
'level' => $session['level'] ?? '',
|
||||
'date' => date('d/m/Y', strtotime($session['session_date'])),
|
||||
'time' => substr($session['start_time'], 0, 5) . ' - ' . substr($session['end_time'], 0, 5),
|
||||
'recipients' => $recipients
|
||||
];
|
||||
} else {
|
||||
// Altrimenti cancello subito
|
||||
$stmt = $pdo->prepare("DELETE FROM class_sessions WHERE id = ? AND id IN (
|
||||
SELECT cs.id FROM class_sessions cs
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
WHERE c.school_id = ?
|
||||
)");
|
||||
$stmt->execute([$session_id, $school_id]);
|
||||
|
||||
$feedback = '<div class="alert alert-success alert-dismissible fade show">
|
||||
Lezione cancellata con successo!
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invio email cancellazione
|
||||
elseif ($action === 'send_cancellation_email') {
|
||||
$session_id = (int)($_POST['session_id'] ?? 0);
|
||||
$body_text = $_POST['email_body'] ?? '';
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT c.name AS class_name, ct.level, cs.session_date, cs.start_time, cs.end_time
|
||||
FROM class_sessions cs
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
WHERE cs.id = ? AND c.school_id = ?
|
||||
");
|
||||
$stmt->execute([$session_id, $school_id]);
|
||||
$session = $stmt->fetch();
|
||||
|
||||
$class_info = $session['class_name'] . ($session['level'] ? ' (' . ucfirst($session['level']) . ')' : '');
|
||||
$date = $session ? date('d/m/Y', strtotime($session['session_date'])) : '';
|
||||
$time = $session ? substr($session['start_time'], 0, 5) . '-' . substr($session['end_time'], 0, 5) : '';
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT au.email, au.first_name
|
||||
FROM session_bookings sb
|
||||
JOIN auth_users au ON sb.user_id = au.id
|
||||
WHERE sb.session_id = ? AND sb.status IN ('booked','attended','rescheduled')
|
||||
");
|
||||
$stmt->execute([$session_id]);
|
||||
$recipients = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$subject = "Lezione cancellata - {$school_name}";
|
||||
$sent = 0;
|
||||
|
||||
foreach ($recipients as $r) {
|
||||
$personal_body = str_replace(
|
||||
['{nome}', '{classe}', '{data}', '{ora}'],
|
||||
[$r['first_name'] ?: 'Gentile utente', $class_info, $date, $time],
|
||||
$body_text
|
||||
);
|
||||
$result = sendEmail($r['email'], $subject, $personal_body);
|
||||
if ($result['success']) $sent++;
|
||||
}
|
||||
|
||||
// Cancella la lezione DOPO invio email
|
||||
$stmtDel = $pdo->prepare("
|
||||
DELETE cs FROM class_sessions cs
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
WHERE cs.id = ? AND c.school_id = ?
|
||||
");
|
||||
$stmtDel->execute([$session_id, $school_id]);
|
||||
|
||||
|
||||
$feedback = "<div class='alert alert-success alert-dismissible fade show'>Email inviate a {$sent} partecipanti.<button type='button' class='btn-close' data-bs-dismiss='alert'></button></div>";
|
||||
} elseif ($action === 'skip_cancellation_email') {
|
||||
$session_id = (int)($_POST['session_id'] ?? 0);
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
DELETE cs FROM class_sessions cs
|
||||
JOIN class_types ct ON cs.class_type_id = ct.id
|
||||
JOIN classes c ON ct.class_id = c.id
|
||||
WHERE cs.id = ? AND c.school_id = ?
|
||||
");
|
||||
$stmt->execute([$session_id, $school_id]);
|
||||
|
||||
$feedback = "<div class='alert alert-success alert-dismissible fade show'>
|
||||
Lezione cancellata (email non inviata).
|
||||
<button type='button' class='btn-close' data-bs-dismiss='alert'></button>
|
||||
</div>";
|
||||
}
|
||||
|
||||
|
||||
// Marca come persa
|
||||
elseif ($action === 'mark_lost') {
|
||||
$booking_id = (int)($_POST['booking_id'] ?? 0);
|
||||
$stmt = $pdo->prepare("UPDATE session_bookings SET status = 'lost' WHERE id = ? AND session_id IN (SELECT cs.id FROM class_sessions cs JOIN class_types ct ON cs.class_type_id = ct.id JOIN classes c ON ct.class_id = c.id WHERE c.school_id = ?)");
|
||||
$stmt->execute([$booking_id, $school_id]);
|
||||
$feedback = '<div class="alert alert-warning alert-dismissible fade show">Presenza segnata come persa.<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>';
|
||||
}
|
||||
|
||||
// Cancella prenotazione
|
||||
elseif ($action === 'cancel_booking') {
|
||||
$booking_id = (int)($_POST['booking_id'] ?? 0);
|
||||
$stmt = $pdo->prepare("DELETE FROM session_bookings WHERE id = ? AND session_id IN (SELECT cs.id FROM class_sessions cs JOIN class_types ct ON cs.class_type_id = ct.id JOIN classes c ON ct.class_id = c.id WHERE c.school_id = ?)");
|
||||
$stmt->execute([$booking_id, $school_id]);
|
||||
$feedback = '<div class="alert alert-danger alert-dismissible fade show">Prenotazione rimossa.<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Recupero lezioni future
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT
|
||||
cs.id AS session_id,
|
||||
cs.session_date,
|
||||
cs.start_time,
|
||||
cs.end_time,
|
||||
c.name AS class_name,
|
||||
ct.level,
|
||||
ct.room_name,
|
||||
ct.max_capacity,
|
||||
t.first_name,
|
||||
t.last_name,
|
||||
(SELECT COUNT(*) FROM session_bookings sb WHERE sb.session_id = cs.id AND sb.status IN ('booked','attended','rescheduled')) AS booked_count,
|
||||
(SELECT GROUP_CONCAT(CONCAT(sb.id,'|||',au.first_name,' ',au.last_name,'|||',au.email,'|||',COALESCE(au.phone,''),'|||',sb.status) 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','lost')) AS booked_students_details
|
||||
FROM class_sessions cs
|
||||
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
|
||||
WHERE cs.session_date >= CURDATE() AND c.school_id = ?
|
||||
ORDER BY cs.session_date, cs.start_time
|
||||
");
|
||||
$stmt->execute([$school_id]);
|
||||
$sessions = $stmt->fetchAll();
|
||||
|
||||
$grouped = [];
|
||||
foreach ($sessions as $s) {
|
||||
$date = new DateTime($s['session_date']);
|
||||
$month_key = $date->format('Y-m');
|
||||
$month_name = ucfirst(strftime('%B %Y', $date->getTimestamp()));
|
||||
$grouped[$month_key]['name'] = $month_name;
|
||||
$grouped[$month_key]['sessions'][] = $s;
|
||||
}
|
||||
?>
|
||||
|
||||
<!doctype html>
|
||||
<html lang="it">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Lezioni Future - <?php echo htmlspecialchars($school_name); ?></title>
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<?php include('siteinfo.php'); ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<?php include('include/navbar.php'); ?>
|
||||
<?php include('include/topbar.php'); ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
|
||||
<div class="card radius-10 mb-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="me-4">
|
||||
<img src="<?php echo $school['logo'] ? htmlspecialchars($school['logo']) : 'assets/images/default-school-logo.png'; ?>"
|
||||
alt="Logo" class="rounded-circle" style="width: 100px; height: 100px; object-fit: cover;">
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<h4 class="mb-1">Lezioni Future - <?php echo htmlspecialchars($school_name); ?></h4>
|
||||
<p class="mb-0 text-muted">Gestione completa: lista prenotati, P/C, cancellazione con avviso email.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="school_dashboard.php" class="btn btn-outline-primary">← Dashboard</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php echo $feedback; ?>
|
||||
|
||||
<?php if (empty($grouped)): ?>
|
||||
<div class="card radius-10">
|
||||
<div class="card-body text-center py-5">
|
||||
<h5 class="text-muted">Nessuna lezione programmata nel futuro.</h5>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($grouped as $month): ?>
|
||||
<div class="card radius-10 mb-4">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="mb-0"><?php echo htmlspecialchars($month['name']); ?></h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Data</th>
|
||||
<th>Classe</th>
|
||||
<th>Livello</th>
|
||||
<th>Orario</th>
|
||||
<th>Sala</th>
|
||||
<th>Insegnante</th>
|
||||
<th>Prenotati</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($month['sessions'] as $s): ?>
|
||||
<tr id="<?php echo $s['session_id']; ?>">
|
||||
<td><?php echo date('d/m/Y (l)', strtotime($s['session_date'])); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['class_name']); ?></td>
|
||||
<td><?php echo ucfirst($s['level'] ?? '-'); ?></td>
|
||||
<td><?php echo substr($s['start_time'], 0, 5) . ' - ' . substr($s['end_time'], 0, 5); ?></td>
|
||||
<td><?php echo htmlspecialchars($s['room_name'] ?? '—'); ?></td>
|
||||
<td><?php echo $s['first_name'] ? htmlspecialchars($s['first_name'] . ' ' . $s['last_name']) : '<em>Non assegnato</em>'; ?></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-success position-relative"
|
||||
<?php if ($s['booked_count'] > 0): ?>data-bs-toggle="modal" data-bs-target="#studentsModal-<?php echo $s['session_id']; ?>" <?php endif; ?>>
|
||||
<?php echo $s['booked_count']; ?>
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-danger"
|
||||
data-bs-toggle="modal" data-bs-target="#deleteModal-<?php echo $s['session_id']; ?>">
|
||||
<i class="bx bx-trash"></i> Cancella
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODALI PRINCIPALI -->
|
||||
<?php foreach ($sessions as $session): ?>
|
||||
<?php
|
||||
$students_list = [];
|
||||
if (!empty($session['booked_students_details'])) {
|
||||
foreach (explode(';;;', $session['booked_students_details']) as $entry) {
|
||||
if (empty(trim($entry))) continue;
|
||||
$parts = explode('|||', $entry);
|
||||
$students_list[] = [
|
||||
'booking_id' => $parts[0] ?? 0,
|
||||
'name' => $parts[1] ?? '',
|
||||
'email' => $parts[2] ?? '',
|
||||
'phone' => $parts[3] ?? '—',
|
||||
'status' => $parts[4] ?? 'booked'
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- Modale Lista Prenotati + P/C -->
|
||||
<div class="modal fade" id="studentsModal-<?php echo $session['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']); ?> del <?php echo date('d/m/Y', strtotime($session['session_date'])); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<?php if (empty($students_list)): ?>
|
||||
<p class="text-center text-muted">Nessuno prenotato.</p>
|
||||
<?php else: ?>
|
||||
<table class="table table-sm table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Nome</th>
|
||||
<th>Email</th>
|
||||
<th>Telefono</th>
|
||||
<th>Stato</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students_list as $stud): ?>
|
||||
<tr>
|
||||
<td><strong><?php echo htmlspecialchars($stud['name']); ?></strong></td>
|
||||
<td><?php echo htmlspecialchars($stud['email']); ?></td>
|
||||
<td><?php echo htmlspecialchars($stud['phone']); ?></td>
|
||||
<td>
|
||||
<span class="badge <?php echo $stud['status'] === 'lost' ? 'bg-warning' : 'bg-success'; ?>">
|
||||
<?php echo $stud['status'] === 'lost' ? 'Persa' : 'Prenotato'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($stud['status'] !== 'lost'): ?>
|
||||
<button type="button" class="btn btn-sm btn-warning me-1" data-bs-toggle="modal" data-bs-target="#lostModal-<?php echo $stud['booking_id']; ?>">P</button>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="btn btn-sm btn-danger" data-bs-toggle="modal" data-bs-target="#cancelModal-<?php echo $stud['booking_id']; ?>">C</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Chiudi</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modali P e C per ogni studente -->
|
||||
<?php foreach ($students_list as $stud): ?>
|
||||
<div class="modal fade" id="lostModal-<?php echo $stud['booking_id']; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-warning text-dark">
|
||||
<h5 class="modal-title">Segna come Persa</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Confermi di segnare come <strong>persa</strong> la lezione per <strong><?php echo htmlspecialchars($stud['name']); ?></strong>?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||
<form method="POST" style="display:inline;">
|
||||
<input type="hidden" name="action" value="mark_lost">
|
||||
<input type="hidden" name="booking_id" value="<?php echo $stud['booking_id']; ?>">
|
||||
<button type="submit" class="btn btn-warning">Sì, segna persa</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="cancelModal-<?php echo $stud['booking_id']; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title">Rimuovi Prenotazione</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Confermi di rimuovere <strong><?php echo htmlspecialchars($stud['name']); ?></strong> dalla lezione?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||
<form method="POST" style="display:inline;">
|
||||
<input type="hidden" name="action" value="cancel_booking">
|
||||
<input type="hidden" name="booking_id" value="<?php echo $stud['booking_id']; ?>">
|
||||
<button type="submit" class="btn btn-danger">Sì, rimuovi</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<!-- Modale Cancellazione Lezione con checkbox email -->
|
||||
<div class="modal fade" id="deleteModal-<?php echo $session['session_id']; ?>" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title">Cancella Lezione</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Confermi la cancellazione della lezione:</p>
|
||||
<ul>
|
||||
<li><strong>Classe:</strong> <?php echo htmlspecialchars($session['class_name']); ?></li>
|
||||
<li><strong>Data:</strong> <?php echo date('d/m/Y (l)', strtotime($session['session_date'])); ?></li>
|
||||
<li><strong>Orario:</strong> <?php echo substr($session['start_time'], 0, 5); ?> - <?php echo substr($session['end_time'], 0, 5); ?></li>
|
||||
<li><strong>Prenotati:</strong> <?php echo $session['booked_count']; ?></li>
|
||||
</ul>
|
||||
<?php if ($session['booked_count'] > 0): ?>
|
||||
<div class="form-check mt-3">
|
||||
<input class="form-check-input" type="checkbox" id="sendEmail-<?php echo $session['session_id']; ?>">
|
||||
<label class="form-check-label text-primary fw-bold" for="sendEmail-<?php echo $session['session_id']; ?>">
|
||||
Invia email di avviso ai <?php echo $session['booked_count']; ?> partecipanti?
|
||||
</label>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||
<form method="POST" id="deleteForm-<?php echo $session['session_id']; ?>">
|
||||
<input type="hidden" name="action" value="delete_session">
|
||||
<input type="hidden" name="session_id" value="<?php echo $session['session_id']; ?>">
|
||||
<input type="hidden" name="send_email" value="0" id="hiddenEmail-<?php echo $session['session_id']; ?>">
|
||||
<button type="submit" class="btn btn-danger">Cancella Lezione</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const check = document.getElementById('sendEmail-<?php echo $session['session_id']; ?>');
|
||||
const hidden = document.getElementById('hiddenEmail-<?php echo $session['session_id']; ?>');
|
||||
if (check && hidden) {
|
||||
check.addEventListener('change', () => hidden.value = check.checked ? '1' : '0');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<!-- Modale Invio Email Cancellazione -->
|
||||
<?php if ($showEmailModal && $emailData): ?>
|
||||
<div class="modal fade show" id="emailModal" style="display:block;" tabindex="-1" aria-modal="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<form method="POST">
|
||||
<div class="modal-header bg-warning text-dark">
|
||||
<h5 class="modal-title">Invia Avviso Cancellazione</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Stai per cancellare la lezione. Vuoi inviare l'email a <strong><?php echo count($emailData['recipients']); ?> partecipanti</strong>?</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Oggetto</label>
|
||||
<input type="text" class="form-control" value="Lezione cancellata - <?php echo htmlspecialchars($school_name); ?>" readonly>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Messaggio (modificabile)</label>
|
||||
<textarea name="email_body" class="form-control" rows="12" required>Ciao {nome},
|
||||
|
||||
ti informiamo con dispiacere che la lezione di <?php echo htmlspecialchars($emailData['class_name']); ?><?php echo $emailData['level'] ? ' (' . ucfirst($emailData['level']) . ')' : ''; ?>
|
||||
del <?php echo $emailData['date']; ?> alle ore <?php echo $emailData['time']; ?> è stata cancellata.
|
||||
|
||||
Ci scusiamo per il disagio.
|
||||
|
||||
Grazie per la comprensione,
|
||||
|
||||
<?php echo htmlspecialchars($school_name); ?></textarea>
|
||||
<small class="text-muted">{nome} verrà sostituito con il nome del destinatario.</small>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="session_id" value="<?php echo $emailData['session_id']; ?>">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" name="action" value="skip_cancellation_email" class="btn btn-secondary">
|
||||
Salta invio
|
||||
</button>
|
||||
|
||||
<button type="submit" name="action" value="send_cancellation_email" class="btn btn-success">
|
||||
Invia Email
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-backdrop fade show"></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php include('include/footer.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -5,7 +5,7 @@ if (!isset($iduserlogin)) header('Location: login.php');
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$school_id = session('school_id');
|
||||
$school_id = $_SESSION['school_id'];
|
||||
if (!$school_id) die("Nessuna scuola selezionata");
|
||||
|
||||
$stmt = $pdo->prepare("SELECT first_name FROM auth_users WHERE id = ?");
|
||||
|
||||
@ -828,7 +828,8 @@ $daily_sessions = $stmt->fetchAll();
|
||||
<p class="mb-0"><strong>Descrizione:</strong> <?php echo htmlspecialchars($school['description'] ?: 'Non specificata'); ?></p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="school_profile.php" class="btn btn-primary">Modifica Profilo</a>
|
||||
<a href="future_sessions.php" class="btn btn-primary">Calendario Lezioni</a>
|
||||
<a href="school_profile.php" class="btn btn-warning">Modifica Profilo</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -125,7 +125,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['school_id'])) {
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT s.id, s.name, s.logo, s.address_city
|
||||
SELECT
|
||||
s.id,
|
||||
s.name,
|
||||
s.logo,
|
||||
s.address_street,
|
||||
s.address_postal_code,
|
||||
s.address_city,
|
||||
s.address_province,
|
||||
s.address_country
|
||||
FROM user_schools us
|
||||
JOIN schools s ON us.school_id = s.id
|
||||
WHERE us.user_id = ?
|
||||
@ -133,6 +141,7 @@ $stmt = $pdo->prepare("
|
||||
AND s.status = 'active'
|
||||
ORDER BY s.name
|
||||
");
|
||||
|
||||
$stmt->execute([$iduserlogin]);
|
||||
$userSchools = $stmt->fetchAll();
|
||||
// --- VALIDAZIONE school_id: se non appartiene all'utente, la resetto ---
|
||||
@ -180,7 +189,15 @@ if (count($userSchools) > 1 && !empty($_SESSION['school_id']) && !empty($_SESSIO
|
||||
*/
|
||||
if (empty($userSchools)) {
|
||||
$stmt = $pdo->query("
|
||||
SELECT id, name, logo, address_city
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
logo,
|
||||
address_street,
|
||||
address_postal_code,
|
||||
address_city,
|
||||
address_province,
|
||||
address_country
|
||||
FROM schools
|
||||
WHERE status = 'active'
|
||||
ORDER BY name
|
||||
@ -346,12 +363,46 @@ if (empty($userSchools)) {
|
||||
<?php
|
||||
$sid = (int)$school['id'];
|
||||
$sname = $school['name'] ?? '';
|
||||
$scity = $school['address_city'] ?? '';
|
||||
$street = trim($school['address_street'] ?? '');
|
||||
$zip = trim($school['address_postal_code'] ?? '');
|
||||
$city = trim($school['address_city'] ?? '');
|
||||
$prov = trim($school['address_province'] ?? '');
|
||||
$country = trim($school['address_country'] ?? '');
|
||||
|
||||
// Riga 1: Via...
|
||||
$addrLine1 = $street;
|
||||
|
||||
// Riga 2: CAP Città (PR) - Nazione
|
||||
$addrLine2Parts = [];
|
||||
if ($zip !== '') $addrLine2Parts[] = $zip;
|
||||
if ($city !== '') $addrLine2Parts[] = $city;
|
||||
|
||||
$addrLine2 = implode(' ', $addrLine2Parts);
|
||||
if ($prov !== '') $addrLine2 .= ' (' . $prov . ')';
|
||||
if ($country !== '') $addrLine2 .= ' - ' . $country;
|
||||
|
||||
|
||||
$logoPath = null;
|
||||
if (!empty($school['logo']) && file_exists("photoschool/" . $school['logo'])) {
|
||||
$logoPath = "photoschool/" . $school['logo'];
|
||||
$logoRaw = trim((string)($school['logo'] ?? ''));
|
||||
|
||||
if ($logoRaw !== '') {
|
||||
// se in DB è già tipo "photoschool/xxx.jpg" lo uso così com'è
|
||||
$logoRel = ltrim($logoRaw, '/'); // evita "/photoschool/..." (leading slash)
|
||||
|
||||
// controllo file su disco con path reali (stessa cartella o un livello sopra)
|
||||
$disk1 = __DIR__ . '/' . $logoRel;
|
||||
$disk2 = __DIR__ . '/../' . $logoRel;
|
||||
|
||||
if (is_file($disk1)) {
|
||||
$logoPath = $logoRel;
|
||||
} elseif (is_file($disk2)) {
|
||||
$logoPath = '../' . $logoRel;
|
||||
} else {
|
||||
// fallback: provo comunque a mostrarlo (magari esiste via web path)
|
||||
$logoPath = $logoRel;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<div class="card school-card h-100 shadow-sm" onclick="selectSchool(<?= $sid ?>)">
|
||||
@ -371,11 +422,17 @@ if (empty($userSchools)) {
|
||||
<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 if (!empty($addrLine1) || !empty($addrLine2)): ?>
|
||||
<div class="text-muted small mb-0">
|
||||
<div>
|
||||
<i class="bx bx-map me-1"></i><?= htmlspecialchars($addrLine1) ?>
|
||||
</div>
|
||||
<?php if (!empty($addrLine2)): ?>
|
||||
<div><?= htmlspecialchars($addrLine2) ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-footer bg-transparent border-0 pt-0 pb-4 px-4">
|
||||
|
||||
@ -18,12 +18,20 @@ $pdo = $dbHandler->getConnection();
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT s.id, s.name, s.logo
|
||||
SELECT
|
||||
s.id,
|
||||
s.name,
|
||||
s.logo,
|
||||
s.address_street,
|
||||
s.address_city,
|
||||
s.address_postal_code,
|
||||
s.address_province,
|
||||
s.address_country
|
||||
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'
|
||||
AND us.status = 'active'
|
||||
AND s.status = 'active'
|
||||
ORDER BY s.name
|
||||
");
|
||||
$stmt->execute([(int)$iduserlogin]);
|
||||
@ -388,22 +396,70 @@ $active_orders = count(array_filter($orders, fn($o) => $o['status'] === 'complet
|
||||
<?php
|
||||
$sid = (int)$s['id'];
|
||||
$sname = $s['name'];
|
||||
$logoPath = (!empty($s['logo']) && file_exists("photoschool/" . $s['logo']))
|
||||
? "photoschool/" . $s['logo']
|
||||
: null;
|
||||
$logoPath = null;
|
||||
$logoRaw = trim((string)($s['logo'] ?? ''));
|
||||
|
||||
if ($logoRaw !== '') {
|
||||
// se in DB è già "photoschool/xxx.jpg" lo uso così com'è
|
||||
$logoRel = ltrim($logoRaw, '/');
|
||||
|
||||
// check file su disco (stessa cartella di questo file)
|
||||
$disk1 = __DIR__ . '/' . $logoRel;
|
||||
$disk2 = __DIR__ . '/../' . $logoRel;
|
||||
|
||||
if (is_file($disk1)) {
|
||||
$logoPath = $logoRel;
|
||||
} elseif (is_file($disk2)) {
|
||||
$logoPath = '../' . $logoRel;
|
||||
} else {
|
||||
// fallback web
|
||||
$logoPath = $logoRel;
|
||||
}
|
||||
}
|
||||
|
||||
$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">
|
||||
<img src="<?= htmlspecialchars($logoPath) ?>" style="height:50px;width:auto;" class="rounded" onerror="this.style.display='none';">
|
||||
<?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
|
||||
$addrParts = [];
|
||||
|
||||
if (!empty($s['address_street'])) {
|
||||
$addrParts[] = $s['address_street'];
|
||||
}
|
||||
|
||||
$cityLine = trim(
|
||||
($s['address_postal_code'] ?? '') . ' ' .
|
||||
($s['address_city'] ?? '') .
|
||||
(!empty($s['address_province']) ? ' (' . $s['address_province'] . ')' : '')
|
||||
);
|
||||
|
||||
if ($cityLine !== '') {
|
||||
$addrParts[] = $cityLine;
|
||||
}
|
||||
|
||||
if (!empty($s['address_country'])) {
|
||||
$addrParts[] = $s['address_country'];
|
||||
}
|
||||
|
||||
$fullAddress = implode(', ', array_map('trim', $addrParts));
|
||||
?>
|
||||
|
||||
<?php if ($fullAddress !== ''): ?>
|
||||
<div class="text-muted small">
|
||||
<i class="bx bx-map me-1"></i><?= htmlspecialchars($fullAddress) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($isCurrent): ?>
|
||||
<div class="text-success small">Selezionata</div>
|
||||
<?php endif; ?>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user