diff --git a/src/hooks/useUserStore.tsx b/src/hooks/useUserStore.tsx index 598888c..12b0e87 100644 --- a/src/hooks/useUserStore.tsx +++ b/src/hooks/useUserStore.tsx @@ -1,4 +1,5 @@ import { create } from "zustand"; +import { persist, createJSONStorage } from "zustand/middleware"; type User = { id: string; @@ -20,36 +21,42 @@ interface UserState { clearUser: () => void; } -export const useUserStore = create((set, get) => ({ - user: null, - token: null, - isLoggedIn: false, - - setUserAndToken: (user, token) => - set(() => ({ - user, - token, - isLoggedIn: true, - })), - - updateShopId: (shopId) => { - const current = get(); - if (!current.user || !current.token) return; - - const updatedUser = { - ...current.user, - shopId, - }; - - set({ - user: updatedUser, - }); - }, - - clearUser: () => - set(() => ({ +export const useUserStore = create()( + persist( + (set, get) => ({ user: null, token: null, isLoggedIn: false, - })), -})); + + setUserAndToken: (user, token) => + set({ + user, + token, + isLoggedIn: true, + }), + + updateShopId: (shopId) => { + const current = get(); + if (!current.user || !current.token) return; + + set({ + user: { + ...current.user, + shopId, + }, + }); + }, + + clearUser: () => + set({ + user: null, + token: null, + isLoggedIn: false, + }), + }), + { + name: "user-storage", + storage: createJSONStorage(() => localStorage), + }, + ), +); diff --git a/src/pages/SigninPage.tsx b/src/pages/SigninPage.tsx index eb48c77..cd51983 100644 --- a/src/pages/SigninPage.tsx +++ b/src/pages/SigninPage.tsx @@ -1,3 +1,132 @@ +import { AxiosError } from "axios"; +import { useNavigate, Link } from "react-router-dom"; + +import Logo from "../assets/logo/thejulge.svg?react"; +import { useAuthForm } from "../hooks/useAuthForm"; + +import { postAuthentication } from "@/apis/services/authenticationService"; +import Button from "@/components/Button"; +import TextField from "@/components/TextField"; +import { ROUTES } from "@/constants/router"; +import { useUserStore } from "@/hooks/useUserStore"; +import { useModalStore } from "@/store/useModalStore"; + export default function SigninPage() { - return
SigninPage
; + const navigate = useNavigate(); + const { setUserAndToken } = useUserStore(); + const { openModal, closeModal } = useModalStore(); + + const { formData, errors, isFormValid, handleChange, resetForm } = + useAuthForm("signin"); + + const handleSubmit = async () => { + try { + const res = await postAuthentication({ + email: formData.email, + password: formData.password, + }); + + const token = res.data.item.token; + const user = res.data.item.user.item; + + setUserAndToken(user, token); + + resetForm(); + + const route = + user.type === "employer" ? ROUTES.SHOP.ROOT : ROUTES.PROFILE.ROOT; + + openModal({ + type: "message", + message: "로그인에 성공했습니다!", + iconType: "none", + buttons: [ + { + label: "확인", + style: "primary", + onClick: () => { + closeModal(); + }, + }, + ], + onClose: () => { + navigate(route); + }, + }); + } catch (error: unknown) { + const axiosError = error as AxiosError<{ message: string }>; + const message = + axiosError.response?.data?.message ?? "로그인 실패! 다시 시도해주세요."; + + openModal({ + type: "message", + message: message, + iconType: "none", + buttons: [ + { + label: "확인", + style: "primary", + onClick: () => { + closeModal(); + }, + }, + ], + }); + } + }; + + return ( +
+ + + + +
{ + e.preventDefault(); + handleSubmit(); + }} + > + + + + + + + +

+ 회원이 아니신가요?{" "} + + 회원가입하기 + +

+
+ ); } diff --git a/src/pages/SignupPage.tsx b/src/pages/SignupPage.tsx index f8d108e..b2af053 100644 --- a/src/pages/SignupPage.tsx +++ b/src/pages/SignupPage.tsx @@ -12,10 +12,12 @@ import Button from "@/components/Button"; import TextField from "@/components/TextField"; import { ROUTES } from "@/constants/router"; import { useUserStore } from "@/hooks/useUserStore"; +import { useModalStore } from "@/store/useModalStore"; export default function SignupPage() { const navigate = useNavigate(); const { setUserAndToken } = useUserStore(); + const { openModal, closeModal } = useModalStore(); const { formData, @@ -25,9 +27,6 @@ export default function SignupPage() { setFormData, resetForm, } = useAuthForm("signup"); - //Alert 사용시 - // const [alertMessage, setAlertMessage] = useState(""); - // const [nextRoute, setNextRoute] = useState(null); const handleSubmit = async () => { try { @@ -50,33 +49,58 @@ export default function SignupPage() { resetForm(); - navigate( - user.type === "employer" ? ROUTES.SHOP.ROOT : ROUTES.PROFILE.ROOT, - ); - //Alert 사용 - // setAlertMessage("가입이 완료되었습니다!"); - // setNextRoute(user.type === "employer" ? ROUTES.SHOP.ROOT : ROUTES.PROFILE.ROOT); + const route = + user.type === "employer" ? ROUTES.SHOP.ROOT : ROUTES.PROFILE.ROOT; + + openModal({ + type: "message", + message: "가입이 완료되었습니다!", + iconType: "none", + buttons: [ + { + label: "확인", + style: "primary", + onClick: () => { + closeModal(); + }, + }, + ], + onClose: () => { + navigate(route); + }, + }); } } catch (error: unknown) { const axiosError = error as AxiosError<{ message: string }>; const message = - axiosError.response?.data?.message ?? "알 수 없는 에러 발생"; - - console.log(message); - //Alert 사용시 - // setAlertMessage(message ?? "회원가입 실패! 다시 시도해주세요."); - // setNextRoute(null); + axiosError.response?.data?.message ?? + "회원가입 실패! 다시 시도해주세요."; + + openModal({ + type: "message", + message, + iconType: "none", + buttons: [ + { + label: "확인", + style: "primary", + onClick: () => { + closeModal(); + }, + }, + ], + }); } }; return (
- +
{ e.preventDefault(); handleSubmit(); @@ -128,7 +152,7 @@ export default function SignupPage() { setFormData((prev) => ({ ...prev, userType: "employee" })) } className={clsx( - "flex items-center justify-center gap-[9px] rounded-[30px] border px-[41px] py-[13px]", + "flex items-center justify-center gap-[0.5625rem] rounded-[1.875rem] border px-[2.5625rem] py-[0.8125rem]", formData.userType === "employee" ? "border-primary" : "border-gray-30", @@ -155,7 +179,7 @@ export default function SignupPage() { setFormData((prev) => ({ ...prev, userType: "employer" })) } className={clsx( - "flex items-center justify-center gap-[9px] rounded-[30px] border px-[41px] py-[13px]", + "flex items-center justify-center gap-[0.5625rem] rounded-[1.875rem] border px-[2.5625rem] py-[0.8125rem]", formData.userType === "employer" ? "border-primary" : "border-gray-30", @@ -179,7 +203,7 @@ export default function SignupPage() {
-

+

이미 가입하셨나요?{" "} 로그인하기

- - {/* 임시 Alert */} - {/* {alertMessage && ( - { - setAlertMessage(""); - if (nextRoute) { - navigate(nextRoute); - setNextRoute(null); - } - }} - /> - )} */}
); }