Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 988cb53de1 | |||
| d0a468b740 | |||
| 024ab24ceb | |||
| 30d480f053 | |||
| d6f8ff78e1 | |||
| baeaad0d49 | |||
| d0bbf7bdce | |||
| 13c7bd3239 | |||
| 27e8b31ae0 | |||
| aa01f4136d |
+213
-12
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
TV_APP V1.0.0 - Tournament and League Management System
|
TV_APP V1.0.1 - Tournament and League Management System
|
||||||
Flask web application for managing tournaments with multi-camera streaming
|
Flask web application for managing tournaments with multi-camera streaming
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -20,7 +20,8 @@ from app.utils import (
|
|||||||
from app.storage import (
|
from app.storage import (
|
||||||
SettingsStorage, PlayerStorage, TournamentStorage,
|
SettingsStorage, PlayerStorage, TournamentStorage,
|
||||||
ResultsStorage, LeagueStorage, ArchiveStorage,
|
ResultsStorage, LeagueStorage, ArchiveStorage,
|
||||||
TOURNAMENT_FILE, RESULTS_FILE, LEAGUE_FILE
|
TOURNAMENT_FILE, RESULTS_FILE, LEAGUE_FILE,
|
||||||
|
ARCHIVE_DIR, LEAGUE_ARCHIVE_DIR
|
||||||
)
|
)
|
||||||
from app.models import Tournament, Scoring, RoundManager
|
from app.models import Tournament, Scoring, RoundManager
|
||||||
|
|
||||||
@@ -44,10 +45,6 @@ STREAMS = [
|
|||||||
SUPPORTED_LANGUAGES = ['sl', 'en']
|
SUPPORTED_LANGUAGES = ['sl', 'en']
|
||||||
DEFAULT_LANGUAGE = 'sl'
|
DEFAULT_LANGUAGE = 'sl'
|
||||||
|
|
||||||
# Data file paths (organized in data directory)
|
|
||||||
ARCHIVE_DIR = 'data/tournament_archives'
|
|
||||||
LEAGUE_ARCHIVE_DIR = 'data/league_archives'
|
|
||||||
|
|
||||||
# Convenience function wrappers that delegate to storage classes
|
# Convenience function wrappers that delegate to storage classes
|
||||||
def load_settings():
|
def load_settings():
|
||||||
return SettingsStorage.load_settings()
|
return SettingsStorage.load_settings()
|
||||||
@@ -79,6 +76,7 @@ def load_results():
|
|||||||
def save_results(results_data):
|
def save_results(results_data):
|
||||||
return ResultsStorage.save_results(results_data)
|
return ResultsStorage.save_results(results_data)
|
||||||
|
|
||||||
|
|
||||||
def archive_tournament(tournament_data, results_data):
|
def archive_tournament(tournament_data, results_data):
|
||||||
return ArchiveStorage.archive_tournament(tournament_data, results_data)
|
return ArchiveStorage.archive_tournament(tournament_data, results_data)
|
||||||
|
|
||||||
@@ -223,6 +221,9 @@ def analyze_player_performance(player_id, archives_data):
|
|||||||
'best_tournament_score': 0,
|
'best_tournament_score': 0,
|
||||||
'worst_tournament_score': float('inf'),
|
'worst_tournament_score': float('inf'),
|
||||||
'average_tournament_score': 0,
|
'average_tournament_score': 0,
|
||||||
|
'best_4_targets_score': 0,
|
||||||
|
'best_20_targets_score': 0,
|
||||||
|
'best_40_targets_score': 0,
|
||||||
'total_shots_fired': 0,
|
'total_shots_fired': 0,
|
||||||
'performance_trend': [],
|
'performance_trend': [],
|
||||||
'tournament_history': [],
|
'tournament_history': [],
|
||||||
@@ -264,6 +265,17 @@ def analyze_player_performance(player_id, archives_data):
|
|||||||
|
|
||||||
player_stats['total_shots_fired'] += shots_in_tournament
|
player_stats['total_shots_fired'] += shots_in_tournament
|
||||||
|
|
||||||
|
# Track format-specific best scores
|
||||||
|
if tournament_type == '4_targets':
|
||||||
|
if score > player_stats['best_4_targets_score']:
|
||||||
|
player_stats['best_4_targets_score'] = score
|
||||||
|
elif tournament_type == '20_targets':
|
||||||
|
if score > player_stats['best_20_targets_score']:
|
||||||
|
player_stats['best_20_targets_score'] = score
|
||||||
|
elif tournament_type == '40_targets':
|
||||||
|
if score > player_stats['best_40_targets_score']:
|
||||||
|
player_stats['best_40_targets_score'] = score
|
||||||
|
|
||||||
# Calculate and aggregate shot accuracy
|
# Calculate and aggregate shot accuracy
|
||||||
if tournament_type in player_stats['shot_accuracy']:
|
if tournament_type in player_stats['shot_accuracy']:
|
||||||
shot_accuracy = calculate_shot_accuracy(participant)
|
shot_accuracy = calculate_shot_accuracy(participant)
|
||||||
@@ -512,6 +524,43 @@ def view_player_stats(player_id):
|
|||||||
|
|
||||||
# Enhanced API endpoints for the modern archive system
|
# Enhanced API endpoints for the modern archive system
|
||||||
|
|
||||||
|
@app.route('/api/archive/tournament/<filename>/standings')
|
||||||
|
def api_tournament_standings(filename):
|
||||||
|
filepath = os.path.join(ARCHIVE_DIR, filename)
|
||||||
|
data = load_archive_file(filepath)
|
||||||
|
if not data:
|
||||||
|
return jsonify({'error': 'not found'}), 404
|
||||||
|
results_data = data.get('results', {})
|
||||||
|
tournament_type = data.get('tournament', {}).get('tournament_type', '20_targets')
|
||||||
|
participants = []
|
||||||
|
for player_id, p in results_data.get('participants', {}).items():
|
||||||
|
targets = p.get('targets', {})
|
||||||
|
tens = calculate_tens_from_targets(targets)
|
||||||
|
participants.append({'name': p['name'], 'total_score': p['total_score'], 'tens_count': tens})
|
||||||
|
participants.sort(key=lambda x: (x['total_score'], x['tens_count']), reverse=True)
|
||||||
|
for i, p in enumerate(participants):
|
||||||
|
p['rank'] = i + 1
|
||||||
|
return jsonify({
|
||||||
|
'kind': 'tournament',
|
||||||
|
'tournament_type': tournament_type,
|
||||||
|
'created_at': results_data.get('created_at', ''),
|
||||||
|
'archived_at': data.get('archived_at', ''),
|
||||||
|
'participants': participants
|
||||||
|
})
|
||||||
|
|
||||||
|
@app.route('/api/archive/league/<filename>/standings')
|
||||||
|
def api_league_standings(filename):
|
||||||
|
filepath = os.path.join(LEAGUE_ARCHIVE_DIR, filename)
|
||||||
|
data = load_archive_file(filepath)
|
||||||
|
if not data:
|
||||||
|
return jsonify({'error': 'not found'}), 404
|
||||||
|
league_data = data.get('league', {})
|
||||||
|
tournament_type = league_data.get('tournament_type', '20_targets')
|
||||||
|
calculate_league_final_scores(league_data)
|
||||||
|
participants = get_league_final_rankings(league_data)
|
||||||
|
rows = [{'rank': p['rank'], 'name': p['name'], 'final_score': p['final_score'], 'total_score': p['total_score'], 'tournaments_participated': p['tournaments_participated']} for p in participants]
|
||||||
|
return jsonify({'kind': 'league', 'tournament_type': tournament_type, 'archived_at': data.get('archived_at', ''), 'participants': rows})
|
||||||
|
|
||||||
@app.route('/api/archive/stats', methods=['GET'])
|
@app.route('/api/archive/stats', methods=['GET'])
|
||||||
def api_get_archive_stats():
|
def api_get_archive_stats():
|
||||||
"""API endpoint to get archive overview statistics"""
|
"""API endpoint to get archive overview statistics"""
|
||||||
@@ -571,6 +620,10 @@ def api_get_players_with_stats():
|
|||||||
for player in all_players:
|
for player in all_players:
|
||||||
player_stats = analyze_player_performance(player['id'], archives_data)
|
player_stats = analyze_player_performance(player['id'], archives_data)
|
||||||
|
|
||||||
|
total_tens = sum(
|
||||||
|
player_stats['shot_accuracy'][t]['tens']
|
||||||
|
for t in player_stats['shot_accuracy']
|
||||||
|
)
|
||||||
players_with_stats.append({
|
players_with_stats.append({
|
||||||
'id': player['id'],
|
'id': player['id'],
|
||||||
'name': player['name'],
|
'name': player['name'],
|
||||||
@@ -581,7 +634,8 @@ def api_get_players_with_stats():
|
|||||||
'best_tournament_score': player_stats['best_tournament_score'],
|
'best_tournament_score': player_stats['best_tournament_score'],
|
||||||
'average_tournament_score': player_stats['average_tournament_score'],
|
'average_tournament_score': player_stats['average_tournament_score'],
|
||||||
'total_shots_fired': player_stats['total_shots_fired'],
|
'total_shots_fired': player_stats['total_shots_fired'],
|
||||||
'performance_trend': player_stats['tournament_scores'][-8:] if len(player_stats['tournament_scores']) >= 8 else player_stats['tournament_scores'] # Last 8 tournaments for mini chart
|
'total_tens': total_tens,
|
||||||
|
'performance_trend': player_stats['tournament_scores'][-8:] if len(player_stats['tournament_scores']) >= 8 else player_stats['tournament_scores']
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -629,11 +683,21 @@ def view_archived_tournament(filename):
|
|||||||
for i, participant in enumerate(participants):
|
for i, participant in enumerate(participants):
|
||||||
participant['rank'] = i + 1
|
participant['rank'] = i + 1
|
||||||
|
|
||||||
# Use the existing results display template but with archived data
|
# Sanitize tournament_data - convert to JSON-serializable format
|
||||||
|
sanitized_tournament = {
|
||||||
|
'tournament_id': str(tournament_data.get('tournament_id', '')),
|
||||||
|
'tournament_type': str(tournament_data.get('tournament_type', '20_targets')),
|
||||||
|
'total_rounds': tournament_data.get('total_rounds', 1),
|
||||||
|
'created_at': str(tournament_data.get('created_at', ''))
|
||||||
|
}
|
||||||
|
|
||||||
|
embed = request.args.get('embed') == '1'
|
||||||
return render_template('results_display.html',
|
return render_template('results_display.html',
|
||||||
|
tournament=sanitized_tournament,
|
||||||
results=results_data,
|
results=results_data,
|
||||||
participants=participants,
|
participants=participants,
|
||||||
archived=True,
|
archived=True,
|
||||||
|
embed=embed,
|
||||||
archive_info={
|
archive_info={
|
||||||
'filename': filename,
|
'filename': filename,
|
||||||
'archived_at': data.get('archived_at'),
|
'archived_at': data.get('archived_at'),
|
||||||
@@ -658,11 +722,12 @@ def view_archived_league(filename):
|
|||||||
calculate_league_final_scores(league_data)
|
calculate_league_final_scores(league_data)
|
||||||
participants = get_league_final_rankings(league_data)
|
participants = get_league_final_rankings(league_data)
|
||||||
|
|
||||||
# Use the existing league results display template but with archived data
|
embed = request.args.get('embed') == '1'
|
||||||
return render_template('league_scoreboard_display.html',
|
return render_template('league_scoreboard_display.html',
|
||||||
league=league_data,
|
league=league_data,
|
||||||
participants=participants,
|
participants=participants,
|
||||||
archived=True,
|
archived=True,
|
||||||
|
embed=embed,
|
||||||
archive_info={
|
archive_info={
|
||||||
'filename': filename,
|
'filename': filename,
|
||||||
'archived_at': data.get('archived_at'),
|
'archived_at': data.get('archived_at'),
|
||||||
@@ -987,7 +1052,6 @@ def tournament():
|
|||||||
players_data = load_players()
|
players_data = load_players()
|
||||||
tournament_state = load_tournament_state()
|
tournament_state = load_tournament_state()
|
||||||
league_state = load_league_state()
|
league_state = load_league_state()
|
||||||
|
|
||||||
return render_template('tournament.html',
|
return render_template('tournament.html',
|
||||||
players=players_data['players'],
|
players=players_data['players'],
|
||||||
tournament_state=tournament_state,
|
tournament_state=tournament_state,
|
||||||
@@ -1073,7 +1137,21 @@ def results_display():
|
|||||||
translations=get_translations(),
|
translations=get_translations(),
|
||||||
current_language=get_current_language())
|
current_language=get_current_language())
|
||||||
|
|
||||||
# Priority 1.5: Check if current results are from a finished league (even if league state was archived)
|
# Priority 1.5: Check if results contain league_data (from league preview/combiner)
|
||||||
|
elif results and results.get('league_data'):
|
||||||
|
league_data = results.get('league_data')
|
||||||
|
calculate_league_final_scores(league_data)
|
||||||
|
participants = get_league_final_rankings(league_data)
|
||||||
|
|
||||||
|
return render_template('league_scoreboard_display.html',
|
||||||
|
league=league_data,
|
||||||
|
participants=participants,
|
||||||
|
results=None,
|
||||||
|
preview_mode=True,
|
||||||
|
translations=get_translations(),
|
||||||
|
current_language=get_current_language())
|
||||||
|
|
||||||
|
# Priority 1.6: Check if current results are from a finished league (even if league state was archived)
|
||||||
elif results and results.get('league_tournament_number'):
|
elif results and results.get('league_tournament_number'):
|
||||||
# This is a league tournament result, but league state was archived
|
# This is a league tournament result, but league state was archived
|
||||||
# Try to find the archived league data
|
# Try to find the archived league data
|
||||||
@@ -1126,7 +1204,15 @@ def results_display():
|
|||||||
for i, participant in enumerate(participants):
|
for i, participant in enumerate(participants):
|
||||||
participant['rank'] = i + 1
|
participant['rank'] = i + 1
|
||||||
|
|
||||||
|
# Create sanitized tournament data for template
|
||||||
|
sanitized_tournament = {
|
||||||
|
'tournament_id': str(results.get('tournament_id', '')),
|
||||||
|
'tournament_type': str(results.get('tournament_type', '20_targets')),
|
||||||
|
'total_rounds': results.get('total_rounds', 1)
|
||||||
|
}
|
||||||
|
|
||||||
return render_template('results_display.html',
|
return render_template('results_display.html',
|
||||||
|
tournament=sanitized_tournament,
|
||||||
results=results,
|
results=results,
|
||||||
participants=participants,
|
participants=participants,
|
||||||
league=None,
|
league=None,
|
||||||
@@ -1455,6 +1541,25 @@ def reset_tournament():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/tournament/cancel', methods=['POST'])
|
||||||
|
def cancel_league_tournament():
|
||||||
|
"""Cancel the current tournament within a league, rolling back the tournament counter"""
|
||||||
|
try:
|
||||||
|
if os.path.exists(TOURNAMENT_FILE):
|
||||||
|
os.remove(TOURNAMENT_FILE)
|
||||||
|
if os.path.exists(RESULTS_FILE):
|
||||||
|
os.remove(RESULTS_FILE)
|
||||||
|
# Roll back league's current_tournament counter
|
||||||
|
league_state = load_league_state()
|
||||||
|
if league_state and league_state.get('current_tournament', 1) > 1:
|
||||||
|
league_state['current_tournament'] -= 1
|
||||||
|
save_league_state(league_state)
|
||||||
|
return jsonify({'status': 'success'})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||||
|
|
||||||
|
|
||||||
# RESULTS API Routes (Updated)
|
# RESULTS API Routes (Updated)
|
||||||
@app.route('/api/results/participant/<int:player_id>', methods=['POST'])
|
@app.route('/api/results/participant/<int:player_id>', methods=['POST'])
|
||||||
def update_participant_scores(player_id):
|
def update_participant_scores(player_id):
|
||||||
@@ -1566,6 +1671,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')
|
||||||
@@ -1684,6 +1791,100 @@ def get_league():
|
|||||||
else:
|
else:
|
||||||
return jsonify({'status': 'error', 'message': 'No league found'}), 404
|
return jsonify({'status': 'error', 'message': 'No league found'}), 404
|
||||||
|
|
||||||
|
@app.route('/api/dashboard/state', methods=['GET'])
|
||||||
|
def api_dashboard_state():
|
||||||
|
"""Get current dashboard state for polling updates (TV display sync)"""
|
||||||
|
tournament_state = load_tournament_state()
|
||||||
|
league_state = load_league_state()
|
||||||
|
results = load_results()
|
||||||
|
|
||||||
|
tournament_finished = results.get('tournament_finished', False) if results else False
|
||||||
|
league_finished = league_state.get('league_finished', False) if league_state else False
|
||||||
|
|
||||||
|
response_data = {
|
||||||
|
'tournament_active': tournament_state is not None,
|
||||||
|
'current_round': None,
|
||||||
|
'total_rounds': None,
|
||||||
|
'league_active': league_state is not None,
|
||||||
|
'league_tournament': None,
|
||||||
|
'league_total': None,
|
||||||
|
'player_names': [],
|
||||||
|
'tournament_finished': tournament_finished,
|
||||||
|
'league_finished': league_finished,
|
||||||
|
}
|
||||||
|
|
||||||
|
if tournament_state:
|
||||||
|
response_data['current_round'] = tournament_state.get('current_round', 1)
|
||||||
|
response_data['total_rounds'] = tournament_state.get('total_rounds', 1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
current_round_data = get_current_round_data()
|
||||||
|
if current_round_data and isinstance(current_round_data, dict):
|
||||||
|
players = current_round_data.get('players', [])
|
||||||
|
if isinstance(players, list):
|
||||||
|
response_data['player_names'] = [
|
||||||
|
str(p.get('name', 'Unknown')) if isinstance(p, dict) else 'Unknown'
|
||||||
|
for p in players if p
|
||||||
|
]
|
||||||
|
except Exception as e:
|
||||||
|
# Log error but don't fail - player_names will remain empty list
|
||||||
|
print(f"Error getting player names for dashboard state: {e}")
|
||||||
|
response_data['player_names'] = []
|
||||||
|
|
||||||
|
if league_state:
|
||||||
|
response_data['league_tournament'] = league_state.get('current_tournament', 1)
|
||||||
|
response_data['league_total'] = league_state.get('total_tournaments', 6)
|
||||||
|
|
||||||
|
settings = load_settings()
|
||||||
|
response_data['tv_view'] = settings.get('tv_view', 'cameras')
|
||||||
|
response_data['tv_url'] = settings.get('tv_url')
|
||||||
|
|
||||||
|
response_data['event_active'] = False
|
||||||
|
response_data['event_player_names'] = []
|
||||||
|
|
||||||
|
# When no active tournament/results, expose latest archive filename so clients can redirect correctly
|
||||||
|
response_data['archive_filename'] = None
|
||||||
|
response_data['league_archive_filename'] = None
|
||||||
|
if not tournament_state and not results:
|
||||||
|
try:
|
||||||
|
archive_files = sorted(
|
||||||
|
glob.glob(os.path.join(ARCHIVE_DIR, 'tournament_*.json')),
|
||||||
|
key=os.path.getmtime, reverse=True
|
||||||
|
)
|
||||||
|
if archive_files:
|
||||||
|
response_data['archive_filename'] = os.path.basename(archive_files[0])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
league_archive_files = sorted(
|
||||||
|
glob.glob(os.path.join(LEAGUE_ARCHIVE_DIR, 'league_*.json')),
|
||||||
|
key=os.path.getmtime, reverse=True
|
||||||
|
)
|
||||||
|
if league_archive_files:
|
||||||
|
response_data['league_archive_filename'] = os.path.basename(league_archive_files[0])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return jsonify(response_data)
|
||||||
|
|
||||||
|
@app.route('/api/tv/view', methods=['POST'])
|
||||||
|
def set_tv_view():
|
||||||
|
"""Set the desired TV display view (cameras or draft)"""
|
||||||
|
data = request.get_json() or {}
|
||||||
|
view = data.get('view', 'cameras')
|
||||||
|
if view not in ('cameras', 'draft', 'results'):
|
||||||
|
return jsonify({'status': 'error', 'message': 'Invalid view'}), 400
|
||||||
|
settings = load_settings()
|
||||||
|
settings['tv_view'] = view
|
||||||
|
# Optional explicit URL for the TV to navigate to (e.g. a specific league archive)
|
||||||
|
tv_url = data.get('tv_url')
|
||||||
|
if tv_url:
|
||||||
|
settings['tv_url'] = tv_url
|
||||||
|
elif view == 'cameras':
|
||||||
|
settings.pop('tv_url', None)
|
||||||
|
save_settings(settings)
|
||||||
|
return jsonify({'status': 'success', 'tv_view': view})
|
||||||
|
|
||||||
# Add this route to your Flask app (around line 850, with the other mobile routes)
|
# Add this route to your Flask app (around line 850, with the other mobile routes)
|
||||||
|
|
||||||
@app.route('/mobile/remote')
|
@app.route('/mobile/remote')
|
||||||
@@ -2340,4 +2541,4 @@ def set_language(language):
|
|||||||
}), 400
|
}), 400
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
app.run(host='0.0.0.0', port=4000, debug=True)
|
||||||
+1
-1
@@ -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
@@ -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
|
||||||
|
|||||||
+12
-8
@@ -8,14 +8,18 @@ import os
|
|||||||
import glob
|
import glob
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Base directory anchored to this file's location (project root), so paths work
|
||||||
|
# regardless of the current working directory when the app is launched.
|
||||||
|
_BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
# File paths - organized in data directory
|
# File paths - organized in data directory
|
||||||
SETTINGS_FILE = 'data/camera_settings.json'
|
SETTINGS_FILE = os.path.join(_BASE_DIR, 'data', 'camera_settings.json')
|
||||||
PLAYERS_FILE = 'data/players.json'
|
PLAYERS_FILE = os.path.join(_BASE_DIR, 'data', 'players.json')
|
||||||
TOURNAMENT_FILE = 'data/tournament_state.json'
|
TOURNAMENT_FILE = os.path.join(_BASE_DIR, 'data', 'tournament_state.json')
|
||||||
RESULTS_FILE = 'data/tournament_results.json'
|
RESULTS_FILE = os.path.join(_BASE_DIR, 'data', 'tournament_results.json')
|
||||||
LEAGUE_FILE = 'data/league_state.json'
|
LEAGUE_FILE = os.path.join(_BASE_DIR, 'data', 'league_state.json')
|
||||||
ARCHIVE_DIR = 'data/tournament_archives'
|
ARCHIVE_DIR = os.path.join(_BASE_DIR, 'data', 'tournament_archives')
|
||||||
LEAGUE_ARCHIVE_DIR = 'data/league_archives'
|
LEAGUE_ARCHIVE_DIR = os.path.join(_BASE_DIR, 'data', 'league_archives')
|
||||||
|
|
||||||
# Default settings
|
# Default settings
|
||||||
DEFAULT_SETTINGS = {
|
DEFAULT_SETTINGS = {
|
||||||
@@ -40,7 +44,7 @@ class FileStorage:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _ensure_directory(directory):
|
def _ensure_directory(directory):
|
||||||
"""Ensure directory exists"""
|
"""Ensure directory exists"""
|
||||||
if not os.path.exists(directory):
|
if directory and not os.path.exists(directory):
|
||||||
os.makedirs(directory)
|
os.makedirs(directory)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
},
|
},
|
||||||
"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
|
||||||
}
|
},
|
||||||
|
"tv_view": "cameras"
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,275 +0,0 @@
|
|||||||
{
|
|
||||||
"league": {
|
|
||||||
"league_id": "league_20251109_144611",
|
|
||||||
"created_at": "2025-11-09T14:46:11.803719",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"total_tournaments": 5,
|
|
||||||
"current_tournament": 0,
|
|
||||||
"participants": {
|
|
||||||
"2": {
|
|
||||||
"name": "Nik Pleterski",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"6": {
|
|
||||||
"name": "Mateja Senica",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"10": {
|
|
||||||
"name": "Mitja \u010ceh",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"14": {
|
|
||||||
"name": "Karli Proje",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"16": {
|
|
||||||
"name": "Silvo Poro\u010dnik",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"18": {
|
|
||||||
"name": "Matja\u017e Pleterski",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"23": {
|
|
||||||
"name": "Robi Krautberger",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"24": {
|
|
||||||
"name": "Jo\u017ee Verdinek",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"30": {
|
|
||||||
"name": "Maja Hirtl",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"33": {
|
|
||||||
"name": "Namir Uzunovi\u0107",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"34": {
|
|
||||||
"name": "Jo\u017ee Planin\u0161ec",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"35": {
|
|
||||||
"name": "Vanja Kolar",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"36": {
|
|
||||||
"name": "Klara Wankmuller",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"37": {
|
|
||||||
"name": "Milan Stramec",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"39": {
|
|
||||||
"name": "Tia Sudar",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"41": {
|
|
||||||
"name": "Tadej \u0160truc",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"42": {
|
|
||||||
"name": "Jure Glaser",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"43": {
|
|
||||||
"name": "Marko Pokr\u017enik",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"joker_used": false,
|
|
||||||
"tournament_results": [],
|
|
||||||
"total_score": 0,
|
|
||||||
"final_score": 0,
|
|
||||||
"tournaments_participated": 0,
|
|
||||||
"excluded_tournament": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"completed_tournaments": [],
|
|
||||||
"league_finished": false
|
|
||||||
},
|
|
||||||
"archived_at": "2025-11-09T14:46:18.477787"
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
+51
-41
@@ -3,32 +3,32 @@
|
|||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "Domen Pleterski",
|
"name": "Domen Pleterski",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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,
|
||||||
"name": "Jože Verhnjak",
|
"name": "Jože Verhnjak",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"name": "Mateja Senica",
|
"name": "Mateja Senica",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
@@ -38,27 +38,27 @@
|
|||||||
{
|
{
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"name": "Franc Žigart",
|
"name": "Franc Žigart",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 9,
|
"id": 9,
|
||||||
"name": "Janez Božič",
|
"name": "Janez Božič",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 10,
|
"id": 10,
|
||||||
"name": "Mitja Čeh",
|
"name": "Mitja Čeh",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 11,
|
"id": 11,
|
||||||
"name": "Rado Kefer",
|
"name": "Rado Kefer",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"name": "Matej Kvasnik",
|
"name": "Matej Kvasnik",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 13,
|
"id": 13,
|
||||||
@@ -68,57 +68,57 @@
|
|||||||
{
|
{
|
||||||
"id": 14,
|
"id": 14,
|
||||||
"name": "Karli Proje",
|
"name": "Karli Proje",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 15,
|
"id": 15,
|
||||||
"name": "Jan Pleterski",
|
"name": "Jan Pleterski",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 16,
|
"id": 16,
|
||||||
"name": "Silvo Poročnik",
|
"name": "Silvo Poročnik",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 17,
|
"id": 17,
|
||||||
"name": "Dušan Onuk",
|
"name": "Dušan Onuk",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 18,
|
"id": 18,
|
||||||
"name": "Matjaž Pleterski",
|
"name": "Matjaž Pleterski",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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,
|
||||||
"name": "Doris Fesel",
|
"name": "Doris Fesel",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 23,
|
"id": 23,
|
||||||
"name": "Robi Krautberger",
|
"name": "Robi Krautberger",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 24,
|
"id": 24,
|
||||||
"name": "Jože Verdinek",
|
"name": "Jože Verdinek",
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 25,
|
"id": 25,
|
||||||
@@ -128,12 +128,12 @@
|
|||||||
{
|
{
|
||||||
"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,
|
||||||
@@ -148,12 +148,12 @@
|
|||||||
{
|
{
|
||||||
"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,
|
||||||
@@ -163,27 +163,27 @@
|
|||||||
{
|
{
|
||||||
"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,
|
||||||
@@ -193,27 +193,27 @@
|
|||||||
{
|
{
|
||||||
"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,
|
||||||
@@ -223,27 +223,37 @@
|
|||||||
{
|
{
|
||||||
"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": true
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 50,
|
||||||
|
"name": "Vid Ravnjak",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 51,
|
||||||
|
"name": "Robi Ovčar",
|
||||||
|
"enabled": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-08-30T13:09:30.384521",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-08-30T13:09:30.384521",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 0,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 142,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 0,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 180,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 179,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 102,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 72,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 161,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 124,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 167,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 122,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 174,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 144,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 0,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 71,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 180,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 172,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 155,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-08-30T13:09:30.386527",
|
|
||||||
"finished_at": "2025-08-30T15:33:42.405404"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-08-30T15:33:42.405434"
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-09-08T19:19:14.422360",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-09-08T19:19:14.422360",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 129,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 111,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 97,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 119,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 110,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 134,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 101,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 79,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 101,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 110,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 89,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 107,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 107,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 95,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 118,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 82,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 90,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-09-08T19:19:14.422540",
|
|
||||||
"finished_at": "2025-09-08T19:19:26.929175"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-09-08T19:19:26.929203"
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-09-08T19:23:24.597390",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-09-08T19:23:24.597390",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 67,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 85,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 106,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 78,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 104,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 99,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 112,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 106,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 116,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 125,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 81,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 95,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 110,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 101,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 77,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 81,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 83,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-09-08T19:23:24.597575",
|
|
||||||
"finished_at": "2025-09-08T19:23:34.271264"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-09-08T19:23:34.271291"
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-09-08T19:26:24.708355",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-09-08T19:26:24.708355",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 98,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 94,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 98,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 89,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 107,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 115,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 87,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 89,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 97,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 92,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 84,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 106,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 87,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 90,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 126,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 84,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 68,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-09-08T19:26:24.708574",
|
|
||||||
"finished_at": "2025-09-08T19:26:31.871139"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-09-08T19:26:31.871173"
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-09-08T19:27:18.397859",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-09-08T19:27:18.397859",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 85,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 69,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 80,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 118,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 118,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 93,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 81,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 86,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 104,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 83,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 96,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 89,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 94,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 116,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 115,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 85,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-09-08T19:27:18.398031",
|
|
||||||
"finished_at": "2025-09-08T19:27:27.631332"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-09-08T19:27:27.631357"
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-09-08T19:39:27.077222",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-09-08T19:39:27.077222",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 108,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 110,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 89,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 102,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 85,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 112,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 82,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 110,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 74,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 91,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 108,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 98,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 107,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 7
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 117,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 76,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 102,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-09-08T19:39:27.077445",
|
|
||||||
"finished_at": "2025-09-08T19:39:44.030962"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-09-08T19:39:44.030989"
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
{
|
|
||||||
"tournament": {
|
|
||||||
"rounds": [
|
|
||||||
{
|
|
||||||
"round_number": 1,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 12,
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 11,
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "pending"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 2,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 44,
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 48,
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 9,
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 45,
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"round_number": 3,
|
|
||||||
"players": [
|
|
||||||
{
|
|
||||||
"id": 47,
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 46,
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 20,
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 17,
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 15,
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 49,
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"status": "waiting"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"created_at": "2025-09-08T20:15:56.266521",
|
|
||||||
"total_players": 18,
|
|
||||||
"total_rounds": 3,
|
|
||||||
"current_round": 1,
|
|
||||||
"tournament_type": "4_targets"
|
|
||||||
},
|
|
||||||
"results": {
|
|
||||||
"tournament_id": "2025-09-08T20:15:56.266521",
|
|
||||||
"tournament_type": "4_targets",
|
|
||||||
"participants": {
|
|
||||||
"12": {
|
|
||||||
"name": "Matej Kvasnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 81,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"21": {
|
|
||||||
"name": "Marko Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 57,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "Domen Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 78,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "Mateja Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 95,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "Jo\u017ee Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 97,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "Rado Kefer",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 108,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"44": {
|
|
||||||
"name": "Anka Ka\u010dnik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 129,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"48": {
|
|
||||||
"name": "Janja Salcman",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 85,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "Ivan Tandler",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 106,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "Branko Poker\u017enik",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "Janez Bo\u017ei\u010d",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 6,
|
|
||||||
"shot4": 8,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 121,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"45": {
|
|
||||||
"name": "Lidija Blimen",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 9,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 8
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 1,
|
|
||||||
"shot5": 1
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 97,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"47": {
|
|
||||||
"name": "Ljuba Mr\u0161ak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 1,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 10,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 88,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"46": {
|
|
||||||
"name": "Tijana \u0160tumpfl",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 3,
|
|
||||||
"shot5": 3
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 6
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 3,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 9,
|
|
||||||
"shot5": 7
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 100,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"name": "Jo\u017ee Preglav",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 4,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 6,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 10,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 7,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 9,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 5,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 115,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"name": "Du\u0161an Onuk",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 3,
|
|
||||||
"shot3": 3,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 10,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 10,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 9
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 97,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"name": "Jan Pleterski",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 0,
|
|
||||||
"shot3": 2,
|
|
||||||
"shot4": 0,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 7,
|
|
||||||
"shot3": 8,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 9
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 2,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 2,
|
|
||||||
"shot5": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 9,
|
|
||||||
"shot2": 5,
|
|
||||||
"shot3": 1,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 87,
|
|
||||||
"completed": true
|
|
||||||
},
|
|
||||||
"49": {
|
|
||||||
"name": "Jolanda Verhnjak",
|
|
||||||
"targets": {
|
|
||||||
"1": {
|
|
||||||
"shot1": 8,
|
|
||||||
"shot2": 2,
|
|
||||||
"shot3": 7,
|
|
||||||
"shot4": 5,
|
|
||||||
"shot5": 0
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"shot1": 1,
|
|
||||||
"shot2": 8,
|
|
||||||
"shot3": 0,
|
|
||||||
"shot4": 4,
|
|
||||||
"shot5": 10
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"shot1": 0,
|
|
||||||
"shot2": 4,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 7,
|
|
||||||
"shot5": 4
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"shot1": 5,
|
|
||||||
"shot2": 6,
|
|
||||||
"shot3": 4,
|
|
||||||
"shot4": 6,
|
|
||||||
"shot5": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"total_score": 85,
|
|
||||||
"completed": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tournament_finished": true,
|
|
||||||
"created_at": "2025-09-08T20:15:56.266721",
|
|
||||||
"finished_at": "2025-09-08T20:16:01.584621"
|
|
||||||
},
|
|
||||||
"archived_at": "2025-09-08T20:16:01.584647"
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+43
-4
@@ -18,10 +18,12 @@
|
|||||||
"all": "All",
|
"all": "All",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
|
"select": "Select",
|
||||||
"select_all": "Select All",
|
"select_all": "Select All",
|
||||||
"enable_selected": "Enable Selected",
|
"enable_selected": "Enable Selected",
|
||||||
"disable_selected": "Disable Selected",
|
"disable_selected": "Disable Selected",
|
||||||
"print": "Print",
|
"print": "Print",
|
||||||
|
"export": "Export JSON",
|
||||||
"visible": "Visible",
|
"visible": "Visible",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
@@ -75,6 +77,7 @@
|
|||||||
"tournament_management": "Tournament Management",
|
"tournament_management": "Tournament Management",
|
||||||
"tournament_type": "Tournament Type",
|
"tournament_type": "Tournament Type",
|
||||||
"participants": "Participants",
|
"participants": "Participants",
|
||||||
|
"rounds": "Rounds",
|
||||||
"start_tournament": "Start Tournament",
|
"start_tournament": "Start Tournament",
|
||||||
"reset_tournament": "Reset Tournament",
|
"reset_tournament": "Reset Tournament",
|
||||||
"tournament_setup": "Tournament Setup",
|
"tournament_setup": "Tournament Setup",
|
||||||
@@ -94,7 +97,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",
|
||||||
@@ -127,7 +131,7 @@
|
|||||||
"final_rankings": "Final Rankings",
|
"final_rankings": "Final Rankings",
|
||||||
"final_rankings_best_4_of_5": "Final Rankings - Best 4 of 5 Tournaments",
|
"final_rankings_best_4_of_5": "Final Rankings - Best 4 of 5 Tournaments",
|
||||||
"best_4_of_5": "Best 4 of 5 Tournaments",
|
"best_4_of_5": "Best 4 of 5 Tournaments",
|
||||||
"league_champions": "League Champions",
|
"league_champions": "🎖️ League Champions",
|
||||||
"participant": "Participant",
|
"participant": "Participant",
|
||||||
"tournament_scores": "Tournament Scores",
|
"tournament_scores": "Tournament Scores",
|
||||||
"final": "Final",
|
"final": "Final",
|
||||||
@@ -140,6 +144,33 @@
|
|||||||
"highest_score": "Highest Score",
|
"highest_score": "Highest Score",
|
||||||
"average_final": "Average Final",
|
"average_final": "Average Final",
|
||||||
"5_tournament_league": "5 Tournament League - Best 4 Count",
|
"5_tournament_league": "5 Tournament League - Best 4 Count",
|
||||||
|
"combine_leagues": "Combine Leagues",
|
||||||
|
"combine_mode": "Combine Leagues",
|
||||||
|
"convert_mode": "Convert Tournaments to League",
|
||||||
|
"upload_league_files": "Upload League JSON Files",
|
||||||
|
"upload_tournament_files": "Upload Tournament JSON Files",
|
||||||
|
"combine_leagues_desc": "Upload multiple league JSON files to combine them into a single results table.",
|
||||||
|
"convert_tournaments_desc": "Upload 1-5 tournament JSON files to create a league. You can upload partial leagues as tournaments complete. Final scoring uses best 4 results when all 5 are uploaded.",
|
||||||
|
"click_browse": "Click to browse",
|
||||||
|
"drag_drop_files": "or drag and drop league JSON files here",
|
||||||
|
"supports_multiple": "Supports multiple file selection",
|
||||||
|
"clear_all": "Clear All",
|
||||||
|
"combine_preview": "Combine & Preview",
|
||||||
|
"convert_to_league": "Convert to League",
|
||||||
|
"valid_league": "Valid League",
|
||||||
|
"valid_tournament": "Valid Tournament",
|
||||||
|
"participants": "participants",
|
||||||
|
"tournaments": "tournaments",
|
||||||
|
"invalid_format": "Invalid file format",
|
||||||
|
"select_mode": "Select Mode",
|
||||||
|
"start_over": "Start Over",
|
||||||
|
"export_combined_results": "Export Combined Results",
|
||||||
|
"combined_league_info": "Combined League Information",
|
||||||
|
"uploaded_files": "Uploaded Files",
|
||||||
|
"remove": "Remove",
|
||||||
|
"type": "Type",
|
||||||
|
"failed_parse_json": "Failed to parse JSON",
|
||||||
|
"invalid_tournament_format": "Invalid tournament file format",
|
||||||
"joker_used_badge": "Joker Used",
|
"joker_used_badge": "Joker Used",
|
||||||
"search_players_placeholder": "Search players by name...",
|
"search_players_placeholder": "Search players by name...",
|
||||||
"no_players_found": "No players found matching your search criteria.",
|
"no_players_found": "No players found matching your search criteria.",
|
||||||
@@ -166,7 +197,9 @@
|
|||||||
"system": "System",
|
"system": "System",
|
||||||
"camera": "Camera",
|
"camera": "Camera",
|
||||||
"tournaments": "Tournaments",
|
"tournaments": "Tournaments",
|
||||||
"results.most_tens": "Most 10s"
|
"results.most_tens": "Most 10s",
|
||||||
|
"progress": "Progress",
|
||||||
|
"combine_leagues": "Combine Leagues"
|
||||||
},
|
},
|
||||||
"results": {
|
"results": {
|
||||||
"results": "Results",
|
"results": "Results",
|
||||||
@@ -182,12 +215,15 @@
|
|||||||
"average_score": "Average Score",
|
"average_score": "Average Score",
|
||||||
"highest_score": "Highest Score",
|
"highest_score": "Highest Score",
|
||||||
"worst_score": "Worst Score",
|
"worst_score": "Worst Score",
|
||||||
|
"hit_rate": "Hit Rate",
|
||||||
|
"most_common": "Most Common",
|
||||||
"completed": "Completed",
|
"completed": "Completed",
|
||||||
"position": "Position",
|
"position": "Position",
|
||||||
"points": "Points",
|
"points": "Points",
|
||||||
"top_3_winners": "Top 3 Winners"
|
"top_3_winners": "Top 3 Winners"
|
||||||
},
|
},
|
||||||
"players": {
|
"players": {
|
||||||
|
"participants": "Participants",
|
||||||
"player": "Player",
|
"player": "Player",
|
||||||
"players": "Players",
|
"players": "Players",
|
||||||
"player_name": "Player Name",
|
"player_name": "Player Name",
|
||||||
@@ -270,7 +306,10 @@
|
|||||||
"finish_tournament_button": "Finish Tournament & Show Results",
|
"finish_tournament_button": "Finish Tournament & Show Results",
|
||||||
"enter_scores_40_targets": "Enter scores for each participant (40 targets, 2 shots each). Score 0 = miss.",
|
"enter_scores_40_targets": "Enter scores for each participant (40 targets, 2 shots each). Score 0 = miss.",
|
||||||
"enter_scores_20_targets": "Enter scores for each participant (20 targets, 2 shots each). Score 0 = miss.",
|
"enter_scores_20_targets": "Enter scores for each participant (20 targets, 2 shots each). Score 0 = miss.",
|
||||||
"enter_scores_4_targets": "Enter scores for each participant (4 targets, 5 shots each). Score 0 = miss."
|
"enter_scores_4_targets": "Enter scores for each participant (4 targets, 5 shots each). Score 0 = miss.",
|
||||||
|
"fill_zeros": "Fill Zeros",
|
||||||
|
"clear_all_scores": "Clear all scores",
|
||||||
|
"fill_empty_with_zero": "Fill empty entries with 0"
|
||||||
},
|
},
|
||||||
"mobile": {
|
"mobile": {
|
||||||
"mobile_streams": "Mobile Streams",
|
"mobile_streams": "Mobile Streams",
|
||||||
|
|||||||
+33
-5
@@ -18,10 +18,12 @@
|
|||||||
"all": "Vse",
|
"all": "Vse",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"actions": "Dejanja",
|
"actions": "Dejanja",
|
||||||
|
"select": "Izberi",
|
||||||
"select_all": "Izberi Vse",
|
"select_all": "Izberi Vse",
|
||||||
"enable_selected": "Omogoči Izbrane",
|
"enable_selected": "Omogoči Izbrane",
|
||||||
"disable_selected": "Onemogoči Izbrane",
|
"disable_selected": "Onemogoči Izbrane",
|
||||||
"print": "Natisni",
|
"print": "Natisni",
|
||||||
|
"export": "Izvozi JSON",
|
||||||
"visible": "Vidni",
|
"visible": "Vidni",
|
||||||
"date": "Datum",
|
"date": "Datum",
|
||||||
"view": "Oglej",
|
"view": "Oglej",
|
||||||
@@ -74,6 +76,7 @@
|
|||||||
"tournament_management": "Upravljanje Turnirja",
|
"tournament_management": "Upravljanje Turnirja",
|
||||||
"tournament_type": "Tip Turnirja",
|
"tournament_type": "Tip Turnirja",
|
||||||
"participants": "Udeleženci",
|
"participants": "Udeleženci",
|
||||||
|
"rounds": "Krogi",
|
||||||
"start_tournament": "Začni Turnir",
|
"start_tournament": "Začni Turnir",
|
||||||
"reset_tournament": "Ponastavi Turnir",
|
"reset_tournament": "Ponastavi Turnir",
|
||||||
"tournament_setup": "Nastavitev Turnirja",
|
"tournament_setup": "Nastavitev Turnirja",
|
||||||
@@ -95,7 +98,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",
|
||||||
@@ -132,7 +136,7 @@
|
|||||||
"league_complete_info": "Vsi turnirji načrtovani. Zaključi trenutnega za končne rezultate.",
|
"league_complete_info": "Vsi turnirji načrtovani. Zaključi trenutnega za končne rezultate.",
|
||||||
"view_league_results": "Oglej si Rezultate Lige",
|
"view_league_results": "Oglej si Rezultate Lige",
|
||||||
"score_tournament": "Točkuj Turnir",
|
"score_tournament": "Točkuj Turnir",
|
||||||
"league_champions": "Ligaški Prvaki",
|
"league_champions": "🎖️ Ligaški Prvaki",
|
||||||
"participant": "Udeleženec",
|
"participant": "Udeleženec",
|
||||||
"tournament_scores": "Rezultati Turnirjev",
|
"tournament_scores": "Rezultati Turnirjev",
|
||||||
"final": "Končni",
|
"final": "Končni",
|
||||||
@@ -171,8 +175,26 @@
|
|||||||
"system": "Sistem",
|
"system": "Sistem",
|
||||||
"camera": "Kamera",
|
"camera": "Kamera",
|
||||||
"tournaments": "Turnirji",
|
"tournaments": "Turnirji",
|
||||||
"results.most_tens": "Največ Desetk"
|
"results.most_tens": "Največ Desetk",
|
||||||
|
"progress": "Stanje",
|
||||||
|
"combine_leagues": "Združi Lige",
|
||||||
|
"combine_mode": "Združi Lige",
|
||||||
|
"convert_mode": "Pretvori Turnirje v Ligo",
|
||||||
|
"upload_league_files": "Naloži Datoteke Lig",
|
||||||
|
"upload_tournament_files": "Naloži Datoteke Turnirjev",
|
||||||
|
"combine_leagues_desc": "Naloži več datotek lig JSON, da jih združiš v eno tabelo rezultatov.",
|
||||||
|
"convert_tournaments_desc": "Naloži 1-5 datotek turnirjev JSON za ustvarjanje lige. Lahko naložiš delne lige ko turnirji napredujejo. Končno točkovanje uporablja najboljše 4 rezultate, ko so vseh 5 naloženih.",
|
||||||
|
"click_browse": "Klikni za brskanje",
|
||||||
|
"drag_drop_files": "ali povleci in spusti datoteke JSON lig tukaj",
|
||||||
|
"supports_multiple": "Podpira izbiro več datotek",
|
||||||
|
"combine_preview": "Združi in Predoglej",
|
||||||
|
"convert_to_league": "Pretvori v Ligo",
|
||||||
|
"valid_league": "Veljavna Liga",
|
||||||
|
"valid_tournament": "Veljaven Turnir",
|
||||||
|
"participants": "udeleženci",
|
||||||
|
"invalid_format": "Neveljavna oblika datoteke",
|
||||||
|
"select_mode": "Izberi Način",
|
||||||
|
"start_over": "Začni Znova"
|
||||||
},
|
},
|
||||||
"results": {
|
"results": {
|
||||||
"results": "Rezultati",
|
"results": "Rezultati",
|
||||||
@@ -188,12 +210,15 @@
|
|||||||
"average_score": "Povprečni Rezultat",
|
"average_score": "Povprečni Rezultat",
|
||||||
"highest_score": "Najvišji Rezultat",
|
"highest_score": "Najvišji Rezultat",
|
||||||
"worst_score": "Najslabši Rezultat",
|
"worst_score": "Najslabši Rezultat",
|
||||||
|
"hit_rate": "Stopnja Uspešnosti",
|
||||||
|
"most_common": "Najpogostejši",
|
||||||
"completed": "Zaključeno",
|
"completed": "Zaključeno",
|
||||||
"position": "Uvrstitev",
|
"position": "Uvrstitev",
|
||||||
"points": "Točke",
|
"points": "Točke",
|
||||||
"top_3_winners": "Top 3 Zmagovalci"
|
"top_3_winners": "Top 3 Zmagovalci"
|
||||||
},
|
},
|
||||||
"players": {
|
"players": {
|
||||||
|
"participants": "Udeleženci",
|
||||||
"player": "Igralec",
|
"player": "Igralec",
|
||||||
"players": "Igralci",
|
"players": "Igralci",
|
||||||
"player_name": "Ime Igralca",
|
"player_name": "Ime Igralca",
|
||||||
@@ -276,7 +301,10 @@
|
|||||||
"finish_tournament_button": "Zaključi Turnir & Prikaži Rezultate",
|
"finish_tournament_button": "Zaključi Turnir & Prikaži Rezultate",
|
||||||
"enter_scores_40_targets": "Vnesi rezultate za vsakega udeleženca (40 tarč, 2 strela na tarčo). Rezultat 0 = zgrešeno.",
|
"enter_scores_40_targets": "Vnesi rezultate za vsakega udeleženca (40 tarč, 2 strela na tarčo). Rezultat 0 = zgrešeno.",
|
||||||
"enter_scores_20_targets": "Vnesi rezultate za vsakega udeleženca (20 tarč, 2 strela na tarčo). Rezultat 0 = zgrešeno.",
|
"enter_scores_20_targets": "Vnesi rezultate za vsakega udeleženca (20 tarč, 2 strela na tarčo). Rezultat 0 = zgrešeno.",
|
||||||
"enter_scores_4_targets": "Vnesi rezultate za vsakega udeleženca (4 tarče, 5 strelov na tarčo). Rezultat 0 = zgrešeno."
|
"enter_scores_4_targets": "Vnesi rezultate za vsakega udeleženca (4 tarče, 5 strelov na tarčo). Rezultat 0 = zgrešeno.",
|
||||||
|
"fill_zeros": "Napolni Ničle",
|
||||||
|
"clear_all_scores": "Počisti vse rezultate",
|
||||||
|
"fill_empty_with_zero": "Napolni prazne vnose z 0"
|
||||||
},
|
},
|
||||||
"mobile": {
|
"mobile": {
|
||||||
"mobile_streams": "Mobilni Prenosi",
|
"mobile_streams": "Mobilni Prenosi",
|
||||||
|
|||||||
@@ -275,3 +275,10 @@ document.addEventListener('DOMContentLoaded', initI18n);
|
|||||||
window.t = t;
|
window.t = t;
|
||||||
window.changeLanguage = changeLanguage;
|
window.changeLanguage = changeLanguage;
|
||||||
window.createLanguageSelector = createLanguageSelector;
|
window.createLanguageSelector = createLanguageSelector;
|
||||||
|
|
||||||
|
// Export i18n object with useful functions
|
||||||
|
window.i18n = {
|
||||||
|
t: t,
|
||||||
|
updatePageTranslations: translatePage,
|
||||||
|
changeLanguage: changeLanguage
|
||||||
|
};
|
||||||
+362
-241
@@ -24,45 +24,40 @@
|
|||||||
height: calc(100vh - 70px);
|
height: calc(100vh - 70px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 15px;
|
padding: 0px;
|
||||||
gap: 15px;
|
gap: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tournament-header {
|
.tournament-header {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||||
padding: 15px 20px;
|
padding: 10px 16px;
|
||||||
text-align: center;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
margin: 8px 15px 0px 15px;
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
.tournament-header .nav-btn {
|
gap: 12px;
|
||||||
position: absolute;
|
flex-wrap: wrap;
|
||||||
top: 10px;
|
|
||||||
right: 15px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tournament-title {
|
.tournament-title {
|
||||||
font-size: 1.5rem;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
color: #333;
|
color: #333;
|
||||||
margin-bottom: 6px;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tournament-stats {
|
.tournament-stats {
|
||||||
color: #666;
|
color: #888;
|
||||||
font-size: 0.9rem;
|
font-size: 0.82rem;
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tournament-controls {
|
.tournament-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 15px;
|
gap: 10px;
|
||||||
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-nav-btn {
|
.round-nav-btn {
|
||||||
@@ -93,7 +88,7 @@
|
|||||||
.current-round-display {
|
.current-round-display {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #28a745;
|
color: #333;
|
||||||
margin: 0 15px;
|
margin: 0 15px;
|
||||||
min-width: 140px;
|
min-width: 140px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -107,82 +102,123 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 5px;
|
overflow-x: hidden;
|
||||||
|
padding: 10px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
margin: 8px 15px 8px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom scrollbar styling */
|
||||||
|
.rounds-container::-webkit-scrollbar {
|
||||||
|
width: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounds-container::-webkit-scrollbar-track {
|
||||||
|
background: #f5f5f5;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounds-container::-webkit-scrollbar-thumb {
|
||||||
|
background: #5a8fd1;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounds-container::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #4a7db8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row {
|
.round-row {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 10px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.3s ease;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
border: 2px solid #e9ecef;
|
||||||
|
border-left: 5px solid #9ca3af;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.current {
|
.round-row.current {
|
||||||
border-left: 4px solid #28a745;
|
border-left: 5px solid #5a8fd1;
|
||||||
box-shadow: 0 4px 15px rgba(0, 123, 255, 0.25);
|
border-color: #5a8fd1;
|
||||||
|
box-shadow: 0 6px 24px rgba(90, 143, 209, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.completed {
|
.round-row.completed {
|
||||||
border-left: 4px solid #28a745;
|
border-left: 5px solid #28a745;
|
||||||
opacity: 0.95;
|
border-color: #28a745;
|
||||||
|
opacity: 0.98;
|
||||||
|
box-shadow: 0 4px 16px rgba(40, 167, 69, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.waiting {
|
.round-row.waiting {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
|
border-color: #d1d5db;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-header {
|
.round-header {
|
||||||
background: #f8f9fa;
|
background: linear-gradient(135deg, #f8f9fa 0%, #f0f1f3 100%);
|
||||||
border-right: 1px solid #e9ecef;
|
border-right: 3px solid #e9ecef;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px 15px;
|
padding: 14px 16px;
|
||||||
min-width: 120px;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 130px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.current .round-header {
|
.round-row.current .round-header {
|
||||||
background: #e3f2fd;
|
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
||||||
|
border-right-color: #5a8fd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.completed .round-header {
|
.round-row.completed .round-header {
|
||||||
background: #e8f5e8;
|
background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%);
|
||||||
|
border-right-color: #28a745;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-title {
|
.round-title {
|
||||||
font-size: 1rem;
|
font-size: 1.05rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
color: #333;
|
color: #333;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 6px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-badge {
|
.round-badge {
|
||||||
padding: 3px 8px;
|
padding: 4px 10px;
|
||||||
border-radius: 10px;
|
border-radius: 12px;
|
||||||
font-size: 0.65rem;
|
font-size: 0.7rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-badge {
|
.current-badge {
|
||||||
background: #28a745;
|
background: #5a8fd1;
|
||||||
color: white;
|
color: white;
|
||||||
|
box-shadow: 0 2px 8px rgba(90, 143, 209, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.completed-badge {
|
.completed-badge {
|
||||||
background: #28a745;
|
background: #28a745;
|
||||||
color: white;
|
color: white;
|
||||||
|
box-shadow: 0 2px 8px rgba(40, 167, 69, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.waiting-badge {
|
.waiting-badge {
|
||||||
background: #6c757d;
|
background: #9ca3af;
|
||||||
color: white;
|
color: white;
|
||||||
|
box-shadow: 0 2px 6px rgba(156, 163, 175, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.positions-container {
|
.positions-container {
|
||||||
@@ -191,6 +227,7 @@
|
|||||||
grid-template-columns: repeat(6, 1fr);
|
grid-template-columns: repeat(6, 1fr);
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card {
|
.position-card {
|
||||||
@@ -201,49 +238,68 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
box-shadow: 0 2px 6px rgba(156, 163, 175, 0.2);
|
box-shadow: 0 2px 8px rgba(156, 163, 175, 0.18);
|
||||||
min-height: 70px;
|
min-height: 80px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 3px 12px rgba(156, 163, 175, 0.28);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Current round - blue cards */
|
/* Current round - blue cards */
|
||||||
.round-row.current .position-card {
|
.round-row.current .position-card {
|
||||||
border-color: #5a8fd1;
|
border-color: #5a8fd1;
|
||||||
box-shadow: 0 2px 6px rgba(90, 143, 209, 0.2);
|
box-shadow: 0 2px 8px rgba(90, 143, 209, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-row.current .position-card:hover {
|
||||||
|
box-shadow: 0 3px 12px rgba(90, 143, 209, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.current .position-card .position-header {
|
.round-row.current .position-card .position-header {
|
||||||
background: #5a8fd1;
|
background: linear-gradient(135deg, #5a8fd1 0%, #4a7db8 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Completed round - green cards */
|
/* Completed round - green cards */
|
||||||
.round-row.completed .position-card {
|
.round-row.completed .position-card {
|
||||||
border-color: #28a745;
|
border-color: #28a745;
|
||||||
box-shadow: 0 2px 6px rgba(40, 167, 69, 0.2);
|
box-shadow: 0 2px 8px rgba(40, 167, 69, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-row.completed .position-card:hover {
|
||||||
|
box-shadow: 0 3px 12px rgba(40, 167, 69, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.completed .position-card .position-header {
|
.round-row.completed .position-card .position-header {
|
||||||
background: #28a745;
|
background: linear-gradient(135deg, #28a745 0%, #1e7e34 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Waiting round - gray cards */
|
/* Waiting round - gray cards */
|
||||||
.round-row.waiting .position-card {
|
.round-row.waiting .position-card {
|
||||||
border-color: #9ca3af;
|
border-color: #9ca3af;
|
||||||
box-shadow: 0 2px 6px rgba(156, 163, 175, 0.2);
|
box-shadow: 0 2px 8px rgba(156, 163, 175, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-row.waiting .position-card:hover {
|
||||||
|
box-shadow: 0 3px 10px rgba(156, 163, 175, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.waiting .position-card .position-header {
|
.round-row.waiting .position-card .position-header {
|
||||||
background: #9ca3af;
|
background: linear-gradient(135deg, #9ca3af 0%, #8b929f 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-header {
|
.position-header {
|
||||||
background: #9ca3af;
|
background: #9ca3af;
|
||||||
padding: 0;
|
padding: 12px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
min-width: 50px;
|
min-width: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
|
min-height: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card.empty .position-header {
|
.position-card.empty .position-header {
|
||||||
@@ -251,14 +307,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.position-number {
|
.position-number {
|
||||||
font-size: 1.6rem;
|
font-size: 2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: white;
|
color: white;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-body {
|
.position-body {
|
||||||
padding: 10px 12px;
|
padding: 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -266,6 +322,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 0 8px 8px 0;
|
border-radius: 0 8px 8px 0;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card.empty .position-body {
|
.position-card.empty .position-body {
|
||||||
@@ -276,10 +333,13 @@
|
|||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
line-height: 1.3;
|
line-height: 1.4;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
white-space: normal;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card.empty .player-name {
|
.position-card.empty .player-name {
|
||||||
@@ -321,6 +381,14 @@
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.print-logo {
|
||||||
|
display: block !important;
|
||||||
|
height: 80px !important;
|
||||||
|
max-width: 300px !important;
|
||||||
|
object-fit: contain !important;
|
||||||
|
margin: 0 auto 16px auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
@@ -344,20 +412,47 @@
|
|||||||
page-break-inside: avoid;
|
page-break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tournament-title {
|
.tournament-title,
|
||||||
font-size: 24pt !important;
|
|
||||||
font-weight: bold !important;
|
|
||||||
color: #333 !important;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tournament-stats {
|
.tournament-stats {
|
||||||
font-size: 12pt !important;
|
display: none !important;
|
||||||
color: #666 !important;
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-round-info {
|
.tournament-header {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: space-between !important;
|
||||||
|
background: transparent !important;
|
||||||
|
border: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
padding: 0 0 16px 0 !important;
|
||||||
|
margin-bottom: 16px !important;
|
||||||
|
border-bottom: 1px solid #ddd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-logo {
|
||||||
|
display: block !important;
|
||||||
|
height: 80px !important;
|
||||||
|
max-width: 300px !important;
|
||||||
|
object-fit: contain !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-meta {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: flex-end !important;
|
||||||
|
font-size: 11pt !important;
|
||||||
|
color: #555 !important;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-round-info,
|
||||||
|
.round-badge,
|
||||||
|
.round-print-info,
|
||||||
|
.player-id,
|
||||||
|
.no-tournament {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,175 +460,106 @@
|
|||||||
display: block !important;
|
display: block !important;
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
background: transparent !important;
|
||||||
|
|
||||||
.round-row {
|
|
||||||
background: white !important;
|
|
||||||
border: 1px solid #ddd !important;
|
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
margin-bottom: 15px;
|
margin: 0 !important;
|
||||||
page-break-inside: avoid;
|
|
||||||
display: block !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.round-row,
|
||||||
.round-row.current,
|
.round-row.current,
|
||||||
.round-row.completed,
|
.round-row.completed,
|
||||||
.round-row.waiting {
|
.round-row.waiting {
|
||||||
border-left: 1px solid #ddd !important;
|
box-shadow: none !important;
|
||||||
|
page-break-inside: avoid !important;
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
}
|
margin-bottom: 6px !important;
|
||||||
|
min-height: 0 !important;
|
||||||
.round-header {
|
border-top: 1px solid #dee2e6 !important;
|
||||||
background: #f8f9fa !important;
|
border-right: 1px solid #dee2e6 !important;
|
||||||
border: none !important;
|
border-bottom: 1px solid #dee2e6 !important;
|
||||||
border-bottom: 1px solid #ddd !important;
|
border-left: 1px solid #dee2e6 !important;
|
||||||
display: flex !important;
|
border-color: #dee2e6 !important;
|
||||||
justify-content: space-between !important;
|
|
||||||
align-items: center !important;
|
|
||||||
padding: 10px 15px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-row.current .round-header,
|
.round-row.current .round-header,
|
||||||
.round-row.completed .round-header,
|
.round-row.completed .round-header,
|
||||||
.round-row.waiting .round-header {
|
.round-row.waiting .round-header {
|
||||||
background: #f8f9fa !important;
|
background: linear-gradient(135deg, #f8f9fa 0%, #f0f1f3 100%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.round-title {
|
|
||||||
font-size: 14pt !important;
|
|
||||||
font-weight: bold !important;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-badge {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-print-info {
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
gap: 20px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-time-field {
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
gap: 8px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-time-label {
|
|
||||||
font-size: 11pt !important;
|
|
||||||
color: #666 !important;
|
|
||||||
font-weight: 500 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-time-input {
|
|
||||||
border: 2px solid #333 !important;
|
|
||||||
border-radius: 4px !important;
|
|
||||||
padding: 6px 10px !important;
|
|
||||||
width: 100px !important;
|
|
||||||
height: 32px !important;
|
|
||||||
background: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-checkbox-field {
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
gap: 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-checkbox-label {
|
|
||||||
font-size: 11pt !important;
|
|
||||||
color: #666 !important;
|
|
||||||
font-weight: 500 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-checkbox {
|
|
||||||
width: 24px !important;
|
|
||||||
height: 24px !important;
|
|
||||||
border: 2px solid #333 !important;
|
|
||||||
border-radius: 4px !important;
|
|
||||||
background: white !important;
|
|
||||||
display: inline-block !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.positions-container {
|
|
||||||
display: grid !important;
|
|
||||||
grid-template-columns: repeat(3, 1fr) !important;
|
|
||||||
gap: 10px !important;
|
|
||||||
padding: 15px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.position-card {
|
|
||||||
border: 1px solid #5a8fd1 !important;
|
|
||||||
border-radius: 8px !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
background: white !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
min-height: 60px !important;
|
|
||||||
page-break-inside: avoid;
|
|
||||||
display: flex !important;
|
|
||||||
flex-direction: row !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All cards in print have same blue color */
|
|
||||||
.round-row.current .position-card,
|
.round-row.current .position-card,
|
||||||
.round-row.completed .position-card,
|
.round-row.completed .position-card,
|
||||||
.round-row.waiting .position-card {
|
.round-row.waiting .position-card {
|
||||||
border-color: #5a8fd1 !important;
|
border-color: #5a8fd1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-header {
|
|
||||||
background: #5a8fd1 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
display: flex !important;
|
|
||||||
align-items: center !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
flex-shrink: 0 !important;
|
|
||||||
min-width: 40px !important;
|
|
||||||
width: 40px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-row.current .position-card .position-header,
|
.round-row.current .position-card .position-header,
|
||||||
.round-row.completed .position-card .position-header,
|
.round-row.completed .position-card .position-header,
|
||||||
.round-row.waiting .position-card .position-header {
|
.round-row.waiting .position-card .position-header {
|
||||||
background: #5a8fd1 !important;
|
background: #5a8fd1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card.empty .position-header {
|
.round-header {
|
||||||
background: #9ca3af !important;
|
padding: 8px 12px !important;
|
||||||
|
min-width: 90px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-title {
|
||||||
|
font-size: 9pt !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-badge {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.positions-container {
|
||||||
|
gap: 5px !important;
|
||||||
|
padding: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-card {
|
||||||
|
box-shadow: none !important;
|
||||||
|
transform: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
page-break-inside: avoid !important;
|
||||||
|
min-height: 48px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-header {
|
||||||
|
min-width: 36px !important;
|
||||||
|
width: 36px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-number {
|
.position-number {
|
||||||
font-size: 14pt !important;
|
font-size: 1.2rem !important;
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.position-body {
|
|
||||||
padding: 8px 10px !important;
|
|
||||||
background: white !important;
|
|
||||||
flex: 1 !important;
|
|
||||||
display: flex !important;
|
|
||||||
flex-direction: column !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
align-items: center !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.position-card.empty .position-body {
|
|
||||||
background: #f8f9fa !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-name {
|
.player-name {
|
||||||
font-size: 11pt !important;
|
font-size: 10pt !important;
|
||||||
color: #2c3e50 !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.position-card.empty .player-name {
|
/* Done checkbox */
|
||||||
color: #6c757d !important;
|
.print-done-check {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
padding: 0 14px !important;
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
border-left: 1px solid rgba(0,0,0,0.1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-id {
|
.print-done-box {
|
||||||
|
width: 20px !important;
|
||||||
|
height: 20px !important;
|
||||||
|
border: 1.5px solid #555 !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.print-done-label {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,68 +567,53 @@
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print header - show logo in tournament header */
|
|
||||||
.print-header {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tournament-header .print-logo {
|
|
||||||
display: block !important;
|
|
||||||
height: 60px !important;
|
|
||||||
max-width: 160px !important;
|
|
||||||
margin: 0 auto 10px auto !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print-only elements - hidden on screen */
|
/* Print-only elements - hidden on screen */
|
||||||
.print-header,
|
@media screen {
|
||||||
.round-print-info,
|
.round-print-info,
|
||||||
.tournament-header .print-logo {
|
.print-logo,
|
||||||
display: none;
|
.print-meta,
|
||||||
|
.print-done-check {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="/static/js/i18n.js"></script>
|
<script src="/static/js/i18n.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<div class="navbar-title">🏆 <span data-i18n="draft.tournament_draft">Tournament Draft</span></div>
|
<div class="navbar-title">🏆 Razpored Turnirja</div>
|
||||||
<div class="navbar-controls">
|
<div class="navbar-controls">
|
||||||
<a href="/" class="nav-btn">📺 <span data-i18n="navigation.dashboard">Dashboard</span></a>
|
|
||||||
<a href="/tournament" class="nav-btn">🏆 <span data-i18n="navigation.tournament">Tournament</span></a>
|
<a href="/tournament" class="nav-btn">🏆 <span data-i18n="navigation.tournament">Tournament</span></a>
|
||||||
<a href="/tournament/draft" class="nav-btn active">📋 <span data-i18n="tournament.view_draft">Draft</span></a>
|
<a href="/tournament/draft" class="nav-btn active">📋 Razpored</a>
|
||||||
<a href="/results/calculator" class="nav-btn">🎯 <span data-i18n="navigation.calculator">Results Calculator</span></a>
|
<a href="/results/calculator" class="nav-btn">🎯 <span data-i18n="navigation.calculator">Results Calculator</span></a>
|
||||||
|
<a href="/" class="nav-btn">✕</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Print-only header with logo -->
|
|
||||||
<div class="print-header">
|
|
||||||
<img src="/static/logo.png" alt="Logo" class="print-logo" onerror="this.style.display='none'" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
{% if tournament %}
|
{% if tournament %}
|
||||||
<div class="tournament-header">
|
<div class="tournament-header">
|
||||||
<button class="nav-btn" onclick="printDraft()" title="Print Tournament Draft">🖨️ <span data-i18n="general.print">Print</span></button>
|
<img src="/static/logo.png" alt="Logo" class="print-logo" />
|
||||||
<img src="/static/logo.png" alt="Logo" class="print-logo" onerror="this.style.display='none'" />
|
|
||||||
<div class="tournament-title">🎯 <span data-i18n="draft.shooting_tournament">Shooting Tournament</span></div>
|
<div class="tournament-title">🎯 <span data-i18n="draft.shooting_tournament">Shooting Tournament</span></div>
|
||||||
<div class="tournament-stats">
|
<div class="tournament-stats">
|
||||||
{{ tournament.total_players }} <span data-i18n="draft.players">players</span> • {{ tournament.total_rounds }} <span data-i18n="draft.rounds">rounds</span>
|
{{ tournament.total_players }} <span data-i18n="draft.players">players</span> • {{ tournament.total_rounds }} <span data-i18n="draft.rounds">rounds</span>
|
||||||
{% if tournament.current_round %}
|
</div>
|
||||||
<span class="current-round-info"><span data-i18n="draft.currently_on_round">Currently on Round</span> {{ tournament.current_round }}</span>
|
<div class="print-meta">
|
||||||
{% endif %}
|
<div>{{ tournament.total_players }} <span data-i18n="draft.players">igralcev</span></div>
|
||||||
|
<div id="printDate"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if tournament.current_round %}
|
{% if tournament.current_round %}
|
||||||
<div class="tournament-controls">
|
<div class="tournament-controls">
|
||||||
<button class="round-nav-btn" id="prevRoundBtn" onclick="changeRound(-1)" title="Previous Round">
|
<button class="round-nav-btn" id="prevRoundBtn" onclick="changeRound(-1)">←</button>
|
||||||
← <span data-i18n="draft.previous">Previous</span>
|
<span class="current-round-display"><span data-i18n="draft.round">Round</span> {{ tournament.current_round }} / {{ tournament.total_rounds }}</span>
|
||||||
</button>
|
<button class="round-nav-btn" id="nextRoundBtn" onclick="changeRound(1)">→</button>
|
||||||
<span class="current-round-display"><span data-i18n="draft.round">Round</span> {{ tournament.current_round }} <span data-i18n="draft.of">of</span> {{ tournament.total_rounds }}</span>
|
|
||||||
<button class="round-nav-btn" id="nextRoundBtn" onclick="changeRound(1)" title="Next Round">
|
|
||||||
<span data-i18n="draft.next">Next</span> →
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<button class="nav-btn" onclick="printDraft()" title="Print">🖨️</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="rounds-container" data-total-rounds="{{ tournament.total_rounds }}">
|
<div class="rounds-container" data-total-rounds="{{ tournament.total_rounds }}">
|
||||||
@@ -651,6 +662,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="print-done-check">
|
||||||
|
<span class="print-done-box"></span>
|
||||||
|
<span class="print-done-label">Done</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@@ -670,6 +685,24 @@
|
|||||||
let currentRound = {{ tournament.current_round if tournament else 1 }};
|
let currentRound = {{ tournament.current_round if tournament else 1 }};
|
||||||
const totalRounds = {{ tournament.total_rounds if tournament else 1 }};
|
const totalRounds = {{ tournament.total_rounds if tournament else 1 }};
|
||||||
|
|
||||||
|
// TV view toggle — only active when loaded as TV display (?tv=1)
|
||||||
|
const isTvDisplay = new URLSearchParams(window.location.search).get('tv') === '1';
|
||||||
|
if (isTvDisplay) {
|
||||||
|
const btn = document.getElementById('btnSwitchView');
|
||||||
|
if (btn) btn.style.display = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function switchToView() {
|
||||||
|
try {
|
||||||
|
await fetch('/api/tv/view', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ view: 'cameras' })
|
||||||
|
});
|
||||||
|
window.location.href = '/';
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
}
|
||||||
|
|
||||||
function updateRoundNavigation() {
|
function updateRoundNavigation() {
|
||||||
if (tournamentActive) {
|
if (tournamentActive) {
|
||||||
const prevBtn = document.getElementById('prevRoundBtn');
|
const prevBtn = document.getElementById('prevRoundBtn');
|
||||||
@@ -722,8 +755,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set print date
|
||||||
|
const printDateEl = document.getElementById('printDate');
|
||||||
|
if (printDateEl) {
|
||||||
|
const now = new Date();
|
||||||
|
printDateEl.textContent = now.toLocaleDateString('sl-SI', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
||||||
|
}
|
||||||
|
|
||||||
// Print function
|
// Print function
|
||||||
function printDraft() {
|
function printDraft() {
|
||||||
|
document.querySelectorAll('.round-row').forEach(el => {
|
||||||
|
el.classList.remove('current', 'completed', 'waiting');
|
||||||
|
el.classList.add('waiting');
|
||||||
|
});
|
||||||
window.print();
|
window.print();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,7 +780,7 @@
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
} else if (event.key === 'p' || event.key === 'P') {
|
} else if (event.key === 'p' || event.key === 'P') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
window.print();
|
printDraft();
|
||||||
} else if (tournamentActive) {
|
} else if (tournamentActive) {
|
||||||
if (event.key === 'ArrowLeft') {
|
if (event.key === 'ArrowLeft') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -758,15 +802,92 @@
|
|||||||
if (currentRoundRow) {
|
if (currentRoundRow) {
|
||||||
currentRoundRow.scrollIntoView({
|
currentRoundRow.scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
block: 'center'
|
block: 'start'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 300);
|
||||||
|
|
||||||
console.log('🖥️ PC Tournament Draft (Vertical Rows) loaded');
|
// Poll for state changes
|
||||||
console.log('🏆 Tournament active:', tournamentActive);
|
let lastStateHash = null;
|
||||||
console.log(`📊 Displaying ${totalRounds} rounds in vertical layout`);
|
setInterval(async () => {
|
||||||
|
if (document.visibilityState !== 'visible') return;
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/dashboard/state');
|
||||||
|
if (!response.ok) return;
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// If tournament just became inactive, redirect to archive (not reload)
|
||||||
|
if (!data.tournament_active) {
|
||||||
|
if (data.archive_filename) {
|
||||||
|
window.location.href = `/archive/tournament/${data.archive_filename}`;
|
||||||
|
} else if (data.league_archive_filename) {
|
||||||
|
window.location.href = `/archive/league/${data.league_archive_filename}`;
|
||||||
|
} else {
|
||||||
|
window.location.href = '/results';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Follow TV view changes when used as TV display
|
||||||
|
if (isTvDisplay) {
|
||||||
|
if (data.tv_view === 'cameras') { window.location.href = '/'; return; }
|
||||||
|
if (data.tv_view === 'results') {
|
||||||
|
if (data.archive_filename) {
|
||||||
|
window.location.href = `/archive/tournament/${data.archive_filename}?tv=1`;
|
||||||
|
} else if (data.league_archive_filename) {
|
||||||
|
window.location.href = `/archive/league/${data.league_archive_filename}?tv=1`;
|
||||||
|
} else {
|
||||||
|
window.location.href = '/results?tv=1';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload on round change to keep draft display in sync
|
||||||
|
const hash = JSON.stringify({ round: data.current_round });
|
||||||
|
if (lastStateHash !== null && hash !== lastStateHash) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
lastStateHash = hash;
|
||||||
|
updateTvViewBtn(data.tv_view || 'cameras');
|
||||||
|
} catch (e) {}
|
||||||
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── TV VIEW TOGGLE ────────────────────────────────────────────────────────
|
||||||
|
let currentTvView = 'cameras';
|
||||||
|
|
||||||
|
function updateTvViewBtn(view) {
|
||||||
|
currentTvView = view;
|
||||||
|
const btn = document.getElementById('btnTvView');
|
||||||
|
if (!btn) return;
|
||||||
|
if (view === 'draft') {
|
||||||
|
btn.textContent = '📺';
|
||||||
|
btn.style.background = '#28a745';
|
||||||
|
btn.style.color = 'white';
|
||||||
|
btn.style.borderColor = '#1e7e34';
|
||||||
|
} else {
|
||||||
|
btn.textContent = '📺';
|
||||||
|
btn.style.background = '';
|
||||||
|
btn.style.color = '';
|
||||||
|
btn.style.borderColor = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleTvView() {
|
||||||
|
const newView = currentTvView === 'draft' ? 'cameras' : 'draft';
|
||||||
|
try {
|
||||||
|
await fetch('/api/tv/view', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ view: newView })
|
||||||
|
});
|
||||||
|
updateTvViewBtn(newView);
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load initial tv_view state
|
||||||
|
fetch('/api/dashboard/state').then(r => r.json()).then(d => updateTvViewBtn(d.tv_view || 'cameras')).catch(() => {});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+78
-8
@@ -655,6 +655,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display: flex; align-items: center; gap: 15px;">
|
<div style="display: flex; align-items: center; gap: 15px;">
|
||||||
|
{% if settings.tournament_active %}
|
||||||
|
<div class="datetime" style="text-align: right;">
|
||||||
|
<div class="time" id="time"></div>
|
||||||
|
<div class="date" id="date"></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<button class="hamburger-menu" id="menuButton" data-i18n-title="general.settings">
|
<button class="hamburger-menu" id="menuButton" data-i18n-title="general.settings">
|
||||||
<div class="hamburger-line"></div>
|
<div class="hamburger-line"></div>
|
||||||
<div class="hamburger-line"></div>
|
<div class="hamburger-line"></div>
|
||||||
@@ -682,18 +688,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tournament-actions">
|
<div class="tournament-actions">
|
||||||
<a href="/tournament/draft" class="nav-link tournament-btn">📋 <span data-i18n="tournament.view_full_tournament_draft">Oglej si Celoten Žreb Turnirja</span></a>
|
<a href="/tournament/draft" class="nav-link tournament-btn">📋 Razpored Turnirja</a>
|
||||||
|
<a href="/results/calculator" class="nav-link tournament-btn">🎯 <span data-i18n="scoring.results_calculator">Calculator</span></a>
|
||||||
<a href="/tournament" class="nav-link tournament-btn" id="manageTournamentLink">⚙️ <span data-i18n="tournament.manage_tournament">Upravljaj Turnir</span></a>
|
<a href="/tournament" class="nav-link tournament-btn" id="manageTournamentLink">⚙️ <span data-i18n="tournament.manage_tournament">Upravljaj Turnir</span></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if settings.tournament_active %}
|
|
||||||
<div class="settings-group">
|
|
||||||
<a href="/results/calculator" class="nav-link tournament-btn">🎯 <span data-i18n="scoring.results_calculator">Calculator</span></a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Tournaments Section -->
|
<!-- Tournaments Section -->
|
||||||
<div class="settings-group">
|
<div class="settings-group">
|
||||||
<h4 data-i18n="league.tournaments">Turnirji</h4>
|
<h4 data-i18n="league.tournaments">Turnirji</h4>
|
||||||
@@ -771,7 +772,7 @@
|
|||||||
|
|
||||||
<!-- Version Information -->
|
<!-- Version Information -->
|
||||||
<div class="version-info" style="margin-top: 30px; padding: 15px; text-align: center; border-top: 1px solid #e9ecef; color: #6c757d; font-size: 0.85rem;">
|
<div class="version-info" style="margin-top: 30px; padding: 15px; text-align: center; border-top: 1px solid #e9ecef; color: #6c757d; font-size: 0.85rem;">
|
||||||
Version 1.0.0
|
Version 1.0.2
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1088,6 +1089,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TV view toggle (cameras ↔ draft)
|
||||||
// Debounce function
|
// Debounce function
|
||||||
function debounce(func, wait) {
|
function debounce(func, wait) {
|
||||||
let timeout;
|
let timeout;
|
||||||
@@ -1466,11 +1468,79 @@
|
|||||||
}, { once: true });
|
}, { once: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TV Display Auto-Update Polling
|
||||||
|
// (Separate from remote control polling)
|
||||||
|
let lastDashboardStateHash = null;
|
||||||
|
let dashboardPollingInterval = null;
|
||||||
|
|
||||||
|
async function pollDashboardState() {
|
||||||
|
// Only poll when page is visible
|
||||||
|
if (document.visibilityState !== 'visible') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/dashboard/state');
|
||||||
|
if (!response.ok) return;
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// If switched to draft view and tournament is active, follow it
|
||||||
|
if (data.tv_view === 'draft' && data.tournament_active) {
|
||||||
|
window.location.href = '/tournament/draft?tv=1';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If switched to results view, follow it (use explicit tv_url first, then fallback)
|
||||||
|
if (data.tv_view === 'results') {
|
||||||
|
if (data.tv_url) {
|
||||||
|
window.location.href = data.tv_url.includes('?') ? data.tv_url + '&tv=1' : data.tv_url + '?tv=1';
|
||||||
|
} else if (data.archive_filename) {
|
||||||
|
window.location.href = `/archive/tournament/${data.archive_filename}?tv=1`;
|
||||||
|
} else if (data.league_archive_filename) {
|
||||||
|
window.location.href = `/archive/league/${data.league_archive_filename}?tv=1`;
|
||||||
|
} else {
|
||||||
|
window.location.href = '/results?tv=1';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a hash of the state to detect changes
|
||||||
|
const stateHash = JSON.stringify(data);
|
||||||
|
|
||||||
|
// If structural state changed, reload the page
|
||||||
|
if (lastDashboardStateHash !== null && stateHash !== lastDashboardStateHash) {
|
||||||
|
console.log('🔄 Tournament state changed, reloading TV display...');
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastDashboardStateHash = stateHash;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Dashboard polling error:', error);
|
||||||
|
// Silent failure - keep polling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start dashboard polling (every 3 seconds)
|
||||||
|
dashboardPollingInterval = setInterval(pollDashboardState, 3000);
|
||||||
|
|
||||||
|
// Initial poll
|
||||||
|
pollDashboardState();
|
||||||
|
|
||||||
|
// Pause polling when page is hidden
|
||||||
|
document.addEventListener('visibilitychange', () => {
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
pollDashboardState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Cleanup on page unload
|
// Cleanup on page unload
|
||||||
window.addEventListener('beforeunload', function() {
|
window.addEventListener('beforeunload', function() {
|
||||||
if (remotePollingInterval) {
|
if (remotePollingInterval) {
|
||||||
clearInterval(remotePollingInterval);
|
clearInterval(remotePollingInterval);
|
||||||
}
|
}
|
||||||
|
if (dashboardPollingInterval) {
|
||||||
|
clearInterval(dashboardPollingInterval);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -0,0 +1,771 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sl">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title data-i18n="league.combine_leagues">Combine Leagues</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/navbar.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/buttons.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/components.css') }}">
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: #f5f5f5;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
min-height: 100vh;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
background: white;
|
||||||
|
border-bottom: 1px solid #e1e5e9;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 15px 25px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-title {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-btn {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 2px solid #e9ecef;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
color: #333;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-btn:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
border-color: #28a745;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-section {
|
||||||
|
background: white;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area {
|
||||||
|
border: 3px dashed #28a745;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 40px;
|
||||||
|
text-align: center;
|
||||||
|
background: #f8f9fa;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area:hover {
|
||||||
|
background: #e9f7ed;
|
||||||
|
border-color: #1e7e34;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area.drag-over {
|
||||||
|
background: #d4edda;
|
||||||
|
border-color: #28a745;
|
||||||
|
box-shadow: 0 4px 12px rgba(40, 167, 69, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploaded-files {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-left: 4px solid #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item.error {
|
||||||
|
border-left-color: #dc3545;
|
||||||
|
background: #f8d7da;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-details {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-btn {
|
||||||
|
background: #dc3545;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-btn:hover {
|
||||||
|
background: #c82333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 12px 24px;
|
||||||
|
border: 2px solid;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
flex: 1;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: #28a745;
|
||||||
|
color: white;
|
||||||
|
border-color: #1e7e34;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: #1e7e34;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:disabled {
|
||||||
|
background: #6c757d;
|
||||||
|
border-color: #5a6268;
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: #f8f9fa;
|
||||||
|
color: #333;
|
||||||
|
border-color: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
border-color: #dc3545;
|
||||||
|
color: #dc3545;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section {
|
||||||
|
background: white;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-section.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
background: #d4edda;
|
||||||
|
border-left: 4px solid #28a745;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box h3 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
border-left: 4px solid #28a745;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6c757d;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border: 2px solid #28a745;
|
||||||
|
background: white;
|
||||||
|
color: #28a745;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-btn:hover {
|
||||||
|
background: #e9f7ed;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-btn.active {
|
||||||
|
background: #28a745;
|
||||||
|
color: white;
|
||||||
|
border-color: #1e7e34;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="navbar">
|
||||||
|
<h1 class="navbar-title">🔗 <span data-i18n="league.combine_leagues">Combine Leagues</span></h1>
|
||||||
|
<a href="/" class="nav-btn">✕</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="upload-section">
|
||||||
|
<div style="margin-bottom: 20px;">
|
||||||
|
<label style="display: block; margin-bottom: 10px; font-weight: bold; color: #2c3e50;">
|
||||||
|
<span data-i18n="league.select_mode">Select Mode</span>:
|
||||||
|
</label>
|
||||||
|
<div style="display: flex; gap: 10px;">
|
||||||
|
<button class="mode-btn active" id="combineMode" onclick="switchMode('combine')">
|
||||||
|
🔗 <span data-i18n="league.combine_mode">Combine Leagues</span>
|
||||||
|
</button>
|
||||||
|
<button class="mode-btn" id="convertMode" onclick="switchMode('convert')">
|
||||||
|
🔄 <span data-i18n="league.convert_mode">Convert Tournaments to League</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="combineSection">
|
||||||
|
<h2>📤 <span data-i18n="league.upload_league_files">Upload League JSON Files</span></h2>
|
||||||
|
<p style="color: #6c757d; margin-bottom: 20px;">
|
||||||
|
<span data-i18n="league.combine_leagues_desc">Upload multiple league JSON files to combine them into a single results table.</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="convertSection" style="display: none;">
|
||||||
|
<h2>📤 <span data-i18n="league.upload_tournament_files">Upload Tournament JSON Files</span></h2>
|
||||||
|
<p style="color: #6c757d; margin-bottom: 20px;">
|
||||||
|
<span data-i18n="league.convert_tournaments_desc">Upload 1-5 tournament JSON files to create a league. You can upload partial leagues as tournaments complete. Final scoring uses best 4 results when all 5 are uploaded.</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="upload-area" id="uploadArea">
|
||||||
|
<div class="upload-icon">📁</div>
|
||||||
|
<p><strong data-i18n="league.click_browse">Click to browse</strong> <span data-i18n="league.drag_drop_files">or drag and drop league JSON files here</span></p>
|
||||||
|
<p style="font-size: 0.9em; color: #6c757d;"><span data-i18n="league.supports_multiple">Supports multiple file selection</span></p>
|
||||||
|
<input type="file" id="fileInput" class="file-input" accept=".json" multiple>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="uploaded-files" id="uploadedFiles"></div>
|
||||||
|
|
||||||
|
<div class="action-buttons">
|
||||||
|
<button class="btn btn-secondary" id="clearBtn" disabled>
|
||||||
|
🗑️ <span data-i18n="scoring.clear_all">Clear All</span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-primary" id="processBtn" disabled>
|
||||||
|
<span id="processBtnText">🔗 <span data-i18n="league.combine_preview">Combine & Preview</span></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="preview-section" id="previewSection">
|
||||||
|
<div class="info-box">
|
||||||
|
<h3>ℹ️ <span data-i18n="league.combined_league_info">Combined League Information</span></h3>
|
||||||
|
<div id="combinedInfo"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stats-grid" id="statsGrid"></div>
|
||||||
|
|
||||||
|
<div id="resultsDisplay"></div>
|
||||||
|
|
||||||
|
<div class="action-buttons" style="margin-top: 20px;">
|
||||||
|
<button class="btn btn-secondary" onclick="window.location.reload()">
|
||||||
|
🔄 <span data-i18n="league.start_over">Start Over</span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-primary" id="exportBtn">
|
||||||
|
💾 <span data-i18n="league.export_combined_results">Export Combined Results</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/js/i18n.js"></script>
|
||||||
|
<script>
|
||||||
|
let uploadedLeagues = [];
|
||||||
|
let currentMode = 'combine'; // 'combine' or 'convert'
|
||||||
|
|
||||||
|
const uploadArea = document.getElementById('uploadArea');
|
||||||
|
const fileInput = document.getElementById('fileInput');
|
||||||
|
const uploadedFilesDiv = document.getElementById('uploadedFiles');
|
||||||
|
const clearBtn = document.getElementById('clearBtn');
|
||||||
|
const processBtn = document.getElementById('processBtn');
|
||||||
|
const processBtnText = document.getElementById('processBtnText');
|
||||||
|
const previewSection = document.getElementById('previewSection');
|
||||||
|
|
||||||
|
// Helper function to get translated text
|
||||||
|
function t(key) {
|
||||||
|
if (window.i18n && window.i18n.t) {
|
||||||
|
return window.i18n.t(key);
|
||||||
|
}
|
||||||
|
// Fallback if i18n not loaded yet
|
||||||
|
return key.split('.').pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchMode(mode) {
|
||||||
|
currentMode = mode;
|
||||||
|
|
||||||
|
// Update button states
|
||||||
|
document.getElementById('combineMode').classList.toggle('active', mode === 'combine');
|
||||||
|
document.getElementById('convertMode').classList.toggle('active', mode === 'convert');
|
||||||
|
|
||||||
|
// Update sections
|
||||||
|
document.getElementById('combineSection').style.display = mode === 'combine' ? 'block' : 'none';
|
||||||
|
document.getElementById('convertSection').style.display = mode === 'convert' ? 'block' : 'none';
|
||||||
|
|
||||||
|
// Update button text with translations
|
||||||
|
processBtnText.innerHTML = mode === 'combine'
|
||||||
|
? '🔗 <span data-i18n="league.combine_preview">Combine & Preview</span>'
|
||||||
|
: '🔄 <span data-i18n="league.convert_to_league">Convert to League</span>';
|
||||||
|
// Re-apply translations after DOM change
|
||||||
|
if (window.i18n) window.i18n.updatePageTranslations();
|
||||||
|
|
||||||
|
// Clear uploaded files
|
||||||
|
uploadedLeagues = [];
|
||||||
|
updateFileList();
|
||||||
|
previewSection.classList.remove('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Click to upload
|
||||||
|
uploadArea.addEventListener('click', () => fileInput.click());
|
||||||
|
|
||||||
|
// Drag and drop
|
||||||
|
uploadArea.addEventListener('dragover', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
uploadArea.classList.add('drag-over');
|
||||||
|
});
|
||||||
|
|
||||||
|
uploadArea.addEventListener('dragleave', () => {
|
||||||
|
uploadArea.classList.remove('drag-over');
|
||||||
|
});
|
||||||
|
|
||||||
|
uploadArea.addEventListener('drop', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
uploadArea.classList.remove('drag-over');
|
||||||
|
handleFiles(e.dataTransfer.files);
|
||||||
|
});
|
||||||
|
|
||||||
|
// File input change
|
||||||
|
fileInput.addEventListener('change', (e) => {
|
||||||
|
handleFiles(e.target.files);
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleFiles(files) {
|
||||||
|
Array.from(files).forEach(file => {
|
||||||
|
if (file.type === 'application/json' || file.name.endsWith('.json')) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(e.target.result);
|
||||||
|
|
||||||
|
if (currentMode === 'combine') {
|
||||||
|
// Validate it's a league file (handles both archived and raw formats)
|
||||||
|
let leagueData = null;
|
||||||
|
if (data.league && data.league.participants) {
|
||||||
|
// Archived format (wrapped)
|
||||||
|
leagueData = data.league;
|
||||||
|
} else if (data.participants) {
|
||||||
|
// Raw league format (unwrapped)
|
||||||
|
leagueData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leagueData) {
|
||||||
|
uploadedLeagues.push({
|
||||||
|
filename: file.name,
|
||||||
|
data: data,
|
||||||
|
leagueData: leagueData, // Store the actual league data
|
||||||
|
valid: true,
|
||||||
|
type: 'league'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uploadedLeagues.push({
|
||||||
|
filename: file.name,
|
||||||
|
error: 'Invalid league file format',
|
||||||
|
valid: false,
|
||||||
|
type: 'league'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Convert mode - validate it's a tournament file
|
||||||
|
if (data.tournament && data.results && data.results.participants) {
|
||||||
|
uploadedLeagues.push({
|
||||||
|
filename: file.name,
|
||||||
|
data: data,
|
||||||
|
valid: true,
|
||||||
|
type: 'tournament'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uploadedLeagues.push({
|
||||||
|
filename: file.name,
|
||||||
|
error: t('league.invalid_tournament_format'),
|
||||||
|
valid: false,
|
||||||
|
type: 'tournament'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFileList();
|
||||||
|
} catch (error) {
|
||||||
|
uploadedLeagues.push({
|
||||||
|
filename: file.name,
|
||||||
|
error: t('league.failed_parse_json'),
|
||||||
|
valid: false
|
||||||
|
});
|
||||||
|
updateFileList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFileList() {
|
||||||
|
uploadedFilesDiv.innerHTML = '';
|
||||||
|
|
||||||
|
if (uploadedLeagues.length > 0) {
|
||||||
|
const heading = document.createElement('h3');
|
||||||
|
heading.textContent = `📋 ${t('league.uploaded_files')} (${uploadedLeagues.length})`;
|
||||||
|
uploadedFilesDiv.appendChild(heading);
|
||||||
|
|
||||||
|
uploadedLeagues.forEach((league, index) => {
|
||||||
|
const fileItem = document.createElement('div');
|
||||||
|
fileItem.className = 'file-item' + (league.valid ? '' : ' error');
|
||||||
|
|
||||||
|
const fileInfo = document.createElement('div');
|
||||||
|
fileInfo.className = 'file-info';
|
||||||
|
|
||||||
|
const fileName = document.createElement('div');
|
||||||
|
fileName.className = 'file-name';
|
||||||
|
fileName.textContent = league.filename;
|
||||||
|
|
||||||
|
const fileDetails = document.createElement('div');
|
||||||
|
fileDetails.className = 'file-details';
|
||||||
|
|
||||||
|
if (league.valid) {
|
||||||
|
if (league.type === 'league') {
|
||||||
|
const participantCount = Object.keys(league.leagueData.participants).length;
|
||||||
|
const tournamentCount = league.leagueData.total_tournaments || 0;
|
||||||
|
fileDetails.textContent = `✓ ${t('league.valid_league')} | ${participantCount} ${t('league.participants')} | ${tournamentCount} ${t('league.tournaments')}`;
|
||||||
|
} else {
|
||||||
|
const participantCount = Object.keys(league.data.results.participants).length;
|
||||||
|
const tournamentType = league.data.results.tournament_type || '20_targets';
|
||||||
|
fileDetails.textContent = `✓ ${t('league.valid_tournament')} | ${participantCount} ${t('league.participants')} | ${t('league.type')}: ${tournamentType}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fileDetails.textContent = `✗ ${league.error}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInfo.appendChild(fileName);
|
||||||
|
fileInfo.appendChild(fileDetails);
|
||||||
|
|
||||||
|
const removeBtn = document.createElement('button');
|
||||||
|
removeBtn.className = 'remove-btn';
|
||||||
|
removeBtn.textContent = `✗ ${t('league.remove')}`;
|
||||||
|
removeBtn.onclick = () => removeFile(index);
|
||||||
|
|
||||||
|
fileItem.appendChild(fileInfo);
|
||||||
|
fileItem.appendChild(removeBtn);
|
||||||
|
uploadedFilesDiv.appendChild(fileItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
clearBtn.disabled = false;
|
||||||
|
|
||||||
|
const validCount = uploadedLeagues.filter(l => l.valid).length;
|
||||||
|
if (currentMode === 'combine') {
|
||||||
|
processBtn.disabled = validCount < 1; // Allow preview with 1+ files
|
||||||
|
} else {
|
||||||
|
// Convert mode requires 1-5 tournament files
|
||||||
|
processBtn.disabled = validCount < 1 || validCount > 5;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clearBtn.disabled = true;
|
||||||
|
processBtn.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFile(index) {
|
||||||
|
uploadedLeagues.splice(index, 1);
|
||||||
|
updateFileList();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearBtn.addEventListener('click', () => {
|
||||||
|
uploadedLeagues = [];
|
||||||
|
updateFileList();
|
||||||
|
previewSection.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
processBtn.addEventListener('click', async () => {
|
||||||
|
const validFiles = uploadedLeagues.filter(l => l.valid);
|
||||||
|
|
||||||
|
if (currentMode === 'combine') {
|
||||||
|
if (validFiles.length < 1) {
|
||||||
|
alert('Please upload at least 1 valid league file');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to backend for combination
|
||||||
|
const response = await fetch('/api/league/combine', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
leagues: validFiles.map(l => l.leagueData)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
// Store in session and redirect to preview
|
||||||
|
const previewResponse = await fetch('/league/set-preview', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
league: result.combined_league
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (previewResponse.ok) {
|
||||||
|
const previewResult = await previewResponse.json();
|
||||||
|
window.location.href = previewResult.redirect_url;
|
||||||
|
} else {
|
||||||
|
alert('Failed to preview league');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert('Failed to combine leagues');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Convert mode
|
||||||
|
if (validFiles.length < 1 || validFiles.length > 5) {
|
||||||
|
alert('Please upload 1-5 valid tournament files');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to backend for conversion
|
||||||
|
const response = await fetch('/api/league/convert', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
tournaments: validFiles.map(l => l.data)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
// Store in session and redirect to preview
|
||||||
|
const previewResponse = await fetch('/league/set-preview', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
league: result.combined_league
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (previewResponse.ok) {
|
||||||
|
const previewResult = await previewResponse.json();
|
||||||
|
window.location.href = previewResult.redirect_url;
|
||||||
|
} else {
|
||||||
|
alert('Failed to preview league');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert('Failed to convert tournaments to league');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function displayCombinedResults(result) {
|
||||||
|
// Display combined info
|
||||||
|
const sourceType = result.is_partial !== undefined ?
|
||||||
|
(result.is_partial ? 'tournament files (Partial League)' : 'tournament files (Complete League)') :
|
||||||
|
'league files';
|
||||||
|
|
||||||
|
document.getElementById('combinedInfo').innerHTML = `
|
||||||
|
<p><strong>Combined from:</strong> ${result.source_count} ${sourceType}</p>
|
||||||
|
<p><strong>Tournament Type:</strong> ${result.tournament_type}</p>
|
||||||
|
<p><strong>Total Participants:</strong> ${result.total_participants}</p>
|
||||||
|
${result.is_partial ? '<p style="color: #ff9800;"><strong>⚠️ Partial League:</strong> Upload more tournaments to complete the league (5 total needed)</p>' : ''}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Display stats
|
||||||
|
const statsGrid = document.getElementById('statsGrid');
|
||||||
|
statsGrid.innerHTML = `
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">${result.total_participants}</div>
|
||||||
|
<div class="stat-label">Total Players</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">${result.total_tournaments}</div>
|
||||||
|
<div class="stat-label">Total Tournaments</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">${result.highest_score}</div>
|
||||||
|
<div class="stat-label">Highest Score</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="stat-value">${result.avg_score}</div>
|
||||||
|
<div class="stat-label">Average Score</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Store combined data for export
|
||||||
|
window.combinedLeagueData = result.combined_league;
|
||||||
|
|
||||||
|
// Redirect to results display with combined data
|
||||||
|
displayResultsTable(result.participants);
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayResultsTable(participants) {
|
||||||
|
const resultsDisplay = document.getElementById('resultsDisplay');
|
||||||
|
|
||||||
|
let html = `
|
||||||
|
<h2>🏆 Combined Results</h2>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; margin-top: 20px;">
|
||||||
|
<thead>
|
||||||
|
<tr style="background: #667eea; color: white;">
|
||||||
|
<th style="padding: 12px; text-align: left;">Rank</th>
|
||||||
|
<th style="padding: 12px; text-align: left;">Player</th>
|
||||||
|
<th style="padding: 12px; text-align: center;">Final Score</th>
|
||||||
|
<th style="padding: 12px; text-align: center;">Total Score</th>
|
||||||
|
<th style="padding: 12px; text-align: center;">Tournaments</th>
|
||||||
|
<th style="padding: 12px; text-align: center;">10s</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
`;
|
||||||
|
|
||||||
|
participants.forEach((p, i) => {
|
||||||
|
html += `
|
||||||
|
<tr style="border-bottom: 1px solid #dee2e6; ${i % 2 === 0 ? 'background: #f8f9fa;' : ''}">
|
||||||
|
<td style="padding: 12px; font-weight: bold;">${i + 1}</td>
|
||||||
|
<td style="padding: 12px;">${p.name}</td>
|
||||||
|
<td style="padding: 12px; text-align: center; font-weight: bold; color: #667eea;">${p.final_score}</td>
|
||||||
|
<td style="padding: 12px; text-align: center;">${p.total_score}</td>
|
||||||
|
<td style="padding: 12px; text-align: center;">${p.tournaments_participated}</td>
|
||||||
|
<td style="padding: 12px; text-align: center;">${p.total_tens}</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
|
||||||
|
resultsDisplay.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('exportBtn').addEventListener('click', () => {
|
||||||
|
if (window.combinedLeagueData) {
|
||||||
|
// Wrap in archive format to be compatible with results display
|
||||||
|
const archiveData = {
|
||||||
|
league: window.combinedLeagueData,
|
||||||
|
archived_at: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
const dataStr = JSON.stringify(archiveData, null, 2);
|
||||||
|
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = `combined_league_${new Date().toISOString().slice(0, 10)}.json`;
|
||||||
|
link.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -96,22 +96,25 @@
|
|||||||
.league-container {
|
.league-container {
|
||||||
height: calc(100vh - 90px);
|
height: calc(100vh - 90px);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 3fr;
|
grid-template-columns: 1fr 2fr;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Left Column - Header & Champions */
|
/* Left Column - Header & Champions */
|
||||||
.left-column {
|
.left-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 0;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-header {
|
.league-header {
|
||||||
border-radius: 12px;
|
border-radius: 12px 12px 0 0;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
box-shadow: none;
|
||||||
padding: 25px;
|
padding: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
color: white;
|
color: white;
|
||||||
@@ -149,37 +152,37 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-logo {
|
.header-logo {
|
||||||
height: 70px;
|
height: 50px;
|
||||||
max-width: 180px;
|
max-width: 150px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 10px;
|
||||||
filter: brightness(1.2) contrast(1.1);
|
filter: brightness(1.2) contrast(1.1);
|
||||||
background-color: white;
|
background-color: white;
|
||||||
padding: 10px;
|
padding: 6px;
|
||||||
border-radius: 8px;
|
border-radius: 6px;
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-title {
|
.league-title {
|
||||||
font-size: 2.2rem;
|
font-size: 1.8rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: rgb(255, 255, 255);
|
color: rgb(255, 255, 255);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 8px;
|
||||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-subtitle {
|
.league-subtitle {
|
||||||
font-size: 1.1rem;
|
font-size: 0.9rem;
|
||||||
color: rgba(255, 255, 255, 0.95);
|
color: rgba(255, 255, 255, 0.95);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 12px;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-meta {
|
.league-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
gap: 15px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-item {
|
.meta-item {
|
||||||
@@ -187,7 +190,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta-number {
|
.meta-number {
|
||||||
font-size: 1.6rem;
|
font-size: 1.2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -195,83 +198,112 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta-label {
|
.meta-label {
|
||||||
font-size: 0.8rem;
|
font-size: 0.65rem;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.3px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* League Champion Section */
|
/* League Champion Section */
|
||||||
.champion-section {
|
.champion-section {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 0 0 12px 12px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: none;
|
||||||
padding: 25px;
|
padding: 12px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-title {
|
.champion-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.4rem;
|
font-size: 0.9rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-container {
|
.champion-container {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 15px;
|
grid-template-rows: 0.75fr 0.75fr 1.5fr;
|
||||||
|
gap: 10px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-card {
|
.champion-card {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: none;
|
||||||
padding: 20px;
|
padding: 12px 12px 18px 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20px;
|
gap: 8px;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.3s ease;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-left: 5px solid;
|
border: 1px solid #e9ecef;
|
||||||
|
border-top-width: 6px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.champion-card::before {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-card:hover {
|
.champion-card:hover {
|
||||||
transform: translateY(-2px);
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-card.rank-1 {
|
.champion-card.rank-1 {
|
||||||
border-left-color: #ffd700;
|
border-top-color: #ffd700;
|
||||||
background: linear-gradient(135deg, #fff9e6 0%, #ffffff 100%);
|
border-color: #ffd700;
|
||||||
|
background: linear-gradient(135deg, #fffbf0 0%, #fff9e6 100%);
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-card.rank-2 {
|
.champion-card.rank-2 {
|
||||||
border-left-color: #c0c0c0;
|
border-top-color: #c0c0c0;
|
||||||
background: linear-gradient(135deg, #f5f5f5 0%, #ffffff 100%);
|
border-color: #c0c0c0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 0%, #f0f0f0 100%);
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.champion-card.rank-3 {
|
.champion-card.rank-3 {
|
||||||
border-left-color: #cd7f32;
|
border-top-color: #cd7f32;
|
||||||
background: linear-gradient(135deg, #fdf6f0 0%, #ffffff 100%);
|
border-color: #cd7f32;
|
||||||
|
background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 100%);
|
||||||
|
grid-column: 3;
|
||||||
|
grid-row: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-display {
|
.rank-display {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 60px;
|
gap: 2px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medal {
|
||||||
|
font-size: 4.5rem;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-number {
|
.rank-number {
|
||||||
font-size: 1.8rem;
|
font-size: 1.9rem;
|
||||||
font-weight: bold;
|
font-weight: 900;
|
||||||
color: #333;
|
color: #333;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
@@ -280,29 +312,31 @@
|
|||||||
.champion-card.rank-2 .rank-number { color: #696969; }
|
.champion-card.rank-2 .rank-number { color: #696969; }
|
||||||
.champion-card.rank-3 .rank-number { color: #8b4513; }
|
.champion-card.rank-3 .rank-number { color: #8b4513; }
|
||||||
|
|
||||||
.rank-suffix {
|
|
||||||
font-size: 0.7rem;
|
|
||||||
color: #666;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.medal {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.participant-info {
|
.participant-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.participant-name {
|
.participant-name {
|
||||||
font-size: 1.3rem;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
color: #333;
|
color: #2c3e50;
|
||||||
margin-bottom: 5px;
|
margin: 0;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.participant-details {
|
.participant-details {
|
||||||
@@ -315,74 +349,96 @@
|
|||||||
.participant-id {
|
.participant-id {
|
||||||
background: #28a745;
|
background: #28a745;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 3px 10px;
|
padding: 6px 12px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
font-size: 0.8rem;
|
font-size: 0.75rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
box-shadow: 0 2px 8px rgba(40, 167, 69, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.joker-badge {
|
.joker-badge {
|
||||||
background: #ffc107;
|
background: #ffc107;
|
||||||
color: #856404;
|
color: #856404;
|
||||||
padding: 3px 8px;
|
padding: 6px 12px;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
font-size: 0.7rem;
|
font-size: 0.75rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
box-shadow: 0 2px 8px rgba(255, 193, 7, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-display {
|
.score-display {
|
||||||
text-align: right;
|
text-align: center;
|
||||||
min-width: 100px;
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.final-score {
|
.score-number {
|
||||||
font-size: 2rem;
|
font-size: 1.8rem;
|
||||||
font-weight: bold;
|
font-weight: 900;
|
||||||
color: #28a745;
|
color: #28a745;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tens-count {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #ffc107;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
.total-score {
|
.total-score {
|
||||||
font-size: 0.9rem;
|
font-size: 0.8rem;
|
||||||
color: #666;
|
color: #ffc107;
|
||||||
margin-top: 2px;
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tens-count {
|
.tens-count {
|
||||||
font-size: 0.9rem;
|
font-size: 0.8rem;
|
||||||
color: #ffc107;
|
color: #ffc107;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
margin-top: 2px;
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-label {
|
.score-label {
|
||||||
font-size: 0.8rem;
|
font-size: 0.6rem;
|
||||||
color: #666;
|
color: #999;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: bold;
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Right Column - League Table */
|
/* Right Column - League Table */
|
||||||
.right-column {
|
.right-column {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header {
|
.table-header {
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
padding: 15px 20px;
|
padding: 12px 15px;
|
||||||
border-bottom: 1px solid #dee2e6;
|
border-bottom: 1px solid #dee2e6;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-title {
|
.table-title {
|
||||||
font-size: 1.25rem;
|
font-size: 0.95rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -396,12 +452,12 @@
|
|||||||
.league-table {
|
.league-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
font-size: 0.85rem;
|
font-size: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-table th,
|
.league-table th,
|
||||||
.league-table td {
|
.league-table td {
|
||||||
padding: 7px 5px;
|
padding: 6px 4px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-bottom: 1px solid #f1f3f4;
|
border-bottom: 1px solid #f1f3f4;
|
||||||
border-right: 1px solid #f1f3f4;
|
border-right: 1px solid #f1f3f4;
|
||||||
@@ -421,20 +477,20 @@
|
|||||||
|
|
||||||
.league-table th.player-col {
|
.league-table th.player-col {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: 120px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-table th.tournament-col {
|
.league-table th.tournament-col {
|
||||||
width: 70px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-table th.final-col {
|
.league-table th.final-col {
|
||||||
width: 80px;
|
width: 70px;
|
||||||
background: #e3f2fd;
|
background: #e3f2fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.league-table th.tens-col {
|
.league-table th.tens-col {
|
||||||
width: 70px;
|
width: 60px;
|
||||||
background: #fff3cd;
|
background: #fff3cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -786,8 +842,10 @@
|
|||||||
<div class="navbar-title">🎖️ <span data-i18n="league.league_results">League Results</span></div>
|
<div class="navbar-title">🎖️ <span data-i18n="league.league_results">League Results</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-controls">
|
<div class="navbar-controls">
|
||||||
<a href="/" class="nav-btn">📺 <span data-i18n="navigation.dashboard">Dashboard</span></a>
|
<button class="nav-btn" onclick="exportLeagueJSON()">💾 <span data-i18n="general.export">Export JSON</span></button>
|
||||||
<button class="nav-btn" onclick="window.print()">🖨️ <span data-i18n="general.print">Print</span></button>
|
<button class="nav-btn" onclick="window.print()">🖨️ <span data-i18n="general.print">Print</span></button>
|
||||||
|
<button class="nav-btn" id="btnTvView" onclick="toggleTvView()" title="Preklopi pogled na TV zaslonu">📺</button>
|
||||||
|
<a href="/" class="nav-btn">✕</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1043,10 +1101,6 @@
|
|||||||
const topThree = processedParticipants.slice(0, 3);
|
const topThree = processedParticipants.slice(0, 3);
|
||||||
|
|
||||||
return topThree.map(participant => {
|
return topThree.map(participant => {
|
||||||
const suffix = participant.rank === 1 ? 'st' :
|
|
||||||
participant.rank === 2 ? 'nd' :
|
|
||||||
participant.rank === 3 ? 'rd' : 'th';
|
|
||||||
|
|
||||||
const medal = participant.rank === 1 ? '🥇' :
|
const medal = participant.rank === 1 ? '🥇' :
|
||||||
participant.rank === 2 ? '🥈' :
|
participant.rank === 2 ? '🥈' :
|
||||||
participant.rank === 3 ? '🥉' : '';
|
participant.rank === 3 ? '🥉' : '';
|
||||||
@@ -1055,21 +1109,16 @@
|
|||||||
return `
|
return `
|
||||||
<div class="champion-card rank-${participant.rank}">
|
<div class="champion-card rank-${participant.rank}">
|
||||||
<div class="rank-display">
|
<div class="rank-display">
|
||||||
<div class="rank-number">${participant.rank}</div>
|
|
||||||
<div class="rank-suffix">${suffix}</div>
|
|
||||||
<div class="medal">${medal}</div>
|
<div class="medal">${medal}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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-details">
|
|
||||||
<div class="participant-id">ID: ${participant.id}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="score-display">
|
<div class="score-display">
|
||||||
<div class="final-score">${participant.final_score}</div>
|
<div class="score-number">${participant.final_score}</div>
|
||||||
<div class="tens-count">🎯 ${participant.total_tens} × 10</div>
|
<div class="tens-count">🎯 ${participant.total_tens}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -1099,6 +1148,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';
|
||||||
@@ -1199,6 +1250,31 @@
|
|||||||
// Initialize when page loads
|
// Initialize when page loads
|
||||||
document.addEventListener('DOMContentLoaded', initializePage);
|
document.addEventListener('DOMContentLoaded', initializePage);
|
||||||
|
|
||||||
|
// Export league data as JSON
|
||||||
|
function exportLeagueJSON() {
|
||||||
|
const leagueData = {{ league | tojson | safe }};
|
||||||
|
|
||||||
|
// Wrap in archive format for compatibility
|
||||||
|
const archiveData = {
|
||||||
|
league: leagueData,
|
||||||
|
archived_at: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
const dataStr = JSON.stringify(archiveData, null, 2);
|
||||||
|
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
|
||||||
|
// Generate filename with league info
|
||||||
|
const leagueId = leagueData.league_id || 'league';
|
||||||
|
const date = new Date().toISOString().slice(0, 10);
|
||||||
|
link.download = `${leagueId}_${date}.json`;
|
||||||
|
|
||||||
|
link.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
document.addEventListener('keydown', function(event) {
|
document.addEventListener('keydown', function(event) {
|
||||||
if (event.key === 'r' || event.key === 'R') {
|
if (event.key === 'r' || event.key === 'R') {
|
||||||
@@ -1209,6 +1285,59 @@
|
|||||||
window.print();
|
window.print();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── TV VIEW TOGGLE ────────────────────────────────────────────────────────
|
||||||
|
const isTvDisplay = new URLSearchParams(window.location.search).get('tv') === '1';
|
||||||
|
let currentTvView = 'results';
|
||||||
|
|
||||||
|
function updateTvViewBtn(view) {
|
||||||
|
currentTvView = view;
|
||||||
|
const btn = document.getElementById('btnTvView');
|
||||||
|
if (!btn) return;
|
||||||
|
btn.style.background = (view === 'results') ? '#28a745' : '';
|
||||||
|
btn.style.color = (view === 'results') ? 'white' : '';
|
||||||
|
btn.style.borderColor = (view === 'results') ? '#1e7e34' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleTvView() {
|
||||||
|
const newView = currentTvView === 'results' ? 'cameras' : 'results';
|
||||||
|
try {
|
||||||
|
const payload = { view: newView };
|
||||||
|
if (newView === 'results') {
|
||||||
|
// Pass the current page path so the TV follows to this league archive, not a tournament archive
|
||||||
|
payload.tv_url = window.location.pathname;
|
||||||
|
}
|
||||||
|
await fetch('/api/tv/view', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
updateTvViewBtn(newView);
|
||||||
|
if (isTvDisplay && newView === 'cameras') {
|
||||||
|
window.location.href = '/';
|
||||||
|
}
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll to stay in sync and follow back-redirect when in TV mode
|
||||||
|
setInterval(async () => {
|
||||||
|
if (document.visibilityState !== 'visible') return;
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/dashboard/state');
|
||||||
|
if (!r.ok) return;
|
||||||
|
const d = await r.json();
|
||||||
|
updateTvViewBtn(d.tv_view || 'cameras');
|
||||||
|
if (isTvDisplay && d.tv_view !== 'results') {
|
||||||
|
if (d.tv_view === 'draft' && d.tournament_active) {
|
||||||
|
window.location.href = '/tournament/draft?tv=1';
|
||||||
|
} else {
|
||||||
|
window.location.href = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
fetch('/api/dashboard/state').then(r => r.json()).then(d => updateTvViewBtn(d.tv_view || 'cameras')).catch(() => {});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+416
-704
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,8 @@
|
|||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
min-height: 100vh;
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,6 +386,133 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── PLAYERS SPLIT LAYOUT ── */
|
||||||
|
.players-layout {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
height: calc(100vh - 50px);
|
||||||
|
padding: 8px 20px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.players-left-panel {
|
||||||
|
width: 260px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.players-panel-header {
|
||||||
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: linear-gradient(135deg, #28a745 0%, #1e7e34 100%);
|
||||||
|
border-radius: 12px 12px 0 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.players-panel-header-title {
|
||||||
|
font-size: 0.8rem; font-weight: 700; color: white; letter-spacing: 0.3px;
|
||||||
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
|
||||||
|
}
|
||||||
|
.players-panel-count {
|
||||||
|
font-size: 0.7rem; font-weight: 600;
|
||||||
|
background: rgba(255,255,255,0.25); color: white;
|
||||||
|
padding: 2px 7px; border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.players-sort-bar {
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-bottom: 1px solid #e9ecef;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #f8f9fa;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
.players-search {
|
||||||
|
width: 100%; border: 1px solid #dee2e6; border-radius: 6px;
|
||||||
|
padding: 5px 9px; font-size: 0.78rem; outline: none; background: white;
|
||||||
|
}
|
||||||
|
.players-search:focus { border-color: #28a745; }
|
||||||
|
|
||||||
|
.players-sort-btns {
|
||||||
|
display: flex; gap: 4px;
|
||||||
|
}
|
||||||
|
.psort-btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 2px 7px;
|
||||||
|
border: 2px solid #dee2e6; background: white; border-radius: 6px;
|
||||||
|
cursor: pointer; font-size: 0.6rem; font-weight: 600; color: #666;
|
||||||
|
transition: all 0.15s; white-space: nowrap; text-align: center;
|
||||||
|
}
|
||||||
|
.psort-btn.active { background: #28a745; border-color: #1e7e34; color: white; }
|
||||||
|
.psort-btn:hover:not(.active) { border-color: #28a745; color: #28a745; }
|
||||||
|
|
||||||
|
.player-tree-list {
|
||||||
|
flex: 1; overflow-y: auto; overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.player-tree-list::-webkit-scrollbar { width: 5px; }
|
||||||
|
.player-tree-list::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 3px; }
|
||||||
|
|
||||||
|
.player-tree-item {
|
||||||
|
display: flex; align-items: center;
|
||||||
|
padding: 8px 10px 8px 14px;
|
||||||
|
cursor: pointer; border-left: 4px solid transparent;
|
||||||
|
gap: 8px; transition: all 0.15s;
|
||||||
|
}
|
||||||
|
.player-tree-item:hover { background: #f0faf3; border-left-color: #7dcf95; }
|
||||||
|
.player-tree-item.active {
|
||||||
|
background: #28a745; border-left-color: #28a745;
|
||||||
|
font-weight: 700; color: white;
|
||||||
|
}
|
||||||
|
.player-tree-avatar {
|
||||||
|
width: 28px; height: 28px; border-radius: 50%;
|
||||||
|
background: #e9ecef; display: flex; align-items: center; justify-content: center;
|
||||||
|
font-size: 0.75rem; font-weight: 700; color: #666; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.player-tree-item.active .player-tree-avatar { background: rgba(255,255,255,0.25); color: white; }
|
||||||
|
.player-tree-info { flex: 1; min-width: 0; }
|
||||||
|
.player-tree-name { font-size: 0.82rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||||
|
.player-tree-meta { font-size: 0.65rem; color: #999; }
|
||||||
|
.player-tree-item.active .player-tree-meta { color: rgba(255,255,255,0.75); }
|
||||||
|
.player-tree-score {
|
||||||
|
font-size: 0.75rem; font-weight: 700; color: #28a745; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.player-tree-item.active .player-tree-score { color: rgba(255,255,255,0.9); }
|
||||||
|
.player-tree-rank {
|
||||||
|
font-size: 1.1rem; flex-shrink: 0; line-height: 1;
|
||||||
|
}
|
||||||
|
.player-tree-rank-num {
|
||||||
|
width: 24px; height: 24px; border-radius: 50%;
|
||||||
|
background: #cfe2ff; color: #084298;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
font-size: 0.6rem; font-weight: 700; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.player-tree-item.active .player-tree-rank-num {
|
||||||
|
background: rgba(255,255,255,0.3); color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.players-right-panel {
|
||||||
|
flex: 1; overflow: hidden; min-width: 0;
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
}
|
||||||
|
#playerDetailEmbed { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
||||||
|
#playerDetailEmbed iframe { flex: 1; min-height: 0; height: 100%; width: 100%; border: none; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
|
||||||
|
|
||||||
|
.player-placeholder {
|
||||||
|
flex: 1; display: flex; flex-direction: column;
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
color: #ccc; gap: 10px;
|
||||||
|
background: white; border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
.player-placeholder-icon { font-size: 2.5rem; }
|
||||||
|
.player-placeholder-text { font-size: 0.95rem; }
|
||||||
|
|
||||||
/* Compact Controls */
|
/* Compact Controls */
|
||||||
.controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -707,90 +835,44 @@
|
|||||||
<body>
|
<body>
|
||||||
<!-- Navigation Bar -->
|
<!-- Navigation Bar -->
|
||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<div class="navbar-title" data-i18n="players.player_analysis">🎯 👤 Player Analysis</div>
|
<div class="navbar-title">👤 Analiza Igralcev</div>
|
||||||
<div class="navbar-controls">
|
<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 active">👤 <span data-i18n="players.player_analysis">Analiza Igralcev</span></a>
|
||||||
<a href="/archive/player-analysis" class="nav-btn active">👤 <span data-i18n="players.player_analysis">Player Analysis</span></a>
|
|
||||||
<a href="/archive" class="nav-btn">📚 <span data-i18n="navigation.archive">Archive</span></a>
|
<a href="/archive" class="nav-btn">📚 <span data-i18n="navigation.archive">Archive</span></a>
|
||||||
|
<a href="/" class="nav-btn">✕</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="players-layout">
|
||||||
<!-- Stats Overview -->
|
|
||||||
<div class="stats-badges">
|
<!-- LEFT: player tree -->
|
||||||
<div class="stat-badge">
|
<div class="players-left-panel">
|
||||||
<span class="stat-icon">👥</span>
|
<div class="players-panel-header">
|
||||||
<div class="stat-number" id="totalPlayers">Loading...</div>
|
<div class="players-panel-header-title">👥 Igralci</div>
|
||||||
<div class="stat-label" data-i18n="players.total_players">Total Players</div>
|
<div class="players-panel-count" id="playerTreeCount">0</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-badge">
|
<div class="players-sort-bar">
|
||||||
<span class="stat-icon">🎯</span>
|
<input type="text" class="players-search" id="searchBox" placeholder="🔍 Iskanje…" oninput="filterAndSortPlayers()">
|
||||||
<div class="stat-number" id="totalTournaments">Loading...</div>
|
<div class="players-sort-btns">
|
||||||
<div class="stat-label" data-i18n="analysis.total_tournaments">Total Tournaments</div>
|
<button class="psort-btn active" data-sort="best_score" onclick="setSort('best_score')">🏆 Skupaj</button>
|
||||||
|
<button class="psort-btn" data-sort="total_tens" onclick="setSort('total_tens')">🎯 Desetke</button>
|
||||||
|
<button class="psort-btn" data-sort="best_single" onclick="setSort('best_single')">⭐ Enkrat</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-badge">
|
<div class="player-tree-list" id="playerTreeList">
|
||||||
<span class="stat-icon">🏆</span>
|
<div class="loading"><div class="loading-spinner"></div></div>
|
||||||
<div class="stat-number" id="score20Targets">Loading...</div>
|
|
||||||
<div class="stat-label" data-i18n="tournament_types.20_targets">20 Targets</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">🎖️</span>
|
|
||||||
<div class="stat-number" id="score40Targets">Loading...</div>
|
|
||||||
<div class="stat-label" data-i18n="tournament_types.40_targets">40 Targets</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">🥇</span>
|
|
||||||
<div class="stat-number" id="score4Targets">Loading...</div>
|
|
||||||
<div class="stat-label" data-i18n="tournament_types.4_targets">4 Targets</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab Navigation -->
|
<!-- RIGHT: player detail -->
|
||||||
<div class="section">
|
<div class="players-right-panel" id="playersRightPanel">
|
||||||
<div class="tab-navigation">
|
<div class="player-placeholder" id="playerPlaceholder">
|
||||||
<button class="tab-btn active" onclick="switchTab('tournament-leaders')" data-i18n="analysis.overall_champions">🏆 Overall Champions</button>
|
<div class="player-placeholder-icon">👤</div>
|
||||||
<button class="tab-btn" onclick="switchTab('players')" data-i18n="analysis.all_players">👥 All Players</button>
|
<div class="player-placeholder-text">Izberi igralca iz seznama</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Tournament Leaders Tab -->
|
|
||||||
<div id="tournament-leaders" class="tab-content active">
|
|
||||||
<div class="section-title" data-i18n="analysis.overview_champions">Overall Champions by Tournament Type</div>
|
|
||||||
|
|
||||||
<div class="tournament-leaders" id="tournamentLeaders">
|
|
||||||
<div class="loading">
|
|
||||||
<div class="loading-spinner"></div>
|
|
||||||
<p>Loading tournament data...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Players Tab -->
|
|
||||||
<div id="players" class="tab-content">
|
|
||||||
<div class="section-title" data-i18n="analysis.select_player">Izberi igralca za analizo</div>
|
|
||||||
|
|
||||||
<!-- Controls -->
|
|
||||||
<div class="controls">
|
|
||||||
<input type="text" class="search-box" id="searchBox" data-i18n-placeholder="league.search_players_placeholder" placeholder="🔍 Search players by name...">
|
|
||||||
|
|
||||||
<select class="sort-select" id="sortSelect">
|
|
||||||
<option value="name" data-i18n="analysis.sort_by_name">Sort by Name</option>
|
|
||||||
<option value="best_score" data-i18n="analysis.sort_by_best_score">Sort by Best Score</option>
|
|
||||||
<option value="average_score" data-i18n="analysis.sort_by_average_score">Sort by Average Score</option>
|
|
||||||
<option value="total_tournaments" data-i18n="analysis.sort_by_total_tournaments">Sort by Total Tournaments</option>
|
|
||||||
<option value="total_leagues" data-i18n="analysis.sort_by_total_leagues">Sort by Total Leagues</option>
|
|
||||||
<option value="total_shots" data-i18n="analysis.sort_by_total_shots">Sort by Total Shots</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Players Grid -->
|
|
||||||
<div class="players-grid" id="playersGrid">
|
|
||||||
<div class="loading">
|
|
||||||
<div class="loading-spinner"></div>
|
|
||||||
<p>Loading players...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="playerDetailEmbed" style="display:none"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -799,187 +881,15 @@
|
|||||||
let tournamentData = [];
|
let tournamentData = [];
|
||||||
let filteredPlayers = [];
|
let filteredPlayers = [];
|
||||||
let currentFilter = 'all';
|
let currentFilter = 'all';
|
||||||
let currentSort = 'name';
|
let currentSort = 'best_score';
|
||||||
let playersWithStats = [];
|
let playersWithStats = [];
|
||||||
|
|
||||||
// Initialize page
|
// Initialize page
|
||||||
function initializePage() {
|
function initializePage() {
|
||||||
loadPlayerStats();
|
loadPlayerStats();
|
||||||
loadTournamentLeaders();
|
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch between tabs
|
|
||||||
function switchTab(tabName) {
|
|
||||||
// Hide all tab contents
|
|
||||||
document.querySelectorAll('.tab-content').forEach(content => {
|
|
||||||
content.classList.remove('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove active class from all tab buttons
|
|
||||||
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
||||||
btn.classList.remove('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show selected tab content
|
|
||||||
document.getElementById(tabName).classList.add('active');
|
|
||||||
|
|
||||||
// Add active class to clicked button
|
|
||||||
event.target.classList.add('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load tournament leaders data
|
|
||||||
async function loadTournamentLeaders() {
|
|
||||||
try {
|
|
||||||
const response = await fetch('/api/archive/tournament-leaders');
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.status === 'success') {
|
|
||||||
tournamentData = result.tournament_types;
|
|
||||||
renderTournamentLeaders();
|
|
||||||
updateOverallStats();
|
|
||||||
} else {
|
|
||||||
console.error('Failed to load tournament data:', result.message);
|
|
||||||
document.getElementById('tournamentLeaders').innerHTML = `
|
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">🎯</div>
|
|
||||||
<h3 data-i18n="analysis.unable_load_data">Ne morem naložiti podatkov turnirja</h3>
|
|
||||||
<p>${result.message || 'Please try refreshing the page'}</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading tournament data:', error);
|
|
||||||
document.getElementById('tournamentLeaders').innerHTML = `
|
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">🎯</div>
|
|
||||||
<h3>Unable to Load Tournament Data</h3>
|
|
||||||
<p>Please try refreshing the page</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render tournament leaders
|
|
||||||
function renderTournamentLeaders() {
|
|
||||||
const leadersContainer = document.getElementById('tournamentLeaders');
|
|
||||||
|
|
||||||
if (tournamentData.length === 0) {
|
|
||||||
leadersContainer.innerHTML = `
|
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">🎯</div>
|
|
||||||
<h3 data-i18n="analysis.no_tournament_data">Ni podatkov o turnirju</h3>
|
|
||||||
<p>Tournament results will appear here once available</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort tournament types by target count: 4, 20, 40
|
|
||||||
const sortOrder = ['4_targets', '20_targets', '40_targets'];
|
|
||||||
const sortedTournamentData = [...tournamentData].sort((a, b) => {
|
|
||||||
const indexA = sortOrder.indexOf(a.id);
|
|
||||||
const indexB = sortOrder.indexOf(b.id);
|
|
||||||
|
|
||||||
// If not in sortOrder, put at end
|
|
||||||
if (indexA === -1 && indexB === -1) return 0;
|
|
||||||
if (indexA === -1) return 1;
|
|
||||||
if (indexB === -1) return -1;
|
|
||||||
|
|
||||||
return indexA - indexB;
|
|
||||||
});
|
|
||||||
|
|
||||||
leadersContainer.innerHTML = sortedTournamentData.map(tournamentType => {
|
|
||||||
// Get translated tournament name and description based on tournament type
|
|
||||||
let translatedName = tournamentType.name;
|
|
||||||
let translatedDescription = tournamentType.description;
|
|
||||||
|
|
||||||
switch(tournamentType.id) {
|
|
||||||
case '4_targets':
|
|
||||||
translatedName = t('tournament_types.4_targets');
|
|
||||||
translatedDescription = t('tournament_types.4_targets_desc');
|
|
||||||
break;
|
|
||||||
case '20_targets':
|
|
||||||
translatedName = t('tournament_types.20_targets');
|
|
||||||
translatedDescription = t('tournament_types.20_targets_desc');
|
|
||||||
break;
|
|
||||||
case '40_targets':
|
|
||||||
translatedName = t('tournament_types.40_targets');
|
|
||||||
translatedDescription = t('tournament_types.40_targets_desc');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `
|
|
||||||
<div class="tournament-card" data-type="${tournamentType.id}">
|
|
||||||
<div class="tournament-header">
|
|
||||||
<div class="tournament-name">${translatedName}</div>
|
|
||||||
<div class="tournament-date">${tournamentType.total_tournaments} ${tournamentType.total_tournaments === 1 ? t('tournament.tournament') : t('tournament.tournaments')}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="text-align: center; margin-bottom: 28px; color: rgba(255, 255, 255, 0.95); font-size: 1rem; font-weight: 500; position: relative; z-index: 3; background: rgba(0, 0, 0, 0.15); padding: 14px 24px; border-radius: 14px; backdrop-filter: blur(15px); border: 1px solid rgba(255, 255, 255, 0.25); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);">
|
|
||||||
${translatedDescription}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="leaders-grid">
|
|
||||||
<div class="leader-category">
|
|
||||||
<div class="category-title">🏆 ${t('analysis.best_score')}</div>
|
|
||||||
<div class="leader-info">
|
|
||||||
<div class="leader-name">${tournamentType.best_score.player_name || t('messages.no_data')}</div>
|
|
||||||
<div class="leader-score">${tournamentType.best_score.score || 0}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="leader-category">
|
|
||||||
<div class="category-title">🎯 ${t('analysis.most_tens')}</div>
|
|
||||||
<div class="leader-info">
|
|
||||||
<div class="leader-name">${tournamentType.most_tens.player_name || t('messages.no_data')}</div>
|
|
||||||
<div class="leader-score tens">${tournamentType.most_tens.tens || 0}x 🎯</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update overall statistics
|
|
||||||
function updateOverallStats() {
|
|
||||||
let totalTournaments = 0;
|
|
||||||
let score20Targets = 0;
|
|
||||||
let score40Targets = 0;
|
|
||||||
let score4Targets = 0;
|
|
||||||
|
|
||||||
// Calculate statistics across all tournament types
|
|
||||||
tournamentData.forEach(tournamentType => {
|
|
||||||
totalTournaments += tournamentType.total_tournaments || 0;
|
|
||||||
|
|
||||||
// Get best scores for each tournament type using the id field
|
|
||||||
if (tournamentType.id === '20_targets' && tournamentType.best_score) {
|
|
||||||
score20Targets = tournamentType.best_score.score || 0;
|
|
||||||
} else if (tournamentType.id === '40_targets' && tournamentType.best_score) {
|
|
||||||
score40Targets = tournamentType.best_score.score || 0;
|
|
||||||
} else if (tournamentType.id === '4_targets' && tournamentType.best_score) {
|
|
||||||
score4Targets = tournamentType.best_score.score || 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('totalTournaments').textContent = totalTournaments;
|
|
||||||
document.getElementById('score20Targets').textContent = score20Targets || '-';
|
|
||||||
document.getElementById('score40Targets').textContent = score40Targets || '-';
|
|
||||||
document.getElementById('score4Targets').textContent = score4Targets || '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get tournament type display name
|
|
||||||
function getTournamentTypeDisplay(tournamentType) {
|
|
||||||
const typeMap = {
|
|
||||||
'20_targets': t('tournament_types.20_targets_full'),
|
|
||||||
'40_targets': t('tournament_types.40_targets_full'),
|
|
||||||
'4_targets': t('tournament_types.4_targets_full')
|
|
||||||
};
|
|
||||||
return typeMap[tournamentType] || tournamentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format date for display
|
// Format date for display
|
||||||
function formatDate(dateString) {
|
function formatDate(dateString) {
|
||||||
if (!dateString) return t('analysis.unknown_date');
|
if (!dateString) return t('analysis.unknown_date');
|
||||||
@@ -1026,7 +936,7 @@
|
|||||||
filteredPlayers = [...playersWithStats];
|
filteredPlayers = [...playersWithStats];
|
||||||
|
|
||||||
// Update total players count
|
// Update total players count
|
||||||
document.getElementById('totalPlayers').textContent = playersData.length;
|
document.getElementById('playerTreeCount').textContent = playersData.length;
|
||||||
|
|
||||||
filterAndSortPlayers();
|
filterAndSortPlayers();
|
||||||
} else {
|
} else {
|
||||||
@@ -1041,176 +951,95 @@
|
|||||||
|
|
||||||
// Setup event listeners
|
// Setup event listeners
|
||||||
function setupEventListeners() {
|
function setupEventListeners() {
|
||||||
const searchBox = document.getElementById('searchBox');
|
// search handled inline via oninput on the input element
|
||||||
const sortSelect = document.getElementById('sortSelect');
|
}
|
||||||
|
|
||||||
searchBox.addEventListener('input', filterAndSortPlayers);
|
function setSort(sort) {
|
||||||
sortSelect.addEventListener('change', (e) => {
|
currentSort = sort;
|
||||||
currentSort = e.target.value;
|
document.querySelectorAll('.psort-btn').forEach(b =>
|
||||||
filterAndSortPlayers();
|
b.classList.toggle('active', b.dataset.sort === sort));
|
||||||
});
|
filterAndSortPlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter and sort players
|
// Filter and sort players
|
||||||
function filterAndSortPlayers() {
|
function filterAndSortPlayers() {
|
||||||
const searchTerm = document.getElementById('searchBox').value.toLowerCase();
|
const searchTerm = document.getElementById('searchBox').value.toLowerCase();
|
||||||
|
|
||||||
// Filter players
|
// Sort full list and assign permanent ranks
|
||||||
filteredPlayers = playersData.filter(player => {
|
const sorted = [...playersData].sort((a, b) => {
|
||||||
|
switch (currentSort) {
|
||||||
|
case 'best_score': return (b.stats?.best_tournament_score || 0) - (a.stats?.best_tournament_score || 0);
|
||||||
|
case 'total_tens': return (b.stats?.total_tens || 0) - (a.stats?.total_tens || 0);
|
||||||
|
case 'best_single': return (b.stats?.best_tournament_score || 0) - (a.stats?.best_tournament_score || 0);
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sorted.forEach((p, i) => { p._rank = i + 1; });
|
||||||
|
|
||||||
|
// Filter preserving original rank
|
||||||
|
filteredPlayers = sorted.filter(player => {
|
||||||
const matchesSearch = player.name.toLowerCase().includes(searchTerm);
|
const matchesSearch = player.name.toLowerCase().includes(searchTerm);
|
||||||
const matchesFilter = currentFilter === 'all' ||
|
const matchesFilter = currentFilter === 'all' ||
|
||||||
(currentFilter === 'current' && player.current_player) ||
|
(currentFilter === 'current' && player.current_player) ||
|
||||||
(currentFilter === 'archived' && !player.current_player);
|
(currentFilter === 'archived' && !player.current_player);
|
||||||
|
|
||||||
return matchesSearch && matchesFilter;
|
return matchesSearch && matchesFilter;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort players
|
|
||||||
filteredPlayers.sort((a, b) => {
|
|
||||||
switch (currentSort) {
|
|
||||||
case 'name':
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
case 'best_score':
|
|
||||||
return (b.stats?.best_tournament_score || 0) - (a.stats?.best_tournament_score || 0);
|
|
||||||
case 'average_score':
|
|
||||||
return (b.stats?.average_tournament_score || 0) - (a.stats?.average_tournament_score || 0);
|
|
||||||
case 'total_tournaments':
|
|
||||||
return (b.stats?.total_tournaments || 0) - (a.stats?.total_tournaments || 0);
|
|
||||||
case 'total_leagues':
|
|
||||||
return (b.stats?.total_leagues || 0) - (a.stats?.total_leagues || 0);
|
|
||||||
case 'total_shots':
|
|
||||||
return (b.stats?.total_shots_fired || 0) - (a.stats?.total_shots_fired || 0);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
renderPlayers();
|
renderPlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render players with stats
|
// Render players into the tree panel
|
||||||
|
let activePlayerId = null;
|
||||||
|
|
||||||
function renderPlayers() {
|
function renderPlayers() {
|
||||||
const playersGrid = document.getElementById('playersGrid');
|
const treeList = document.getElementById('playerTreeList');
|
||||||
|
document.getElementById('playerTreeCount').textContent = filteredPlayers.length;
|
||||||
|
|
||||||
if (filteredPlayers.length === 0) {
|
if (filteredPlayers.length === 0) {
|
||||||
playersGrid.innerHTML = `
|
treeList.innerHTML = `<div style="padding:24px;text-align:center;color:#bbb;font-size:0.82rem">Ni zadetkov</div>`;
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">👤</div>
|
|
||||||
<h3>No Players Found</h3>
|
|
||||||
<p>Try adjusting your search or filter criteria</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
playersGrid.innerHTML = filteredPlayers.map(player => `
|
treeList.innerHTML = filteredPlayers.map((player) => {
|
||||||
<div class="player-card ${player.current_player ? 'current-player' : 'archived-player'}"
|
const initials = player.name.split(' ').map(w => w[0]).join('').slice(0, 2).toUpperCase();
|
||||||
onclick="viewPlayerStats(${player.id})">
|
const active = player.id === activePlayerId ? ' active' : '';
|
||||||
<div class="player-header">
|
let scoreVal, scoreMeta;
|
||||||
<div class="player-name">${player.name}</div>
|
if (currentSort === 'total_tens') {
|
||||||
|
scoreVal = player.stats?.total_tens || 0;
|
||||||
|
scoreMeta = `${scoreVal} 🎯`;
|
||||||
|
} else {
|
||||||
|
scoreVal = player.stats?.best_tournament_score || 0;
|
||||||
|
scoreMeta = `${scoreVal} pts`;
|
||||||
|
}
|
||||||
|
const rank = player._rank || 0;
|
||||||
|
const rankHtml = rank === 1 ? `<div class="player-tree-rank">🥇</div>`
|
||||||
|
: rank === 2 ? `<div class="player-tree-rank">🥈</div>`
|
||||||
|
: rank === 3 ? `<div class="player-tree-rank">🥉</div>`
|
||||||
|
: `<div class="player-tree-rank-num">${rank}</div>`;
|
||||||
|
return `<div class="player-tree-item${active}" onclick="selectPlayer(${player.id})">
|
||||||
|
${rankHtml}
|
||||||
|
<div class="player-tree-info">
|
||||||
|
<div class="player-tree-name">${player.name}</div>
|
||||||
|
<div class="player-tree-meta">${player.stats?.total_tournaments || 0}T · ${scoreMeta}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>`;
|
||||||
<div class="player-stats">
|
}).join('');
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">🎯</span>
|
|
||||||
<span class="label">${t('tournament.tournaments')}:</span>
|
|
||||||
<span class="value">${player.stats?.total_tournaments || 0}</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">🏆</span>
|
|
||||||
<span class="label">${t('league.league')}:</span>
|
|
||||||
<span class="value">${player.stats?.total_leagues || 0}</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">📈</span>
|
|
||||||
<span class="label">${t('analysis.best_score_label')}</span>
|
|
||||||
<span class="value">${player.stats?.best_tournament_score || 0}</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">📊</span>
|
|
||||||
<span class="label">${t('results.average_score')}</span>
|
|
||||||
<span class="value">${Math.round(player.stats?.average_tournament_score || 0)}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="player-chart">
|
|
||||||
<canvas class="chart-canvas" id="chart-${player.id}"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`).join('');
|
|
||||||
|
|
||||||
// Create mini charts for each player
|
|
||||||
setTimeout(() => {
|
|
||||||
filteredPlayers.forEach(player => {
|
|
||||||
if (player.stats?.performance_trend) {
|
|
||||||
createMiniChart(player);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render players without stats (fallback)
|
// Render players without stats (fallback)
|
||||||
function renderPlayersBasic() {
|
function renderPlayersBasic() {
|
||||||
// If we can't get stats, try to get basic player list
|
|
||||||
fetch('/api/players')
|
fetch('/api/players')
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const basicPlayers = data.players || [];
|
const basicPlayers = data.players || [];
|
||||||
const playersGrid = document.getElementById('playersGrid');
|
playersData = basicPlayers.map(p => ({ id: p.id, name: p.name, current_player: p.enabled, stats: {} }));
|
||||||
|
filteredPlayers = [...playersData];
|
||||||
if (basicPlayers.length === 0) {
|
document.getElementById('playerTreeCount').textContent = playersData.length;
|
||||||
playersGrid.innerHTML = `
|
renderPlayers();
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">👤</div>
|
|
||||||
<h3>No Players Found</h3>
|
|
||||||
<p>No player data available</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
playersGrid.innerHTML = basicPlayers.map(player => `
|
|
||||||
<div class="player-card ${player.enabled ? 'current-player' : 'archived-player'}"
|
|
||||||
onclick="viewPlayerStats(${player.id})">
|
|
||||||
<div class="player-header">
|
|
||||||
<div class="player-name">${player.name}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="player-stats">
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">🎯</span>
|
|
||||||
<span class="label">${t('tournament.tournaments')}:</span>
|
|
||||||
<span class="value">Loading...</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">🏆</span>
|
|
||||||
<span class="label">${t('league.league')}:</span>
|
|
||||||
<span class="value">Loading...</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">📈</span>
|
|
||||||
<span class="label">${t('analysis.best_score_label')}</span>
|
|
||||||
<span class="value">Loading...</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="icon">📊</span>
|
|
||||||
<span class="label">${t('results.average_score')}</span>
|
|
||||||
<span class="value">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`).join('');
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(() => {
|
||||||
console.error('Error loading basic players:', error);
|
document.getElementById('playerTreeList').innerHTML =
|
||||||
const playersGrid = document.getElementById('playersGrid');
|
`<div style="padding:24px;text-align:center;color:#bbb;font-size:0.82rem">Napaka pri nalaganju</div>`;
|
||||||
playersGrid.innerHTML = `
|
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">❌</div>
|
|
||||||
<h3>Error Loading Players</h3>
|
|
||||||
<p>Unable to load player data</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1265,9 +1094,20 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Navigate to player stats
|
// Select player — load stats into right panel iframe
|
||||||
|
function selectPlayer(playerId) {
|
||||||
|
activePlayerId = playerId;
|
||||||
|
renderPlayers();
|
||||||
|
|
||||||
|
document.getElementById('playerPlaceholder').style.display = 'none';
|
||||||
|
const embed = document.getElementById('playerDetailEmbed');
|
||||||
|
embed.style.display = 'block';
|
||||||
|
embed.innerHTML = `<iframe src="/archive/player/${playerId}"></iframe>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate to player stats (kept for compatibility)
|
||||||
function viewPlayerStats(playerId) {
|
function viewPlayerStats(playerId) {
|
||||||
window.location.href = `/archive/player/${playerId}`;
|
selectPlayer(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize page when DOM is loaded and translations are ready
|
// Initialize page when DOM is loaded and translations are ready
|
||||||
|
|||||||
+648
-224
@@ -25,6 +25,9 @@
|
|||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.in-iframe .navbar { display: none; }
|
||||||
|
body.in-iframe { background: transparent; }
|
||||||
|
|
||||||
/* Standardized Container */
|
/* Standardized Container */
|
||||||
.container {
|
.container {
|
||||||
max-width: 1400px;
|
max-width: 1400px;
|
||||||
@@ -73,6 +76,45 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tournament Badge Styling */
|
||||||
|
.stat-badge.tournament-badge {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tournament-scores {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tournament-score-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tournament-type {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: #999;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tournament-emoji {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tournament-best {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
/* Charts Section */
|
/* Charts Section */
|
||||||
.charts-section {
|
.charts-section {
|
||||||
min-height: 450px;
|
min-height: 450px;
|
||||||
@@ -147,7 +189,7 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
width: 100%;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -625,6 +667,49 @@
|
|||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shot Count Cards */
|
||||||
|
.shot-count-cards {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(70px, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 25px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-count-card {
|
||||||
|
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-count-card:hover {
|
||||||
|
box-shadow: 0 4px 12px rgba(40, 167, 69, 0.15);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
border-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-score {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #28a745;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-count {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
.history-list {
|
.history-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -968,7 +1053,226 @@
|
|||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Responsive Shot Count Cards */
|
||||||
|
.shot-count-cards {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-count-card {
|
||||||
|
min-height: 80px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-score {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shot-count {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Overall Accuracy Dashboard */
|
||||||
|
.overall-top-section {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gauge-section {
|
||||||
|
flex: 0 0 100%;
|
||||||
|
min-height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-group {
|
||||||
|
flex: 0 0 100%;
|
||||||
|
grid-template-columns: 2fr 2fr;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overall-bottom-section {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overall-bar-chart,
|
||||||
|
.overall-radar-chart {
|
||||||
|
min-height: 280px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-icon {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-value {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gauge-stats {
|
||||||
|
gap: 15px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gauge-stat-value {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accuracy-gauge-wrapper {
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── SINGLE CARD LAYOUT ── */
|
||||||
|
body { overflow: hidden; }
|
||||||
|
|
||||||
|
.ps-layout {
|
||||||
|
display: flex; gap: 8px;
|
||||||
|
height: calc(100vh - 50px);
|
||||||
|
padding: 8px 12px 10px;
|
||||||
|
}
|
||||||
|
body.in-iframe .ps-layout { height: 100vh; }
|
||||||
|
|
||||||
|
.ps-card {
|
||||||
|
background: white; border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
overflow: hidden; display: flex; flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ps-left {
|
||||||
|
flex: 1; min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card header */
|
||||||
|
.ps-topbar {
|
||||||
|
display: flex; align-items: center;
|
||||||
|
padding: 6px 12px; flex-shrink: 0; gap: 8px;
|
||||||
|
background: #f8f9fa; border-bottom: 2px solid #e9ecef;
|
||||||
|
border-radius: 10px 10px 0 0;
|
||||||
|
}
|
||||||
|
.ps-type-btns { display: flex; gap: 4px; flex-shrink: 0; }
|
||||||
|
.ps-type-btns .type-btn {
|
||||||
|
padding: 7px 10px; font-size: 0.7rem; border-radius: 6px;
|
||||||
|
border: 2px solid #dee2e6; background: white; color: #666;
|
||||||
|
cursor: pointer; font-weight: 600; transition: all 0.15s; white-space: nowrap;
|
||||||
|
flex-shrink: 0; width: auto;
|
||||||
|
}
|
||||||
|
.ps-type-btns .type-btn.active.targets-40 { background: #8b00ff; border-color: #6a00cc; color: white; }
|
||||||
|
.ps-type-btns .type-btn.active.targets-20 { background: #fd7e14; border-color: #e06c0a; color: white; }
|
||||||
|
.ps-type-btns .type-btn.active.targets-4 { background: #28a745; border-color: #1e7e34; color: white; }
|
||||||
|
.ps-type-btns .type-btn:hover:not(.active) { border-color: #28a745; color: #28a745; }
|
||||||
|
.ps-mini-stats { display: flex; gap: 20px; margin-left: auto; }
|
||||||
|
.ps-mini-stats .chart-stat { text-align: center; }
|
||||||
|
.ps-mini-stats .chart-stat-value { font-size: 0.85rem; font-weight: 700; color: #28a745; line-height: 1.1; }
|
||||||
|
.ps-mini-stats .chart-stat-label { font-size: 0.6rem; color: #aaa; }
|
||||||
|
|
||||||
|
/* Graph sections */
|
||||||
|
.ps-sections { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; }
|
||||||
|
.ps-section {
|
||||||
|
display: flex; flex-direction: column; flex: 1; min-height: 0;
|
||||||
|
border-bottom: 1px solid #e9ecef; padding: 6px 14px 4px;
|
||||||
|
}
|
||||||
|
.ps-section:last-child { border-bottom: none; }
|
||||||
|
.ps-section-header {
|
||||||
|
display: flex; align-items: baseline; gap: 6px; flex-shrink: 0; margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.ps-section-title {
|
||||||
|
font-size: 0.7rem; font-weight: 700; color: #444; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ps-section-desc {
|
||||||
|
font-size: 0.6rem; color: #aaa;
|
||||||
|
}
|
||||||
|
.ps-section-body {
|
||||||
|
display: flex; gap: 8px; flex: 1; min-height: 0;
|
||||||
|
}
|
||||||
|
.ps-chart-wrap {
|
||||||
|
flex: 1; min-width: 0; min-height: 0; position: relative;
|
||||||
|
}
|
||||||
|
.ps-chart-wrap canvas { width: 100% !important; height: 100% !important; }
|
||||||
|
.ps-radar-wrap { flex: 0 0 30%; }
|
||||||
|
|
||||||
|
/* Shot count badges */
|
||||||
|
.ps-shot-counts {
|
||||||
|
flex: 0 0 72px; border-left: 1px solid #e9ecef;
|
||||||
|
display: flex; flex-direction: column; justify-content: space-around;
|
||||||
|
padding: 4px 8px; gap: 2px;
|
||||||
|
}
|
||||||
|
.ps-sc-row {
|
||||||
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
|
gap: 4px; font-size: 0.62rem;
|
||||||
|
}
|
||||||
|
.ps-sc-badge {
|
||||||
|
width: 18px; height: 18px; border-radius: 5px;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
font-weight: 700; font-size: 0.6rem; color: white; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.ps-sc-count {
|
||||||
|
font-size: 0.68rem; font-weight: 600; color: #555; text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right: history column */
|
||||||
|
.ps-right {
|
||||||
|
width: 220px; flex-shrink: 0; display: flex; flex-direction: column;
|
||||||
|
}
|
||||||
|
.ps-hist-header {
|
||||||
|
display: flex; flex-direction: column; gap: 5px;
|
||||||
|
padding: 7px 10px; flex-shrink: 0;
|
||||||
|
background: #f8f9fa; border-bottom: 2px solid #e9ecef;
|
||||||
|
border-radius: 10px 10px 0 0;
|
||||||
|
}
|
||||||
|
.ps-hist-title { font-size: 0.78rem; font-weight: 700; color: #444; }
|
||||||
|
.ps-hist-tabs { display: flex; gap: 4px; }
|
||||||
|
.ps-hist-tabs .history-tab {
|
||||||
|
flex: 1; padding: 3px 6px; font-size: 0.65rem; border-radius: 6px;
|
||||||
|
border: 2px solid #dee2e6; background: white; color: #555;
|
||||||
|
cursor: pointer; font-weight: 600; transition: all 0.15s; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ps-hist-tabs .history-tab.active { background: #28a745; border-color: #1e7e34; color: white; }
|
||||||
|
.ps-hist-tabs .history-tab:hover:not(.active) { border-color: #28a745; color: #28a745; }
|
||||||
|
|
||||||
|
.ps-history-body { flex: 1; overflow-y: auto; min-height: 0; }
|
||||||
|
.ps-history-body::-webkit-scrollbar { width: 4px; }
|
||||||
|
.ps-history-body::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 2px; }
|
||||||
|
|
||||||
|
.ps-hist-item {
|
||||||
|
display: flex; align-items: center; gap: 6px;
|
||||||
|
padding: 7px 10px 7px 12px;
|
||||||
|
cursor: pointer; border-left: 3px solid transparent;
|
||||||
|
transition: all 0.15s; border-bottom: 1px solid #f5f5f5; font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
.ps-hist-item:hover { background: #f0faf3; border-left-color: #28a745; }
|
||||||
|
.ps-hist-item.active { background: #28a745; border-left-color: #1e7e34; color: white; }
|
||||||
|
.ps-hist-date { color: #888; font-size: 0.68rem; flex-shrink: 0; }
|
||||||
|
.ps-hist-item.active .ps-hist-date { color: rgba(255,255,255,0.8); }
|
||||||
|
.ps-hist-info { flex: 1; min-width: 0; }
|
||||||
|
.ps-hist-score { font-weight: 700; color: #28a745; flex-shrink: 0; font-size: 0.88rem; }
|
||||||
|
.ps-hist-item.active .ps-hist-score { color: white; }
|
||||||
|
.ps-hist-arrow { color: #ddd; flex-shrink: 0; font-size: 0.72rem; }
|
||||||
|
|
||||||
|
.ps-league-scores { display: flex; gap: 3px; flex-wrap: wrap; }
|
||||||
|
.ps-ls { font-size: 0.68rem; padding: 1px 4px; border-radius: 4px; background: #f0f0f0; }
|
||||||
|
.ps-ls-joker { opacity: 0.5; }
|
||||||
|
.ps-ls-excl { text-decoration: line-through; color: #999; background: #fee; }
|
||||||
|
|
||||||
|
.history-tab-content { display: none; }
|
||||||
|
.history-tab-content.active { display: block; }
|
||||||
</style>
|
</style>
|
||||||
<script src="/static/js/i18n.js"></script>
|
<script src="/static/js/i18n.js"></script>
|
||||||
</head>
|
</head>
|
||||||
@@ -977,240 +1281,127 @@
|
|||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<div class="navbar-title">📊 {{ player.name }} - <span data-i18n="players.player_stats">Stats</span></div>
|
<div class="navbar-title">📊 {{ player.name }} - <span data-i18n="players.player_stats">Stats</span></div>
|
||||||
<div class="navbar-controls">
|
<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 active">👤 <span data-i18n="players.player_analysis">Player Analysis</span></a>
|
<a href="/archive/player-analysis" class="nav-btn active">👤 <span data-i18n="players.player_analysis">Player Analysis</span></a>
|
||||||
<a href="/archive" class="nav-btn">📚 <span data-i18n="navigation.archive">Archive</span></a>
|
<a href="/archive" class="nav-btn">📚 <span data-i18n="navigation.archive">Archive</span></a>
|
||||||
|
<a href="/" class="nav-btn">✕</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="ps-layout">
|
||||||
<!-- Stats Overview -->
|
|
||||||
<div class="stats-badges">
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">🏆</span>
|
|
||||||
<div class="stat-number">{{ stats.total_tournaments }}</div>
|
|
||||||
<div class="stat-label" data-i18n="tournament.tournaments">Tournaments</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">🎖️</span>
|
|
||||||
<div class="stat-number">{{ stats.total_leagues }}</div>
|
|
||||||
<div class="stat-label" data-i18n="league.league">Leagues</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">⭐</span>
|
|
||||||
<div class="stat-number">{{ stats.best_tournament_score }}</div>
|
|
||||||
<div class="stat-label" data-i18n="results.best_score">Best Score</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">📊</span>
|
|
||||||
<div class="stat-number">{{ stats.average_tournament_score|round|int if stats.average_tournament_score > 0 else 0 }}</div>
|
|
||||||
<div class="stat-label" data-i18n="results.average_score">Average</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">🔫</span>
|
|
||||||
<div class="stat-number">{{ stats.total_shots_fired|default(0) }}</div>
|
|
||||||
<div class="stat-label" data-i18n="results.total_shots">Total Shots</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-badge">
|
|
||||||
<span class="stat-icon">📉</span>
|
|
||||||
<div class="stat-number">{{ stats.worst_tournament_score if stats.worst_tournament_score > 0 else 0 }}</div>
|
|
||||||
<div class="stat-label" data-i18n="results.worst_score">Worst Score</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Card 1: Overall Accuracy (Colorful - No Filters) -->
|
<!-- LEFT: stats card -->
|
||||||
<div class="overall-accuracy-card">
|
<div class="ps-card ps-left">
|
||||||
<div class="panel-title">📊 <span data-i18n="analysis.shot_accuracy">Overall Shot Accuracy</span></div>
|
|
||||||
|
|
||||||
<!-- Overall Shot Accuracy Section -->
|
<!-- Card header: filter buttons -->
|
||||||
<div class="overall-content-wrapper">
|
<div class="ps-topbar ps-topbar-header">
|
||||||
<div class="overall-chart-left">
|
<div class="tournament-type-buttons ps-type-btns">
|
||||||
<canvas id="overallAccuracyChart"></canvas>
|
<button class="type-btn active targets-40" data-type="40 Targets"><span>💪</span> 40T</button>
|
||||||
|
<button class="type-btn targets-20" data-type="20 Targets"><span>⚡</span> 20T</button>
|
||||||
|
<button class="type-btn targets-4" data-type="4 Targets"><span>🎯</span> 4T</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="overall-radar-right">
|
<div class="ps-mini-stats">
|
||||||
<canvas id="overallRadarChart"></canvas>
|
<div class="chart-stat"><div class="chart-stat-value" id="gameCount">0</div><div class="chart-stat-label">Iger</div></div>
|
||||||
|
<div class="chart-stat"><div class="chart-stat-value" id="bestScore">0</div><div class="chart-stat-label">Najboljši</div></div>
|
||||||
|
<div class="chart-stat"><div class="chart-stat-value" id="avgScore">0</div><div class="chart-stat-label">Povprečje</div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Card 2: Filtered Accuracy (Main Outer Card - White) -->
|
<div class="ps-sections">
|
||||||
<div style="background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); padding: 24px; margin-bottom: 30px; border: 1px solid #e9ecef;">
|
|
||||||
<div class="panel-title">📊 <span data-i18n="analysis.comparison">Filtered Analysis</span></div>
|
|
||||||
|
|
||||||
<!-- Filter Controls (Top - Outside inner cards) -->
|
<!-- Section 1: Natančnost -->
|
||||||
<div class="tournament-type-buttons" style="margin-bottom: 30px;">
|
<div class="ps-section">
|
||||||
<button class="type-btn active targets-40" data-type="40 Targets">
|
<div class="ps-section-header">
|
||||||
<span>💪</span> <span data-i18n="tournament_types.40_targets">40 Targets</span>
|
<span class="ps-section-title">🎯 Natančnost strelov</span>
|
||||||
</button>
|
<span class="ps-section-desc">Kako pogosto zadeneš posamezno vrednost</span>
|
||||||
<button class="type-btn targets-20" data-type="20 Targets">
|
</div>
|
||||||
<span>⚡</span> <span data-i18n="tournament_types.20_targets">20 Targets</span>
|
<div class="ps-section-body">
|
||||||
</button>
|
<div class="ps-chart-wrap"><canvas id="accuracyChart"></canvas></div>
|
||||||
<button class="type-btn targets-4" data-type="4 Targets">
|
|
||||||
<span>🎯</span> <span data-i18n="tournament_types.4_targets">4 Targets</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Stats Inner Card -->
|
|
||||||
<div style="background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border-radius: 8px; padding: 16px; margin-bottom: 20px; border: 1px solid #e9ecef;">
|
|
||||||
<div class="chart-info" id="chartInfo">
|
|
||||||
<div class="chart-stats">
|
|
||||||
<div class="chart-stat">
|
|
||||||
<div class="chart-stat-value" id="gameCount">0</div>
|
|
||||||
<div class="chart-stat-label" data-i18n="tournament.tournaments">Games</div>
|
|
||||||
</div>
|
|
||||||
<div class="chart-stat">
|
|
||||||
<div class="chart-stat-value" id="avgScore">0</div>
|
|
||||||
<div class="chart-stat-label" data-i18n="results.average_score">Average</div>
|
|
||||||
</div>
|
|
||||||
<div class="chart-stat">
|
|
||||||
<div class="chart-stat-value" id="bestScore">0</div>
|
|
||||||
<div class="chart-stat-label" data-i18n="results.best_score">Best</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Performance Line Chart Inner Card -->
|
<!-- Section 2: Napredek + Profil -->
|
||||||
<div style="background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border-radius: 8px; padding: 16px; margin-bottom: 20px; border: 1px solid #e9ecef;">
|
<div class="ps-section">
|
||||||
<div class="chart-container">
|
<div class="ps-section-body">
|
||||||
<canvas id="tournamentChart"></canvas>
|
<div style="display:flex; flex-direction:column; flex:1; min-width:0; min-height:0;">
|
||||||
</div>
|
<div class="ps-section-header">
|
||||||
</div>
|
<span class="ps-section-title">📈 Napredek</span>
|
||||||
|
<span class="ps-section-desc">Rezultati skozi čas po turnirjih</span>
|
||||||
<!-- Filtered Shot Accuracy Charts Container -->
|
</div>
|
||||||
<div class="accuracy-charts-container">
|
<div class="ps-chart-wrap" style="flex:1; min-height:0;"><canvas id="tournamentChart"></canvas></div>
|
||||||
<!-- Shot Accuracy Bar Chart Card -->
|
</div>
|
||||||
<div style="background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border-radius: 8px; padding: 16px; border: 1px solid #e9ecef;">
|
<div style="display:flex; flex-direction:column; flex:0 0 32%; min-height:0; border-left:1px solid #e9ecef; padding-left:10px;">
|
||||||
<div class="accuracy-section">
|
<div class="ps-section-header">
|
||||||
<div class="accuracy-chart-container">
|
<span class="ps-section-title">🕸 Profil</span>
|
||||||
<canvas id="accuracyChart"></canvas>
|
<span class="ps-section-desc">Razporeditev strelov</span>
|
||||||
|
</div>
|
||||||
|
<div class="ps-chart-wrap" style="flex:1; min-height:0;"><canvas id="accuracyRadarChart"></canvas></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Shot Accuracy Radar Chart Card -->
|
</div>
|
||||||
<div style="background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border-radius: 8px; padding: 16px; border: 1px solid #e9ecef;">
|
|
||||||
<div class="accuracy-section">
|
</div><!-- ps-left card -->
|
||||||
<div class="accuracy-chart-container">
|
|
||||||
<canvas id="accuracyRadarChart"></canvas>
|
<!-- RIGHT: history card -->
|
||||||
|
<div class="ps-card ps-right">
|
||||||
|
<div class="ps-hist-header">
|
||||||
|
<div class="ps-hist-title">📜 Zgodovina</div>
|
||||||
|
<div class="history-tabs ps-hist-tabs">
|
||||||
|
<button class="history-tab active" data-tab="tournaments">🎯 T</button>
|
||||||
|
<button class="history-tab" data-tab="leagues">🏆 L</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ps-history-body">
|
||||||
|
<!-- Tournament History -->
|
||||||
|
<div id="tournaments-tab" class="history-tab-content active">
|
||||||
|
{% if stats.tournament_history %}
|
||||||
|
{% for tournament in stats.tournament_history %}
|
||||||
|
<div class="ps-hist-item" onclick="window.location.href='/archive/tournament/{{ tournament.filename }}'">
|
||||||
|
<div class="ps-hist-date">{{ tournament.date[:10] if tournament.date != 'Unknown' else '?' }}</div>
|
||||||
|
<div class="ps-hist-info">
|
||||||
|
<span class="tournament-type-badge" data-tournament-type="{{ tournament.tournament_type }}">{{ tournament.tournament_type.replace('_targets','T') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ps-hist-score">{{ tournament.score }}</div>
|
||||||
|
<div class="ps-hist-arrow">→</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="empty-state"><div class="empty-icon">🎯</div><div>Ni zgodovine</div></div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
<!-- League History -->
|
||||||
|
<div id="leagues-tab" class="history-tab-content">
|
||||||
<!-- Bottom Section - History Tables in Single Card -->
|
{% if stats.league_history %}
|
||||||
<div class="history-section">
|
{% for league in stats.league_history %}
|
||||||
<div class="panel-title">📜 <span data-i18n="analysis.player_history">Player History</span></div>
|
<div class="ps-hist-item" onclick="window.location.href='/archive/league/{{ league.filename }}'">
|
||||||
|
<div class="ps-hist-date">{{ league.date[:10] if league.date != 'Unknown' else '?' }}</div>
|
||||||
<!-- Tab Navigation -->
|
<div class="ps-hist-info ps-league-scores">
|
||||||
<div class="history-tabs">
|
|
||||||
<button class="history-tab active" data-tab="tournaments">
|
|
||||||
🎯 <span data-i18n="analysis.tournament_history">Tournament History</span>
|
|
||||||
</button>
|
|
||||||
<button class="history-tab" data-tab="leagues">
|
|
||||||
🏆 <span data-i18n="league.league_championship">League History</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Tournament History Table -->
|
|
||||||
<div id="tournaments-tab" class="history-tab-content active">
|
|
||||||
{% if stats.tournament_history %}
|
|
||||||
<div class="table-wrapper">
|
|
||||||
<table class="history-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-i18n="general.date">Date</th>
|
|
||||||
<th data-i18n="general.type">Type</th>
|
|
||||||
<th data-i18n="results.score">Score</th>
|
|
||||||
<th data-i18n="results.shots">Shots</th>
|
|
||||||
<th data-i18n="general.action">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for tournament in stats.tournament_history %}
|
|
||||||
<tr class="history-table-row" onclick="window.location.href='/archive/tournament/{{ tournament.filename }}'">
|
|
||||||
<td class="date-cell">{{ tournament.date[:10] if tournament.date != 'Unknown' else 'Unknown' }}</td>
|
|
||||||
<td><span class="tournament-type-badge" data-tournament-type="{{ tournament.tournament_type }}">{{ tournament.tournament_type.replace('_', ' ')|title }}</span></td>
|
|
||||||
<td class="score-cell"><strong>{{ tournament.score }}</strong></td>
|
|
||||||
<td>{{ tournament.shots_fired }}</td>
|
|
||||||
<td><span class="view-link" data-i18n="general.view">View →</span></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">🎯</div>
|
|
||||||
<div data-i18n="messages.no_archives_found">No tournament history</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- League History Table -->
|
|
||||||
<div id="leagues-tab" class="history-tab-content">
|
|
||||||
{% if stats.league_history %}
|
|
||||||
<div class="table-wrapper">
|
|
||||||
<table class="history-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th data-i18n="general.date">Date</th>
|
|
||||||
<th colspan="5" style="text-align: center;">Tournament Scores</th>
|
|
||||||
<th data-i18n="league.final">Final Score</th>
|
|
||||||
<th data-i18n="general.action">Action</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th style="text-align: center;">T1</th>
|
|
||||||
<th style="text-align: center;">T2</th>
|
|
||||||
<th style="text-align: center;">T3</th>
|
|
||||||
<th style="text-align: center;">T4</th>
|
|
||||||
<th style="text-align: center;">T5</th>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for league in stats.league_history %}
|
|
||||||
<tr class="history-table-row league-history-row" data-league-index="{{ loop.index0 }}" onclick="window.location.href='/archive/league/{{ league.filename }}'">
|
|
||||||
<td class="date-cell">{{ league.date[:10] if league.date != 'Unknown' else 'Unknown' }}</td>
|
|
||||||
{% if league.tournament_results %}
|
{% if league.tournament_results %}
|
||||||
{% for i in range(league.tournament_results|length) %}
|
{% for i in range(league.tournament_results|length) %}
|
||||||
{% set result = league.tournament_results[i] %}
|
{% set result = league.tournament_results[i] %}
|
||||||
{% set tournament_num = i + 1 %}
|
{% set is_excluded = league.excluded_tournament and league.excluded_tournament == (i+1) %}
|
||||||
{% set is_excluded = league.excluded_tournament and league.excluded_tournament == tournament_num %}
|
{% set is_joker = result.joker or not result.participated %}
|
||||||
{% set is_joker = result.joker or not result.participated %}
|
<span class="ps-ls {% if is_joker %}ps-ls-joker{% elif is_excluded %}ps-ls-excl{% endif %}">
|
||||||
<td style="text-align: center;" class="league-score-cell {% if is_joker %}joker-tournament{% elif is_excluded %}excluded-tournament{% endif %}"
|
{% if is_joker %}🃏{% elif is_excluded %}<s>{{ result.score if result else '-' }}</s>{% else %}{{ result.score if result else '-' }}{% endif %}
|
||||||
title="{% if is_joker %}Joker used (skipped){% elif is_excluded %}Lowest score - excluded from final{% endif %}">
|
</span>
|
||||||
{% if is_joker %}<span style="opacity: 0.7;">🃏</span>{% elif is_excluded %}<span class="removed-score">{{ result.score if result else '-' }}</span>{% else %}{{ result.score if result else '-' }}{% endif %}
|
{% endfor %}
|
||||||
</td>
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
<td style="text-align: center;">-</td>
|
|
||||||
<td style="text-align: center;">-</td>
|
|
||||||
<td style="text-align: center;">-</td>
|
|
||||||
<td style="text-align: center;">-</td>
|
|
||||||
<td style="text-align: center;">-</td>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="score-cell"><strong>{{ league.final_score }}</strong></td>
|
</div>
|
||||||
<td><span class="view-link" data-i18n="general.view">View →</span></td>
|
<div class="ps-hist-score">{{ league.final_score }}</div>
|
||||||
</tr>
|
<div class="ps-hist-arrow">→</div>
|
||||||
{% endfor %}
|
</div>
|
||||||
</tbody>
|
{% endfor %}
|
||||||
</table>
|
{% else %}
|
||||||
</div>
|
<div class="empty-state"><div class="empty-icon">🏆</div><div>Ni zgodovine</div></div>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<div class="empty-state">
|
</div>
|
||||||
<div class="empty-icon">🏆</div>
|
</div><!-- ps-history-body -->
|
||||||
<div data-i18n="messages.no_archives_found">No league history</div>
|
</div><!-- ps-right card -->
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div><!-- ps-layout -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Player data from Flask
|
// Player data from Flask
|
||||||
@@ -1342,11 +1533,75 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create overall accuracy bar chart
|
// Create overall bar chart
|
||||||
createOverallAccuracyChart(totalCounts);
|
createOverallAccuracyChart(totalCounts);
|
||||||
|
|
||||||
// Create overall radar chart
|
// Create overall pie chart
|
||||||
createOverallRadarChart(totalCounts);
|
createOverallRadarChart(totalCounts);
|
||||||
|
|
||||||
|
// Populate shot count cards
|
||||||
|
populateShotCountCards(totalCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate shot count cards below charts
|
||||||
|
function populateShotCountCards(totalCounts) {
|
||||||
|
const scoreMap = {
|
||||||
|
10: totalCounts.tens,
|
||||||
|
9: totalCounts.nines,
|
||||||
|
8: totalCounts.eights,
|
||||||
|
7: totalCounts.sevens,
|
||||||
|
6: totalCounts.sixes,
|
||||||
|
5: totalCounts.fives,
|
||||||
|
4: totalCounts.fours,
|
||||||
|
3: totalCounts.threes,
|
||||||
|
2: totalCounts.twos,
|
||||||
|
1: totalCounts.ones,
|
||||||
|
0: totalCounts.zeros
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update shot count cards
|
||||||
|
for (const [score, count] of Object.entries(scoreMap)) {
|
||||||
|
const countElement = document.getElementById(`count-${score}`);
|
||||||
|
if (countElement) {
|
||||||
|
countElement.textContent = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update top stat badges
|
||||||
|
updateTopStatsBadges(totalCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update top stat badges with overall metrics
|
||||||
|
function updateTopStatsBadges(totalCounts) {
|
||||||
|
// Perfect 10s count
|
||||||
|
const totalTensBadge = document.getElementById('totalTens-badge');
|
||||||
|
if (totalTensBadge) {
|
||||||
|
totalTensBadge.textContent = totalCounts.tens;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate most common shot value
|
||||||
|
let mostCommonShot = 0;
|
||||||
|
let maxCount = 0;
|
||||||
|
|
||||||
|
const shotScores = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
|
||||||
|
const shotCountsArray = [
|
||||||
|
totalCounts.tens, totalCounts.nines, totalCounts.eights,
|
||||||
|
totalCounts.sevens, totalCounts.sixes, totalCounts.fives,
|
||||||
|
totalCounts.fours, totalCounts.threes, totalCounts.twos,
|
||||||
|
totalCounts.ones, totalCounts.zeros
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let i = 0; i < shotScores.length; i++) {
|
||||||
|
if (shotCountsArray[i] > maxCount) {
|
||||||
|
maxCount = shotCountsArray[i];
|
||||||
|
mostCommonShot = shotScores[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mostCommonBadge = document.getElementById('mostCommon-badge');
|
||||||
|
if (mostCommonBadge) {
|
||||||
|
mostCommonBadge.textContent = mostCommonShot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create overall accuracy bar chart
|
// Create overall accuracy bar chart
|
||||||
@@ -1505,6 +1760,124 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create accuracy gauge chart (doughnut showing overall accuracy percentage)
|
||||||
|
let accuracyGaugeChartInstance = null;
|
||||||
|
|
||||||
|
function createAccuracyGaugeChart(totalCounts) {
|
||||||
|
const canvas = document.getElementById('accuracyGaugeChart');
|
||||||
|
if (!canvas) {
|
||||||
|
console.warn('Accuracy gauge chart canvas not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// Destroy existing chart if it exists
|
||||||
|
if (accuracyGaugeChartInstance) {
|
||||||
|
accuracyGaugeChartInstance.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate accuracy percentage (perfect shots 8-10 / total shots)
|
||||||
|
const perfectShots = totalCounts.tens + totalCounts.nines + totalCounts.eights;
|
||||||
|
const totalShots = Object.values(totalCounts).reduce((a, b) => a + b, 0);
|
||||||
|
const accuracyPercentage = totalShots > 0 ? Math.round((perfectShots / totalShots) * 100) : 0;
|
||||||
|
|
||||||
|
// Calculate consistency score (lower variance = higher consistency)
|
||||||
|
const shotValues = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
|
||||||
|
const shotCounts = [totalCounts.tens, totalCounts.nines, totalCounts.eights, totalCounts.sevens, totalCounts.sixes, totalCounts.fives, totalCounts.fours, totalCounts.threes, totalCounts.twos, totalCounts.ones, totalCounts.zeros];
|
||||||
|
|
||||||
|
let mean = 0;
|
||||||
|
if (totalShots > 0) {
|
||||||
|
mean = shotValues.reduce((sum, val, i) => sum + (val * shotCounts[i]), 0) / totalShots;
|
||||||
|
}
|
||||||
|
|
||||||
|
let variance = 0;
|
||||||
|
if (totalShots > 0) {
|
||||||
|
variance = shotValues.reduce((sum, val, i) => sum + (Math.pow(val - mean, 2) * shotCounts[i]), 0) / totalShots;
|
||||||
|
}
|
||||||
|
const consistency = Math.max(0, Math.round(100 - (variance * 5))); // Scale variance to 0-100
|
||||||
|
|
||||||
|
// Update DOM with percentages
|
||||||
|
document.getElementById('accuracyPercentage').textContent = accuracyPercentage + '%';
|
||||||
|
document.getElementById('consistencyScore').textContent = consistency;
|
||||||
|
|
||||||
|
const gaugeData = [accuracyPercentage, 100 - accuracyPercentage];
|
||||||
|
|
||||||
|
accuracyGaugeChartInstance = new Chart(ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: ['Accuracy', 'Missed'],
|
||||||
|
datasets: [{
|
||||||
|
data: gaugeData,
|
||||||
|
backgroundColor: ['#28a745', '#f0f0f0'],
|
||||||
|
borderColor: ['#28a745', '#e0e0e0'],
|
||||||
|
borderWidth: 3,
|
||||||
|
circumference: 180,
|
||||||
|
rotation: 270
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: { display: false },
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
return context.label + ': ' + context.parsed + '%';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update stat cards with performance metrics
|
||||||
|
function updateStatCards(statsData, totalCounts) {
|
||||||
|
try {
|
||||||
|
// Count tournaments
|
||||||
|
const tournaments = statsData.tournament_history ? statsData.tournament_history.length : 0;
|
||||||
|
document.getElementById('totalTournaments').textContent = tournaments;
|
||||||
|
|
||||||
|
// Count total 10s
|
||||||
|
const totalTens = totalCounts.tens || 0;
|
||||||
|
document.getElementById('totalTens').textContent = totalTens;
|
||||||
|
|
||||||
|
// Calculate variance
|
||||||
|
const shotValues = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
|
||||||
|
const shotCounts = [totalCounts.tens, totalCounts.nines, totalCounts.eights, totalCounts.sevens, totalCounts.sixes, totalCounts.fives, totalCounts.fours, totalCounts.threes, totalCounts.twos, totalCounts.ones, totalCounts.zeros];
|
||||||
|
const totalShots = shotCounts.reduce((a, b) => a + b, 0);
|
||||||
|
|
||||||
|
let mean = 0;
|
||||||
|
if (totalShots > 0) {
|
||||||
|
mean = shotValues.reduce((sum, val, i) => sum + (val * shotCounts[i]), 0) / totalShots;
|
||||||
|
}
|
||||||
|
|
||||||
|
let variance = 0;
|
||||||
|
if (totalShots > 0) {
|
||||||
|
variance = shotValues.reduce((sum, val, i) => sum + (Math.pow(val - mean, 2) * shotCounts[i]), 0) / totalShots;
|
||||||
|
}
|
||||||
|
document.getElementById('scoreVariance').textContent = variance.toFixed(2);
|
||||||
|
|
||||||
|
// Calculate range (highest - lowest non-zero score)
|
||||||
|
let minScore = null;
|
||||||
|
let maxScore = null;
|
||||||
|
|
||||||
|
for (let i = 0; i < shotValues.length; i++) {
|
||||||
|
if (shotCounts[i] > 0) {
|
||||||
|
if (maxScore === null) maxScore = shotValues[i];
|
||||||
|
minScore = shotValues[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const range = maxScore !== null ? (maxScore - minScore) : 0;
|
||||||
|
document.getElementById('scoreRange').textContent = range;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating stat cards:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load shot accuracy data from template context
|
// Load shot accuracy data from template context
|
||||||
function loadShotAccuracyData() {
|
function loadShotAccuracyData() {
|
||||||
try {
|
try {
|
||||||
@@ -1672,16 +2045,62 @@
|
|||||||
const avgScore = gameCount > 0 ? Math.round(scores.reduce((a, b) => a + b, 0) / gameCount) : 0;
|
const avgScore = gameCount > 0 ? Math.round(scores.reduce((a, b) => a + b, 0) / gameCount) : 0;
|
||||||
const bestScore = gameCount > 0 ? Math.max(...scores) : 0;
|
const bestScore = gameCount > 0 ? Math.max(...scores) : 0;
|
||||||
|
|
||||||
|
// Calculate most common shot value
|
||||||
|
let mostCommonShot = 0;
|
||||||
|
const shotCounts = { 10: 0, 9: 0, 8: 0, 7: 0, 6: 0, 5: 0, 4: 0, 3: 0, 2: 0, 1: 0, 0: 0 };
|
||||||
|
|
||||||
|
tournaments.forEach(tournament => {
|
||||||
|
if (tournament.shot_breakdown) {
|
||||||
|
const breakdown = tournament.shot_breakdown;
|
||||||
|
shotCounts[10] += breakdown.tens || 0;
|
||||||
|
shotCounts[9] += breakdown.nines || 0;
|
||||||
|
shotCounts[8] += breakdown.eights || 0;
|
||||||
|
shotCounts[7] += breakdown.sevens || 0;
|
||||||
|
shotCounts[6] += breakdown.sixes || 0;
|
||||||
|
shotCounts[5] += breakdown.fives || 0;
|
||||||
|
shotCounts[4] += breakdown.fours || 0;
|
||||||
|
shotCounts[3] += breakdown.threes || 0;
|
||||||
|
shotCounts[2] += breakdown.twos || 0;
|
||||||
|
shotCounts[1] += breakdown.ones || 0;
|
||||||
|
shotCounts[0] += breakdown.zeros || 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Find shot value with highest count
|
||||||
|
let maxCount = 0;
|
||||||
|
for (const [score, count] of Object.entries(shotCounts)) {
|
||||||
|
if (count > maxCount) {
|
||||||
|
maxCount = count;
|
||||||
|
mostCommonShot = parseInt(score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update basic stats
|
// Update basic stats
|
||||||
document.getElementById('gameCount').textContent = gameCount;
|
document.getElementById('gameCount').textContent = gameCount;
|
||||||
document.getElementById('avgScore').textContent = avgScore;
|
|
||||||
document.getElementById('bestScore').textContent = bestScore;
|
document.getElementById('bestScore').textContent = bestScore;
|
||||||
|
document.getElementById('avgScore').textContent = avgScore;
|
||||||
|
const mcEl = document.getElementById('mostCommonShot'); if (mcEl) mcEl.textContent = mostCommonShot;
|
||||||
|
|
||||||
// Update shot accuracy stats (if available in tournament data)
|
// Update shot accuracy stats (if available in tournament data)
|
||||||
updateAccuracyStats(tournaments);
|
updateAccuracyStats(tournaments);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update shot accuracy statistics
|
// Update shot accuracy statistics
|
||||||
|
function renderShotCountTable(counts) {
|
||||||
|
const el = document.getElementById('shotCountTable');
|
||||||
|
if (!el) return;
|
||||||
|
const labels = [10,9,8,7,6,5,4,3,2,1,0];
|
||||||
|
const colors = [
|
||||||
|
'#1a7a3c','#2d9e54','#3db86a','#5ec47c','#88d4a0',
|
||||||
|
'#b0dfc0','#c5c5c5','#e0a89a','#e07a6e','#d95050','#c0392b'
|
||||||
|
];
|
||||||
|
el.innerHTML = labels.map((lbl, i) => `
|
||||||
|
<div class="ps-sc-row">
|
||||||
|
<div class="ps-sc-badge" style="background:${colors[i]}">${lbl}</div>
|
||||||
|
<div class="ps-sc-count">${counts[i]}</div>
|
||||||
|
</div>`).join('');
|
||||||
|
}
|
||||||
|
|
||||||
function updateAccuracyStats(tournaments) {
|
function updateAccuracyStats(tournaments) {
|
||||||
let tens = 0, nines = 0, eights = 0, sevens = 0, sixes = 0;
|
let tens = 0, nines = 0, eights = 0, sevens = 0, sixes = 0;
|
||||||
let fives = 0, fours = 0, threes = 0, twos = 0, ones = 0, zeros = 0;
|
let fives = 0, fours = 0, threes = 0, twos = 0, ones = 0, zeros = 0;
|
||||||
@@ -1748,6 +2167,9 @@
|
|||||||
// Render accuracy bar chart
|
// Render accuracy bar chart
|
||||||
createAccuracyChart(tens, nines, eights, sevens, sixes, fives, fours, threes, twos, ones, zeros);
|
createAccuracyChart(tens, nines, eights, sevens, sixes, fives, fours, threes, twos, ones, zeros);
|
||||||
|
|
||||||
|
// Render shot count table
|
||||||
|
renderShotCountTable([tens, nines, eights, sevens, sixes, fives, fours, threes, twos, ones, zeros]);
|
||||||
|
|
||||||
console.log(`Shot accuracy for ${currentTournamentType}:`, {
|
console.log(`Shot accuracy for ${currentTournamentType}:`, {
|
||||||
tens, nines, eights, sevens, sixes, fives, fours, threes, twos, ones, zeros
|
tens, nines, eights, sevens, sixes, fives, fours, threes, twos, ones, zeros
|
||||||
});
|
});
|
||||||
@@ -1767,17 +2189,17 @@
|
|||||||
function generateColorfulArray() {
|
function generateColorfulArray() {
|
||||||
// Color mapping from green (perfect 10) to red (misses 0): labels are [10,9,8,7,6,5,4,3,2,1,0]
|
// Color mapping from green (perfect 10) to red (misses 0): labels are [10,9,8,7,6,5,4,3,2,1,0]
|
||||||
return [
|
return [
|
||||||
'#2E7D32', // 10 - green (perfect)
|
'#4A9D6F', // 10 - medium green (perfect)
|
||||||
'#388E3C', // 9 - green
|
'#5BA97A', // 9 - medium green
|
||||||
'#43A047', // 8 - green
|
'#6CB585', // 8 - medium green
|
||||||
'#558B2F', // 7 - light green
|
'#7DC285', // 7 - medium light green
|
||||||
'#9CCC65', // 6 - lime green
|
'#8FCC7F', // 6 - medium lime green
|
||||||
'#FDD835', // 5 - yellow
|
'#D4B84D', // 5 - medium yellow
|
||||||
'#FBC02D', // 4 - golden yellow
|
'#CDA642', // 4 - medium golden yellow
|
||||||
'#FFA726', // 3 - orange
|
'#D99A5D', // 3 - medium orange
|
||||||
'#FF7043', // 2 - light orange-red
|
'#D87A6C', // 2 - medium light orange-red
|
||||||
'#E53935', // 1 - red
|
'#C85C5C', // 1 - medium red
|
||||||
'#C62828' // 0 - dark red (miss)
|
'#B84A4A' // 0 - medium dark red (miss)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2071,6 +2493,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window.self !== window.top) document.body.classList.add('in-iframe');
|
||||||
|
|
||||||
// Initialize page when i18n is ready
|
// Initialize page when i18n is ready
|
||||||
window.addEventListener('i18nReady', initializePage);
|
window.addEventListener('i18nReady', initializePage);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+1384
-399
File diff suppressed because it is too large
Load Diff
+253
-120
@@ -96,7 +96,7 @@
|
|||||||
.tv-container {
|
.tv-container {
|
||||||
height: calc(100vh - 90px);
|
height: calc(100vh - 90px);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 3fr;
|
grid-template-columns: 1fr 2fr;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
@@ -105,18 +105,26 @@
|
|||||||
.left-column {
|
.left-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-header {
|
.results-header {
|
||||||
border-radius: 12px;
|
border-radius: 12px 12px 0 0;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
box-shadow: none;
|
||||||
padding: 25px;
|
padding: 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
color: white;
|
color: white;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dynamic header colors based on tournament type */
|
/* Dynamic header colors based on tournament type */
|
||||||
@@ -149,37 +157,37 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-logo {
|
.header-logo {
|
||||||
height: 70px;
|
height: 60px;
|
||||||
max-width: 180px;
|
max-width: 160px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 12px;
|
||||||
filter: brightness(1.2) contrast(1.1);
|
filter: brightness(1.2) contrast(1.1);
|
||||||
background-color: white;
|
background-color: white;
|
||||||
padding: 10px;
|
padding: 8px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-title {
|
.results-title {
|
||||||
font-size: 2.2rem;
|
font-size: 2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: rgb(255, 255, 255);
|
color: rgb(255, 255, 255);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 6px;
|
||||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-subtitle {
|
.results-subtitle {
|
||||||
font-size: 1.1rem;
|
font-size: 1rem;
|
||||||
color: rgba(255, 255, 255, 0.95);
|
color: rgba(255, 255, 255, 0.95);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 12px;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-meta {
|
.results-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
gap: 20px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-item {
|
.meta-item {
|
||||||
@@ -187,7 +195,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta-number {
|
.meta-number {
|
||||||
font-size: 1.8rem;
|
font-size: 1.2rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -195,83 +203,120 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta-label {
|
.meta-label {
|
||||||
font-size: 0.8rem;
|
font-size: 0.65rem;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.3px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modern Podium Design */
|
/* Modern Podium Design */
|
||||||
.podium-section {
|
.podium-section {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 0 0 12px 12px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
padding: 12px;
|
||||||
padding: 25px;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow: visible;
|
||||||
|
min-height: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-title {
|
.podium-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.4rem;
|
font-size: 0.9rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-container {
|
.podium-container {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 15px;
|
grid-template-rows: 0.75fr 0.75fr 1.5fr;
|
||||||
|
gap: 10px;
|
||||||
|
overflow: hidden;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-card {
|
.podium-card {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: none;
|
||||||
padding: 20px;
|
padding: 12px 12px 18px 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20px;
|
gap: 8px;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.3s ease;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-left: 5px solid;
|
border: 1px solid #e9ecef;
|
||||||
|
border-top-width: 6px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.podium-card::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
left: 1px;
|
||||||
|
right: 1px;
|
||||||
|
bottom: 1px;
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0) 100%);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
border-radius: 0 0 11px 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-card:hover {
|
.podium-card:hover {
|
||||||
transform: translateY(-2px);
|
box-shadow: none;
|
||||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-card.rank-1 {
|
.podium-card.rank-1 {
|
||||||
border-left-color: #ffd700;
|
border-top-color: #ffd700;
|
||||||
background: linear-gradient(135deg, #fff9e6 0%, #ffffff 100%);
|
border-color: #ffd700;
|
||||||
|
background: linear-gradient(135deg, #fffbf0 0%, #fff9e6 100%);
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-card.rank-2 {
|
.podium-card.rank-2 {
|
||||||
border-left-color: #c0c0c0;
|
border-top-color: #c0c0c0;
|
||||||
background: linear-gradient(135deg, #f5f5f5 0%, #ffffff 100%);
|
border-color: #c0c0c0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 0%, #f0f0f0 100%);
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-card.rank-3 {
|
.podium-card.rank-3 {
|
||||||
border-left-color: #cd7f32;
|
border-top-color: #cd7f32;
|
||||||
background: linear-gradient(135deg, #fdf6f0 0%, #ffffff 100%);
|
border-color: #cd7f32;
|
||||||
|
background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 100%);
|
||||||
|
grid-column: 3;
|
||||||
|
grid-row: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-display {
|
.rank-display {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 60px;
|
gap: 2px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medal {
|
||||||
|
font-size: 4.5rem;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-number {
|
.rank-number {
|
||||||
font-size: 1.8rem;
|
font-size: 1.9rem;
|
||||||
font-weight: bold;
|
font-weight: 900;
|
||||||
color: #333;
|
color: #333;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
@@ -280,86 +325,90 @@
|
|||||||
.podium-card.rank-2 .rank-number { color: #696969; }
|
.podium-card.rank-2 .rank-number { color: #696969; }
|
||||||
.podium-card.rank-3 .rank-number { color: #8b4513; }
|
.podium-card.rank-3 .rank-number { color: #8b4513; }
|
||||||
|
|
||||||
.rank-suffix {
|
|
||||||
font-size: 0.7rem;
|
|
||||||
color: #666;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.medal {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.participant-info {
|
.participant-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.participant-name {
|
.participant-name {
|
||||||
font-size: 1.3rem;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
color: #333;
|
color: #2c3e50;
|
||||||
margin-bottom: 5px;
|
margin: 0;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.participant-id {
|
.participant-id {
|
||||||
background: #28a745;
|
display: none;
|
||||||
color: white;
|
|
||||||
padding: 3px 10px;
|
|
||||||
border-radius: 12px;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
font-weight: bold;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-display {
|
.score-display {
|
||||||
text-align: right;
|
text-align: center;
|
||||||
min-width: 100px;
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-number {
|
.score-number {
|
||||||
font-size: 2rem;
|
font-size: 1.8rem;
|
||||||
font-weight: bold;
|
font-weight: 900;
|
||||||
color: #28a745;
|
color: #28a745;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tens-count {
|
.tens-count {
|
||||||
font-size: 1rem;
|
font-size: 1.2rem;
|
||||||
color: #ffc107;
|
color: #ffc107;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
margin-top: 2px;
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-label {
|
.score-label {
|
||||||
font-size: 0.8rem;
|
font-size: 0.6rem;
|
||||||
color: #666;
|
color: #999;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: bold;
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Right Column - Full Results Table */
|
/* Right Column - Full Results Table */
|
||||||
.right-column {
|
.right-column {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header {
|
.table-header {
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
padding: 15px 20px;
|
padding: 8px 12px;
|
||||||
border-bottom: 1px solid #dee2e6;
|
border-bottom: 1px solid #dee2e6;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-title {
|
.table-title {
|
||||||
font-size: 1.25rem;
|
font-size: 0.95rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -367,17 +416,19 @@
|
|||||||
|
|
||||||
.table-container {
|
.table-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow: auto;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-table {
|
.results-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
font-size: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-table th,
|
.results-table th,
|
||||||
.results-table td {
|
.results-table td {
|
||||||
padding: 10px 8px;
|
padding: 4px 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-bottom: 1px solid #f1f3f4;
|
border-bottom: 1px solid #f1f3f4;
|
||||||
border-right: 1px solid #f1f3f4;
|
border-right: 1px solid #f1f3f4;
|
||||||
@@ -388,15 +439,15 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #495057;
|
color: #495057;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: 0.8rem;
|
font-size: 0.65rem;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.3px;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-table th.rank-col {
|
.results-table th.rank-col {
|
||||||
width: 80px;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-table th.player-col {
|
.results-table th.player-col {
|
||||||
@@ -405,12 +456,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.results-table th.score-col {
|
.results-table th.score-col {
|
||||||
width: 100px;
|
width: auto;
|
||||||
background: #e3f2fd;
|
background: #e3f2fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-table th.tens-col {
|
.results-table th.tens-col {
|
||||||
width: 100px;
|
width: auto;
|
||||||
background: #fff3cd;
|
background: #fff3cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,30 +503,30 @@
|
|||||||
.rank-2 { color: #6c757d; }
|
.rank-2 { color: #6c757d; }
|
||||||
.rank-3 { color: #8b4513; }
|
.rank-3 { color: #8b4513; }
|
||||||
|
|
||||||
|
.results-table tbody {
|
||||||
|
display: table-row-group;
|
||||||
|
}
|
||||||
|
|
||||||
.player-cell {
|
.player-cell {
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
padding-left: 12px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-name {
|
.player-name {
|
||||||
font-size: 1rem;
|
font-size: 0.75rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
word-break: keep-all;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
hyphens: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-cell {
|
.score-cell {
|
||||||
background: #e3f2fd !important;
|
background: #e3f2fd !important;
|
||||||
font-size: 1.1rem;
|
font-size: 0.75rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #1976d2;
|
color: #1976d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tens-cell {
|
.tens-cell {
|
||||||
background: #fff3cd !important;
|
background: #fff3cd !important;
|
||||||
font-size: 1rem;
|
font-size: 0.75rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #856404;
|
color: #856404;
|
||||||
}
|
}
|
||||||
@@ -484,10 +535,10 @@
|
|||||||
.stats-footer {
|
.stats-footer {
|
||||||
background: white;
|
background: white;
|
||||||
border-top: 1px solid #dee2e6;
|
border-top: 1px solid #dee2e6;
|
||||||
padding: 10px 20px;
|
padding: 6px 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
font-size: 0.8rem;
|
font-size: 0.7rem;
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -569,37 +620,47 @@
|
|||||||
color: #333 !important;
|
color: #333 !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
border: 2px solid #ddd !important;
|
border: 2px solid #ddd !important;
|
||||||
padding: 20px;
|
border-radius: 8px !important;
|
||||||
margin-bottom: 20px;
|
padding: 16px 20px !important;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
overflow: visible !important;
|
||||||
|
position: static !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-header::before {
|
.results-header::before {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.results-header * {
|
||||||
|
position: static !important;
|
||||||
|
z-index: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
.header-logo {
|
.header-logo {
|
||||||
height: 60px !important;
|
display: block !important;
|
||||||
max-width: 160px !important;
|
height: 50px !important;
|
||||||
|
max-width: 140px !important;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
filter: none !important;
|
filter: none !important;
|
||||||
margin-bottom: 15px;
|
backdrop-filter: none !important;
|
||||||
}
|
|
||||||
|
|
||||||
.results-title {
|
|
||||||
font-size: 24pt !important;
|
|
||||||
font-weight: bold !important;
|
|
||||||
color: #333 !important;
|
|
||||||
text-shadow: none !important;
|
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-subtitle {
|
.results-title {
|
||||||
font-size: 14pt !important;
|
font-size: 20pt !important;
|
||||||
color: #666 !important;
|
font-weight: bold !important;
|
||||||
|
color: #111 !important;
|
||||||
text-shadow: none !important;
|
text-shadow: none !important;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results-subtitle {
|
||||||
|
font-size: 11pt !important;
|
||||||
|
color: #555 !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results-meta {
|
.results-meta {
|
||||||
@@ -607,14 +668,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.meta-number {
|
.meta-number {
|
||||||
color: #333 !important;
|
font-size: 14pt !important;
|
||||||
|
color: #111 !important;
|
||||||
text-shadow: none !important;
|
text-shadow: none !important;
|
||||||
font-size: 16pt !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-label {
|
.meta-label {
|
||||||
|
font-size: 9pt !important;
|
||||||
color: #666 !important;
|
color: #666 !important;
|
||||||
font-size: 10pt !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.podium-section {
|
.podium-section {
|
||||||
@@ -656,8 +717,10 @@
|
|||||||
<div class="navbar-title">🏆 <span data-i18n="tournament.tournament_results">Tournament Results</span></div>
|
<div class="navbar-title">🏆 <span data-i18n="tournament.tournament_results">Tournament Results</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-controls">
|
<div class="navbar-controls">
|
||||||
<a href="/" class="nav-btn">📺 <span data-i18n="navigation.dashboard">Dashboard</span></a>
|
<button class="nav-btn" onclick="exportResultsJSON()">💾 <span data-i18n="general.export">Export JSON</span></button>
|
||||||
<button class="nav-btn" onclick="printResults()">🖨️ <span data-i18n="general.print">Print</span></button>
|
<button class="nav-btn" onclick="printResults()">🖨️ <span data-i18n="general.print">Print</span></button>
|
||||||
|
<button class="nav-btn" id="btnTvView" onclick="toggleTvView()" title="Preklopi pogled na TV zaslonu">📺</button>
|
||||||
|
<a href="/" class="nav-btn">✕</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -833,10 +896,6 @@
|
|||||||
const topThree = processedParticipants.slice(0, 3);
|
const topThree = processedParticipants.slice(0, 3);
|
||||||
|
|
||||||
return topThree.map(participant => {
|
return topThree.map(participant => {
|
||||||
const suffix = participant.rank === 1 ? 'st' :
|
|
||||||
participant.rank === 2 ? 'nd' :
|
|
||||||
participant.rank === 3 ? 'rd' : 'th';
|
|
||||||
|
|
||||||
const medal = participant.rank === 1 ? '🥇' :
|
const medal = participant.rank === 1 ? '🥇' :
|
||||||
participant.rank === 2 ? '🥈' :
|
participant.rank === 2 ? '🥈' :
|
||||||
participant.rank === 3 ? '🥉' : '';
|
participant.rank === 3 ? '🥉' : '';
|
||||||
@@ -844,8 +903,6 @@
|
|||||||
return `
|
return `
|
||||||
<div class="podium-card rank-${participant.rank}">
|
<div class="podium-card rank-${participant.rank}">
|
||||||
<div class="rank-display">
|
<div class="rank-display">
|
||||||
<div class="rank-number">${participant.rank}</div>
|
|
||||||
<div class="rank-suffix">${suffix}</div>
|
|
||||||
<div class="medal">${medal}</div>
|
<div class="medal">${medal}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -856,7 +913,7 @@
|
|||||||
|
|
||||||
<div class="score-display">
|
<div class="score-display">
|
||||||
<div class="score-number">${participant.total_score}</div>
|
<div class="score-number">${participant.total_score}</div>
|
||||||
<div class="tens-count">🎯 ${participant.tens_count} × 10</div>
|
<div class="tens-count">🎯 ${participant.tens_count}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -962,6 +1019,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export results as JSON
|
||||||
|
function exportResultsJSON() {
|
||||||
|
const tournamentData = {{ tournament | tojson | safe }};
|
||||||
|
const resultsData = {{ results | tojson | safe }};
|
||||||
|
|
||||||
|
// Wrap in archive format for compatibility
|
||||||
|
const archiveData = {
|
||||||
|
tournament: tournamentData,
|
||||||
|
results: resultsData,
|
||||||
|
archived_at: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
const dataStr = JSON.stringify(archiveData, null, 2);
|
||||||
|
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
|
||||||
|
// Generate filename with tournament info
|
||||||
|
const tournamentId = tournamentData.tournament_id || 'tournament';
|
||||||
|
const date = new Date().toISOString().slice(0, 10);
|
||||||
|
link.download = `${tournamentId}_${date}.json`;
|
||||||
|
|
||||||
|
link.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize when page loads
|
// Initialize when page loads
|
||||||
document.addEventListener('DOMContentLoaded', initializePage);
|
document.addEventListener('DOMContentLoaded', initializePage);
|
||||||
|
|
||||||
@@ -975,6 +1059,55 @@
|
|||||||
window.print();
|
window.print();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── TV VIEW TOGGLE ────────────────────────────────────────────────────────
|
||||||
|
const isTvDisplay = new URLSearchParams(window.location.search).get('tv') === '1';
|
||||||
|
let currentTvView = 'results';
|
||||||
|
|
||||||
|
function updateTvViewBtn(view) {
|
||||||
|
currentTvView = view;
|
||||||
|
const btn = document.getElementById('btnTvView');
|
||||||
|
if (!btn) return;
|
||||||
|
btn.style.background = (view === 'results') ? '#28a745' : '';
|
||||||
|
btn.style.color = (view === 'results') ? 'white' : '';
|
||||||
|
btn.style.borderColor= (view === 'results') ? '#1e7e34' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleTvView() {
|
||||||
|
const newView = currentTvView === 'results' ? 'cameras' : 'results';
|
||||||
|
try {
|
||||||
|
await fetch('/api/tv/view', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ view: newView })
|
||||||
|
});
|
||||||
|
updateTvViewBtn(newView);
|
||||||
|
if (isTvDisplay && newView === 'cameras') {
|
||||||
|
window.location.href = '/';
|
||||||
|
}
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll to stay in sync and follow back-redirect when in TV mode
|
||||||
|
let lastResultsStateHash = null;
|
||||||
|
setInterval(async () => {
|
||||||
|
if (document.visibilityState !== 'visible') return;
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/dashboard/state');
|
||||||
|
if (!r.ok) return;
|
||||||
|
const d = await r.json();
|
||||||
|
updateTvViewBtn(d.tv_view || 'cameras');
|
||||||
|
if (isTvDisplay && d.tv_view !== 'results') {
|
||||||
|
if (d.tv_view === 'draft' && d.tournament_active) {
|
||||||
|
window.location.href = '/tournament/draft?tv=1';
|
||||||
|
} else {
|
||||||
|
window.location.href = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
fetch('/api/dashboard/state').then(r => r.json()).then(d => updateTvViewBtn(d.tv_view || 'cameras')).catch(() => {});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+624
-580
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user