Files
2026-08-30 11:25:19 +02:00

244 lines
7.1 KiB
PHP

<?php
function fetch_api($url) {
$context = stream_context_create([
"http" => [
"ignore_errors" => true
]
]);
$json = @file_get_contents($url, false, $context);
return $json ? json_decode($json, true) : [];
}
$messages = fetch_api("https://api.sat.regattatech.de/api/v1/message");
$resultsData = fetch_api("https://api.sat.regattatech.de/api/v1/results/current/");
$rennplanData = fetch_api("https://api.sat.regattatech.de/api/v1/rennplan/current/");
$results = $resultsData['ergebnisse'] ?? [];
$rennplan = $rennplanData['rennplan'] ?? [];
$lastResultUUIDs = array_column($results, 'uuid');
$nextRaces = [];
foreach ($rennplan as $lauf) {
foreach ($lauf as $rennen) {
if (!in_array($rennen['uuid'], $lastResultUUIDs)) {
$nextRaces[] = $rennen;
}
}
}
$nextRaces = array_slice($nextRaces, 0, 3);
function render_message_box($message) {
$typeMap = [
'info' => 'success',
'warning' => 'warning',
'error' => 'danger'
];
$type = $typeMap[$message['type'] ?? ''] ?? 'secondary';
$text = htmlspecialchars($message['message'] ?? '', ENT_QUOTES, 'UTF-8');
return "<div class='alert alert-{$type} fs-5' role='alert'>{$text}</div>";
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>RegattaTech.DE Ergebnis TV</title>
<link href="/res/css/bootstrap.min.css" rel="stylesheet">
<style>
#resultsBox {
max-height: 600px;
overflow-y: auto;
position: relative;
}
body {
font-size: 1.25rem;
}
h5, h6 {
font-size: 1.5rem;
}
</style>
</head>
<body class="bg-light">
<div class="container-fluid py-3 bg-white border-bottom">
<div class="d-flex justify-content-between align-items-center">
<img src="/res/img/regattatech_logo.png" height="70">
<h3 id="clock" class="m-0 fw-bold"></h3>
<img src="/res/img/sat_logo.png" height="70">
</div>
</div>
<div class="container mt-4">
<div id="messages">
<?php
if (!empty($messages)) {
echo render_message_box($messages);
}
?>
</div>
<div class="row mt-4">
<!-- Ergebnisse -->
<div class="col-lg-7">
<h5 class="fw-bold">Letzte Ergebnisse</h5>
<div id="resultsBox" class="bg-white border rounded p-3">
<?php
if (empty($results)) {
echo "<p class='text-muted'>Noch keine Ergebnisse vorhanden</p>";
} else {
$lauf = null;
$latest = array_reverse(array_slice($results, -10));
foreach ($latest as $res) {
if ($lauf !== ($res['lauf'] ?? null)) {
echo "<h3 class='mt-4'>Lauf " .
htmlspecialchars($res['lauf'] ?? '', ENT_QUOTES, 'UTF-8') .
"</h3>";
$lauf = $res['lauf'] ?? null;
}
echo "<div class='mb-3'>";
echo "<strong>" .
htmlspecialchars($res['title'] ?? '', ENT_QUOTES, 'UTF-8') .
"</strong><br>";
if (!empty($res['bahn1'])) {
$boot = $res['bahn1']['boot'] ?? '';
$zeit = $res['bahn1']['zeit'] ?? '';
echo "Bahn 1: " .
htmlspecialchars($boot, ENT_QUOTES, 'UTF-8') .
" - " .
htmlspecialchars($zeit, ENT_QUOTES, 'UTF-8') .
"<br>";
}
if (!empty($res['bahn2'])) {
$boot = $res['bahn2']['boot'] ?? '';
$zeit = $res['bahn2']['zeit'] ?? '';
echo "Bahn 2: " .
htmlspecialchars($boot, ENT_QUOTES, 'UTF-8') .
" - " .
htmlspecialchars($zeit, ENT_QUOTES, 'UTF-8') .
"<br>";
}
if (!empty($res['bahn3'])) {
$boot = $res['bahn3']['boot'] ?? '';
$zeit = $res['bahn3']['zeit'] ?? '';
echo "Bahn 3: " .
htmlspecialchars($boot, ENT_QUOTES, 'UTF-8') .
" - " .
htmlspecialchars($zeit, ENT_QUOTES, 'UTF-8') .
"<br>";
}
echo "</div>";
}
}
?>
</div>
</div>
<!-- Nächste Rennen -->
<div class="col-lg-5">
<h5 class="fw-bold">Nächste Rennen</h5>
<div class="bg-white border rounded p-3">
<?php
foreach ($nextRaces as $rennen) {
echo "<div class='mb-4'>";
echo "<strong>" .
htmlspecialchars($rennen['name'] ?? '', ENT_QUOTES, 'UTF-8') .
" (" .
htmlspecialchars($rennen['zeit'] ?? '', ENT_QUOTES, 'UTF-8') .
")</strong><br>";
if (isset($rennen['bahn1'])) {
echo "Bahn 1: " .
htmlspecialchars($rennen['bahn1'], ENT_QUOTES, 'UTF-8') .
"<br>";
}
if (isset($rennen['bahn2'])) {
echo "Bahn 2: " .
htmlspecialchars($rennen['bahn2'], ENT_QUOTES, 'UTF-8') .
"<br>";
}
if (isset($rennen['bahn3'])) {
echo "Bahn 3: " .
htmlspecialchars($rennen['bahn3'], ENT_QUOTES, 'UTF-8') .
"<br>";
}
echo "</div>";
}
?>
</div>
</div>
</div>
<div class="row mt-5 align-items-center">
<div class="col-lg-10">
<div class="p-4 bg-white rounded border fs-5">
<strong>
Alle Ergebnisse & Rennpläne Live und als App unter
apps.sport-am-tankumsee.de oder den QR Code Scannen
</strong>
</div>
</div>
<div class="col-lg-2 text-end">
<img src="/res/img/qrcode.png" class="img-fluid" alt="QR Code">
</div>
</div>
</div>
<script>
function updateClock() {
const now = new Date();
document.getElementById('clock').innerText =
now.toLocaleTimeString('de-DE');
}
setInterval(updateClock, 1000);
updateClock();
setInterval(() => location.reload(), 15000);
let scrollDirection = 1;
setInterval(() => {
const box = document.getElementById('resultsBox');
if (box.scrollHeight > box.clientHeight) {
if (box.scrollTop + box.clientHeight >= box.scrollHeight) {
scrollDirection = -1;
}
if (box.scrollTop <= 0) {
scrollDirection = 1;
}
box.scrollTop += scrollDirection * 1;
}
}, 100);
</script>
</body>
</html>