Show an error when a guess fails and keep the input for retrying

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:18 +01:00
1 parent bcb8259489
commit 148449bcae
3 files changed
+28 -26

No files matched your search

+2 -5
View File
@@ -14,15 +14,12 @@ const GuessForm: React.FC<GuessFormProps> = ({ input, onInputChange, onSubmit, d
const { language } = useLanguage();
const t = translations[language];
const inputRef = useRef<HTMLInputElement>(null);
const prevInputRef = useRef(input);
// Focus input when it gets cleared after submission
useEffect(() => {
if (prevInputRef.current && !input && !loading) {
if (!loading && !disabled) {
inputRef.current?.focus();
}
prevInputRef.current = input;
}, [input, loading]);
}, [loading, disabled]);
const handleSubmit = (e: React.FormEvent) => {
onSubmit(e);
+22 -21
View File
@@ -27,7 +27,7 @@ export default function HomeClient({ session }: { session: Session }) {
const [loading, setLoading] = useState(false);
const timerRef = useRef<NodeJS.Timeout | null>(null);
const [howToPlayOpen, setHowToPlayOpen] = useState(false);
const [repeatMessage, setRepeatMessage] = useState("");
const [errorMessage, setErrorMessage] = useState("");
const { language } = useLanguage();
const t = translations[language];
const [goalAmount, setGoalAmount] = useState(100);
@@ -83,49 +83,50 @@ export default function HomeClient({ session }: { session: Session }) {
setTimerStarted(false);
setMatches([]);
setInput("");
setRepeatMessage("");
setErrorMessage("");
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const trimmedInput = input.trim();
if (!trimmedInput) return;
if (matches.some((m) => m.input.toLowerCase() === trimmedInput.toLowerCase() && !m.name)) {
setRepeatMessage(t.alreadySubmitted);
if (matches.some((m) => !m.name && m.input.toLowerCase() === trimmedInput.toLowerCase())) {
setErrorMessage(t.alreadySubmitted);
return;
}
setRepeatMessage("");
setErrorMessage("");
setLoading(true);
try {
const guessedIds = matches.filter((m) => m.correct && m.id).map((m) => m.id!);
const guessedIds = matches.flatMap((m) => (m.correct && m.id ? [m.id] : []));
const res = await fetch("/api/guess", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ input: trimmedInput, guessedIds }),
});
const data: Match | null = res.ok ? await res.json() : null;
if (res.ok) {
const data = (await res.json()) as Match;
if (!data) {
setErrorMessage(res.status === 401 ? t.sessionExpired : t.guessFailed);
return;
}
if (data.id && matches.some((m) => m.id && m.id === data.id)) {
setRepeatMessage(t.alreadySubmitted);
setInput("");
return;
}
setMatches((prev) => [...prev, data]);
setInput("");
if (data.id && matches.some((m) => m.id === data.id)) {
setErrorMessage(t.alreadySubmitted);
return;
}
setMatches((prev) => [...prev, data]);
if (data.correct && !timerStarted) {
startTimer();
}
if (data.correct && !timerStarted) {
startTimer();
}
} catch (error) {
console.error("Error submitting guess:", error);
setRepeatMessage("An error occurred. Please try again.");
setErrorMessage(t.guessFailed);
} finally {
setLoading(false);
setInput("");
}
};
@@ -175,14 +176,14 @@ export default function HomeClient({ session }: { session: Session }) {
input={input}
onInputChange={(e) => {
setInput(e.target.value);
setRepeatMessage("");
setErrorMessage("");
}}
onSubmit={handleSubmit}
disabled={correctMatchesCount === goalAmount}
loading={loading}
/>
<Score matchesCount={correctMatchesCount} goalAmount={goalAmount} />
{repeatMessage && <div className="mb-2 font-semibold text-red-500">{repeatMessage}</div>}
{errorMessage && <div className="mb-2 font-semibold text-red-500">{errorMessage}</div>}
{matches.length > 0 && (
<>
<h2 className="mt-4 text-2xl">{t.submittedAnswers}</h2>
+4
View File
@@ -22,6 +22,8 @@ export const translations = {
tryAgain: "Try logging in again",
notPayingMember: "not a paying member",
goalSelectorLabel: "Number of gamers to name:",
guessFailed: "Something went wrong. Please try again.",
sessionExpired: "Your session has expired. Reload the page to log in again.",
},
no: {
submittedAnswers: "Dine svar",
@@ -45,5 +47,7 @@ export const translations = {
tryAgain: "Logg på igjen",
notPayingMember: "ikke betalende medlem",
goalSelectorLabel: "Velg antall som må navngis:",
guessFailed: "Noe gikk galt. Prøv igjen.",
sessionExpired: "Økten din har utløpt. Last inn siden på nytt for å logge inn igjen.",
},
};