From da0cccfb0e3e1b46f762e088ce642520f3bd621c Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 9 Aug 2024 16:53:37 +0200 Subject: [PATCH] add sign-up page --- src/components/auth-redirect/index.tsx | 3 +- src/pages/sign-up.tsx | 49 +++++++++++++++++++ src/services/todolist-api/auth/auth.api.ts | 7 ++- src/services/todolist-api/auth/auth.hooks.ts | 6 +++ .../todolist-api/todolist-api.instance.ts | 30 ++++++------ .../todolist-api/todolists/todolists.types.ts | 10 +++- 6 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 src/pages/sign-up.tsx diff --git a/src/components/auth-redirect/index.tsx b/src/components/auth-redirect/index.tsx index 0602a73..8b03e6c 100644 --- a/src/components/auth-redirect/index.tsx +++ b/src/components/auth-redirect/index.tsx @@ -10,7 +10,8 @@ import { useMeQuery } from "@/services"; export const AuthRedirect: FC<{ children: ReactNode }> = ({ children }) => { const router = useRouter(); const { data: user, isLoading } = useMeQuery(); - const isAuthPage = router.pathname === "/login"; + const isAuthPage = + router.pathname === "/login" || router.pathname === "/sign-up"; useEffect(() => { if (!isLoading && !user && !isAuthPage) { diff --git a/src/pages/sign-up.tsx b/src/pages/sign-up.tsx new file mode 100644 index 0000000..85fb9aa --- /dev/null +++ b/src/pages/sign-up.tsx @@ -0,0 +1,49 @@ +import type { FormEvent } from "react"; +import React from "react"; + +import type { NextPage } from "next"; + +import { Button, Input } from "@/components"; +import { useSignUpMutation } from "@/services"; + +const Login: NextPage = () => { + const { mutate: signUp } = useSignUpMutation(); + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + const formData = new FormData(e.currentTarget); + + const values = Object.fromEntries(formData) as any; + signUp(values); + }; + + return ( +
+
+

Sign up

+ + + + + + +
+
+ ); +}; + +export default Login; diff --git a/src/services/todolist-api/auth/auth.api.ts b/src/services/todolist-api/auth/auth.api.ts index 1ed665f..7c707f3 100644 --- a/src/services/todolist-api/auth/auth.api.ts +++ b/src/services/todolist-api/auth/auth.api.ts @@ -3,6 +3,7 @@ import type { LogoutResponse, MeResponse, PostLoginArgs, + PostSignUpArgs, } from "../todolists"; import { handleError } from "@/helpers"; @@ -12,7 +13,7 @@ export const AuthApi = { async login(args: PostLoginArgs) { const res = await todolistApiInstance.post( "/auth/login", - args + args, ); localStorage.setItem("accessToken", res.data.accessToken); @@ -20,7 +21,11 @@ export const AuthApi = { return res.data; }, + async signUp(args: PostSignUpArgs) { + const res = await todolistApiInstance.post("/auth/sign-up", args); + return res.data; + }, async logout() { const res = await todolistApiInstance.delete("/auth/login"); diff --git a/src/services/todolist-api/auth/auth.hooks.ts b/src/services/todolist-api/auth/auth.hooks.ts index e2d8b95..cab23ad 100644 --- a/src/services/todolist-api/auth/auth.hooks.ts +++ b/src/services/todolist-api/auth/auth.hooks.ts @@ -38,3 +38,9 @@ export const useLogoutMutation = () => { }, }); }; + +export const useSignUpMutation = () => { + return useMutation({ + mutationFn: AuthApi.signUp, + }); +}; diff --git a/src/services/todolist-api/todolist-api.instance.ts b/src/services/todolist-api/todolist-api.instance.ts index 4732ab1..2d701ff 100644 --- a/src/services/todolist-api/todolist-api.instance.ts +++ b/src/services/todolist-api/todolist-api.instance.ts @@ -7,7 +7,7 @@ const mutex = new Mutex(); let refreshedAt: number | null = null; export const todolistApiInstance = axios.create({ - baseURL: "http://localhost:3000" + baseURL: "http://localhost:3000", }); async function refreshAccessToken(): Promise { @@ -19,9 +19,9 @@ async function refreshAccessToken(): Promise { {}, { headers: { - Authorization: `Bearer ${localStorage.getItem("refreshToken")}` - } - } + Authorization: `Bearer ${localStorage.getItem("refreshToken")}`, + }, + }, ); localStorage.setItem("accessToken", res.data.accessToken); @@ -42,14 +42,15 @@ todolistApiInstance.interceptors.request.use( return config; }, - (error) => Promise.reject(error) + (error) => Promise.reject(error), ); todolistApiInstance.interceptors.response.use( (response) => response, async (error) => { - if(error?.response?.request?.responseURL?.includes("refresh-token")){ - return } + if (error?.response?.request?.responseURL?.includes("refresh-token")) { + return; + } await mutex.waitForUnlock(); const originalRequest = error.config; // Check for a 401 response and if this request hasn't been retried yet @@ -61,9 +62,7 @@ todolistApiInstance.interceptors.response.use( if (refreshedAt && refreshedAt + 60000 > new Date().getTime()) { // If the token has been refreshed within the last minute, use the refreshed token - originalRequest.headers[ - "Authorization" - ] = `Bearer ${localStorage.getItem("accessToken")}`; + originalRequest.headers.Authorization = `Bearer ${localStorage.getItem("accessToken")}`; release(); return todolistApiInstance(originalRequest); @@ -72,11 +71,14 @@ todolistApiInstance.interceptors.response.use( try { const newAccessToken = await refreshAccessToken(); - originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`; + originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; return todolistApiInstance(originalRequest); // Retry the original request with the new token } catch (error) { - router.push("/login"); + console.log(window.location.pathname); + if (!["/login", "/sign-up"].includes(window.location.pathname)) { + router.push("/login"); + } } finally { release(); } @@ -84,12 +86,12 @@ todolistApiInstance.interceptors.response.use( await mutex.waitForUnlock(); const newAccessToken = localStorage.getItem("accessToken"); - originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`; + originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; return todolistApiInstance(originalRequest); // Retry the original request with the new token } } return Promise.reject(error); - } + }, ); diff --git a/src/services/todolist-api/todolists/todolists.types.ts b/src/services/todolist-api/todolists/todolists.types.ts index 82112bd..521d264 100644 --- a/src/services/todolist-api/todolists/todolists.types.ts +++ b/src/services/todolist-api/todolists/todolists.types.ts @@ -29,6 +29,12 @@ export type PostLoginArgs = { rememberMe: boolean; }; +export type PostSignUpArgs = { + email: string; + password: string; + username?: string; +}; + export type LoginResponseData = { accessToken: string; refreshToken: string; @@ -51,8 +57,8 @@ export type CreateTodolistResponseData = { }; export type CreateTaskResponse = Task; -export type DeleteTaskResponse = void; -export type UpdateTaskResponse = void; +export type DeleteTaskResponse = undefined; +export type UpdateTaskResponse = undefined; export enum TaskStatus { OPEN = "OPEN",