415 lines
20 KiB
PHP
415 lines
20 KiB
PHP
<?php
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
require_once __DIR__ . '/TalpaAPI.php';
|
|
|
|
use Dotenv\Dotenv;
|
|
$dotenv = Dotenv::createImmutable(__DIR__);
|
|
$dotenv->load();
|
|
|
|
$api = new TalpaApi();
|
|
$db = new PDO("mysql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_NAME']}", $_ENV['DB_USER'], $_ENV['DB_PASS']);
|
|
|
|
// Array om logs voor console te verzamelen
|
|
$apiLogs = [];
|
|
|
|
// 1. Registratie Infomercial (Stap 1, 2, 4)
|
|
if (isset($_POST['add_commercial'])) {
|
|
$ep = $api->createEpisode($_POST['title'], $_POST['duration'], $_POST['season_id']);
|
|
$apiLogs[] = ['call' => 'Create Episode', 'response' => $api->lastResponse];
|
|
|
|
if (isset($ep['id'])) {
|
|
$asset = $api->createMediaAsset($ep['id']);
|
|
$apiLogs[] = ['call' => 'Create Media Asset', 'response' => $api->lastResponse];
|
|
|
|
if (isset($asset['id'])) {
|
|
$details = $api->getMediaAssetDetails($asset['id']);
|
|
$apiLogs[] = ['call' => 'Get Media Asset Details', 'response' => $api->lastResponse];
|
|
|
|
$label = $details['mediaAssetLabel'] ?? 'Pending';
|
|
$stmt = $db->prepare("INSERT INTO infomercials (title, duration, season_id, content_id, media_asset_id, media_asset_label, upload_status) VALUES (?, ?, ?, ?, ?, ?, 'pending')");
|
|
$stmt->execute([$_POST['title'], $_POST['duration'], $_POST['season_id'], $ep['id'], $asset['id'], $label]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. LOKALE Planning opslaan of bewerken
|
|
if (isset($_POST['schedule_transmission'])) {
|
|
$stmt = $db->prepare("SELECT duration FROM infomercials WHERE id = ?");
|
|
$stmt->execute([$_POST['infomercial_id']]);
|
|
$commDuration = $stmt->fetchColumn();
|
|
|
|
if (!empty($_POST['edit_id'])) {
|
|
$stmt = $db->prepare("UPDATE transmissions SET infomercial_id=?, channel=?, template=?, start_date=?, start_time=?, duration=?, api_status='pending' WHERE id=?");
|
|
$stmt->execute([$_POST['infomercial_id'], $_POST['channel'], $_POST['template'], $_POST['start_date'], $_POST['start_time'], $commDuration, $_POST['edit_id']]);
|
|
} else {
|
|
$stmt = $db->prepare("INSERT INTO transmissions (infomercial_id, channel, template, start_date, start_time, duration, api_status) VALUES (?, ?, ?, ?, ?, ?, 'pending')");
|
|
$stmt->execute([$_POST['infomercial_id'], $_POST['channel'], $_POST['template'], $_POST['start_date'], $_POST['start_time'], $commDuration]);
|
|
}
|
|
header("Location: index.php?view_date=" . $_POST['start_date']);
|
|
exit;
|
|
}
|
|
|
|
// 3. Handmatige Sync naar Talpa (Stap 3 op verzoek)
|
|
if (isset($_POST['sync_item'])) {
|
|
$stmt = $db->prepare("SELECT t.*, c.content_id FROM transmissions t JOIN infomercials c ON t.infomercial_id = c.id WHERE t.id = ?");
|
|
$stmt->execute([$_POST['sync_id']]);
|
|
$tx = $stmt->fetch();
|
|
|
|
$res = $api->createTransmission([
|
|
"channel" => $tx['channel'],
|
|
"template" => $tx['template'],
|
|
"startDate" => $tx['start_date'],
|
|
"startTime" => $tx['start_time'],
|
|
"duration" => $tx['duration'],
|
|
"contentId" => $tx['content_id']
|
|
]);
|
|
$apiLogs[] = ['call' => 'Sync Transmission', 'response' => $api->lastResponse];
|
|
|
|
$status = (isset($res['id']) || (isset($res['statusCode']) && $res['statusCode'] == 201)) ? 'synced' : 'error';
|
|
$db->prepare("UPDATE transmissions SET api_status = ?, api_response = ? WHERE id = ?")
|
|
->execute([$status, json_encode($res), $_POST['sync_id']]);
|
|
}
|
|
|
|
// 4. Media Asset Label en Status bijwerken
|
|
if (isset($_POST['update_media_asset'])) {
|
|
$stmt = $db->prepare("UPDATE infomercials SET media_asset_label = ?, upload_status = ? WHERE id = ?");
|
|
$stmt->execute([$_POST['media_asset_label'], $_POST['upload_status'], $_POST['infomercial_id']]);
|
|
header("Location: index.php?view_date=" . $selectedDate);
|
|
exit;
|
|
}
|
|
|
|
// Data ophalen
|
|
$infomercials = $db->query("SELECT * FROM infomercials ORDER BY created_at DESC")->fetchAll();
|
|
$selectedDate = $_GET['view_date'] ?? date('Y-m-d');
|
|
$stmt = $db->prepare("SELECT t.*, c.title, c.duration as comm_duration FROM transmissions t JOIN infomercials c ON t.infomercial_id = c.id WHERE t.start_date = ? ORDER BY t.start_time ASC");
|
|
$stmt->execute([$selectedDate]);
|
|
$dailySchedule = $stmt->fetchAll();
|
|
|
|
$editItem = null;
|
|
if (isset($_GET['edit'])) {
|
|
$stmt = $db->prepare("SELECT * FROM transmissions WHERE id = ?");
|
|
$stmt->execute([$_GET['edit']]);
|
|
$editItem = $stmt->fetch();
|
|
}
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="nl">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Dashboard - Telvero Talpa</title>
|
|
<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">
|
|
<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 active" href="index.php">Dashboard</a>
|
|
<a class="nav-link" href="planner.php">Excel Planner</a>
|
|
<a class="nav-link" 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 mt-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h1><i class="bi bi-speedometer2"></i> Dashboard</h1>
|
|
<a href="calendar.php" class="btn btn-primary btn-lg">
|
|
<i class="bi bi-calendar-week"></i> Open Kalender
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Statistics Cards -->
|
|
<div class="row mb-4">
|
|
<?php
|
|
$totalCommercials = $db->query("SELECT COUNT(*) FROM infomercials")->fetchColumn();
|
|
$uploadedCommercials = $db->query("SELECT COUNT(*) FROM infomercials WHERE upload_status = 'uploaded'")->fetchColumn();
|
|
$totalTransmissions = $db->query("SELECT COUNT(*) FROM transmissions")->fetchColumn();
|
|
$pendingSync = $db->query("SELECT COUNT(*) FROM transmissions WHERE api_status = 'pending'")->fetchColumn();
|
|
$syncedTransmissions = $db->query("SELECT COUNT(*) FROM transmissions WHERE api_status = 'synced'")->fetchColumn();
|
|
?>
|
|
|
|
<div class="col-md-3">
|
|
<div class="stat-card">
|
|
<div class="stat-number"><?= $totalCommercials ?></div>
|
|
<div class="stat-label">Totaal Infomercials</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="stat-card success">
|
|
<div class="stat-number"><?= $uploadedCommercials ?></div>
|
|
<div class="stat-label">Geüpload</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="stat-card info">
|
|
<div class="stat-number"><?= $totalTransmissions ?></div>
|
|
<div class="stat-label">Geplande Uitzendingen</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="stat-card warning">
|
|
<div class="stat-number"><?= $pendingSync ?></div>
|
|
<div class="stat-label">Wacht op Sync</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h2 class="mb-3"><i class="bi bi-grid-3x3"></i> Snelle Acties</h2>
|
|
<div class="row mb-4">
|
|
<div class="col-md-3">
|
|
<div class="card shadow-sm h-100">
|
|
<div class="card-body text-center">
|
|
<i class="bi bi-table" style="font-size: 3rem; color: #2ecc71;"></i>
|
|
<h5 class="mt-3">Excel Planner</h5>
|
|
<p class="text-muted">Tabel-gebaseerde planning</p>
|
|
<a href="planner.php" class="btn btn-success">
|
|
<i class="bi bi-arrow-right-circle"></i> Open Planner
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card shadow-sm h-100">
|
|
<div class="card-body text-center">
|
|
<i class="bi bi-calendar-plus" style="font-size: 3rem; color: #3498db;"></i>
|
|
<h5 class="mt-3">Kalender View</h5>
|
|
<p class="text-muted">Visuele tijdlijn planning</p>
|
|
<a href="calendar.php" class="btn btn-primary">
|
|
<i class="bi bi-arrow-right-circle"></i> Open Kalender
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card shadow-sm h-100">
|
|
<div class="card-body text-center">
|
|
<i class="bi bi-collection-play" style="font-size: 3rem; color: #e74c3c;"></i>
|
|
<h5 class="mt-3">Infomercials</h5>
|
|
<p class="text-muted">Registreer en beheer</p>
|
|
<a href="infomercials.php" class="btn btn-danger">
|
|
<i class="bi bi-arrow-right-circle"></i> Naar Infomercials
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card shadow-sm h-100">
|
|
<div class="card-body text-center">
|
|
<i class="bi bi-calendar3" style="font-size: 3rem; color: #9b59b6;"></i>
|
|
<h5 class="mt-3">Blok Templates</h5>
|
|
<p class="text-muted">Beheer tijdblokken</p>
|
|
<a href="blocks.php" class="btn btn-secondary">
|
|
<i class="bi bi-arrow-right-circle"></i> Naar Blokken
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h2 class="mb-3"><i class="bi bi-clock-history"></i> Recente Activiteit</h2>
|
|
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="card p-3 shadow-sm">
|
|
<h5>1. Infomercial Registreren</h5>
|
|
<form method="POST">
|
|
<input type="text" name="title" class="form-control mb-2" placeholder="Product Naam" required>
|
|
<input type="text" name="duration" class="form-control mb-2" placeholder="Duur (HH:MM:SS)" required>
|
|
<input type="hidden" name="season_id" value="<?= $_ENV['TV_SEASON_ID'] ?>">
|
|
<button type="submit" name="add_commercial" class="btn btn-primary w-100">Registreren bij Talpa</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-8">
|
|
<div class="card p-3 shadow-sm">
|
|
<h5>2. <?= $editItem ? 'Planning Bewerken' : 'Tijdblok Reserveren' ?></h5>
|
|
<form method="POST" class="row g-2" id="planningForm">
|
|
<input type="hidden" name="edit_id" value="<?= $editItem['id'] ?? '' ?>">
|
|
<div class="col-md-6">
|
|
<select name="infomercial_id" id="commercial_select" class="form-select" required>
|
|
<option value="">Selecteer Infomercial...</option>
|
|
<?php foreach($infomercials as $c): ?>
|
|
<option value="<?= $c['id'] ?>" data-duration="<?= $c['duration'] ?>" <?= (isset($editItem) && $editItem['infomercial_id'] == $c['id']) ? 'selected' : '' ?>>
|
|
<?= htmlspecialchars($c['title']) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3"><input type="date" name="start_date" class="form-control" value="<?= $editItem['start_date'] ?? $selectedDate ?>" required></div>
|
|
<div class="col-md-3"><input type="time" name="start_time" class="form-control" value="<?= $editItem['start_time'] ?? '' ?>" required></div>
|
|
|
|
<div class="col-md-4">
|
|
<label class="small text-muted">Duur (automatisch)</label>
|
|
<input type="text" id="display_duration" class="form-control" value="<?= $editItem['duration'] ?? '' ?>" readonly>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="small text-muted">Channel</label>
|
|
<input type="text" name="channel" class="form-control" value="<?= $editItem['channel'] ?? 'NET5' ?>" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="small text-muted">Template</label>
|
|
<input type="text" name="template" class="form-control" value="<?= $editItem['template'] ?? 'HOME030' ?>" required>
|
|
</div>
|
|
|
|
<div class="col-md-12 mt-3">
|
|
<button type="submit" name="schedule_transmission" class="btn btn-success w-100"><?= $editItem ? 'Bijwerken' : 'Opslaan' ?></button>
|
|
<?php if($editItem): ?> <a href="index.php?view_date=<?= $selectedDate ?>" class="btn btn-link w-100 text-muted">Annuleren</a> <?php endif; ?>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<h2 class="mb-3"><i class="bi bi-calendar-check"></i> Uitzendingen vandaag</h2>
|
|
<div class="card shadow-sm">
|
|
<div class="card-body">
|
|
<form method="GET" class="row g-2 mb-3">
|
|
<div class="col-md-3">
|
|
<input type="date" name="view_date" class="form-control" value="<?= $selectedDate ?>">
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="submit" class="btn btn-secondary">
|
|
<i class="bi bi-search"></i> Bekijk Datum
|
|
</button>
|
|
</div>
|
|
<div class="col-md-7 text-end">
|
|
<a href="calendar.php" class="btn btn-primary">
|
|
<i class="bi bi-calendar-week"></i> Open in Kalender View
|
|
</a>
|
|
</div>
|
|
</form>
|
|
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-dark">
|
|
<tr><th>Tijd</th><th>Zender</th><th>Product</th><th>Duur</th><th>Sync Status</th><th>Acties</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach($dailySchedule as $tx): ?>
|
|
<tr>
|
|
<td><?= substr($tx['start_time'], 0, 5) ?></td>
|
|
<td><span class="badge bg-secondary"><?= htmlspecialchars($tx['channel']) ?></span></td>
|
|
<td><?= htmlspecialchars($tx['title']) ?></td>
|
|
<td><?= $tx['duration'] ?></td>
|
|
<td>
|
|
<span class="badge <?= $tx['api_status'] == 'synced' ? 'bg-success' : ($tx['api_status'] == 'error' ? 'bg-danger' : 'bg-warning text-dark') ?>">
|
|
<?= ucfirst($tx['api_status']) ?>
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<div class="action-buttons justify-content-center">
|
|
<a href="?edit=<?= $tx['id'] ?>&view_date=<?= $selectedDate ?>" class="btn-icon btn-icon-xs btn-icon-primary">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
<?php if($tx['api_status'] !== 'synced'): ?>
|
|
<form method="POST" style="display:inline;">
|
|
<input type="hidden" name="sync_id" value="<?= $tx['id'] ?>">
|
|
<button type="submit" name="sync_item" class="btn-icon btn-icon-xs btn-icon-success">
|
|
<i class="bi bi-cloud-upload"></i>
|
|
</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<h2 class="mt-4 mb-3"><i class="bi bi-file-earmark-text"></i> Media Asset Management</h2>
|
|
|
|
<div class="card shadow-sm">
|
|
<div class="card-body p-0">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-secondary">
|
|
<tr>
|
|
<th>Titel</th>
|
|
<th>Duur</th>
|
|
<th>Content ID</th>
|
|
<th>Label (Filename)</th>
|
|
<th>Upload Status</th>
|
|
<th style="width: 120px;">Actie</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach($infomercials as $c): ?>
|
|
<tr>
|
|
<form method="POST">
|
|
<input type="hidden" name="infomercial_id" value="<?= $c['id'] ?>">
|
|
<td><?= htmlspecialchars($c['title']) ?></td>
|
|
<td><span class="badge bg-info text-dark"><?= $c['duration'] ?></span></td>
|
|
<td><code><?= htmlspecialchars($c['content_id']) ?></code></td>
|
|
<td>
|
|
<input type="text" name="media_asset_label" class="form-control form-control-sm" value="<?= htmlspecialchars($c['media_asset_label']) ?>">
|
|
</td>
|
|
<td>
|
|
<select name="upload_status" class="form-select form-select-sm">
|
|
<option value="pending" <?= ($c['upload_status'] ?? 'pending') == 'pending' ? 'selected' : '' ?>>Pending</option>
|
|
<option value="uploaded" <?= ($c['upload_status'] ?? '') == 'uploaded' ? 'selected' : '' ?>>Uploaded</option>
|
|
</select>
|
|
</td>
|
|
<td>
|
|
<button type="submit" name="update_media_asset" class="btn btn-sm btn-primary">Opslaan</button>
|
|
</td>
|
|
</form>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="mt-5 py-4 bg-dark text-white text-center">
|
|
<div class="container">
|
|
<p class="mb-0">
|
|
<i class="bi bi-tv"></i> Telvero Talpa Planning System © 2026
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
// Bestaande JS voor duur selectie
|
|
const select = document.getElementById('commercial_select');
|
|
const durationInput = document.getElementById('display_duration');
|
|
select.addEventListener('change', function() {
|
|
const selectedOption = this.options[this.selectedIndex];
|
|
const duration = selectedOption.getAttribute('data-duration');
|
|
durationInput.value = duration || '';
|
|
});
|
|
|
|
// LOGGING NAAR CONSOLE
|
|
const apiLogs = <?= json_encode($apiLogs) ?>;
|
|
if (apiLogs.length > 0) {
|
|
console.group("Talpa API Logs");
|
|
apiLogs.forEach(log => {
|
|
console.log("%c" + log.call, "color: #007bff; font-weight: bold;", log.response);
|
|
});
|
|
console.groupEnd();
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|