Show a message with the final time when the goal is reached

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
leanderandClaude Opus 5.5 committed 2026-10-31 01:43:56 +01:00
1 parent 16de8afe42
commit c6c22f9268
3 files changed
+26 -20

No files matched your search

+8 -2
View File
@@ -17,7 +17,7 @@ import LanguageMenu from "./LanguageMenu";
import LogoutButton from "./LogoutButton"; import LogoutButton from "./LogoutButton";
import RestartButton from "./RestartButton"; import RestartButton from "./RestartButton";
import Score from "./Score"; import Score from "./Score";
import Timer from "./Timer"; import Timer, { formatTime } from "./Timer";
export default function HomeClient({ session }: { session: Session }) { export default function HomeClient({ session }: { session: Session }) {
const [input, setInput] = useState(""); const [input, setInput] = useState("");
@@ -51,6 +51,7 @@ export default function HomeClient({ session }: { session: Session }) {
}, []); }, []);
const correctMatchesCount = useMemo(() => matches.filter((m) => m.correct).length, [matches]); const correctMatchesCount = useMemo(() => matches.filter((m) => m.correct).length, [matches]);
const goalReached = correctMatchesCount >= goalAmount;
const elapsedSeconds = () => Math.floor((Date.now() - startedAtRef.current) / 1000); const elapsedSeconds = () => Math.floor((Date.now() - startedAtRef.current) / 1000);
@@ -181,10 +182,15 @@ export default function HomeClient({ session }: { session: Session }) {
setErrorMessage(""); setErrorMessage("");
}} }}
onSubmit={handleSubmit} onSubmit={handleSubmit}
disabled={correctMatchesCount === goalAmount} disabled={goalReached}
loading={loading} loading={loading}
/> />
<Score matchesCount={correctMatchesCount} goalAmount={goalAmount} /> <Score matchesCount={correctMatchesCount} goalAmount={goalAmount} />
{goalReached && (
<p className="text-xl font-semibold text-green-600">
{t.goalReached.replace("{count}", String(goalAmount)).replace("{time}", formatTime(timer))}
</p>
)}
{errorMessage && <div className="mb-2 font-semibold text-red-500">{errorMessage}</div>} {errorMessage && <div className="mb-2 font-semibold text-red-500">{errorMessage}</div>}
{matches.length > 0 && ( {matches.length > 0 && (
<> <>
+16 -18
View File
@@ -5,27 +5,25 @@ interface TimerProps {
timer: number; timer: number;
} }
const Timer: React.FC<TimerProps> = ({ timer }) => { const padZero = (num: number): string => String(num).padStart(2, "0");
const formatTime = (seconds: number): string => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
const padZero = (num: number): string => String(num).padStart(2, "0"); export const formatTime = (seconds: number): string => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
if (hours > 0) { if (hours > 0) {
return `${padZero(hours)}:${padZero(minutes)}:${padZero(remainingSeconds)}`; return `${padZero(hours)}:${padZero(minutes)}:${padZero(remainingSeconds)}`;
} }
return `${padZero(minutes)}:${padZero(remainingSeconds)}`; return `${padZero(minutes)}:${padZero(remainingSeconds)}`;
};
return (
<span className="text-accent-secondary bg-accent-secondary-light border-accent-secondary flex items-center gap-1 rounded-2xl border-2 p-2 font-bold">
<MdOutlineTimer className="text-xl" />
{formatTime(timer)}
</span>
);
}; };
const Timer: React.FC<TimerProps> = ({ timer }) => (
<span className="text-accent-secondary bg-accent-secondary-light border-accent-secondary flex items-center gap-1 rounded-2xl border-2 p-2 font-bold">
<MdOutlineTimer className="text-xl" />
{formatTime(timer)}
</span>
);
export default Timer; export default Timer;
+2
View File
@@ -22,6 +22,7 @@ export const translations = {
tryAgain: "Try logging in again", tryAgain: "Try logging in again",
notPayingMember: "not a paying member", notPayingMember: "not a paying member",
goalSelectorLabel: "Number of gamers to name:", goalSelectorLabel: "Number of gamers to name:",
goalReached: "You named {count} UiO Gamers in {time}!",
guessFailed: "Something went wrong. Please try again.", guessFailed: "Something went wrong. Please try again.",
sessionExpired: "Your session has expired. Reload the page to log in again.", sessionExpired: "Your session has expired. Reload the page to log in again.",
}, },
@@ -47,6 +48,7 @@ export const translations = {
tryAgain: "Logg på igjen", tryAgain: "Logg på igjen",
notPayingMember: "ikke betalende medlem", notPayingMember: "ikke betalende medlem",
goalSelectorLabel: "Velg antall som må navngis:", goalSelectorLabel: "Velg antall som må navngis:",
goalReached: "Du navnga {count} UiO-Gamere på {time}!",
guessFailed: "Noe gikk galt. Prøv igjen.", guessFailed: "Noe gikk galt. Prøv igjen.",
sessionExpired: "Økten din har utløpt. Last inn siden på nytt for å logge inn igjen.", sessionExpired: "Økten din har utløpt. Last inn siden på nytt for å logge inn igjen.",
}, },