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 RestartButton from "./RestartButton";
import Score from "./Score";
import Timer from "./Timer";
import Timer, { formatTime } from "./Timer";
export default function HomeClient({ session }: { session: Session }) {
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 goalReached = correctMatchesCount >= goalAmount;
const elapsedSeconds = () => Math.floor((Date.now() - startedAtRef.current) / 1000);
@@ -181,10 +182,15 @@ export default function HomeClient({ session }: { session: Session }) {
setErrorMessage("");
}}
onSubmit={handleSubmit}
disabled={correctMatchesCount === goalAmount}
disabled={goalReached}
loading={loading}
/>
<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>}
{matches.length > 0 && (
<>
+16 -18
View File
@@ -5,27 +5,25 @@ interface TimerProps {
timer: number;
}
const Timer: React.FC<TimerProps> = ({ timer }) => {
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");
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) {
return `${padZero(hours)}:${padZero(minutes)}:${padZero(remainingSeconds)}`;
}
if (hours > 0) {
return `${padZero(hours)}:${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>
);
return `${padZero(minutes)}:${padZero(remainingSeconds)}`;
};
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;
+2
View File
@@ -22,6 +22,7 @@ export const translations = {
tryAgain: "Try logging in again",
notPayingMember: "not a paying member",
goalSelectorLabel: "Number of gamers to name:",
goalReached: "You named {count} UiO Gamers in {time}!",
guessFailed: "Something went wrong. Please try again.",
sessionExpired: "Your session has expired. Reload the page to log in again.",
},
@@ -47,6 +48,7 @@ export const translations = {
tryAgain: "Logg på igjen",
notPayingMember: "ikke betalende medlem",
goalSelectorLabel: "Velg antall som må navngis:",
goalReached: "Du navnga {count} UiO-Gamere på {time}!",
guessFailed: "Noe gikk galt. Prøv igjen.",
sessionExpired: "Økten din har utløpt. Last inn siden på nytt for å logge inn igjen.",
},