diff --git a/src/components/nav/PublicNavLinks.tsx b/src/components/nav/PublicNavLinks.tsx
index 2201f8a..66cb39d 100644
--- a/src/components/nav/PublicNavLinks.tsx
+++ b/src/components/nav/PublicNavLinks.tsx
@@ -28,11 +28,18 @@ export default function PublicNavLinks(){
}
{
!jwt &&
-
+ <>
+
Login
-
+
+
+ Signup
+
+ >
}
>
);
diff --git a/src/hooks/AuthHooks.ts b/src/hooks/AuthHooks.ts
new file mode 100644
index 0000000..ceb59a2
--- /dev/null
+++ b/src/hooks/AuthHooks.ts
@@ -0,0 +1,20 @@
+import { Account } from "@/interface/Account";
+import { api } from "@/util/AxiosUtil";
+import { useMutation } from "@tanstack/react-query";
+
+
+export function useSignup(){
+ return useMutation({
+ mutationKey: ["signup"],
+ mutationFn: async (account: Account) => {
+ const response = await api.post("/auth/signup", account);
+
+ if(response.status !== 200){
+ throw new Error("Failed to signup");
+ }
+ else if(response.data.errors){
+ throw new Error(response.data.errors.join(", "));
+ }
+ }
+ });
+}
diff --git a/src/hooks/GameHooks.ts b/src/hooks/GameHooks.ts
index ac305a3..f726e3b 100644
--- a/src/hooks/GameHooks.ts
+++ b/src/hooks/GameHooks.ts
@@ -1,6 +1,7 @@
import { Game } from "@/interface/Game";
import { api } from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+import { AxiosError } from "axios";
export function useGetGame(gameId: string, disabled: boolean){
@@ -33,16 +34,20 @@ export function useGetGames(page: number, pageSize: number, searchTerm?: string)
params.append("searchTerm", searchTerm);
}
- const response = await api.get(`/game?${params}`);
+ //TODO: Change all queries to follow this pattern
+ try{
+ const response = await api.get(`/game?${params}`);
- if(response.status !== 200){
- throw new Error("Failed to get games");
+ return response.data as Game[];
}
- else if(response.data.errors){
- throw new Error(response.data.errors.join(", "));
+ catch(error){
+ if(error instanceof AxiosError && error.response?.data.errors){
+ throw new Error(error.response?.data.errors.join(", "));
+ }
+ else{
+ throw error;
+ }
}
-
- return response.data as Game[];
}
});
}
diff --git a/src/pages/public/SignupPage.tsx b/src/pages/public/SignupPage.tsx
index 3da5b26..0dce6e9 100644
--- a/src/pages/public/SignupPage.tsx
+++ b/src/pages/public/SignupPage.tsx
@@ -1,7 +1,88 @@
+import PrimaryButton from "@/components/button/PrimaryButton";
+import PasswordInput from "@/components/input/PasswordInput";
+import TextInput from "@/components/input/TextInput";
+import { useSignup } from "@/hooks/AuthHooks";
+import { Account } from "@/interface/Account";
+import { useTimedModal } from "@/providers/TimedModalProvider";
+import { useState } from "react";
+import { useNavigate } from "react-router";
+
+
export default function SignupPage(){
+ const navigate = useNavigate();
+ const [ username, setUsername ] = useState("");
+ const [ password, setPassword ] = useState("");
+ const [ secondPassword, setSecondPassword ] = useState("");
+ const [ email, setEmail ] = useState("");
+
+ const signupQuery = useSignup();
+
+
+ const { addSuccessMessage, addErrorMessage } = useTimedModal();
+
+
+ const signup = () => {
+ if(password !== secondPassword){
+ addErrorMessage("Passwords do not match");
+ return;
+ }
+
+ const account = {
+ username,
+ password,
+ email
+ } as Account;
+
+ signupQuery.mutate(account);
+ }
+
+ if(signupQuery.status === "success"){
+ addSuccessMessage("Signed up successfully");
+ navigate("/login");
+ }
+ else if(signupQuery.status === "error"){
+ addErrorMessage("Failed to signup: " + signupQuery.error.message);
+ signupQuery.reset();
+ }
+
+
return (
-
- Signup Page
-
+
+
+
setUsername(e.target.value)}
+ />
+ setEmail(e.target.value)}
+ />
+ setPassword(e.target.value)}
+ />
+ setSecondPassword(e.target.value)}
+ />
+
+ Sign Up
+
+
+
);
}