yogiboook_new/public/userarea/propagation_manager.php
2025-12-25 21:12:29 +01:00

404 lines
21 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// propagation_overview.php - Propagation Blocks Overview (Grouped, not single sessions)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include('include/headscript.php');
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
if (!isset($iduserlogin)) {
die("Errore: ID utente non definito.");
}
/*
|--------------------------------------------------------------------------
| 1) Load school owned by current user
|--------------------------------------------------------------------------
*/
$stmt = $pdo->prepare("SELECT id, name, logo FROM schools WHERE owner_id = ? LIMIT 1");
$stmt->execute([(int)$iduserlogin]);
$school = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$school) {
die("Errore: Nessuna scuola trovata per questo account.");
}
$school_id = (int)$school['id'];
$school_name = $school['name'] ?? 'School';
/*
|--------------------------------------------------------------------------
| 2) Helpers
|--------------------------------------------------------------------------
*/
function itDayLabel(string $dow): string
{
$map = [
'monday' => 'Lunedì',
'tuesday' => 'Martedì',
'wednesday' => 'Mercoledì',
'thursday' => 'Giovedì',
'friday' => 'Venerdì',
'saturday' => 'Sabato',
'sunday' => 'Domenica'
];
return $map[$dow] ?? ucfirst($dow);
}
function safeTime($t): string
{
// expects "HH:MM:SS" or "HH:MM"
if (!$t) return '—';
return substr((string)$t, 0, 5);
}
/*
|--------------------------------------------------------------------------
| 3) Handle delete block propagation (bookings + sessions for that block)
|--------------------------------------------------------------------------
| Block key = propagation_id + class_type_id + start_time + end_time
|--------------------------------------------------------------------------
*/
$feedback = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'delete_propagation_block') {
$propagation_id = trim($_POST['propagation_id'] ?? '');
$class_type_id = (int)($_POST['class_type_id'] ?? 0);
$start_time = trim($_POST['start_time'] ?? '');
$end_time = trim($_POST['end_time'] ?? '');
if ($propagation_id === '' || $class_type_id <= 0 || $start_time === '' || $end_time === '') {
$feedback = '<div class="alert alert-danger alert-dismissible fade show">
Parametri non validi per la cancellazione della propagazione.
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>';
} else {
try {
$pdo->beginTransaction();
// Delete bookings for sessions matching this block (only this school)
$stmtDelBookings = $pdo->prepare("
DELETE sb
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
WHERE c.school_id = ?
AND cs.propagation_id = ?
AND cs.class_type_id = ?
AND cs.start_time = ?
AND cs.end_time = ?
");
$stmtDelBookings->execute([$school_id, $propagation_id, $class_type_id, $start_time, $end_time]);
$deletedBookings = $stmtDelBookings->rowCount();
// Delete sessions for this block (only this school)
$stmtDelSessions = $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 c.school_id = ?
AND cs.propagation_id = ?
AND cs.class_type_id = ?
AND cs.start_time = ?
AND cs.end_time = ?
");
$stmtDelSessions->execute([$school_id, $propagation_id, $class_type_id, $start_time, $end_time]);
$deletedSessions = $stmtDelSessions->rowCount();
$pdo->commit();
$feedback = "<div class='alert alert-success alert-dismissible fade show'>
Propagazione rimossa con successo.
<br><small>
<strong>Codice:</strong> " . htmlspecialchars($propagation_id) . " |
<strong>Sessioni eliminate:</strong> {$deletedSessions} |
<strong>Prenotazioni eliminate:</strong> {$deletedBookings}
</small>
<button type='button' class='btn-close' data-bs-dismiss='alert'></button>
</div>";
} catch (Throwable $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
$feedback = "<div class='alert alert-danger alert-dismissible fade show'>
Errore durante la cancellazione: " . htmlspecialchars($e->getMessage()) . "
<button type='button' class='btn-close' data-bs-dismiss='alert'></button>
</div>";
}
}
}
}
/*
|--------------------------------------------------------------------------
| 4) Load propagation blocks (GROUPED - no single sessions list)
|--------------------------------------------------------------------------
| One row per propagation_id + class_type + time range.
|--------------------------------------------------------------------------
*/
$stmt = $pdo->prepare("
SELECT
cs.propagation_id,
ct.id AS class_type_id,
c.name AS class_name,
ct.level,
ct.day_of_week,
cs.start_time,
cs.end_time,
MIN(cs.session_date) AS range_start,
MAX(cs.session_date) AS range_end,
COUNT(DISTINCT cs.id) AS sessions_count,
SUM(CASE WHEN sb.id IS NULL THEN 0 ELSE 1 END) AS bookings_count
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 session_bookings sb ON sb.session_id = cs.id
WHERE c.school_id = ?
AND cs.propagation_id IS NOT NULL
AND cs.propagation_id <> ''
GROUP BY
cs.propagation_id,
ct.id,
c.name,
ct.level,
ct.day_of_week,
cs.start_time,
cs.end_time
ORDER BY range_start DESC, c.name ASC, cs.start_time ASC
");
$stmt->execute([$school_id]);
$blocks = $stmt->fetchAll(PDO::FETCH_ASSOC);
/*
|--------------------------------------------------------------------------
| 5) Optional quick counters for a nicer header
|--------------------------------------------------------------------------
*/
$totalBlocks = count($blocks);
$totalSessions = 0;
$totalBookings = 0;
foreach ($blocks as $b) {
$totalSessions += (int)($b['sessions_count'] ?? 0);
$totalBookings += (int)($b['bookings_count'] ?? 0);
}
?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Propagazioni - <?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">
<!-- Header (same style as your other pages) -->
<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: 90px; height: 90px; object-fit: cover;">
</div>
<div class="flex-grow-1">
<h4 class="mb-1">Propagazioni - <?php echo htmlspecialchars($school_name); ?></h4>
<p class="mb-0 text-muted">
Vista “a blocchi”: codice propagazione + classe + giorno/ora + range (daa).
Nessun elenco di singole sessioni.
</p>
</div>
<div class="text-end">
<a href="school_dashboard.php" class="btn btn-outline-primary">← Dashboard</a>
</div>
</div>
<!-- Small summary badges -->
<div class="mt-3 d-flex flex-wrap gap-2">
<span class="badge bg-primary">Blocchi: <?php echo (int)$totalBlocks; ?></span>
<span class="badge bg-info text-dark">Sessioni generate: <?php echo (int)$totalSessions; ?></span>
<span class="badge bg-secondary">Prenotazioni totali: <?php echo (int)$totalBookings; ?></span>
</div>
</div>
</div>
<?php echo $feedback; ?>
<?php if (empty($blocks)): ?>
<div class="card radius-10">
<div class="card-body text-center py-5">
<h5 class="text-muted">Nessuna propagazione trovata.</h5>
<p class="text-muted mb-0">Quando generi lezioni propagate, appariranno qui raggruppate per blocchi.</p>
</div>
</div>
<?php else: ?>
<!-- Main table -->
<div class="card radius-10">
<div class="card-header bg-primary text-white d-flex align-items-center justify-content-between">
<h5 class="mb-0">Blocchi di Propagazione</h5>
<div class="d-flex align-items-center gap-2">
<input type="text" id="quickSearch" class="form-control form-control-sm"
placeholder="Cerca codice / classe / giorno..." style="max-width: 320px;">
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0" id="blocksTable">
<thead class="table-light">
<tr>
<th style="white-space:nowrap;">Codice</th>
<th>Classe</th>
<th style="white-space:nowrap;">Giorno</th>
<th style="white-space:nowrap;">Ora</th>
<th style="white-space:nowrap;">Da</th>
<th style="white-space:nowrap;">A</th>
<th style="white-space:nowrap;" class="text-center">Sessioni</th>
<th style="white-space:nowrap;" class="text-center">Prenotazioni</th>
<th style="white-space:nowrap;" class="text-end">Azioni</th>
</tr>
</thead>
<tbody>
<?php foreach ($blocks as $b): ?>
<?php
$pid = $b['propagation_id'];
$hash = md5($pid . '|' . $b['class_type_id'] . '|' . $b['start_time'] . '|' . $b['end_time']);
$dayLabel = itDayLabel((string)$b['day_of_week']);
$timeLabel = safeTime($b['start_time']) . ' - ' . safeTime($b['end_time']);
$from = $b['range_start'] ? date('d/m/Y', strtotime($b['range_start'])) : '—';
$to = $b['range_end'] ? date('d/m/Y', strtotime($b['range_end'])) : '—';
$sessionsCount = (int)($b['sessions_count'] ?? 0);
$bookingsCount = (int)($b['bookings_count'] ?? 0);
$level = $b['level'] ? ucfirst($b['level']) : '';
?>
<tr>
<td>
<code><?php echo htmlspecialchars($pid); ?></code>
<div class="text-muted"><small>ID tipo: <?php echo (int)$b['class_type_id']; ?></small></div>
</td>
<td>
<div class="fw-bold"><?php echo htmlspecialchars($b['class_name']); ?></div>
<?php if ($level): ?>
<small class="text-muted">Livello: <?php echo htmlspecialchars($level); ?></small>
<?php endif; ?>
</td>
<td><?php echo htmlspecialchars($dayLabel); ?></td>
<td><span class="badge bg-light text-dark"><?php echo htmlspecialchars($timeLabel); ?></span></td>
<td><?php echo $from; ?></td>
<td><?php echo $to; ?></td>
<td class="text-center"><span class="badge bg-info text-dark"><?php echo $sessionsCount; ?></span></td>
<td class="text-center"><span class="badge bg-secondary"><?php echo $bookingsCount; ?></span></td>
<td class="text-end">
<button type="button"
class="btn btn-sm btn-danger"
data-bs-toggle="modal"
data-bs-target="#deleteBlockModal-<?php echo $hash; ?>">
<i class="bx bx-trash"></i> Cancella
</button>
</td>
</tr>
<!-- Delete modal (clean and safe) -->
<div class="modal fade" id="deleteBlockModal-<?php echo $hash; ?>" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form method="POST">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title">Cancella Blocco Propagazione</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Stai per cancellare questo blocco:</p>
<ul class="mb-3">
<li><strong>Codice:</strong> <code><?php echo htmlspecialchars($pid); ?></code></li>
<li><strong>Classe:</strong> <?php echo htmlspecialchars($b['class_name']); ?> <?php echo $level ? '(' . htmlspecialchars($level) . ')' : ''; ?></li>
<li><strong>Giorno:</strong> <?php echo htmlspecialchars($dayLabel); ?></li>
<li><strong>Ora:</strong> <?php echo htmlspecialchars($timeLabel); ?></li>
<li><strong>Range:</strong> <?php echo $from; ?> → <?php echo $to; ?></li>
<li><strong>Sessioni:</strong> <?php echo $sessionsCount; ?> | <strong>Prenotazioni:</strong> <?php echo $bookingsCount; ?></li>
</ul>
<div class="alert alert-warning mb-0">
Verranno eliminate:
<ul class="mb-0">
<li>tutte le righe in <code>session_bookings</code> collegate a queste sessioni</li>
<li>tutte le righe in <code>class_sessions</code> di questo blocco</li>
</ul>
<small>Operazione irreversibile.</small>
</div>
<input type="hidden" name="action" value="delete_propagation_block">
<input type="hidden" name="propagation_id" value="<?php echo htmlspecialchars($pid); ?>">
<input type="hidden" name="class_type_id" value="<?php echo (int)$b['class_type_id']; ?>">
<input type="hidden" name="start_time" value="<?php echo htmlspecialchars($b['start_time']); ?>">
<input type="hidden" name="end_time" value="<?php echo htmlspecialchars($b['end_time']); ?>">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
<button type="submit" class="btn btn-danger">Sì, cancella</button>
</div>
</form>
</div>
</div>
</div>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Quick search JS (no dependencies) -->
<script>
document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('quickSearch');
const table = document.getElementById('blocksTable');
if (!input || !table) return;
input.addEventListener('input', () => {
const q = input.value.toLowerCase().trim();
const rows = table.querySelectorAll('tbody tr');
rows.forEach(tr => {
const text = tr.innerText.toLowerCase();
tr.style.display = (text.includes(q)) ? '' : 'none';
});
});
});
</script>
<?php endif; ?>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
</body>
</html>