Skip to content

Commit

Permalink
refactor: improve error display on login/register
Browse files Browse the repository at this point in the history
  • Loading branch information
cecelot committed Jun 15, 2024
1 parent 9ff361a commit 081756d
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 22 deletions.
40 changes: 30 additions & 10 deletions client/src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
"use client";

import ErrorableFormInput from "@/components/input/Field";
import { BASE_API_URL } from "@/lib";
import { Button, Input } from "@headlessui/react";
import { Optional } from "@/types";
import { Button } from "@headlessui/react";
import { useState } from "react";

export default function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [usernameError, setUsernameError] = useState<Optional<string>>();
const [passwordError, setPasswordError] = useState<Optional<string>>();

const onClick = (_: unknown) => {
return (async () => {
Expand All @@ -27,7 +31,22 @@ export default function Login() {
if (res.status === 200) {
window.location.href = to;
} else {
alert("Invalid username or password!");
switch (res.status) {
case 404: {
setUsernameError("No user exists with that username.");
setPasswordError(undefined);
break;
}
case 403: {
setUsernameError(undefined);
setPasswordError("Incorrect password! Try again.");
break;
}
default:
setUsernameError("An unexpected error occurred.");
setPasswordError(undefined);
}
// setErrorCode(res.status);
}
})();
};
Expand All @@ -36,17 +55,18 @@ export default function Login() {
<main className="text-center mx-auto m-4">
<h1 className="text-3xl font-semibold mb-5">Login</h1>
<form className="flex flex-col mx-auto space-y-3 max-w-60">
<Input
<ErrorableFormInput
placeholder="Username"
className="bg-crust text-subtext0 rounded-lg p-3"
onChange={(e) => setUsername(e.currentTarget.value)}
></Input>
<Input
type="text"
setText={setUsername}
errorText={usernameError}
/>
<ErrorableFormInput
placeholder="Password"
className="bg-crust text-subtext0 rounded-lg p-3"
type="password"
onChange={(e) => setPassword(e.currentTarget.value)}
></Input>
setText={setPassword}
errorText={passwordError}
/>
<Button
onClick={onClick}
className="text-text border-2 border-green hover:bg-mantle transition-all rounded-lg p-3"
Expand Down
39 changes: 27 additions & 12 deletions client/src/app/register/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"use client";

import { Button, Input } from "@headlessui/react";
import ErrorableFormInput from "@/components/input/Field";
import { Optional } from "@/types";
import { Button } from "@headlessui/react";
import { useState } from "react";

export default function Login() {
interface RegisterRouteReply {
message: string;
}

export default function Register() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [usernameError, setUsernameError] = useState<Optional<string>>();
const [passwordError, setPasswordError] = useState<Optional<string>>();

const onClick = (_: unknown) => {
return (async () => {
Expand All @@ -23,10 +31,16 @@ export default function Login() {
const to = decodeURIComponent(
new URLSearchParams(window.location.search).get("to") || "/"
);
if (res.status === 200) {
if (res.status === 201) {
window.location.href = to;
} else {
alert(JSON.stringify(await res.json()));
const { message }: RegisterRouteReply = await res.json();
if (message.includes("Username")) {
setUsernameError(message);
} else setUsernameError(undefined);
if (message.includes("Password")) {
setPasswordError(message);
} else setPasswordError(undefined);
}
})();
};
Expand All @@ -35,17 +49,18 @@ export default function Login() {
<main className="text-center mx-auto m-4">
<h1 className="text-3xl font-semibold mb-5">Register</h1>
<form className="flex flex-col mx-auto space-y-3 max-w-60">
<Input
<ErrorableFormInput
placeholder="Username"
className="bg-crust text-subtext0 rounded-lg p-3"
onChange={(e) => setUsername(e.currentTarget.value)}
></Input>
<Input
type="text"
setText={setUsername}
errorText={usernameError}
/>
<ErrorableFormInput
placeholder="Password"
className="bg-crust text-subtext0 rounded-lg p-3"
type="password"
onChange={(e) => setPassword(e.currentTarget.value)}
></Input>
setText={setPassword}
errorText={passwordError}
/>
<Button
onClick={onClick}
className="text-text border-2 border-green hover:bg-mantle transition-all rounded-lg p-3"
Expand Down
32 changes: 32 additions & 0 deletions client/src/components/input/Field.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Input } from "@headlessui/react";
import { HTMLInputTypeAttribute } from "react";

interface FieldProps {
type: HTMLInputTypeAttribute;
placeholder: string;
errorText?: string;
setText: (value: string) => void;
}

export default function ErrorableFormInput({
type,
placeholder,
errorText,
setText,
}: FieldProps) {
return (
<>
<Input
type={type}
placeholder={placeholder}
className="bg-crust text-subtext0 rounded-lg p-3"
onChange={(e) => setText(e.currentTarget.value)}
></Input>
{errorText && (
<p className="text-xs text-red">
{errorText || "An unexpected error occurred."}
</p>
)}
</>
);
}
2 changes: 2 additions & 0 deletions client/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export type Optional<T> = T | undefined;

export enum Piece {
Black,
White,
Expand Down

0 comments on commit 081756d

Please sign in to comment.