mirror of
https://github.com/UiO-Gaming/name-100-uio-gamers.git
synced 2026-11-05 13:56:53 +01:00
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:
1 parent
16de8afe42
commit
c6c22f9268
3 files changed
+26
-20
No files matched your search
@@ -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 && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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.",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in new issue
Block a user