diff --git a/src/app/page.tsx b/src/app/page.tsx index e68abe6..7ca5a68 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,103 +1,135 @@ -import Image from "next/image"; +"use client"; -export default function Home() { +import { LanguageProvider, useLanguage } from "@/LanguageContext"; +import { translations } from "@/translations"; +import React, { useMemo, useRef, useState } from "react"; +import Footer from "./components/Footer"; +import GuessesList from "./components/GuessesList"; +import GuessForm from "./components/GuessForm"; +import Header from "./components/Header"; +import HowToPlay from "./components/HowToPlay"; +import HowToPlayButton from "./components/HowToPlayButton"; +import LanguageMenu from "./components/LanguageMenu"; +import RestartButton from "./components/RestartButton"; +import Score from "./components/Score"; +import Timer from "./components/Timer"; +import type { Match } from "./types"; + +export default function HomePageWithLanguage() { return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. - Save and see your changes instantly. -
  4. -
+ + + + ); +} -
- - Vercel logomark - Deploy now - - - Read our docs - -
+function Home() { + const [input, setInput] = useState(""); + const [matches, setMatches] = useState([]); + const [timer, setTimer] = useState(0); + const [timerStarted, setTimerStarted] = useState(false); + const timerRef = useRef(null); + const [howToPlayOpen, setHowToPlayOpen] = useState(false); + const [repeatMessage, setRepeatMessage] = useState(""); + const { language } = useLanguage(); + const t = translations[language]; + + const correctMatchesCount = useMemo(() => matches.filter((m) => m.correct).length, [matches]); + + const startTimer = () => { + if (!timerStarted) { + setTimerStarted(true); + timerRef.current = setInterval(() => { + setTimer((prev) => prev + 1); + }, 1000); + } + }; + + const stopTimer = () => { + if (timerRef.current) { + clearInterval(timerRef.current); + timerRef.current = null; + } + }; + + React.useEffect(() => { + return () => stopTimer(); + }, []); + + // Stop timer when 100 correct guesses are made + React.useEffect(() => { + if (correctMatchesCount === 100) { + stopTimer(); + } + }, [correctMatchesCount]); + + const handleRestart = () => { + stopTimer(); + setTimer(0); + setTimerStarted(false); + setMatches([]); + setInput(""); + setRepeatMessage(""); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const trimmedInput = input.trim(); + if (!trimmedInput) return; + if (matches.some((m) => m.input.toLowerCase() === trimmedInput.toLowerCase())) { + setRepeatMessage(t.alreadySubmitted); + return; + } + setRepeatMessage(""); + const res = await fetch("/api/guess", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ input: trimmedInput }), + }); + if (res.ok) { + const data = await res.json(); + setMatches((prev) => [...prev, { input: trimmedInput, ...data }]); + if (data.correct && !timerStarted) { + startTimer(); + } + } + setInput(""); + }; + + return ( +
+
+ + setHowToPlayOpen(true)} ariaLabel={t.howToPlayTitle} /> +
+
+
+ {timerStarted && ( +
+ + +
+ )} + { + setInput(e.target.value); + setRepeatMessage(""); + }} + onSubmit={handleSubmit} + disabled={correctMatchesCount === 100} + /> + + {repeatMessage &&
{repeatMessage}
} + {matches.length > 0 && ( + <> +

{t.submittedAnswers}

+ + + )}
- +
); }