Files
Sdk_TV_app/templates/modern_archive_index.html
T
2025-11-12 17:49:56 +01:00

789 lines
24 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title data-i18n="navigation.archive"> Arhiv</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/css/base.css">
<link rel="stylesheet" href="/static/css/navbar.css">
<link rel="stylesheet" href="/static/css/buttons.css">
<link rel="stylesheet" href="/static/css/components.css">
<link rel="stylesheet" href="/static/css/responsive.css">
<style>
/* Archive specific styles */
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
background: #f5f5f5;
font-family: Arial, sans-serif;
min-height: 100vh;
}
/* Container */
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
/* Stats Overview */
.stats-badges {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 15px;
margin-bottom: 30px;
}
.stat-badge {
background: white;
border-radius: 12px;
padding: 15px;
text-align: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
border: 1px solid #e9ecef;
transition: transform 0.3s ease;
}
.stat-badge:hover {
transform: translateY(-2px);
}
.stat-icon {
font-size: 1.5rem;
margin-bottom: 8px;
display: block;
}
.stat-number {
font-size: 1.5rem;
font-weight: bold;
color: #333;
margin-bottom: 5px;
}
.stat-label {
color: #666;
font-size: 0.75rem;
font-weight: 500;
}
/* Section */
.section {
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 20px;
margin-bottom: 30px;
}
.section-title {
font-size: 1.3rem;
font-weight: bold;
color: #333;
margin-bottom: 20px;
border-bottom: 3px solid #28a745;
padding-bottom: 10px;
}
/* Filter and Search Controls */
.controls-section {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 20px;
align-items: center;
}
.search-box {
flex: 1;
min-width: 200px;
padding: 10px 15px;
border: 2px solid #e9ecef;
border-radius: 8px;
font-size: 0.95rem;
transition: border-color 0.2s ease;
}
.search-box:focus {
outline: none;
border-color: #28a745;
}
.filter-group {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.filter-label {
font-weight: 600;
color: #333;
font-size: 0.9rem;
align-self: center;
}
.filter-btn {
background: #f8f9fa;
border: 2px solid #e9ecef;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 0.9rem;
transition: all 0.2s ease;
font-weight: 500;
color: #333;
text-decoration: none;
}
.filter-btn.active {
background: #28a745;
color: white;
border-color: #28a745;
}
.league-filter-btn {
background: #f8f9fa;
border: 2px solid #e9ecef;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 0.9rem;
transition: all 0.2s ease;
font-weight: 500;
color: #333;
text-decoration: none;
}
.league-filter-btn.active {
background: #28a745;
color: white;
border-color: #28a745;
}
.sort-select {
padding: 8px 12px;
border: 2px solid #e9ecef;
border-radius: 6px;
font-size: 0.9rem;
cursor: pointer;
background: white;
color: #333;
transition: border-color 0.2s ease;
}
.sort-select:focus {
outline: none;
border-color: #28a745;
}
/* List View Table */
.tournaments-list {
width: 100%;
border-collapse: collapse;
}
.tournaments-list thead {
background: #f8f9fa;
border-bottom: 2px solid #dee2e6;
}
.tournaments-list th {
padding: 12px 15px;
text-align: left;
font-weight: 600;
color: #333;
font-size: 0.9rem;
}
.tournaments-list th:first-child {
width: 140px;
text-align: center;
}
.tournaments-list th:nth-child(2) {
width: 120px;
text-align: center;
}
.tournaments-list th:nth-child(3) {
width: 100px;
text-align: center;
}
.tournaments-list th:nth-child(4) {
width: 100px;
text-align: center;
}
.tournaments-list th:nth-child(5) {
width: 100px;
text-align: center;
}
.tournaments-list tbody tr {
border-bottom: 1px solid #e9ecef;
transition: all 0.2s ease;
cursor: pointer;
position: relative;
background-color: #f8f9fa;
}
/* 40 targets = Purple */
.tournaments-list tbody tr[data-targets="40"] {
background: linear-gradient(90deg, rgba(147, 51, 234, 0.18) 0%, rgba(196, 77, 245, 0.12) 100%);
}
.tournaments-list tbody tr[data-targets="40"]:hover {
background: linear-gradient(90deg, rgba(147, 51, 234, 0.28) 0%, rgba(196, 77, 245, 0.22) 100%);
}
/* 20 targets = Yellow */
.tournaments-list tbody tr[data-targets="20"] {
background: linear-gradient(90deg, rgba(234, 179, 8, 0.18) 0%, rgba(250, 204, 21, 0.12) 100%);
}
.tournaments-list tbody tr[data-targets="20"]:hover {
background: linear-gradient(90deg, rgba(234, 179, 8, 0.28) 0%, rgba(250, 204, 21, 0.22) 100%);
}
/* 4 targets = Green */
.tournaments-list tbody tr[data-targets="4"] {
background: linear-gradient(90deg, rgba(34, 197, 94, 0.18) 0%, rgba(74, 222, 128, 0.12) 100%);
}
.tournaments-list tbody tr[data-targets="4"]:hover {
background: linear-gradient(90deg, rgba(34, 197, 94, 0.28) 0%, rgba(74, 222, 128, 0.22) 100%);
}
.tournaments-list td {
padding: 12px 15px;
color: #333;
font-size: 0.9rem;
}
.tournaments-list tbody tr td:first-child {
width: 140px;
font-weight: 600;
color: #2c3e50;
text-align: center;
}
.tournaments-list tbody tr td:nth-child(2) {
width: 120px;
text-align: center;
}
.tournaments-list tbody tr td:nth-child(3) {
width: 100px;
text-align: center;
}
.tournaments-list tbody tr td:nth-child(4) {
width: 100px;
text-align: center;
}
.tournaments-list tbody tr td:nth-child(5) {
width: 100px;
text-align: center;
}
.tournament-name {
font-weight: 600;
color: #28a745;
}
.tournament-type {
display: inline-block;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
text-align: center;
min-width: 80px;
}
.type-40 {
background: #c4d9f8;
color: #6b21a8;
}
.type-20 {
background: #fef08a;
color: #b45309;
}
.type-4 {
background: #86efac;
color: #166534;
}
.tournament-date {
color: #666;
font-size: 0.85rem;
display: block;
white-space: nowrap;
}
.tournament-info {
color: #666;
font-size: 0.85rem;
}
.tournament-actions {
text-align: center;
}
.view-btn {
background: #28a745;
color: white;
border: none;
padding: 6px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 0.85rem;
transition: all 0.2s ease;
text-decoration: none !important;
display: inline-block;
font-weight: 600;
}
.view-btn:hover {
background: #1e7e34;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
/* Color buttons based on tournament type */
.tournament-row[data-targets="40"] .view-btn {
background: #9333ea;
}
.tournament-row[data-targets="40"] .view-btn:hover {
background: #7e22ce;
}
.tournament-row[data-targets="20"] .view-btn {
background: #eab308;
color: #333;
}
.tournament-row[data-targets="20"] .view-btn:hover {
background: #ca8a04;
color: white;
}
.tournament-row[data-targets="4"] .view-btn {
background: #22c55e;
}
.tournament-row[data-targets="4"] .view-btn:hover {
background: #16a34a;
}
.league-row[data-targets="40"] .view-btn {
background: #9333ea;
}
.league-row[data-targets="40"] .view-btn:hover {
background: #7e22ce;
}
.league-row[data-targets="20"] .view-btn {
background: #eab308;
color: #333;
}
.league-row[data-targets="20"] .view-btn:hover {
background: #ca8a04;
color: white;
}
.league-row[data-targets="4"] .view-btn {
background: #22c55e;
}
.league-row[data-targets="4"] .view-btn:hover {
background: #16a34a;
}
.empty-state {
text-align: center;
padding: 40px 20px;
color: #999;
}
.empty-state-icon {
font-size: 3rem;
margin-bottom: 10px;
}
/* Responsive */
@media (max-width: 768px) {
.controls-section {
flex-direction: column;
}
.search-box {
width: 100%;
}
.filter-group {
width: 100%;
justify-content: flex-start;
}
.tournaments-list {
font-size: 0.85rem;
}
.tournaments-list th,
.tournaments-list td {
padding: 10px 8px;
}
.tournament-name {
max-width: 200px;
word-break: break-word;
}
}
</style>
<script src="/static/js/i18n.js"></script>
</head>
<body>
<div class="navbar">
<div class="navbar-title" data-i18n="navigation.archive">📚 Arhiv</div>
<div class="navbar-controls">
<a href="/" class="nav-btn">📺 <span data-i18n="navigation.dashboard">Dashboard</span></a>
<a href="/archive/player-analysis" class="nav-btn">👤 <span data-i18n="players.player_analysis">Player Analysis</span></a>
<a href="/archive" class="nav-btn active">📚 <span data-i18n="navigation.archive">Archive</span></a>
</div>
</div>
<div class="container">
<!-- Stats Overview -->
<div class="stats-badges">
<div class="stat-badge">
<span class="stat-icon">🎖️</span>
<div class="stat-number">{{ leagues|length if leagues else 0 }}</div>
<div class="stat-label" data-i18n="league.completed_leagues">Zaključene Lige</div>
</div>
<div class="stat-badge">
<span class="stat-icon">🏆</span>
<div class="stat-number">{{ tournaments|length if tournaments else 0 }}</div>
<div class="stat-label" data-i18n="analysis.total_tournaments">Skupaj Turnirjev</div>
</div>
<div class="stat-badge">
<span class="stat-icon">💪</span>
<div class="stat-number">{{ tournaments|selectattr('tournament_type', 'equalto', '40_targets')|list|length if tournaments else 0 }}</div>
<div class="stat-label" data-i18n="tournament_types.40_target_tournaments">40-Tarčni Turnirji</div>
</div>
<div class="stat-badge">
<span class="stat-icon"></span>
<div class="stat-number">{{ tournaments|selectattr('tournament_type', 'equalto', '20_targets')|list|length if tournaments else 0 }}</div>
<div class="stat-label" data-i18n="tournament_types.20_target_tournaments">20-Tarčni Turnirji</div>
</div>
<div class="stat-badge">
<span class="stat-icon">🎯</span>
<div class="stat-number">{{ tournaments|selectattr('tournament_type', 'equalto', '4_targets')|list|length if tournaments else 0 }}</div>
<div class="stat-label" data-i18n="tournament_types.4_target_tournaments">4-Tarčni Turnirji</div>
</div>
<div class="stat-badge">
<span class="stat-icon">👥</span>
<div class="stat-number">{{ stats.total_players if stats else 0 }}</div>
<div class="stat-label" data-i18n="players.enabled_players">Omogočeni Igralci</div>
</div>
</div>
<!-- Tournaments Section -->
{% if tournaments %}
<div class="section">
<div class="section-title">
<span data-i18n="analysis.total_tournaments">🏆 Turnirji</span>
</div>
<!-- Controls -->
<div class="controls-section">
<input type="text" id="searchInput" class="search-box" placeholder="Iskanje po datumu..." data-i18n-placeholder="general.search">
<div class="filter-group">
<span class="filter-label" data-i18n="general.filter">Filtrer:</span>
<button class="filter-btn active" data-filter="all" onclick="filterTournaments('all')" data-i18n="general.all">Vsi</button>
<button class="filter-btn" data-filter="40" onclick="filterTournaments('40')">💪 <span data-i18n="tournament_types.40_target_tournaments">40 Tarčni</span></button>
<button class="filter-btn" data-filter="20" onclick="filterTournaments('20')"><span data-i18n="tournament_types.20_target_tournaments">20 Tarčni</span></button>
<button class="filter-btn" data-filter="4" onclick="filterTournaments('4')">🎯 <span data-i18n="tournament_types.4_target_tournaments">4 Tarčni</span></button>
</div>
<select id="sortSelect" class="sort-select" onchange="sortTournaments(this.value)">
<option value="date_newest" data-i18n="general.newest_first">Najnovejši Prvo</option>
<option value="date_oldest" data-i18n="general.oldest_first">Najstarejši Prvo</option>
</select>
</div>
<!-- Tournaments Table -->
<table class="tournaments-list">
<thead>
<tr>
<th data-i18n="general.date">Datum</th>
<th data-i18n="general.type">Tip</th>
<th data-i18n="players.participants">Igralci</th>
<th data-i18n="tournament.rounds">Krogi</th>
<th data-i18n="general.action">Akcija</th>
</tr>
</thead>
<tbody id="tournamentsTableBody">
{% for tournament in tournaments %}
<tr class="tournament-row" data-targets="{{ tournament.tournament_type.split('_')[0] }}" data-date="{{ tournament.archived_at }}" data-name="{{ tournament.archived_at[:10] if tournament.archived_at != 'Unknown' else 'Unknown' }}">
<td class="date-cell">{{ tournament.archived_at[:10] if tournament.archived_at != 'Unknown' else 'Unknown' }}</td>
<td>
<span class="tournament-type {% if tournament.tournament_type == '40_targets' %}type-40{% elif tournament.tournament_type == '20_targets' %}type-20{% elif tournament.tournament_type == '4_targets' %}type-4{% endif %}">
{% if tournament.tournament_type == '40_targets' %}💪 40
{% elif tournament.tournament_type == '20_targets' %}⚡ 20
{% elif tournament.tournament_type == '4_targets' %}🎯 4
{% else %}Other{% endif %}
</span>
</td>
<td>{{ tournament.participants_count }}</td>
<td>{{ tournament.total_rounds | default('N/A') }}</td>
<td>
<a href="/archive/tournament/{{ tournament.filename }}" class="view-btn" onclick="viewTournament(event, '{{ tournament.filename }}')" data-i18n="general.view">Ogled</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div id="emptyState" class="empty-state" style="display: none;">
<div class="empty-state-icon">🏜️</div>
<p data-i18n="messages.no_tournaments_found">Nobenih turnirjev, ki bi ustrezali vašim filtrom</p>
</div>
</div>
{% endif %}
<!-- Leagues Section -->
{% if leagues %}
<div class="section">
<div class="section-title">
<span data-i18n="messages.league_championships">🎖️ Ligaška Prvenstva</span>
</div>
<!-- Controls for Leagues -->
<div class="controls-section">
<input type="text" id="leagueSearchInput" class="search-box" placeholder="Iskanje po datumu..." data-i18n-placeholder="general.search">
<div class="filter-group">
<span class="filter-label" data-i18n="general.filter">Filtrer:</span>
<button class="league-filter-btn active" data-filter="all" onclick="filterLeagues('all')" data-i18n="general.all">Vsi</button>
<button class="league-filter-btn" data-filter="40" onclick="filterLeagues('40')">💪 <span data-i18n="tournament_types.40_target_tournaments">40 Tarčni</span></button>
<button class="league-filter-btn" data-filter="20" onclick="filterLeagues('20')"><span data-i18n="tournament_types.20_target_tournaments">20 Tarčni</span></button>
<button class="league-filter-btn" data-filter="4" onclick="filterLeagues('4')">🎯 <span data-i18n="tournament_types.4_target_tournaments">4 Tarčni</span></button>
</div>
<select id="leagueSortSelect" class="sort-select" onchange="sortLeagues(this.value)">
<option value="date_newest" data-i18n="general.newest_first">Najnovejši Prvo</option>
<option value="date_oldest" data-i18n="general.oldest_first">Najstarejši Prvo</option>
</select>
</div>
<table class="tournaments-list">
<thead>
<tr>
<th data-i18n="general.date">Datum</th>
<th data-i18n="general.type">Tip</th>
<th data-i18n="players.participants">Igralci</th>
<th data-i18n="league.progress">Napredovanje</th>
<th data-i18n="general.action">Akcija</th>
</tr>
</thead>
<tbody id="leaguesTableBody">
{% for league in leagues %}
<tr class="league-row" data-targets="{{ league.tournament_type.split('_')[0] }}" data-date="{{ league.archived_at }}" data-name="{{ league.archived_at[:10] if league.archived_at != 'Unknown' else 'Unknown' }}">
<td class="date-cell">{{ league.archived_at[:10] if league.archived_at != 'Unknown' else 'Unknown' }}</td>
<td>
<span class="tournament-type {% if league.tournament_type == '40_targets' %}type-40{% elif league.tournament_type == '20_targets' %}type-20{% elif league.tournament_type == '4_targets' %}type-4{% endif %}">
{% if league.tournament_type == '40_targets' %}💪 40
{% elif league.tournament_type == '20_targets' %}⚡ 20
{% elif league.tournament_type == '4_targets' %}🎯 4
{% else %}Other{% endif %}
</span>
</td>
<td>{{ league.participants_count }}</td>
<td>{{ league.completed_tournaments }}/{{ league.total_tournaments }}</td>
<td>
<a href="/archive/league/{{ league.filename }}" class="view-btn" data-i18n="general.view">Ogled</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div id="leaguesEmptyState" class="empty-state" style="display: none;">
<div class="empty-state-icon">🏜️</div>
<p data-i18n="messages.no_tournaments_found">Nobenih turnirjev, ki bi ustrezali vašim filtrom</p>
</div>
</div>
{% endif %}
</div>
<script>
// Tournament state
let currentTournamentFilter = 'all';
let currentTournamentSort = 'date_newest';
// League state
let currentLeagueFilter = 'all';
let currentLeagueSort = 'date_newest';
// Format date from YYYY-MM-DD to DD.MM.YY
function formatDate(dateString) {
if (!dateString || dateString === 'Unknown') return 'Unknown';
const parts = dateString.split('-');
if (parts.length !== 3) return dateString;
const year = parts[0].slice(-2); // Get last 2 digits of year
const month = parts[1];
const day = parts[2];
return `${day}.${month}.${year}`;
}
// Tournament filtering
function filterTournaments(filter) {
currentTournamentFilter = filter;
updateTournamentsDisplay();
// Update button states
document.querySelectorAll('.filter-btn[data-filter]').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`.filter-btn[data-filter="${filter}"]`).classList.add('active');
}
function sortTournaments(sortOption) {
currentTournamentSort = sortOption;
updateTournamentsDisplay();
}
// League filtering
function filterLeagues(filter) {
currentLeagueFilter = filter;
updateLeaguesDisplay();
// Update button states for league-specific filter buttons
document.querySelectorAll('.league-filter-btn[data-filter]').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`.league-filter-btn[data-filter="${filter}"]`).classList.add('active');
}
function sortLeagues(sortOption) {
currentLeagueSort = sortOption;
updateLeaguesDisplay();
}
function updateTournamentsDisplay() {
const tournamentsTableBody = document.getElementById('tournamentsTableBody');
if (tournamentsTableBody) {
updateTable(tournamentsTableBody, 'emptyState', currentTournamentFilter, currentTournamentSort, 'searchInput');
}
}
function updateLeaguesDisplay() {
const leaguesTableBody = document.getElementById('leaguesTableBody');
if (leaguesTableBody) {
updateTable(leaguesTableBody, 'leaguesEmptyState', currentLeagueFilter, currentLeagueSort, 'leagueSearchInput');
}
}
function updateTable(tableBody, emptyStateId, filter, sort, searchInputId) {
const searchInput = document.getElementById(searchInputId);
const searchText = searchInput?.value?.toLowerCase() || '';
// Get all current rows in the table
const allRows = Array.from(tableBody.querySelectorAll('tr'));
// Track visible rows
let visibleRowsArray = [];
// Show/hide rows based on filter and search
allRows.forEach(row => {
const targets = row.dataset.targets;
const name = row.dataset.name?.toLowerCase() || '';
const matchesFilter = filter === 'all' || targets === filter;
const matchesSearch = name.includes(searchText);
if (matchesFilter && matchesSearch) {
row.style.display = '';
visibleRowsArray.push(row);
} else {
row.style.display = 'none';
}
});
// Sort visible rows
visibleRowsArray.sort((a, b) => {
switch(sort) {
case 'date_newest':
return new Date(b.dataset.date) - new Date(a.dataset.date);
case 'date_oldest':
return new Date(a.dataset.date) - new Date(b.dataset.date);
default:
return 0;
}
});
// Reorder visible rows in DOM
visibleRowsArray.forEach(row => {
tableBody.appendChild(row);
});
// Show/hide empty state
const emptyState = document.getElementById(emptyStateId);
if (emptyState) {
if (visibleRowsArray.length === 0) {
emptyState.style.display = 'block';
} else {
emptyState.style.display = 'none';
}
}
}
function viewTournament(event, filename) {
if (event && event.preventDefault) {
event.preventDefault();
}
window.location.href = `/archive/tournament/${filename}`;
}
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', function() {
// Format all date cells
const dateCells = document.querySelectorAll('.date-cell');
dateCells.forEach(cell => {
const dateText = cell.textContent.trim();
cell.textContent = formatDate(dateText);
});
// Add search input event listeners
const searchInput = document.getElementById('searchInput');
if (searchInput) {
searchInput.addEventListener('input', updateTournamentsDisplay);
}
const leagueSearchInput = document.getElementById('leagueSearchInput');
if (leagueSearchInput) {
leagueSearchInput.addEventListener('input', updateLeaguesDisplay);
}
// Initialize display
updateTournamentsDisplay();
updateLeaguesDisplay();
});
</script>
</body>
</html>