// src/scripts/index.js // Modularized logic from original index.astro // --- State --- let games = []; let currentGameId = null; let playerNameHistory = []; // --- DOM Selectors --- const screens = { 'new-game-screen': document.getElementById('new-game-screen'), 'game-list-screen': document.getElementById('game-list-screen'), 'game-detail-screen': document.getElementById('game-detail-screen'), 'game-history-screen': document.getElementById('game-history-screen') }; // --- Screen Management --- function showScreen(screenId) { const currentScreen = document.querySelector('.screen.active'); const newScreen = document.getElementById(screenId); if (currentScreen) { currentScreen.classList.remove('active'); currentScreen.classList.add('slide-out'); setTimeout(() => { currentScreen.classList.remove('slide-out'); newScreen.classList.add('active'); newScreen.classList.add('slide-in'); setTimeout(() => { newScreen.classList.remove('slide-in'); }, 300); }, 300); } else { newScreen.classList.add('active'); } if (screenId === 'new-game-screen') { updateNameHistory(); } } // --- Loading Overlay --- function showLoading() { document.querySelector('.loading-overlay').style.display = 'block'; document.querySelector('.loading-indicator').style.display = 'block'; } function hideLoading() { document.querySelector('.loading-overlay').style.display = 'none'; document.querySelector('.loading-indicator').style.display = 'none'; } // --- Game Data Management --- function loadGames() { const savedGames = localStorage.getItem('bscscore_games'); if (savedGames) { games = JSON.parse(savedGames); renderGames(); } } function saveGames() { localStorage.setItem('bscscore_games', JSON.stringify(games)); } // --- Player Name History --- function updateNameHistory() { const allNames = games.flatMap(game => [game.player1, game.player2, game.player3].filter(Boolean)); const nameLastUsed = {}; games.forEach(game => { if (game.player1) nameLastUsed[game.player1] = Math.max(nameLastUsed[game.player1] || 0, new Date(game.updatedAt).getTime()); if (game.player2) nameLastUsed[game.player2] = Math.max(nameLastUsed[game.player2] || 0, new Date(game.updatedAt).getTime()); if (game.player3) nameLastUsed[game.player3] = Math.max(nameLastUsed[game.player3] || 0, new Date(game.updatedAt).getTime()); }); playerNameHistory = [...new Set(Object.keys(nameLastUsed))].sort((a, b) => nameLastUsed[b] - nameLastUsed[a]); updateNameSelects(); } function updateNameSelects() { const player1Select = document.getElementById('player1-select'); const player2Select = document.getElementById('player2-select'); const player3Select = document.getElementById('player3-select'); while (player1Select.options.length > 1) player1Select.remove(1); while (player2Select.options.length > 1) player2Select.remove(1); while (player3Select.options.length > 1) player3Select.remove(1); playerNameHistory.forEach(name => { const option1 = new Option(name, name); const option2 = new Option(name, name); const option3 = new Option(name, name); player1Select.add(option1); player2Select.add(option2); player3Select.add(option3); }); } function updatePlayerInput(playerId) { const select = document.getElementById(`${playerId}-select`); const input = document.getElementById(playerId); if (select.value) { input.value = select.value; } } // --- Validation Modal --- function showValidationModal(message) { const modal = document.getElementById('validation-modal'); const modalMessage = document.getElementById('validation-modal-message'); modalMessage.textContent = message; modal.classList.add('show'); } function closeValidationModal() { const modal = document.getElementById('validation-modal'); modal.classList.remove('show'); } // --- New Game Creation --- function createNewGame() { const player1Name = document.getElementById('player1').value.trim(); const player2Name = document.getElementById('player2').value.trim(); const player3Name = document.getElementById('player3').value.trim(); const gameType = document.getElementById('game-type').value; const raceTo = document.getElementById('race-to').value; if (!player1Name || !player2Name) { showValidationModal('Bitte Namen für beide Spieler eingeben'); return; } const newGame = { id: Date.now(), player1: player1Name, player2: player2Name, player3: player3Name || null, score1: 0, score2: 0, score3: 0, gameType: gameType, raceTo: raceTo ? parseInt(raceTo) : null, status: 'active', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; games.push(newGame); saveGames(); updateNameHistory(); renderGames(); showGameDetail(newGame.id); } // --- Score Update --- function updateScore(gameId, player, change) { const game = games.find(g => g.id === gameId); if (!game || game.status === 'completed') return; if (player === 1) { game.score1 = Math.max(0, game.score1 + change); } else if (player === 2) { game.score2 = Math.max(0, game.score2 + change); } else if (player === 3) { game.score3 = Math.max(0, game.score3 + change); } game.updatedAt = new Date().toISOString(); if (game.raceTo && (game.score1 >= game.raceTo || game.score2 >= game.raceTo || (game.player3 && game.score3 >= game.raceTo))) { showGameCompletionModal(); } saveGames(); renderGames(); if (document.getElementById('game-detail-screen').classList.contains('active')) { document.getElementById('score1').textContent = game.score1; document.getElementById('score2').textContent = game.score2; document.getElementById('score3').textContent = game.score3; } } // --- Game Deletion --- function deleteGame(gameId) { const game = games.find(g => g.id === gameId); if (!game) return; currentGameId = gameId; const modal = document.getElementById('modal'); const modalTitle = document.getElementById('modal-title'); const modalMessage = document.getElementById('modal-message'); modalTitle.textContent = 'Spiel löschen'; modalMessage.textContent = `Möchten Sie das Spiel zwischen ${game.player1} und ${game.player2} wirklich löschen?`; modal.classList.add('show'); } function closeModal() { const modal = document.getElementById('modal'); modal.classList.remove('show'); currentGameId = null; } function confirmDeleteGame(gameId) { if (!gameId) return; showLoading(); setTimeout(() => { const gameIndex = games.findIndex(g => g.id === gameId); if (gameIndex !== -1) { games.splice(gameIndex, 1); saveGames(); renderGames(); if (currentGameId === gameId) { showScreen('game-list-screen'); } } hideLoading(); closeModal(); }, 500); } // --- Game Rendering --- function renderGames(filter = 'all') { const gamesContainer = document.getElementById('games-container'); const filteredGames = games .filter(game => { if (filter === 'active') return game.status === 'active'; if (filter === 'completed') return game.status === 'completed'; return true; }) .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)); if (filteredGames.length === 0) { gamesContainer.innerHTML = '
Keine Spiele vorhanden
'; return; } gamesContainer.innerHTML = filteredGames.map(game => { const playerNames = game.player3 ? `${game.player1} vs ${game.player2} vs ${game.player3}` : `${game.player1} vs ${game.player2}`; const scores = game.player3 ? `${game.score1} - ${game.score2} - ${game.score3}` : `${game.score1} - ${game.score2}`; return `
${game.gameType}${game.raceTo ? ` | ${game.raceTo}` : ''}
${playerNames}
${scores}
`; }).join(''); } // --- Game Detail --- function showGameDetail(gameId) { const game = games.find(g => g.id === gameId); if (!game) return; currentGameId = gameId; document.getElementById('game-title').textContent = `${game.gameType}${game.raceTo ? ` | Race to ${game.raceTo}` : ''}`; document.getElementById('player1-name').textContent = game.player1; document.getElementById('player2-name').textContent = game.player2; const player3Score = document.getElementById('player3-score'); if (game.player3) { document.getElementById('player3-name').textContent = game.player3; document.getElementById('score3').textContent = game.score3; player3Score.style.display = 'flex'; } else { player3Score.style.display = 'none'; } document.getElementById('score1').textContent = game.score1; document.getElementById('score2').textContent = game.score2; const player1Container = document.querySelector('.player-score:first-child'); const player2Container = document.querySelector('.player-score:nth-child(2)'); const player3Container = document.getElementById('player3-score'); player1Container.classList.toggle('franky', game.player1 === 'Fränky'); player2Container.classList.toggle('franky', game.player2 === 'Fränky'); player3Container.classList.toggle('franky', game.player3 === 'Fränky'); const controlButton = document.getElementById('game-control'); if (game.status === 'completed') { controlButton.textContent = 'Zurück zur Liste'; controlButton.onclick = () => showScreen('game-list-screen'); controlButton.classList.add('disabled'); } else { controlButton.textContent = 'Spiel beenden'; controlButton.onclick = () => finishGame(); controlButton.classList.remove('disabled'); } const scoreButtons = document.querySelectorAll('.score-button'); scoreButtons.forEach(button => { button.disabled = game.status === 'completed'; }); showScreen('game-detail-screen'); } // --- Game Completion Modal --- function showGameCompletionModal() { const game = games.find(g => g.id === currentGameId); if (!game) return; const modal = document.getElementById('game-completion-modal'); const finalScores = modal.querySelector('.final-scores'); const winnerAnnouncement = modal.querySelector('.winner-announcement'); let scoreHtml = ''; scoreHtml += `
${game.player1} ${game.score1}
`; scoreHtml += `
${game.player2} ${game.score2}
`; if (game.player3) { scoreHtml += `
${game.player3} ${game.score3}
`; } finalScores.innerHTML = scoreHtml; const scores = [game.score1, game.score2]; if (game.player3) scores.push(game.score3); const maxScore = Math.max(...scores); const winners = []; if (game.score1 === maxScore) winners.push(game.player1); if (game.score2 === maxScore) winners.push(game.player2); if (game.player3 && game.score3 === maxScore) winners.push(game.player3); const winnerText = winners.length > 1 ? `Unentschieden zwischen ${winners.join(' und ')}` : `${winners[0]} hat gewonnen!`; winnerAnnouncement.innerHTML = `

${winnerText}

`; modal.classList.add('show'); } function closeGameCompletionModal() { document.getElementById('game-completion-modal').classList.remove('show'); } function confirmGameCompletion() { const game = games.find(g => g.id === currentGameId); if (!game) return; game.status = 'completed'; game.updatedAt = new Date().toISOString(); saveGames(); renderGames(); showGameDetail(currentGameId); closeGameCompletionModal(); } // --- Game Finish --- function finishGame() { const game = games.find(g => g.id === currentGameId); if (!game) return; showGameCompletionModal(); } // --- Filter Games --- function filterGames(filter) { document.querySelectorAll('.filter-button').forEach(button => { button.classList.remove('active'); }); document.querySelector(`.filter-button[onclick=\"filterGames('${filter}')\"]`).classList.add('active'); renderGames(filter); } // --- Fullscreen --- function toggleFullscreen() { if (!document.fullscreenElement) { document.documentElement.requestFullscreen().catch(err => { console.log(`Error attempting to enable fullscreen: ${err.message}`); }); } else { document.exitFullscreen(); } } document.addEventListener('fullscreenchange', () => { const button = document.getElementById('fullscreen-toggle'); if (document.fullscreenElement) { button.innerHTML = ``; } else { button.innerHTML = ``; } }); // --- Event Listeners --- document.addEventListener('DOMContentLoaded', () => { loadGames(); // Attach event listeners for navigation, game creation, modals, etc. document.querySelectorAll('.nav-button').forEach(btn => { if (btn.textContent.includes('Neues Spiel')) btn.onclick = () => showScreen('new-game-screen'); if (btn.textContent.includes('Abbrechen')) btn.onclick = () => showScreen('game-list-screen'); if (btn.textContent.includes('Zurück zur Liste')) btn.onclick = () => showScreen('game-list-screen'); }); document.querySelectorAll('.filter-button').forEach((btn, idx) => { if (btn.textContent === 'Alle') btn.onclick = () => filterGames('all'); if (btn.textContent === 'Aktiv') btn.onclick = () => filterGames('active'); if (btn.textContent === 'Abgeschlossen') btn.onclick = () => filterGames('completed'); }); // Attach fullscreen toggle event const fullscreenBtn = document.getElementById('fullscreen-toggle'); if (fullscreenBtn) fullscreenBtn.addEventListener('click', toggleFullscreen); // Modal buttons const modal = document.getElementById('modal'); if (modal) { modal.querySelector('.close-button').onclick = closeModal; modal.querySelector('.modal-button.cancel').onclick = closeModal; modal.querySelector('.modal-button.confirm').onclick = () => confirmDeleteGame(currentGameId); } const validationModal = document.getElementById('validation-modal'); if (validationModal) { validationModal.querySelector('.close-button').onclick = closeValidationModal; validationModal.querySelector('.modal-button.cancel').onclick = closeValidationModal; } const gameCompletionModal = document.getElementById('game-completion-modal'); if (gameCompletionModal) { gameCompletionModal.querySelector('.btn.btn--warning').onclick = confirmGameCompletion; gameCompletionModal.querySelector('.btn:not(.btn--warning)').onclick = closeGameCompletionModal; } // New game creation const startGameBtn = document.querySelector('.nav-button'); if (startGameBtn && startGameBtn.textContent.includes('Spiel starten')) { startGameBtn.onclick = createNewGame; } // Player name selects ['player1', 'player2', 'player3'].forEach(pid => { const select = document.getElementById(`${pid}-select`); if (select) select.onchange = () => updatePlayerInput(pid); }); // Score buttons document.querySelectorAll('.score-button').forEach((btn, idx) => { btn.onclick = () => { const player = Math.floor(idx / 2) + 1; const change = idx % 2 === 0 ? -1 : 1; updateScore(currentGameId, player, change); }; }); }); // Initial screen showScreen('game-list-screen'); window.toggleFullscreen = toggleFullscreen;