Timer integration
This commit is contained in:
parent
5bcc4c570f
commit
d43866615b
99
src/components/RoundTimer.tsx
Normal file
99
src/components/RoundTimer.tsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { Timer, Play, Pause, RotateCcw } from 'lucide-react';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
|
||||||
|
interface RoundTimerProps {
|
||||||
|
roundNumber: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RoundTimer = ({ roundNumber }: RoundTimerProps) => {
|
||||||
|
const [seconds, setSeconds] = useState(0);
|
||||||
|
const [isRunning, setIsRunning] = useState(true); // Auto-start beim Laden
|
||||||
|
const [isPaused, setIsPaused] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Reset timer wenn neue Runde startet
|
||||||
|
setSeconds(0);
|
||||||
|
setIsRunning(true);
|
||||||
|
setIsPaused(false);
|
||||||
|
}, [roundNumber]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let interval: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
|
if (isRunning && !isPaused) {
|
||||||
|
interval = setInterval(() => {
|
||||||
|
setSeconds((prev) => prev + 1);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (interval) clearInterval(interval);
|
||||||
|
};
|
||||||
|
}, [isRunning, isPaused]);
|
||||||
|
|
||||||
|
const togglePause = () => {
|
||||||
|
setIsPaused((prev) => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
setSeconds(0);
|
||||||
|
setIsPaused(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatTime = (totalSeconds: number): string => {
|
||||||
|
const hours = Math.floor(totalSeconds / 3600);
|
||||||
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
const secs = totalSeconds % 60;
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
return `${minutes}:${secs.toString().padStart(2, '0')}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="card-apple p-4 flex items-center justify-between gap-4">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className={`p-2 rounded-xl transition-colors ${
|
||||||
|
isPaused
|
||||||
|
? 'bg-muted text-muted-foreground'
|
||||||
|
: 'bg-primary/10 text-primary animate-pulse'
|
||||||
|
}`}>
|
||||||
|
<Timer className="w-5 h-5" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium text-muted-foreground">Rundenzeit</p>
|
||||||
|
<p className="text-2xl font-bold text-foreground tabular-nums">
|
||||||
|
{formatTime(seconds)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={togglePause}
|
||||||
|
className="rounded-xl h-9 w-9"
|
||||||
|
title={isPaused ? 'Fortsetzen' : 'Pausieren'}
|
||||||
|
>
|
||||||
|
{isPaused ? (
|
||||||
|
<Play className="w-4 h-4" />
|
||||||
|
) : (
|
||||||
|
<Pause className="w-4 h-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={reset}
|
||||||
|
className="rounded-xl h-9 w-9"
|
||||||
|
title="Zurücksetzen"
|
||||||
|
>
|
||||||
|
<RotateCcw className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -4,6 +4,7 @@ import { Trophy, Star, Clock, Play, CheckCircle, AlertCircle } from 'lucide-reac
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { MatchScoreInput } from '@/components/MatchScoreInput';
|
import { MatchScoreInput } from '@/components/MatchScoreInput';
|
||||||
import { ScoreboardModal } from '@/components/ScoreboardModal';
|
import { ScoreboardModal } from '@/components/ScoreboardModal';
|
||||||
|
import { RoundTimer } from '@/components/RoundTimer';
|
||||||
|
|
||||||
const WaitingTeam = ({ team }: { team: Team }) => (
|
const WaitingTeam = ({ team }: { team: Team }) => (
|
||||||
<div className="flex items-center gap-3 p-3 bg-waiting/10 rounded-xl border border-waiting/20">
|
<div className="flex items-center gap-3 p-3 bg-waiting/10 rounded-xl border border-waiting/20">
|
||||||
@ -160,6 +161,8 @@ export const TournamentView = () => {
|
|||||||
|
|
||||||
{currentRound && (
|
{currentRound && (
|
||||||
<>
|
<>
|
||||||
|
<RoundTimer roundNumber={currentRound.roundNumber} />
|
||||||
|
|
||||||
<div className="card-apple p-4 bg-primary/5 border-primary/20">
|
<div className="card-apple p-4 bg-primary/5 border-primary/20">
|
||||||
<p className="text-sm text-center text-muted-foreground">
|
<p className="text-sm text-center text-muted-foreground">
|
||||||
<span className="font-semibold text-primary">Runde {currentRound.roundNumber}</span> –
|
<span className="font-semibold text-primary">Runde {currentRound.roundNumber}</span> –
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user