From a905e575f483dae9fcf8f31f1d7676e8f03e7428 Mon Sep 17 00:00:00 2001 From: lashman Date: Tue, 16 Dec 2025 22:05:26 +0200 Subject: [PATCH] hud and timer bar --- frontend/src/components/InfoBar.tsx | 125 ++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 frontend/src/components/InfoBar.tsx diff --git a/frontend/src/components/InfoBar.tsx b/frontend/src/components/InfoBar.tsx new file mode 100644 index 0000000..79f8007 --- /dev/null +++ b/frontend/src/components/InfoBar.tsx @@ -0,0 +1,125 @@ +import { useEffect } from 'react' +import { useTranslation } from 'react-i18next' +import { IconClockFilled, IconCircleCheckFilled, IconEyeFilled, IconBookmarkFilled, IconChecks, + IconBoltFilled, IconPlayerTrackNextFilled, IconArrowBackUp, IconArrowForwardUp, + IconPencil, IconBallpenFilled, IconShieldCheckFilled } from '@tabler/icons-react' +import { useStore } from '../store' +import Tooltip from './ui/Tooltip' + +export default function InfoBar() { + const elapsed = useStore((s) => s.elapsed) + const startTime = useStore((s) => s.startTime) + const paused = useStore((s) => s.paused) + const tick = useStore((s) => s.tick) + const selectedCell = useStore((s) => s.selectedCell) + const checkCell = useStore((s) => s.checkCell) + const revealLetter = useStore((s) => s.revealLetter) + const revealWord = useStore((s) => s.revealWord) + const validateSolution = useStore((s) => s.validateSolution) + const gameMode = useStore((s) => s.gameMode) + const timeLimit = useStore((s) => s.timeLimit) + const marathonCount = useStore((s) => s.marathonCount) + const hintsUsed = useStore((s) => s.hintsUsed) + const solved = useStore((s) => s.solved) + const undo = useStore((s) => s.undo) + const redo = useStore((s) => s.redo) + const undoStack = useStore((s) => s.undoStack) + const redoStack = useStore((s) => s.redoStack) + const pencilMode = useStore((s) => s.pencilMode) + const togglePencilMode = useStore((s) => s.togglePencilMode) + const autoCheck = useStore((s) => s.autoCheck) + const toggleAutoCheck = useStore((s) => s.toggleAutoCheck) + const { t } = useTranslation() + useEffect(() => { + if (!startTime || paused) return + const id = setInterval(tick, 1000) + return () => clearInterval(id) + }, [startTime, paused, tick]) + + const isSpeedRun = gameMode === 'speedrun' + const isMarathon = gameMode === 'marathon' + + const displayTime = isSpeedRun && timeLimit > 0 + ? Math.max(0, timeLimit - elapsed) + : elapsed + const mins = Math.floor(displayTime / 60) + const secs = displayTime % 60 + const timeWarning = isSpeedRun && timeLimit > 0 && (timeLimit - elapsed) <= 30 + + return ( +
+ + {isSpeedRun && + + {hintsUsed > 0 && ( + {hintsUsed === 1 ? t('game.hintsUsed', { count: hintsUsed }) : t('game.hintsUsed_plural', { count: hintsUsed })} + )} + + {!solved && ( + <> + + + + + + + + + + + + + {!isSpeedRun && !isMarathon && ( + <> + + + + + + + + + + + + + + + + + )} + + + + + + + + )} +
+ ) +}