Signup page (mostly) working

This commit is contained in:
2025-03-15 20:20:14 -04:00
parent 0eeedf1e3b
commit 49243a71a1
4 changed files with 127 additions and 14 deletions

View File

@@ -28,11 +28,18 @@ export default function PublicNavLinks(){
} }
{ {
!jwt && !jwt &&
<NavLink <>
to="/login" <NavLink
> to="/login"
>
Login Login
</NavLink> </NavLink>
<NavLink
to="/signup"
>
Signup
</NavLink>
</>
} }
</> </>
); );

20
src/hooks/AuthHooks.ts Normal file
View File

@@ -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(", "));
}
}
});
}

View File

@@ -1,6 +1,7 @@
import { Game } from "@/interface/Game"; import { Game } from "@/interface/Game";
import { api } from "@/util/AxiosUtil"; import { api } from "@/util/AxiosUtil";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
export function useGetGame(gameId: string, disabled: boolean){ export function useGetGame(gameId: string, disabled: boolean){
@@ -33,16 +34,20 @@ export function useGetGames(page: number, pageSize: number, searchTerm?: string)
params.append("searchTerm", searchTerm); 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){ return response.data as Game[];
throw new Error("Failed to get games");
} }
else if(response.data.errors){ catch(error){
throw new Error(response.data.errors.join(", ")); if(error instanceof AxiosError && error.response?.data.errors){
throw new Error(error.response?.data.errors.join(", "));
}
else{
throw error;
}
} }
return response.data as Game[];
} }
}); });
} }

View File

@@ -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(){ 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 ( return (
<div> <main
Signup Page className="flex flex-col items-center justify-center"
</div> >
<div
className="flex flex-col items-center justify-center gap-y-4"
>
<TextInput
id="signupUsername"
placeholder="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<TextInput
id="signupEmail"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<PasswordInput
id="signupPassword"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<PasswordInput
id="signupSecondPassword"
placeholder="Confirm Password"
value={secondPassword}
onChange={(e) => setSecondPassword(e.target.value)}
/>
<PrimaryButton
onClick={signup}
>
Sign Up
</PrimaryButton>
</div>
</main>
); );
} }