From 4f4626260fd3ae5224f91ed616132be03026de2b Mon Sep 17 00:00:00 2001 From: Mathias Wagner Date: Thu, 24 Apr 2025 21:19:15 +0200 Subject: [PATCH] Translate UI text to German for Lobby, Results, and Voting screens to enhance localization --- client/src/components/LobbyScreen.jsx | 2 +- client/src/components/ResultsScreen.jsx | 72 +++++++++++++++---------- client/src/components/VotingScreen.jsx | 27 +++++++++- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/client/src/components/LobbyScreen.jsx b/client/src/components/LobbyScreen.jsx index bc45fbc..c1f3a78 100644 --- a/client/src/components/LobbyScreen.jsx +++ b/client/src/components/LobbyScreen.jsx @@ -143,7 +143,7 @@ const LobbyScreen = () => { Abbrechen diff --git a/client/src/components/ResultsScreen.jsx b/client/src/components/ResultsScreen.jsx index a309ca3..747a009 100644 --- a/client/src/components/ResultsScreen.jsx +++ b/client/src/components/ResultsScreen.jsx @@ -9,42 +9,49 @@ const ResultsScreen = () => { const [showBattleHistory, setShowBattleHistory] = useState(false); const [confetti, setConfetti] = useState(true); - // Winner information + // Gewinner-Informationen const winner = lobby?.finalWinner; const winnerVideoId = getYouTubeId(winner?.youtubeLink); - // Confetti effect for winner celebration + // Konfetti-Effekt für die Siegerfeier useEffect(() => { if (confetti) { - // Create confetti animation + // Konfetti-Animation erstellen const createConfetti = () => { const confettiContainer = document.createElement('div'); confettiContainer.className = 'confetti'; - // Random position and color + // Zufällige Position, Größe und Farbe const left = Math.random() * 100; const colors = ['#f94144', '#f3722c', '#f8961e', '#f9c74f', '#90be6d', '#43aa8b', '#577590']; const color = colors[Math.floor(Math.random() * colors.length)]; + const size = Math.random() * 0.7 + 0.3; // Zwischen 0.3 und 1rem + const rotation = Math.random() * 360; // Zufällige Rotation + const duration = Math.random() * 3 + 2; // Zwischen 2 und 5 Sekunden confettiContainer.style.left = `${left}%`; confettiContainer.style.backgroundColor = color; + confettiContainer.style.width = `${size}rem`; + confettiContainer.style.height = `${size * 0.6}rem`; + confettiContainer.style.transform = `rotate(${rotation}deg)`; + confettiContainer.style.animation = `confetti-fall ${duration}s linear forwards`; document.querySelector('.results-screen').appendChild(confettiContainer); - // Remove after animation + // Nach Animation entfernen setTimeout(() => { confettiContainer.remove(); - }, 5000); + }, duration * 1000); }; - // Create multiple confetti pieces + // Mehrere Konfetti-Stücke erstellen const confettiInterval = setInterval(() => { - for (let i = 0; i < 3; i++) { + for (let i = 0; i < 5; i++) { createConfetti(); } - }, 300); + }, 200); - // Stop confetti after some time + // Konfetti nach einiger Zeit stoppen setTimeout(() => { clearInterval(confettiInterval); setConfetti(false); @@ -56,7 +63,7 @@ const ResultsScreen = () => { } }, [confetti]); - // Get YouTube video ID from link + // YouTube-Video-ID aus Link extrahieren function getYouTubeId(url) { if (!url) return null; @@ -69,7 +76,7 @@ const ResultsScreen = () => { if (!winner) { return (
-

Calculating results...

+

Ergebnisse werden berechnet...

); } @@ -77,14 +84,14 @@ const ResultsScreen = () => { return (
-

Winner!

+

Gewinner!

{winner.title}

-

by {winner.artist}

-

Submitted by: {winner.submittedByName}

+

von {winner.artist}

+

Eingereicht von: {winner.submittedByName}

{winnerVideoId ? ( @@ -104,17 +111,17 @@ const ResultsScreen = () => { onClick={() => setShowBattleHistory(!showBattleHistory)} > - {showBattleHistory ? 'Hide Battle History' : 'Show Battle History'} + {showBattleHistory ? 'Kampfverlauf ausblenden' : 'Kampfverlauf anzeigen'}
{showBattleHistory && (
-

Battle History

+

Kampfverlauf

{lobby?.battles?.map((battle, index) => { @@ -122,13 +129,13 @@ const ResultsScreen = () => { const song1VideoId = getYouTubeId(battle.song1?.youtubeLink); const song2VideoId = battle.song2 ? getYouTubeId(battle.song2.youtubeLink) : null; - // Handle bye rounds + // Freilos-Runden behandeln const isByeRound = battle.bye === true || !battle.song2; return (
-

Round {battle.round + 1}, Battle {index + 1} {isByeRound ? "(Automatic Advance)" : ""}

+

Runde {battle.round + 1}, Kampf {index + 1} {isByeRound ? "(Automatisches Weiterkommen)" : ""}

@@ -136,19 +143,28 @@ const ResultsScreen = () => {
{battle.song1.title}

{battle.song1.artist}

- {battle.song1Votes} votes + {battle.song1Votes} Stimmen
-
VS
+
{isByeRound ? 'FREILOS' : 'VS'}
-
-
-
{battle.song2.title}
-

{battle.song2.artist}

- {battle.song2Votes} votes + {battle.song2 ? ( +
+
+
{battle.song2.title}
+

{battle.song2.artist}

+ {battle.song2Votes} Stimmen +
-
+ ) : ( +
+
+
Automatisches Freilos
+

Kein Gegner

+
+
+ )}
); diff --git a/client/src/components/VotingScreen.jsx b/client/src/components/VotingScreen.jsx index 92cae9d..b3c6047 100644 --- a/client/src/components/VotingScreen.jsx +++ b/client/src/components/VotingScreen.jsx @@ -10,6 +10,7 @@ function VotingScreen() { const [hasVoted, setHasVoted] = useState(false); const [selectedSong, setSelectedSong] = useState(null); const [countdown, setCountdown] = useState(null); + const [processingByeAdvance, setProcessingByeAdvance] = useState(false); // Hole aktuellen Kampf const battle = lobby?.currentBattle || null; @@ -61,6 +62,24 @@ function VotingScreen() { await submitVote(selectedSong); // setHasVoted wird jetzt durch den useEffect behandelt, der die Stimmen prüft }; + + // Handle bye round advancement - für automatisches Weiterkommen + const handleByeAdvance = async () => { + if (processingByeAdvance) return; + + setProcessingByeAdvance(true); + try { + // Alle Spieler im Bye-Modus "stimmen" automatisch für das einzige Lied + if (battle && battle.song1 && !battle.song2 && battle.song1.id) { + await submitVote(battle.song1.id); + } + } catch (error) { + console.error("Fehler beim Fortfahren:", error); + } finally { + // Verzögerung, um mehrere Klicks zu verhindern + setTimeout(() => setProcessingByeAdvance(false), 1000); + } + }; // Hole YouTube-Video-IDs aus Links const getYouTubeId = (url) => { @@ -120,8 +139,12 @@ function VotingScreen() {
-