telvero_whatson_talpa/calendar.php
2026-02-19 10:58:47 +01:00

338 lines
16 KiB
PHP

<?php
/**
* Calendar Planning View
* Main interface for drag-and-drop TV scheduling
*/
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/helpers.php';
use Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
$db = getDbConnection();
// Get all infomercials with colors for sidebar
$infomercials = $db->query("
SELECT id, title, duration, color_code, series_code, upload_status
FROM infomercials
WHERE upload_status = 'uploaded'
ORDER BY title ASC
")->fetchAll();
// Auto-assign colors to infomercials without colors
foreach ($infomercials as $infomercial) {
if (empty($infomercial['color_code'])) {
$stmt = $db->query("SELECT color_code FROM infomercials WHERE color_code IS NOT NULL");
$existingColors = $stmt->fetchAll(PDO::FETCH_COLUMN);
$newColor = generateDistinctColor($existingColors);
$stmt = $db->prepare("UPDATE infomercials SET color_code = ? WHERE id = ?");
$stmt->execute([$newColor, $infomercial['id']]);
}
}
// Refresh infomercials after color assignment
$infomercials = $db->query("
SELECT id, title, duration, color_code, series_code, upload_status
FROM infomercials
WHERE upload_status = 'uploaded'
ORDER BY title ASC
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kalender Planning - Telvero Talpa</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<!-- FullCalendar -->
<link href='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@6.1.10/index.global.min.css' rel='stylesheet' />
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body class="bg-light">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="bi bi-tv"></i> Telvero Talpa Planner
</a>
<div class="navbar-nav">
<a class="nav-link" href="index.php">Dashboard</a>
<a class="nav-link" href="planner.php">Planner</a>
<a class="nav-link active" href="calendar.php">Kalender</a>
<a class="nav-link" href="blocks.php">Blokken</a>
<a class="nav-link" href="infomercials.php">Infomercials</a>
</div>
</div>
</nav>
<div class="container-fluid mt-4">
<!-- Alert Container -->
<div id="alertContainer"></div>
<!-- Block Info Display & Zoom Controls -->
<div class="row mb-3">
<div class="col-md-9">
<div class="card shadow-sm">
<div class="card-header bg-info text-white py-2 d-flex justify-content-between align-items-center">
<h6 class="mb-0">
<i class="bi bi-calendar3"></i> Actieve Blokken voor Vandaag
</h6>
<button type="button" class="btn-icon btn-icon-sm btn-icon-success" onclick="showSyncBlockModal()">
<i class="bi bi-cloud-upload"></i>
</button>
</div>
<div class="card-body p-2" id="blockInfoContainer">
<p class="text-muted small mb-0">Laden...</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card shadow-sm">
<div class="card-header bg-secondary text-white py-2">
<h6 class="mb-0">
<i class="bi bi-zoom-in"></i> Zoom
</h6>
</div>
<div class="card-body p-2">
<div class="action-buttons w-100 justify-content-center">
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary" onclick="adjustZoom(0.8)">
<i class="bi bi-dash-circle"></i>
</button>
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary" onclick="adjustZoom(1.0)">
<i class="bi bi-arrow-clockwise"></i>
</button>
<button type="button" class="btn-icon btn-icon-sm btn-icon-secondary" onclick="adjustZoom(1.2)">
<i class="bi bi-plus-circle"></i>
</button>
</div>
<div class="mt-2 text-center">
<small class="text-muted">Huidige: <span id="zoomLevel">100%</span></small>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Sidebar with draggable infomercials -->
<div class="col-md-3">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h5 class="mb-0">
<i class="bi bi-collection-play"></i> Beschikbare Infomercials
</h5>
</div>
<div class="card-body p-2">
<!-- Search -->
<div class="mb-3">
<input type="text"
class="form-control form-control-sm"
placeholder="Zoeken..."
onkeyup="filterCommercials(this.value)">
</div>
<!-- Infomercial List -->
<div class="infomercial-sidebar">
<?php if (empty($infomercials)): ?>
<div class="text-center text-muted p-3">
<i class="bi bi-inbox" style="font-size: 2rem;"></i>
<p class="mt-2 small">Geen infomercials beschikbaar</p>
<a href="infomercials.php" class="btn btn-sm btn-primary">
Voeg Infomercial Toe
</a>
</div>
<?php else: ?>
<?php foreach ($infomercials as $infomercial): ?>
<div class="infomercial-item"
style="border-left-color: <?= htmlspecialchars($infomercial['color_code']) ?>;"
data-infomercial-id="<?= $infomercial['id'] ?>"
data-title="<?= htmlspecialchars($infomercial['title']) ?>"
data-duration="<?= $infomercial['duration'] ?>"
data-color="<?= htmlspecialchars($infomercial['color_code']) ?>"
data-series-code="<?= htmlspecialchars($infomercial['series_code'] ?? '') ?>">
<div class="d-flex align-items-center">
<div class="color-preview me-2"
style="background-color: <?= htmlspecialchars($infomercial['color_code']) ?>; width: 20px; height: 20px; border-radius: 3px;">
</div>
<div class="flex-grow-1">
<div class="infomercial-title">
<?= htmlspecialchars($infomercial['title']) ?>
</div>
<div class="infomercial-duration">
<i class="bi bi-clock"></i> <?= $infomercial['duration'] ?>
</div>
</div>
<div>
<i class="bi bi-grip-vertical text-muted"></i>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="mt-3 p-2 bg-light rounded">
<small class="text-muted">
<i class="bi bi-info-circle"></i>
Sleep infomercials naar de kalender om te plannen
</small>
</div>
</div>
</div>
<!-- Legend -->
<div class="card shadow-sm mt-3">
<div class="card-header bg-secondary text-white">
<h6 class="mb-0"><i class="bi bi-palette"></i> Legenda</h6>
</div>
<div class="card-body p-2">
<div class="small text-muted">
<p class="mb-0">Kleuren worden automatisch toegewezen per infomercial</p>
</div>
</div>
</div>
</div>
<!-- Calendar -->
<div class="col-md-9">
<div class="card shadow-sm">
<div class="card-body">
<div id="calendar"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Event Details Modal -->
<div class="modal fade" id="eventModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="eventTitle">Uitzending Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="eventDetails">
<!-- Details will be populated by JavaScript -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" id="deleteEventBtn">
<i class="bi bi-trash"></i> Verwijderen
</button>
<button type="button" class="btn btn-success" id="syncEventBtn">
<i class="bi bi-cloud-upload"></i> Sync
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Sluiten</button>
</div>
</div>
</div>
</div>
<!-- Block Time Editor Modal -->
<div class="modal fade" id="blockTimeModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Blok Starttijd Aanpassen</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="blockDate">
<input type="hidden" id="blockChannel">
<div class="mb-3">
<label class="form-label">Nieuwe Starttijd</label>
<input type="time" class="form-control" id="blockStartTime">
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="recalculateTransmissions" checked>
<label class="form-check-label" for="recalculateTransmissions">
Herbereken alle uitzendingen in dit blok
</label>
</div>
<div class="alert alert-info mt-3">
<i class="bi bi-info-circle"></i>
Als je "herbereken" aanvinkt, worden alle uitzendingen in dit blok opnieuw getimed vanaf de nieuwe starttijd.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuleren</button>
<button type="button" class="btn btn-primary" onclick="saveBlockTime()">
<i class="bi bi-check-circle"></i> Opslaan
</button>
</div>
</div>
</div>
</div>
<!-- Sync Block Modal -->
<div class="modal fade" id="syncBlockModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Blok Synchroniseren naar Talpa</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Datum</label>
<input type="date" class="form-control" id="syncBlockDate" value="<?= date('Y-m-d') ?>">
</div>
<div class="mb-3">
<label class="form-label">Zender</label>
<select class="form-select" id="syncBlockChannel">
<option value="SBS9">SBS9</option>
<option value="NET5">NET5</option>
<option value="SBS6">SBS6</option>
</select>
</div>
<div class="alert alert-info">
<i class="bi bi-info-circle"></i>
Dit synchroniseert alle uitzendingen in het geselecteerde blok naar Talpa.
Alleen uitzendingen die nog niet gesynchroniseerd zijn worden verzonden.
</div>
<div id="syncBlockProgress" class="d-none">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar" style="width: 100%"></div>
</div>
<p class="text-center mt-2 mb-0">Synchroniseren...</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuleren</button>
<button type="button" class="btn btn-primary" onclick="syncBlock()">
<i class="bi bi-cloud-upload"></i> Synchroniseren
</button>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@6.1.10/index.global.min.js'></script>
<script src="assets/js/calendar-init.js"></script>
</body>
</html>