Radek Davidek 2f3eeebe72 added icon
2025-11-01 13:37:05 +01:00

239 lines
5.7 KiB
HTML

<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="icon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TVCOM Přenosy</title>
<style>
body {
font-family: system-ui, sans-serif;
margin: 20px;
background: #f5f5f5;
color: #333;
}
h1 {
text-align: center;
margin-bottom: 20px;
}
.filters {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
}
input, select, button {
padding: 6px 10px;
font-size: 15px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 15px;
}
.card {
background: white;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.2s;
}
.card:hover {
transform: scale(1.02);
}
.card img {
width: 100%;
height: 160px;
object-fit: cover;
}
.card-content {
padding: 10px;
}
.title {
font-weight: bold;
margin-bottom: 5px;
}
.meta {
font-size: 0.9em;
color: #666;
}
#loading {
text-align: center;
font-size: 1.2em;
margin-top: 30px;
}
@media ( max-width : 500px) {
.card img {
height: 120px;
}
}
</style>
</head>
<body>
<h1>📺 TVCOM Přenosy</h1>
<div class="filters">
<input id="search" type="text" placeholder="Hledat přenos..." /> <input
id="datePicker" type="date" /> <select id="sportFilter">
<option value="">Všechny sporty</option>
</select>
<button id="refreshBtn">♻️ Obnovit data</button>
</div>
<div id="loading">Načítám data...</div>
<div id="list" class="grid" style="display: none"></div>
<script>
const API_BASE = "";
const urlParams = new URLSearchParams(window.location.search);
const apiKey = urlParams.get('apiKey');
const listEl = document.getElementById('list');
const loadingEl = document.getElementById('loading');
const searchEl = document.getElementById('search');
const sportFilterEl = document.getElementById('sportFilter');
const datePicker = document.getElementById('datePicker');
const refreshBtn = document.getElementById('refreshBtn');
let all = [];
// === inicializace ===
const today = new Date().toISOString().substring(0, 10);
datePicker.value = today;
fetchForDate(today);
// === změna datumu ===
datePicker.addEventListener('change', () => {
const dateStr = datePicker.value;
if (dateStr) fetchForDate(dateStr);
});
// === debounce funkce ===
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// === vyhledávání ===
const debouncedApplyFilters = debounce(applyFilters, 300);
searchEl.addEventListener('input', debouncedApplyFilters);
sportFilterEl.addEventListener('change', applyFilters);
// === tlačítko obnovit ===
refreshBtn.addEventListener('click', () => {
loadingEl.style.display = 'block';
listEl.style.display = 'none';
const now = new Date().toISOString().substring(0, 10);
datePicker.value = now;
fetch(`${API_BASE}/refresh?apiKey=${apiKey}`)
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(() => {
// po úspěšném refresh načteme aktuální den
const now = new Date().toISOString().substring(0, 10);
datePicker.value = now;
return fetchForDate(now);
})
.catch(err => {
console.error(err);
loadingEl.textContent = "❌ Chyba při obnově dat: " + err;
});
});
// === načtení dat pro daný den ===
function fetchForDate(dateStr) {
loadingEl.style.display = 'block';
listEl.style.display = 'none';
return fetch(`${API_BASE}/transmissions?date=${encodeURIComponent(dateStr)}&apiKey=${apiKey}`)
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(data => {
all = data || [];
populateSports();
applyFilters();
loadingEl.style.display = 'none';
listEl.style.display = 'grid';
})
.catch(err => {
console.error(err);
loadingEl.textContent = "❌ Chyba při načítání dat: " + err;
});
}
// === naplnění filtrů podle dostupných sportů ===
function populateSports() {
const sports = [...new Set(all.map(t => t.sport).filter(Boolean))].sort();
sportFilterEl.innerHTML = '<option value="">Všechny sporty</option>';
for (const s of sports) {
const opt = document.createElement('option');
opt.value = s;
opt.textContent = s;
sportFilterEl.appendChild(opt);
}
}
// === aplikace filtrů a vykreslení ===
function applyFilters() {
const query = searchEl.value.toLowerCase();
const sport = sportFilterEl.value;
const filtered = all.filter(t => {
return (!query || t.title.toLowerCase().includes(query) || (t.league||'').toLowerCase().includes(query)) &&
(!sport || t.sport === sport);
});
renderList(filtered);
}
// === formátování data a času ===
function formatDateTime(dateStr, timeStr) {
if (!dateStr || !timeStr) return '';
const dt = new Date(dateStr + 'T' + timeStr);
return dt.toLocaleString('cs-CZ', { dateStyle: 'short', timeStyle: 'short' });
}
// === vykreslení seznamu ===
function renderList(items) {
listEl.innerHTML = '';
if (!items.length) {
listEl.innerHTML = '<div style="grid-column:1/-1;text-align:center;">Žádné přenosy</div>';
return;
}
for (const t of items) {
const div = document.createElement('div');
div.className = 'card';
const dateTimeStr = formatDateTime(t.date, t.time);
div.innerHTML = `
<a href="${t.link}" target="_blank">
<img src="${t.image || 'https://via.placeholder.com/400x160?text=Žádný+obrázek'}" alt="">
<div class="card-content">
<div class="title">${t.title}</div>
<div class="meta">${dateTimeStr}</div>
<div class="meta">${t.sport}${t.league || ''} ${t.leaguePart || ''}</div>
</div>
</a>
`;
listEl.appendChild(div);
}
}
</script>
</body>
</html>