799 lines
26 KiB
JavaScript
799 lines
26 KiB
JavaScript
const STORAGE_KEY = 'turnierplaner_data';
|
|
const ROTATION_STATE_KEY = 'turnierplaner_rotation';
|
|
const SCORES_KEY = 'turnierplaner_scores';
|
|
let timerInterval = null;
|
|
let timerSeconds = 0;
|
|
let isRunning = false;
|
|
let allTeams = [];
|
|
let fieldCount = 0; // Anzahl der physischen Felder (jedes Feld hat 2 Feldhälften)
|
|
let rotationState = {};
|
|
let matchScores = {}; // { "league:fieldNum": {team1Score, team2Score}, ... }
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
loadTournamentData();
|
|
setupTimerInput();
|
|
loadMatchScores();
|
|
});
|
|
|
|
function loadTournamentData() {
|
|
const stored = localStorage.getItem(STORAGE_KEY);
|
|
if (!stored) {
|
|
console.warn('Keine Turnierdaten gefunden');
|
|
return;
|
|
}
|
|
|
|
const data = JSON.parse(stored);
|
|
allTeams = data;
|
|
fieldCount = parseInt(data.fieldCount) || 0;
|
|
|
|
// Lade oder initialisiere Rotations-State
|
|
loadRotationState(data);
|
|
|
|
// Populate fields mit aktuellem State
|
|
displayCurrentRound();
|
|
}
|
|
|
|
function loadRotationState(data) {
|
|
const stored = localStorage.getItem(ROTATION_STATE_KEY);
|
|
|
|
if (stored) {
|
|
rotationState = JSON.parse(stored);
|
|
} else {
|
|
// Initialisiere mit Startzustand
|
|
rotationState = {
|
|
bundesliga: {
|
|
round: 0,
|
|
teamOrder: data.bundesliga.map((t, i) => i)
|
|
},
|
|
champions: {
|
|
round: 0,
|
|
teamOrder: data.champions.map((t, i) => i)
|
|
}
|
|
};
|
|
saveRotationState();
|
|
}
|
|
}
|
|
|
|
function saveRotationState() {
|
|
localStorage.setItem(ROTATION_STATE_KEY, JSON.stringify(rotationState));
|
|
}
|
|
|
|
function displayCurrentRound() {
|
|
displayLeagueRound('bundesliga', allTeams.bundesliga);
|
|
displayLeagueRound('champions', allTeams.champions);
|
|
}
|
|
|
|
function displayLeagueRound(league, teams) {
|
|
// Jedes Feld hat 2 Feldhälften, also maximal fieldCount * 2 Teams können gleichzeitig spielen
|
|
const maxPlayingTeams = fieldCount * 2;
|
|
const playingTeamsCount = Math.min(teams.length, maxPlayingTeams);
|
|
const fieldsPerLeague = Math.ceil(playingTeamsCount / 2); // Anzahl Felder für diese Liga
|
|
const state = rotationState[league];
|
|
|
|
// Bestimme Offset für Feldnummern - Champions League beginnt nach Bundesliga
|
|
let fieldNumberOffset = 0;
|
|
if (league === 'champions') {
|
|
const bundesligaPlayingTeams = Math.min(allTeams.bundesliga.length, fieldCount * 2);
|
|
fieldNumberOffset = Math.ceil(bundesligaPlayingTeams / 2);
|
|
}
|
|
|
|
// Aktualisiere Felder basierend auf teamOrder
|
|
const container = document.getElementById(`${league}-fields`);
|
|
container.innerHTML = '';
|
|
|
|
for (let i = 0; i < fieldsPerLeague; i++) {
|
|
// Info-Box für Feldnummer (nur Label)
|
|
const fieldInfoBox = document.createElement('div');
|
|
fieldInfoBox.className = 'field-info-box';
|
|
const fieldNum = fieldNumberOffset + i + 1;
|
|
fieldInfoBox.innerHTML = `<div class="field-info-number">Feld ${fieldNum}:</div>`;
|
|
container.appendChild(fieldInfoBox);
|
|
|
|
// Team 1 (mittlere Spalte) mit Score-Input
|
|
const team1Index = state.teamOrder[i * 2];
|
|
const team1 = teams[team1Index] || {};
|
|
const fieldCard1 = document.createElement('div');
|
|
fieldCard1.className = 'field-card';
|
|
const scoreKey = getScoreKey(league, fieldNum);
|
|
const existingScore = matchScores[scoreKey] || { team1Score: '', team2Score: '' };
|
|
fieldCard1.innerHTML = `
|
|
<div class="field-card-content">
|
|
<div class="team-name">${team1.name || '-'}</div>
|
|
<input type="number" class="score-input" value="${existingScore.team1Score}" placeholder="0"
|
|
onchange="updateMatchScore('${league}', ${fieldNum}, this.value, document.getElementById('score-${league}-${fieldNum}-t2').value)">
|
|
</div>
|
|
`;
|
|
fieldCard1.id = `score-${league}-${fieldNum}-t1-card`;
|
|
container.appendChild(fieldCard1);
|
|
|
|
// Team 2 (rechte Spalte) mit Score-Input
|
|
const team2Index = state.teamOrder[i * 2 + 1];
|
|
const team2 = teams[team2Index] || {};
|
|
const fieldCard2 = document.createElement('div');
|
|
fieldCard2.className = 'field-card';
|
|
fieldCard2.innerHTML = `
|
|
<div class="field-card-content">
|
|
<input type="number" class="score-input" value="${existingScore.team2Score}" placeholder="0"
|
|
id="score-${league}-${fieldNum}-t2"
|
|
onchange="updateMatchScore('${league}', ${fieldNum}, document.getElementById('score-${league}-${fieldNum}-t1-card').querySelector('.score-input').value, this.value)">
|
|
<div class="team-name">${team2.name || '-'}</div>
|
|
</div>
|
|
`;
|
|
container.appendChild(fieldCard2);
|
|
}
|
|
|
|
// Aktualisiere wartende Teams
|
|
updateWaitingTeams(league, teams, fieldsPerLeague, state.teamOrder);
|
|
}
|
|
|
|
function updateWaitingTeams(league, teams, fieldsPerLeague, teamOrder) {
|
|
const container = document.getElementById(`${league}-waiting`);
|
|
container.innerHTML = '';
|
|
|
|
// Anzahl der spielenden Teams = fieldsPerLeague * 2 (2 Teams pro Feld)
|
|
const playingTeamsCount = fieldsPerLeague * 2;
|
|
const waitingIndices = teamOrder.slice(playingTeamsCount);
|
|
|
|
if (waitingIndices.length === 0) {
|
|
container.innerHTML = '<div class="no-waiting-teams">Alle Teams spielen</div>';
|
|
} else {
|
|
waitingIndices.forEach(teamIndex => {
|
|
const team = teams[teamIndex];
|
|
const badge = document.createElement('div');
|
|
badge.className = 'waiting-team-badge';
|
|
badge.textContent = team.name;
|
|
badge.title = `${team.club || ''} - ${team.motto || ''}`;
|
|
container.appendChild(badge);
|
|
});
|
|
}
|
|
}
|
|
|
|
function populateFields(league, teams, fieldCount) {
|
|
const container = document.getElementById(`${league}-fields`);
|
|
const totalFields = parseInt(fieldCount);
|
|
const fieldsPerLeague = Math.ceil(totalFields / 2);
|
|
|
|
container.innerHTML = '';
|
|
|
|
for (let i = 1; i <= fieldsPerLeague; i++) {
|
|
const fieldCard = document.createElement('div');
|
|
fieldCard.className = 'field-card';
|
|
|
|
// Zuweisung von Teams zu Feldern (Round-Robin)
|
|
const teamIndex = (i - 1) % teams.length;
|
|
const team = teams[teamIndex] || {};
|
|
|
|
fieldCard.innerHTML = `
|
|
<div class="field-number">Feld ${i}</div>
|
|
<div class="field-team">${team.name || '-'}</div>
|
|
`;
|
|
|
|
fieldCard.setAttribute('data-field', i);
|
|
fieldCard.setAttribute('data-league', league);
|
|
fieldCard.setAttribute('data-team', team.name || '');
|
|
|
|
container.appendChild(fieldCard);
|
|
}
|
|
}
|
|
|
|
function populateWaitingTeams(league, teams, fieldCount) {
|
|
const container = document.getElementById(`${league}-waiting`);
|
|
const totalFields = parseInt(fieldCount);
|
|
const fieldsPerLeague = Math.ceil(totalFields / 2);
|
|
|
|
container.innerHTML = '';
|
|
|
|
// Teams die auf Feldern spielen
|
|
const playingTeamIndices = new Set();
|
|
for (let i = 0; i < fieldsPerLeague; i++) {
|
|
playingTeamIndices.add(i % teams.length);
|
|
}
|
|
|
|
// Wartende Teams sind alle Teams, die nicht gerade spielen
|
|
const waitingTeams = teams.filter((team, index) => !playingTeamIndices.has(index));
|
|
|
|
if (waitingTeams.length === 0) {
|
|
container.innerHTML = '<div class="no-waiting-teams">Alle Teams spielen</div>';
|
|
} else {
|
|
waitingTeams.forEach(team => {
|
|
const badge = document.createElement('div');
|
|
badge.className = 'waiting-team-badge';
|
|
badge.textContent = team.name;
|
|
badge.title = `${team.club || ''} - ${team.motto || ''}`;
|
|
container.appendChild(badge);
|
|
});
|
|
}
|
|
}
|
|
|
|
// Timer Functions
|
|
function setupTimerInput() {
|
|
const timerInput = document.getElementById('timerInput');
|
|
timerInput.addEventListener('keypress', (e) => {
|
|
if (e.key === 'Enter') {
|
|
const value = timerInput.value.trim();
|
|
if (value) {
|
|
parseAndSetTimer(value);
|
|
timerInput.value = '';
|
|
timerInput.blur(); // Remove focus after input
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function parseAndSetTimer(timeStr) {
|
|
let seconds = 0;
|
|
|
|
if (timeStr.includes(':')) {
|
|
// Parse MM:SS format
|
|
const parts = timeStr.split(':');
|
|
if (parts.length === 2) {
|
|
const minutes = parseInt(parts[0]) || 0;
|
|
seconds = parseInt(parts[1]) || 0;
|
|
seconds = minutes * 60 + seconds;
|
|
}
|
|
} else {
|
|
// Parse as just seconds
|
|
seconds = parseInt(timeStr) || 0;
|
|
}
|
|
|
|
if (seconds > 0) {
|
|
// Stop current timer if running
|
|
if (isRunning) {
|
|
pauseTimer();
|
|
}
|
|
|
|
timerSeconds = seconds;
|
|
updateTimerDisplay();
|
|
|
|
// Start timer automatically
|
|
startTimer();
|
|
}
|
|
}
|
|
|
|
function toggleTimer() {
|
|
if (isRunning) {
|
|
pauseTimer();
|
|
} else {
|
|
startTimer();
|
|
}
|
|
}
|
|
|
|
function startTimer() {
|
|
if (isRunning) return;
|
|
|
|
isRunning = true;
|
|
const btn = document.getElementById('timerBtn');
|
|
btn.textContent = 'Pause';
|
|
|
|
timerInterval = setInterval(() => {
|
|
if (timerSeconds > 0) {
|
|
timerSeconds--;
|
|
updateTimerDisplay();
|
|
} else {
|
|
pauseTimer();
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
function pauseTimer() {
|
|
if (!isRunning) return;
|
|
|
|
isRunning = false;
|
|
const btn = document.getElementById('timerBtn');
|
|
btn.textContent = 'Start';
|
|
|
|
if (timerInterval) {
|
|
clearInterval(timerInterval);
|
|
timerInterval = null;
|
|
}
|
|
}
|
|
|
|
function updateTimerDisplay() {
|
|
const minutes = Math.floor(timerSeconds / 60);
|
|
const seconds = timerSeconds % 60;
|
|
|
|
const display = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
|
document.getElementById('timerDisplay').textContent = display;
|
|
}
|
|
|
|
// Modal Functions
|
|
function openPointsModal() {
|
|
document.getElementById('pointsModal').style.display = 'block';
|
|
}
|
|
|
|
function closePointsModal() {
|
|
document.getElementById('pointsModal').style.display = 'none';
|
|
}
|
|
|
|
function openResultsModal() {
|
|
document.getElementById('resultsModal').style.display = 'block';
|
|
}
|
|
|
|
function closeResultsModal() {
|
|
document.getElementById('resultsModal').style.display = 'none';
|
|
}
|
|
|
|
function savePoints(event) {
|
|
event.preventDefault();
|
|
|
|
const field = document.getElementById('pointsField').value;
|
|
const team = document.getElementById('pointsTeam').value;
|
|
const points = document.getElementById('pointsValue').value;
|
|
|
|
if (!field || !points) {
|
|
alert('Bitte alle Felder ausfüllen');
|
|
return;
|
|
}
|
|
|
|
// TODO: Punkte speichern (z.B. in localStorage oder an Server)
|
|
console.log('Punkte gespeichert:', { field, team, points });
|
|
alert(`✅ Punkte für ${team} gespeichert!`);
|
|
|
|
// Reset form
|
|
document.getElementById('pointsField').value = '';
|
|
document.getElementById('pointsTeam').value = '';
|
|
document.getElementById('pointsValue').value = '';
|
|
|
|
closePointsModal();
|
|
}
|
|
|
|
function saveResults(event) {
|
|
event.preventDefault();
|
|
|
|
const field = document.getElementById('resultsField').value;
|
|
const team = document.getElementById('resultsTeam').value;
|
|
const sets = document.getElementById('resultsSets').value;
|
|
const opponent = document.getElementById('resultsOpponent').value;
|
|
|
|
if (!field || !sets) {
|
|
alert('Bitte alle Pflichtfelder ausfüllen');
|
|
return;
|
|
}
|
|
|
|
// TODO: Ergebnisse speichern (z.B. in localStorage oder an Server)
|
|
console.log('Ergebnis gespeichert:', { field, team, sets, opponent });
|
|
alert(`✅ Ergebnis für ${team} gespeichert!`);
|
|
|
|
// Reset form
|
|
document.getElementById('resultsField').value = '';
|
|
document.getElementById('resultsTeam').value = '';
|
|
document.getElementById('resultsSets').value = '';
|
|
document.getElementById('resultsOpponent').value = '';
|
|
|
|
closeResultsModal();
|
|
}
|
|
|
|
// Close modal when clicking outside
|
|
window.addEventListener('click', (event) => {
|
|
const pointsModal = document.getElementById('pointsModal');
|
|
const resultsModal = document.getElementById('resultsModal');
|
|
|
|
if (event.target === pointsModal) {
|
|
closePointsModal();
|
|
}
|
|
if (event.target === resultsModal) {
|
|
closeResultsModal();
|
|
}
|
|
});
|
|
|
|
function goBack() {
|
|
// Stop timer before navigating
|
|
if (isRunning) {
|
|
pauseTimer();
|
|
}
|
|
window.location.href = 'index.html';
|
|
}
|
|
|
|
// Rotation Logic
|
|
function nextRound() {
|
|
// Inkrementiere Runden-Nummer
|
|
rotationState.bundesliga.round++;
|
|
rotationState.champions.round++;
|
|
|
|
// Leere die Scores für die neue Runde
|
|
matchScores = {};
|
|
saveMatchScores();
|
|
|
|
rotateLeague('bundesliga', allTeams.bundesliga);
|
|
rotateLeague('champions', allTeams.champions);
|
|
saveRotationState();
|
|
displayCurrentRound();
|
|
console.log('Nächste Runde!', rotationState);
|
|
}
|
|
|
|
function rotateLeague(league, teams) {
|
|
// Jedes Feld hat 2 Feldhälften - maximale spielende Teams = fieldCount * 2
|
|
const maxPlayingTeams = fieldCount * 2;
|
|
const playingTeamsCount = Math.min(teams.length, maxPlayingTeams);
|
|
const state = rotationState[league];
|
|
|
|
const totalTeams = teams.length;
|
|
const waitingCount = totalTeams - playingTeamsCount;
|
|
|
|
// Fall 1: Keine wartenden Teams (Anzahl Teams = fieldCount * 2)
|
|
// Team 1 bleibt stehen, alle anderen rotieren um 1 Position weiter
|
|
if (waitingCount === 0) {
|
|
// [0, 1, 2, 3, 4, 5] -> [0, 2, 3, 4, 5, 1]
|
|
// Team an Index 0 bleibt, Team an Index 1 geht ans Ende, Rest rückt auf
|
|
if (state.teamOrder.length > 1) {
|
|
const secondTeam = state.teamOrder.splice(1, 1)[0];
|
|
state.teamOrder.push(secondTeam);
|
|
}
|
|
console.log(`${league} Fall 1: Team ${teams[state.teamOrder[0]].name} bleibt stehen, andere rotieren`);
|
|
}
|
|
// Fall 2: Genau 1 wartendes Team (Anzahl Teams = fieldCount * 2 + 1)
|
|
// Alle rotieren um 1 Position, wartendes Team kommt aufs Randfeld
|
|
else if (waitingCount === 1) {
|
|
// [0, 1, 2, 3, 4, 5, 6(wartend)] -> [1, 2, 3, 4, 5, 6, 0]
|
|
// Einfach erstes Team ans Ende verschieben
|
|
const first = state.teamOrder.shift();
|
|
state.teamOrder.push(first);
|
|
console.log(`${league} Fall 2: Team ${teams[first].name} geht warten, Team ${teams[state.teamOrder[playingTeamsCount - 1]].name} kommt ins Spiel`);
|
|
}
|
|
// Fall 3: Mehrere wartende Teams (Anzahl Teams > fieldCount * 2 + 1)
|
|
// Alle wartenden sollen spielen, max 1 Runde Pause
|
|
else {
|
|
// [0, 1, 2, 3(spielend), 4, 5, 6, 7(wartend)] -> [4, 5, 6, 7(jetzt spielend), 0, 1, 2, 3(jetzt wartend)]
|
|
// Wartende Teams kommen nach vorne, spielende Teams gehen warten
|
|
const playingTeams = state.teamOrder.slice(0, playingTeamsCount);
|
|
const waitingTeams = state.teamOrder.slice(playingTeamsCount);
|
|
|
|
state.teamOrder = [...waitingTeams, ...playingTeams];
|
|
console.log(`${league} Fall 3: Wartende Teams spielen jetzt, spielende Teams warten`);
|
|
}
|
|
}
|
|
|
|
// ===== SCORE & PUNKTE-SYSTEM =====
|
|
|
|
function loadMatchScores() {
|
|
const stored = localStorage.getItem(SCORES_KEY);
|
|
if (stored) {
|
|
matchScores = JSON.parse(stored);
|
|
} else {
|
|
matchScores = {};
|
|
}
|
|
}
|
|
|
|
function saveMatchScores() {
|
|
localStorage.setItem(SCORES_KEY, JSON.stringify(matchScores));
|
|
}
|
|
|
|
function getScoreKey(league, fieldNum) {
|
|
return `${league}:${fieldNum}`;
|
|
}
|
|
|
|
function updateMatchScore(league, fieldNum, team1Score, team2Score) {
|
|
const key = getScoreKey(league, fieldNum);
|
|
matchScores[key] = {
|
|
round: rotationState[league].round,
|
|
team1Score: parseInt(team1Score) || 0,
|
|
team2Score: parseInt(team2Score) || 0
|
|
};
|
|
saveMatchScores();
|
|
}
|
|
|
|
function calculatePoints(team1Score, team2Score) {
|
|
// Berechnet Punkte für Team 1 und Team 2 basierend auf Spielstand
|
|
const diff = Math.abs(team1Score - team2Score);
|
|
|
|
if (team1Score > team2Score) {
|
|
// Team 1 gewinnt
|
|
return {
|
|
team1Points: diff + 2,
|
|
team2Points: -diff
|
|
};
|
|
} else if (team2Score > team1Score) {
|
|
// Team 2 gewinnt
|
|
return {
|
|
team1Points: -diff,
|
|
team2Points: diff + 2
|
|
};
|
|
} else {
|
|
// Unentschieden
|
|
return {
|
|
team1Points: 0,
|
|
team2Points: 0
|
|
};
|
|
}
|
|
}
|
|
|
|
function getTeamPointsHistory() {
|
|
// Erstellt eine Punkte-Historie für alle Teams in beiden Ligen
|
|
const history = {
|
|
bundesliga: {},
|
|
champions: {}
|
|
};
|
|
|
|
// Initialisiere leere Arrays für jedes Team
|
|
allTeams.bundesliga.forEach((team, idx) => {
|
|
history.bundesliga[idx] = [];
|
|
});
|
|
allTeams.champions.forEach((team, idx) => {
|
|
history.champions[idx] = [];
|
|
});
|
|
|
|
// Gehe durch alle gespeicherten Scores
|
|
Object.keys(matchScores).forEach(key => {
|
|
const [league, fieldNum] = key.split(':');
|
|
const score = matchScores[key];
|
|
const fieldNumInt = parseInt(fieldNum);
|
|
|
|
const state = rotationState[league];
|
|
const teamsInLeague = league === 'bundesliga' ? allTeams.bundesliga : allTeams.champions;
|
|
|
|
// Berechne fieldsPerLeague basierend auf fieldCount
|
|
const maxPlayingTeams = fieldCount * 2;
|
|
const playingTeamsCount = Math.min(teamsInLeague.length, maxPlayingTeams);
|
|
const fieldsPerLeague = Math.ceil(playingTeamsCount / 2);
|
|
|
|
// Bestimme Offset für Feldnummern
|
|
const bundesligaPlayingTeams = Math.min(allTeams.bundesliga.length, fieldCount * 2);
|
|
const bundesligaFields = Math.ceil(bundesligaPlayingTeams / 2);
|
|
const fieldOffset = league === 'bundesliga' ? 0 : bundesligaFields;
|
|
const i = fieldNumInt - fieldOffset - 1;
|
|
|
|
if (i >= 0 && i < fieldsPerLeague && state && state.teamOrder) {
|
|
const team1Index = state.teamOrder[i * 2];
|
|
const team2Index = state.teamOrder[i * 2 + 1];
|
|
|
|
if (team1Index !== undefined && team2Index !== undefined) {
|
|
const points = calculatePoints(score.team1Score, score.team2Score);
|
|
|
|
if (!history[league][team1Index][score.round]) {
|
|
history[league][team1Index][score.round] = 0;
|
|
}
|
|
if (!history[league][team2Index][score.round]) {
|
|
history[league][team2Index][score.round] = 0;
|
|
}
|
|
|
|
history[league][team1Index][score.round] = points.team1Points;
|
|
history[league][team2Index][score.round] = points.team2Points;
|
|
}
|
|
}
|
|
});
|
|
|
|
return history;
|
|
}
|
|
|
|
// ===== MODAL FUNCTIONS =====
|
|
|
|
function openPointsModal() {
|
|
const history = getTeamPointsHistory();
|
|
const content = document.getElementById('pointsDisplayContent');
|
|
content.innerHTML = '';
|
|
|
|
// Bundesliga
|
|
if (allTeams.bundesliga.length > 0) {
|
|
content.appendChild(createLeaguePointsSection('bundesliga', 'Bundesliga', allTeams.bundesliga, history.bundesliga));
|
|
}
|
|
|
|
// Champions League
|
|
if (allTeams.champions.length > 0) {
|
|
content.appendChild(createLeaguePointsSection('champions', 'Champions League', allTeams.champions, history.champions));
|
|
}
|
|
|
|
document.getElementById('pointsModal').style.display = 'block';
|
|
}
|
|
|
|
function createLeaguePointsSection(leagueId, leagueName, teams, history) {
|
|
const section = document.createElement('div');
|
|
section.className = 'league-points-section';
|
|
|
|
// Header
|
|
const header = document.createElement('div');
|
|
header.className = 'league-points-header';
|
|
header.innerHTML = leagueName;
|
|
section.appendChild(header);
|
|
|
|
// Table
|
|
const table = document.createElement('table');
|
|
table.className = 'points-table';
|
|
|
|
// Berechne maximale Runde
|
|
let maxRound = 0;
|
|
Object.keys(history).forEach(teamId => {
|
|
if (history[teamId] && history[teamId].length) {
|
|
maxRound = Math.max(maxRound, history[teamId].length - 1);
|
|
}
|
|
});
|
|
|
|
// Header Row
|
|
const headerRow = document.createElement('tr');
|
|
headerRow.innerHTML = '<th>Team</th>';
|
|
for (let r = 0; r <= maxRound; r++) {
|
|
const th = document.createElement('th');
|
|
th.innerHTML = `Runde ${r + 1}`;
|
|
headerRow.appendChild(th);
|
|
}
|
|
const totalTh = document.createElement('th');
|
|
totalTh.innerHTML = 'Gesamt';
|
|
headerRow.appendChild(totalTh);
|
|
table.appendChild(headerRow);
|
|
|
|
// Team Rows
|
|
teams.forEach((team, teamIdx) => {
|
|
const row = document.createElement('tr');
|
|
|
|
// Team Name
|
|
const nameCell = document.createElement('td');
|
|
nameCell.style.textAlign = 'left';
|
|
nameCell.style.fontWeight = '500';
|
|
nameCell.innerHTML = team.name;
|
|
row.appendChild(nameCell);
|
|
|
|
// Points per round
|
|
let totalPoints = 0;
|
|
const teamHistory = history[teamIdx] || [];
|
|
|
|
for (let r = 0; r <= maxRound; r++) {
|
|
const cell = document.createElement('td');
|
|
const points = teamHistory[r] !== undefined ? teamHistory[r] : '-';
|
|
|
|
if (points !== '-') {
|
|
totalPoints += points;
|
|
const pointsDiv = document.createElement('div');
|
|
pointsDiv.className = 'points-value';
|
|
|
|
if (points > 0) {
|
|
pointsDiv.classList.add('positive');
|
|
pointsDiv.innerHTML = `+${points}`;
|
|
} else if (points < 0) {
|
|
pointsDiv.classList.add('negative');
|
|
pointsDiv.innerHTML = `${points}`;
|
|
} else {
|
|
pointsDiv.classList.add('neutral');
|
|
pointsDiv.innerHTML = '0';
|
|
}
|
|
cell.appendChild(pointsDiv);
|
|
} else {
|
|
cell.innerHTML = '-';
|
|
}
|
|
row.appendChild(cell);
|
|
}
|
|
|
|
// Total Points
|
|
const totalCell = document.createElement('td');
|
|
const totalDiv = document.createElement('div');
|
|
totalDiv.className = 'points-value points-total';
|
|
totalDiv.innerHTML = totalPoints > 0 ? `+${totalPoints}` : `${totalPoints}`;
|
|
totalCell.appendChild(totalDiv);
|
|
row.appendChild(totalCell);
|
|
|
|
table.appendChild(row);
|
|
});
|
|
|
|
section.appendChild(table);
|
|
return section;
|
|
}
|
|
|
|
function closePointsModal() {
|
|
document.getElementById('pointsModal').style.display = 'none';
|
|
}
|
|
|
|
function openScoreboard() {
|
|
const history = getTeamPointsHistory();
|
|
const content = document.getElementById('scoreboardContent');
|
|
content.innerHTML = '';
|
|
|
|
// Erstelle Daten für beide Ligen mit Gesamtpunkten
|
|
const leaguesData = [
|
|
{ id: 'bundesliga', name: 'Bundesliga', teams: allTeams.bundesliga, history: history.bundesliga },
|
|
{ id: 'champions', name: 'Champions League', teams: allTeams.champions, history: history.champions }
|
|
];
|
|
|
|
leaguesData.forEach(league => {
|
|
if (league.teams.length > 0) {
|
|
// Berechne Gesamtpunkte für jedes Team
|
|
const teamScores = league.teams.map((team, idx) => {
|
|
const teamHistory = league.history[idx] || [];
|
|
const totalPoints = teamHistory.reduce((sum, pts) => sum + (pts || 0), 0);
|
|
return { idx, name: team.name, points: totalPoints };
|
|
});
|
|
|
|
// Sortiere absteigend nach Punkten
|
|
teamScores.sort((a, b) => b.points - a.points);
|
|
|
|
// Erstelle die Liga-Section
|
|
const section = document.createElement('div');
|
|
section.className = 'scoreboard-league';
|
|
|
|
const header = document.createElement('div');
|
|
header.className = 'scoreboard-league-header';
|
|
header.innerHTML = league.name;
|
|
section.appendChild(header);
|
|
|
|
const list = document.createElement('ul');
|
|
list.className = 'scoreboard-list';
|
|
|
|
teamScores.forEach((score, rank) => {
|
|
const item = document.createElement('li');
|
|
item.className = 'scoreboard-item';
|
|
|
|
const rankDiv = document.createElement('div');
|
|
rankDiv.className = 'scoreboard-rank';
|
|
rankDiv.innerHTML = `${rank + 1}.`;
|
|
item.appendChild(rankDiv);
|
|
|
|
const nameDiv = document.createElement('div');
|
|
nameDiv.className = 'scoreboard-team-name';
|
|
nameDiv.innerHTML = score.name;
|
|
item.appendChild(nameDiv);
|
|
|
|
const pointsDiv = document.createElement('div');
|
|
pointsDiv.className = 'scoreboard-points';
|
|
if (score.points > 0) {
|
|
pointsDiv.classList.add('positive');
|
|
pointsDiv.innerHTML = `+${score.points}`;
|
|
} else if (score.points < 0) {
|
|
pointsDiv.classList.add('negative');
|
|
pointsDiv.innerHTML = `${score.points}`;
|
|
} else {
|
|
pointsDiv.innerHTML = '0';
|
|
}
|
|
item.appendChild(pointsDiv);
|
|
|
|
list.appendChild(item);
|
|
});
|
|
|
|
section.appendChild(list);
|
|
content.appendChild(section);
|
|
}
|
|
});
|
|
|
|
document.getElementById('scoreboardModal').style.display = 'block';
|
|
}
|
|
|
|
function closeScoreboard() {
|
|
document.getElementById('scoreboardModal').style.display = 'none';
|
|
}
|
|
|
|
function confirmReset() {
|
|
document.getElementById('resetConfirmModal').style.display = 'block';
|
|
}
|
|
|
|
function closeResetConfirm() {
|
|
document.getElementById('resetConfirmModal').style.display = 'none';
|
|
}
|
|
|
|
function performReset() {
|
|
// Lade die Rohdaten (Teams, Feldanzahl)
|
|
const stored = localStorage.getItem(STORAGE_KEY);
|
|
if (!stored) return;
|
|
|
|
const data = JSON.parse(stored);
|
|
|
|
// Setze Rotationsstates zurück auf Anfangszustand
|
|
rotationState = {
|
|
bundesliga: {
|
|
round: 0,
|
|
teamOrder: data.bundesliga.map((t, i) => i)
|
|
},
|
|
champions: {
|
|
round: 0,
|
|
teamOrder: data.champions.map((t, i) => i)
|
|
}
|
|
};
|
|
|
|
// Leere alle Scores
|
|
matchScores = {};
|
|
|
|
// Speichere zurückgesetzte States
|
|
saveRotationState();
|
|
saveMatchScores();
|
|
|
|
// Aktualisiere die UI
|
|
displayCurrentRound();
|
|
|
|
// Schließe das Modal
|
|
closeResetConfirm();
|
|
|
|
alert('✅ Turnier wurde zurückgesetzt! Alle Runden und Scores wurden gelöscht.');
|
|
}
|
|
|
|
function openResultsModal() {
|
|
document.getElementById('resultsModal').style.display = 'block';
|
|
}
|
|
|
|
function closeResultsModal() {
|
|
document.getElementById('resultsModal').style.display = 'none';
|
|
} |