Liga krog3

This commit is contained in:
bl3kunja-FW
2026-01-17 09:36:27 +01:00
parent 27e8b31ae0
commit 13c7bd3239
13 changed files with 2027 additions and 46 deletions
+1 -1
View File
@@ -10,4 +10,4 @@ class Config:
SECRET_KEY = os.getenv('SECRET_KEY', 'your-secret-key-for-sessions') SECRET_KEY = os.getenv('SECRET_KEY', 'your-secret-key-for-sessions')
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true' DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
HOST = os.getenv('HOST', '0.0.0.0') HOST = os.getenv('HOST', '0.0.0.0')
PORT = int(os.getenv('PORT', 5000)) PORT = int(os.getenv('PORT', 5001))
+2 -1
View File
@@ -131,7 +131,8 @@ class Tournament:
'name': player['name'], 'name': player['name'],
'targets': targets, 'targets': targets,
'total_score': 0, 'total_score': 0,
'completed': False 'completed': False,
'joker_selected': False # Track if joker was selected in calculator
} }
return results return results
+2 -2
View File
@@ -9,7 +9,7 @@
}, },
"display_options": { "display_options": {
"show_titles": true, "show_titles": true,
"title_size": 1.2, "title_size": 1.4,
"target_number_size": 1.4 "target_number_size": 1.7
} }
} }
@@ -0,0 +1,134 @@
{
"league": {
"league_id": "league_20251115_093831",
"created_at": "2025-11-15T09:38:31.193555",
"tournament_type": "20_targets",
"total_tournaments": 5,
"current_tournament": 0,
"participants": {
"1": {
"name": "Domen Pleterski",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"5": {
"name": "Jože Verhnjak",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"7": {
"name": "Branko Pokeržnik",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"9": {
"name": "Janez Božič",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"10": {
"name": "Mitja Čeh",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"11": {
"name": "Rado Kefer",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"14": {
"name": "Karli Proje",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"15": {
"name": "Jan Pleterski",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"16": {
"name": "Silvo Poročnik",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"17": {
"name": "Dušan Onuk",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"18": {
"name": "Matjaž Pleterski",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"22": {
"name": "Doris Fesel",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"24": {
"name": "Jože Verdinek",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"50": {
"name": "Vid Ravnjak",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"51": {
"name": "Robi Ovčar",
"joker_used": false,
"tournament_results": [],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
}
},
"completed_tournaments": [],
"league_finished": false
},
"archived_at": "2025-11-15T09:39:06.974580"
}
+457
View File
@@ -0,0 +1,457 @@
{
"league_id": "league_20251115_094741",
"created_at": "2025-11-15T09:47:41.711914",
"tournament_type": "20_targets",
"total_tournaments": 5,
"current_tournament": 3,
"participants": {
"1": {
"name": "Domen Pleterski",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 320,
"tens_count": 3,
"participated": true
},
{
"tournament": 2,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
},
{
"tournament": 3,
"score": 320,
"tens_count": 2,
"participated": true
}
],
"total_score": 640,
"final_score": 0,
"tournaments_participated": 0
},
"5": {
"name": "Jože Verhnjak",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 295,
"tens_count": 2,
"participated": true
},
{
"tournament": 2,
"score": 293,
"tens_count": 3,
"participated": true
},
{
"tournament": 3,
"score": 293,
"tens_count": 2,
"participated": true
}
],
"total_score": 881,
"final_score": 0,
"tournaments_participated": 0
},
"7": {
"name": "Branko Pokeržnik",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 316,
"tens_count": 1,
"participated": true
},
{
"tournament": 2,
"score": 332,
"tens_count": 3,
"participated": true
},
{
"tournament": 3,
"score": 318,
"tens_count": 1,
"participated": true
}
],
"total_score": 966,
"final_score": 0,
"tournaments_participated": 0
},
"9": {
"name": "Janez Božič",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 264,
"tens_count": 2,
"participated": true
},
{
"tournament": 2,
"score": 276,
"tens_count": 0,
"participated": true
},
{
"tournament": 3,
"score": 261,
"tens_count": 1,
"participated": true
}
],
"total_score": 801,
"final_score": 0,
"tournaments_participated": 0
},
"10": {
"name": "Mitja Čeh",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 329,
"tens_count": 1,
"participated": true
},
{
"tournament": 2,
"score": 312,
"tens_count": 4,
"participated": true
},
{
"tournament": 3,
"score": 307,
"tens_count": 2,
"participated": true
}
],
"total_score": 948,
"final_score": 0,
"tournaments_participated": 0
},
"11": {
"name": "Rado Kefer",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 275,
"tens_count": 0,
"participated": true
},
{
"tournament": 2,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
},
{
"tournament": 3,
"score": 314,
"tens_count": 3,
"participated": true
}
],
"total_score": 589,
"final_score": 0,
"tournaments_participated": 0
},
"14": {
"name": "Karli Proje",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
},
{
"tournament": 2,
"score": 0,
"tens_count": 0,
"participated": true
},
{
"tournament": 3,
"score": 0,
"tens_count": 0,
"participated": true
}
],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"15": {
"name": "Jan Pleterski",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 269,
"tens_count": 1,
"participated": true
},
{
"tournament": 2,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
},
{
"tournament": 3,
"score": 267,
"tens_count": 1,
"participated": true
}
],
"total_score": 536,
"final_score": 0,
"tournaments_participated": 0
},
"16": {
"name": "Silvo Poročnik",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 293,
"tens_count": 3,
"participated": true
},
{
"tournament": 2,
"score": 278,
"tens_count": 3,
"participated": true
},
{
"tournament": 3,
"score": 282,
"tens_count": 3,
"participated": true
}
],
"total_score": 853,
"final_score": 0,
"tournaments_participated": 0
},
"17": {
"name": "Dušan Onuk",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 313,
"tens_count": 4,
"participated": true
},
{
"tournament": 2,
"score": 325,
"tens_count": 2,
"participated": true
},
{
"tournament": 3,
"score": 192,
"tens_count": 3,
"participated": true
}
],
"total_score": 830,
"final_score": 0,
"tournaments_participated": 0
},
"18": {
"name": "Matjaž Pleterski",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 280,
"tens_count": 2,
"participated": true
},
{
"tournament": 2,
"score": 276,
"tens_count": 4,
"participated": true
},
{
"tournament": 3,
"score": 307,
"tens_count": 0,
"participated": true
}
],
"total_score": 863,
"final_score": 0,
"tournaments_participated": 0
},
"22": {
"name": "Doris Fesel",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
},
{
"tournament": 2,
"score": 0,
"tens_count": 0,
"participated": true
},
{
"tournament": 3,
"score": 0,
"tens_count": 0,
"participated": true
}
],
"total_score": 0,
"final_score": 0,
"tournaments_participated": 0
},
"24": {
"name": "Jože Verdinek",
"joker_used": false,
"tournament_results": [
{
"tournament": 1,
"score": 311,
"tens_count": 5,
"participated": true
},
{
"tournament": 2,
"score": 315,
"tens_count": 5,
"participated": true
},
{
"tournament": 3,
"score": 312,
"tens_count": 2,
"participated": true
}
],
"total_score": 938,
"final_score": 0,
"tournaments_participated": 0
},
"50": {
"name": "Vid Ravnjak",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 302,
"tens_count": 6,
"participated": true
},
{
"tournament": 2,
"score": 309,
"tens_count": 4,
"participated": true
},
{
"tournament": 3,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
}
],
"total_score": 611,
"final_score": 0,
"tournaments_participated": 0
},
"51": {
"name": "Robi Ovčar",
"joker_used": true,
"tournament_results": [
{
"tournament": 1,
"score": 269,
"tens_count": 1,
"participated": true
},
{
"tournament": 2,
"score": 0,
"tens_count": 0,
"participated": false,
"joker": true
},
{
"tournament": 3,
"score": 265,
"tens_count": 1,
"participated": true
}
],
"total_score": 534,
"final_score": 0,
"tournaments_participated": 0
}
},
"completed_tournaments": [
{
"tournament_number": 1,
"tournament_type": "20_targets",
"finished_at": "2025-11-15T11:50:43.358782",
"results_summary": {
"participants": 15,
"shots_per_participant": 40,
"total_shots": 600,
"format_description": "20 Targets (2 shots each)"
}
},
{
"tournament_number": 2,
"tournament_type": "20_targets",
"finished_at": "2025-12-13T12:13:29.550924",
"results_summary": {
"participants": 12,
"shots_per_participant": 40,
"total_shots": 480,
"format_description": "20 Targets (2 shots each)"
}
},
{
"tournament_number": 3,
"tournament_type": "20_targets",
"finished_at": "2026-01-10T11:34:15.800129",
"results_summary": {
"participants": 14,
"shots_per_participant": 40,
"total_shots": 560,
"format_description": "20 Targets (2 shots each)"
}
}
],
"league_finished": false
}
+45 -35
View File
@@ -8,17 +8,17 @@
{ {
"id": 2, "id": 2,
"name": "Nik Pleterski", "name": "Nik Pleterski",
"enabled": true "enabled": false
}, },
{ {
"id": 3, "id": 3,
"name": "Ivan Tandler", "name": "Ivan Tandler",
"enabled": true "enabled": false
}, },
{ {
"id": 4, "id": 4,
"name": "Mateja Pleterski", "name": "Mateja Pleterski",
"enabled": true "enabled": false
}, },
{ {
"id": 5, "id": 5,
@@ -28,7 +28,7 @@
{ {
"id": 6, "id": 6,
"name": "Mateja Senica", "name": "Mateja Senica",
"enabled": true "enabled": false
}, },
{ {
"id": 7, "id": 7,
@@ -38,7 +38,7 @@
{ {
"id": 8, "id": 8,
"name": "Franc Žigart", "name": "Franc Žigart",
"enabled": true "enabled": false
}, },
{ {
"id": 9, "id": 9,
@@ -58,12 +58,12 @@
{ {
"id": 12, "id": 12,
"name": "Matej Kvasnik", "name": "Matej Kvasnik",
"enabled": true "enabled": false
}, },
{ {
"id": 13, "id": 13,
"name": "Angelca Mrak", "name": "Angelca Mrak",
"enabled": true "enabled": false
}, },
{ {
"id": 14, "id": 14,
@@ -93,17 +93,17 @@
{ {
"id": 19, "id": 19,
"name": "Franc Rizmal", "name": "Franc Rizmal",
"enabled": true "enabled": false
}, },
{ {
"id": 20, "id": 20,
"name": "Jože Preglav", "name": "Jože Preglav",
"enabled": true "enabled": false
}, },
{ {
"id": 21, "id": 21,
"name": "Marko Blimen", "name": "Marko Blimen",
"enabled": true "enabled": false
}, },
{ {
"id": 22, "id": 22,
@@ -113,7 +113,7 @@
{ {
"id": 23, "id": 23,
"name": "Robi Krautberger", "name": "Robi Krautberger",
"enabled": true "enabled": false
}, },
{ {
"id": 24, "id": 24,
@@ -123,126 +123,136 @@
{ {
"id": 25, "id": 25,
"name": "Andrej Herman", "name": "Andrej Herman",
"enabled": true "enabled": false
}, },
{ {
"id": 26, "id": 26,
"name": "Jakob Herman", "name": "Jakob Herman",
"enabled": true "enabled": false
}, },
{ {
"id": 27, "id": 27,
"name": "Janez Mrak", "name": "Janez Mrak",
"enabled": true "enabled": false
}, },
{ {
"id": 28, "id": 28,
"name": "Anže Kolar", "name": "Anže Kolar",
"enabled": true "enabled": false
}, },
{ {
"id": 29, "id": 29,
"name": "Alen Kolar", "name": "Alen Kolar",
"enabled": true "enabled": false
}, },
{ {
"id": 30, "id": 30,
"name": "Maja Hirtl", "name": "Maja Hirtl",
"enabled": true "enabled": false
}, },
{ {
"id": 31, "id": 31,
"name": "Dejan Kučnik", "name": "Dejan Kučnik",
"enabled": true "enabled": false
}, },
{ {
"id": 32, "id": 32,
"name": "David Strniša", "name": "David Strniša",
"enabled": true "enabled": false
}, },
{ {
"id": 33, "id": 33,
"name": "Namir Uzunović", "name": "Namir Uzunović",
"enabled": true "enabled": false
}, },
{ {
"id": 34, "id": 34,
"name": "Jože Planinšec", "name": "Jože Planinšec",
"enabled": true "enabled": false
}, },
{ {
"id": 35, "id": 35,
"name": "Vanja Kolar", "name": "Vanja Kolar",
"enabled": true "enabled": false
}, },
{ {
"id": 36, "id": 36,
"name": "Klara Wankmuller", "name": "Klara Wankmuller",
"enabled": true "enabled": false
}, },
{ {
"id": 37, "id": 37,
"name": "Milan Stramec", "name": "Milan Stramec",
"enabled": true "enabled": false
}, },
{ {
"id": 38, "id": 38,
"name": "Bojan Sudar", "name": "Bojan Sudar",
"enabled": true "enabled": false
}, },
{ {
"id": 39, "id": 39,
"name": "Tia Sudar", "name": "Tia Sudar",
"enabled": true "enabled": false
}, },
{ {
"id": 40, "id": 40,
"name": "Jaka Cvar", "name": "Jaka Cvar",
"enabled": true "enabled": false
}, },
{ {
"id": 41, "id": 41,
"name": "Tadej Štruc", "name": "Tadej Štruc",
"enabled": true "enabled": false
}, },
{ {
"id": 42, "id": 42,
"name": "Jure Glaser", "name": "Jure Glaser",
"enabled": true "enabled": false
}, },
{ {
"id": 43, "id": 43,
"name": "Marko Pokržnik", "name": "Marko Pokržnik",
"enabled": true "enabled": false
}, },
{ {
"id": 44, "id": 44,
"name": "Anka Kačnik", "name": "Anka Kačnik",
"enabled": true "enabled": false
}, },
{ {
"id": 45, "id": 45,
"name": "Lidija Blimen", "name": "Lidija Blimen",
"enabled": true "enabled": false
}, },
{ {
"id": 46, "id": 46,
"name": "Tijana Štumpfl", "name": "Tijana Štumpfl",
"enabled": true "enabled": false
}, },
{ {
"id": 47, "id": 47,
"name": "Ljuba Mršak", "name": "Ljuba Mršak",
"enabled": true "enabled": false
}, },
{ {
"id": 48, "id": 48,
"name": "Janja Salcman", "name": "Janja Salcman",
"enabled": true "enabled": false
}, },
{ {
"id": 49, "id": 49,
"name": "Jolanda Verhnjak", "name": "Jolanda Verhnjak",
"enabled": false
},
{
"id": 50,
"name": "Vid Ravnjak",
"enabled": true
},
{
"id": 51,
"name": "Robi Ovčar",
"enabled": true "enabled": true
} }
] ]
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -95,7 +95,8 @@
"created": "Created", "created": "Created",
"tournaments": "Tournaments", "tournaments": "Tournaments",
"league_tournament": "League Tournament", "league_tournament": "League Tournament",
"finished": "Finished" "finished": "Finished",
"view_current_results": "View Current Standings"
}, },
"tournament_types": { "tournament_types": {
"4_targets": "4 Targets", "4_targets": "4 Targets",
+2 -1
View File
@@ -96,7 +96,8 @@
"league_completed": "Liga Zaključena", "league_completed": "Liga Zaključena",
"section_title": "Sekcija", "section_title": "Sekcija",
"finished": "Zaključeno", "finished": "Zaključeno",
"targets": "Število Tarč" "targets": "Število Tarč",
"view_current_results": "Oglej Trenutne Rezultate"
}, },
"tournament_types": { "tournament_types": {
"4_targets": "4 Tarče", "4_targets": "4 Tarče",
+2
View File
@@ -1100,6 +1100,8 @@
tournamentCells += '<td><span class="tournament-score joker">🃏</span></td>'; tournamentCells += '<td><span class="tournament-score joker">🃏</span></td>';
} else { } else {
const score = result.score; const score = result.score;
const tensCount = result.tens_count || 0;
// Check if this specific tournament index should be excluded // Check if this specific tournament index should be excluded
const isExcluded = best4Logic.excludedIndices.includes(participatedTournamentIndex) && best4Logic.allScores.length > 4; const isExcluded = best4Logic.excludedIndices.includes(participatedTournamentIndex) && best4Logic.allScores.length > 4;
const scoreClass = isExcluded ? 'excluded' : 'counted'; const scoreClass = isExcluded ? 'excluded' : 'counted';
+109
View File
@@ -236,6 +236,44 @@
font-weight: bold; font-weight: bold;
} }
.joker-checkbox-wrapper {
margin-top: 8px;
}
.joker-label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
padding: 6px 12px;
background: #fff3cd;
border: 2px solid #ffc107;
border-radius: 8px;
transition: all 0.2s ease;
}
.joker-label:hover {
background: #ffc107;
border-color: #ff9800;
}
.joker-checkbox-calc {
cursor: pointer;
width: 18px;
height: 18px;
}
.joker-checkbox-calc:disabled {
cursor: not-allowed;
opacity: 0.6;
}
.joker-text {
font-size: 0.9rem;
font-weight: 600;
color: #856404;
}
.participant-status { .participant-status {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -670,6 +708,19 @@
<div class="participant-info"> <div class="participant-info">
<div class="participant-name">{{ participant.name }}</div> <div class="participant-name">{{ participant.name }}</div>
<div class="participant-id">ID: {{ player_id }}</div> <div class="participant-id">ID: {{ player_id }}</div>
{% if league_state %}
<div class="joker-checkbox-wrapper" onclick="event.stopPropagation()">
<label class="joker-label">
<input type="checkbox"
class="joker-checkbox-calc"
id="joker-calc-{{ player_id }}"
data-player-id="{{ player_id }}"
{% if league_state.participants[player_id|string] and league_state.participants[player_id|string].joker_used %}disabled checked{% endif %}
onchange="handleJokerChange({{ player_id }})">
<span class="joker-text">🃏 <span data-i18n="league.joker_used">Joker</span></span>
</label>
</div>
{% endif %}
</div> </div>
<div class="participant-status"> <div class="participant-status">
<div class="score-display"> <div class="score-display">
@@ -1338,6 +1389,49 @@
} }
} }
// Handle joker checkbox change
function handleJokerChange(playerId) {
const checkbox = document.getElementById(`joker-calc-${playerId}`);
const isChecked = checkbox.checked;
// If checked, warn user that all scores will be set to zero
if (isChecked) {
if (confirm('Marking this player as using their Joker will set all their scores to zero. Continue?')) {
// Set all scores to zero
const participant = results.participants[playerId];
if (participant && participant.targets) {
Object.keys(participant.targets).forEach(targetId => {
const target = participant.targets[targetId];
Object.keys(target).forEach(shotKey => {
if (shotKey.startsWith('shot')) {
target[shotKey] = 0;
}
});
});
}
participant.total_score = 0;
participant.completed = true; // Mark as completed since joker is used
participant.joker_selected = true; // Mark joker as selected in results
// Update UI
updateParticipantTotal(playerId);
updateParticipantStatus(playerId);
updateParticipantTens(playerId);
updateOverallProgress();
updateOverallTens();
// Disable the checkbox so it can't be unchecked
checkbox.disabled = true;
// Save the change
savePlayerData(playerId);
} else {
// User cancelled, uncheck the box
checkbox.checked = false;
}
}
}
// Keyboard shortcuts // Keyboard shortcuts
document.addEventListener('keydown', function(event) { document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 's') { if (event.ctrlKey && event.key === 's') {
@@ -1361,6 +1455,21 @@
updateParticipantTens(parseInt(playerId)); updateParticipantTens(parseInt(playerId));
}); });
// Initialize joker checkboxes for league tournaments
{% if league_state %}
const leagueState = {{ league_state | tojson | safe }};
Object.keys(results.participants).forEach(playerId => {
const checkbox = document.getElementById(`joker-calc-${playerId}`);
if (checkbox && leagueState.participants && leagueState.participants[playerId]) {
const participant = leagueState.participants[playerId];
if (participant.joker_used) {
checkbox.checked = true;
checkbox.disabled = true;
}
}
});
{% endif %}
updateOverallProgress(); updateOverallProgress();
updateOverallTens(); updateOverallTens();
+25 -2
View File
@@ -767,14 +767,22 @@
font-weight: bold; font-weight: bold;
transition: all 0.2s ease; transition: all 0.2s ease;
min-width: 200px; min-width: 200px;
text-decoration: none; text-decoration: none !important;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
display: inline-block;
} }
.action-btn:hover { .action-btn:hover {
background: #1e7e34; background: #1e7e34;
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3); box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3);
text-decoration: none !important;
}
.action-btn:focus,
.action-btn:active,
.action-btn:visited {
text-decoration: none !important;
} }
.action-btn:disabled { .action-btn:disabled {
@@ -800,6 +808,16 @@
background: #c82333; background: #c82333;
} }
.action-btn.info {
background: #007bff;
border-color: #0056b3;
}
.action-btn.info:hover {
background: #0056b3;
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.4);
}
.player-count { .player-count {
margin: 20px 0; margin: 20px 0;
font-size: 1.2rem; font-size: 1.2rem;
@@ -1606,7 +1624,7 @@
<input type="checkbox" <input type="checkbox"
class="joker-checkbox" class="joker-checkbox"
id="joker_{{ player_id }}" id="joker_{{ player_id }}"
{% if participant.joker_used %}disabled{% endif %} {% if participant.joker_used %}disabled checked{% endif %}
data-player-id="{{ player_id }}"> data-player-id="{{ player_id }}">
</div> </div>
{% endfor %} {% endfor %}
@@ -1614,6 +1632,11 @@
</div> </div>
<div class="action-buttons"> <div class="action-buttons">
{% if league_state.completed_tournaments|length > 0 %}
<a href="/results" class="action-btn info">
📊 <span data-i18n="tournament.view_current_results">View Current Standings</span>
</a>
{% endif %}
<button class="action-btn success" onclick="startNextTournament()"> <button class="action-btn success" onclick="startNextTournament()">
🚀 <span data-i18n="league.start_tournament_number">Začni Turnir</span> {{ league_state.current_tournament + 1 }} 🚀 <span data-i18n="league.start_tournament_number">Začni Turnir</span> {{ league_state.current_tournament + 1 }}
</button> </button>
+2 -1
View File
@@ -1,6 +1,5 @@
""" """
TV_APP V1.0.0 - Tournament and League Management System TV_APP V1.0.0 - Tournament and League Management System
Flask web application for managing tournaments with multi-camera streaming
""" """
from flask import Flask, render_template, request, redirect, jsonify, session from flask import Flask, render_template, request, redirect, jsonify, session
@@ -1594,6 +1593,8 @@ def finish_tournament():
'participated': False, 'participated': False,
'joker': True 'joker': True
}) })
# Mark joker as used for this player
participant['joker_used'] = True
# Calculate total shots correctly for any tournament type # Calculate total shots correctly for any tournament type
tournament_type = results.get('tournament_type', '20_targets') tournament_type = results.get('tournament_type', '20_targets')