diff --git a/.env b/.env new file mode 100644 index 0000000..4736b0c --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VITE_SERVER_API=http://3.38.6.154:8080 \ No newline at end of file diff --git a/.pnp.cjs b/.pnp.cjs index c28fd4b..b8c5996 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -46,6 +46,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@types/react", "npm:18.2.42"],\ ["@types/react-dom", "npm:18.2.17"],\ ["@vitejs/plugin-react", "virtual:d381565a46f155a3483e9603bba66b1bab74b707e117d2cdd1de333069c43b6f815aa47f5ab254df4a5f5f7b4d4be2ee5ac1ad793d350b34cd46c00cb769141b#npm:4.2.1"],\ + ["axios", "npm:1.6.2"],\ ["babel-plugin-named-exports-order", "npm:0.0.2"],\ ["eslint", "npm:8.55.0"],\ ["eslint-config-react-app", "virtual:d381565a46f155a3483e9603bba66b1bab74b707e117d2cdd1de333069c43b6f815aa47f5ab254df4a5f5f7b4d4be2ee5ac1ad793d350b34cd46c00cb769141b#npm:7.0.1"],\ @@ -10486,6 +10487,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["axios", [\ + ["npm:1.6.2", {\ + "packageLocation": "./.yarn/cache/axios-npm-1.6.2-2334cb6eee-4a7429e2b7.zip/node_modules/axios/",\ + "packageDependencies": [\ + ["axios", "npm:1.6.2"],\ + ["follow-redirects", "virtual:2334cb6eeeb6b3dfd608966f28539c2de97a7f40c2b9762074181b72a63a8cdcab5646db63b491e1572f204e304748e40aff79a28dbdc8ee85d2dd16cd3803c7#npm:1.15.3"],\ + ["form-data", "npm:4.0.0"],\ + ["proxy-from-env", "npm:1.1.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["axobject-query", [\ ["npm:3.2.1", {\ "packageLocation": "./.yarn/cache/axobject-query-npm-3.2.1-b147b3f32c-a94047e702.zip/node_modules/axobject-query/",\ @@ -14347,10 +14360,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ],\ "linkType": "SOFT"\ }],\ - ["virtual:a313c479c5c7e54d9ec8fbeeea69ff640f56b8989ea2dff42351a3fa5c4061fb80a52d8ede0f0826a181a216820c2d2c3f15da881e7fdf31cef1c446e42f0c45#npm:1.15.3", {\ - "packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-ff48ff82c1/0/cache/follow-redirects-npm-1.15.3-ca69c47b72-584da22ec5.zip/node_modules/follow-redirects/",\ + ["virtual:2334cb6eeeb6b3dfd608966f28539c2de97a7f40c2b9762074181b72a63a8cdcab5646db63b491e1572f204e304748e40aff79a28dbdc8ee85d2dd16cd3803c7#npm:1.15.3", {\ + "packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-be1f4daa7b/0/cache/follow-redirects-npm-1.15.3-ca69c47b72-584da22ec5.zip/node_modules/follow-redirects/",\ "packageDependencies": [\ - ["follow-redirects", "virtual:a313c479c5c7e54d9ec8fbeeea69ff640f56b8989ea2dff42351a3fa5c4061fb80a52d8ede0f0826a181a216820c2d2c3f15da881e7fdf31cef1c446e42f0c45#npm:1.15.3"],\ + ["follow-redirects", "virtual:2334cb6eeeb6b3dfd608966f28539c2de97a7f40c2b9762074181b72a63a8cdcab5646db63b491e1572f204e304748e40aff79a28dbdc8ee85d2dd16cd3803c7#npm:1.15.3"],\ ["@types/debug", null],\ ["debug", null]\ ],\ @@ -15244,7 +15257,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "packageDependencies": [\ ["http-proxy", "npm:1.18.1"],\ ["eventemitter3", "npm:4.0.7"],\ - ["follow-redirects", "virtual:a313c479c5c7e54d9ec8fbeeea69ff640f56b8989ea2dff42351a3fa5c4061fb80a52d8ede0f0826a181a216820c2d2c3f15da881e7fdf31cef1c446e42f0c45#npm:1.15.3"],\ + ["follow-redirects", "virtual:2334cb6eeeb6b3dfd608966f28539c2de97a7f40c2b9762074181b72a63a8cdcab5646db63b491e1572f204e304748e40aff79a28dbdc8ee85d2dd16cd3803c7#npm:1.15.3"],\ ["requires-port", "npm:1.0.0"]\ ],\ "linkType": "HARD"\ @@ -21548,6 +21561,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@types/react", "npm:18.2.42"],\ ["@types/react-dom", "npm:18.2.17"],\ ["@vitejs/plugin-react", "virtual:d381565a46f155a3483e9603bba66b1bab74b707e117d2cdd1de333069c43b6f815aa47f5ab254df4a5f5f7b4d4be2ee5ac1ad793d350b34cd46c00cb769141b#npm:4.2.1"],\ + ["axios", "npm:1.6.2"],\ ["babel-plugin-named-exports-order", "npm:0.0.2"],\ ["eslint", "npm:8.55.0"],\ ["eslint-config-react-app", "virtual:d381565a46f155a3483e9603bba66b1bab74b707e117d2cdd1de333069c43b6f815aa47f5ab254df4a5f5f7b4d4be2ee5ac1ad793d350b34cd46c00cb769141b#npm:7.0.1"],\ diff --git a/.yarn/cache/axios-npm-1.6.2-2334cb6eee-4a7429e2b7.zip b/.yarn/cache/axios-npm-1.6.2-2334cb6eee-4a7429e2b7.zip new file mode 100644 index 0000000..e616f86 Binary files /dev/null and b/.yarn/cache/axios-npm-1.6.2-2334cb6eee-4a7429e2b7.zip differ diff --git a/package.json b/package.json index 4325706..b7402c3 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "@types/node": "^20.10.3", "@types/react": "^18.2.39", "@types/react-dom": "^18.2.17", + "axios": "^1.6.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-responsive": "^9.0.2", diff --git a/src/common/libs/axios.ts b/src/common/libs/axios.ts new file mode 100644 index 0000000..14d302d --- /dev/null +++ b/src/common/libs/axios.ts @@ -0,0 +1,14 @@ +import axios from "axios"; +import { getBearerToken } from "../utils/getBearerToken"; + +export const axiosInstance = axios.create({ + baseURL: import.meta.env.VITE_SERVER_API, +}); + +axiosInstance.interceptors.request.use((config) => { + const token = getBearerToken(); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; +}); diff --git a/src/common/utils/getBearerToken.ts b/src/common/utils/getBearerToken.ts new file mode 100644 index 0000000..5b6252d --- /dev/null +++ b/src/common/utils/getBearerToken.ts @@ -0,0 +1,5 @@ +export function getBearerToken() { + const token = window.localStorage.getItem("token"); + + return token ? token : null; +} diff --git a/src/common/utils/validateForm.ts b/src/common/utils/validateForm.ts index 76b29da..73fbcd8 100644 --- a/src/common/utils/validateForm.ts +++ b/src/common/utils/validateForm.ts @@ -2,23 +2,22 @@ import { FormState } from "@/features/form/states/form-data-state"; export function validateForm(formData: FormState): [Record] { const errorMessage: Record = {}; - const { id, password, name, check_password } = formData; + const { username, userid, email, password, team, devPart } = formData; - if (!name?.trim()) { - errorMessage.name = "이름을 입력해주세요."; + if ("username" in formData && !username?.trim()) { + errorMessage.username = "유저이름을 입력해주세요."; } - if (!id.trim()) { - errorMessage.id = "아이디를 입력해주세요."; + if ("userid" in formData && !userid?.trim()) { + errorMessage.userid = "유저아이디를 입력해주세요."; + } + if (!email.trim()) { + errorMessage.email = "이메일을 입력해주세요."; } if (!password.trim()) { errorMessage.password = "비밀번호를 입력해주세요."; } - if (!check_password?.trim()) { - errorMessage.check_password = "비밀번호를 다시 입력해주세요."; - } - return [errorMessage]; } diff --git a/src/features/auth/queries/dto/login.ts b/src/features/auth/queries/dto/login.ts new file mode 100644 index 0000000..df54fd0 --- /dev/null +++ b/src/features/auth/queries/dto/login.ts @@ -0,0 +1,4 @@ +export interface LoginRequest { + email: string; + password: string; +} diff --git a/src/features/auth/queries/dto/sign-up.ts b/src/features/auth/queries/dto/sign-up.ts new file mode 100644 index 0000000..5bb2b27 --- /dev/null +++ b/src/features/auth/queries/dto/sign-up.ts @@ -0,0 +1,8 @@ +export interface SignUpRequest { + username: string; + userid: string; + email: string; + password: string; + team: number; + devPart: string; +} diff --git a/src/features/auth/queries/usePostLogin.tsx b/src/features/auth/queries/usePostLogin.tsx new file mode 100644 index 0000000..6884edf --- /dev/null +++ b/src/features/auth/queries/usePostLogin.tsx @@ -0,0 +1,15 @@ +import { useMutation } from "@tanstack/react-query"; +import { axiosInstance } from "@/common/libs/axios"; +import { LoginRequest } from "./dto/login"; + +async function postLogin(data: LoginRequest) { + const res = await axiosInstance.post("/app/auth/login", data); + return res.data; +} + +export function usePostLogin() { + return useMutation({ + mutationKey: ["login"], + mutationFn: postLogin, + }); +} diff --git a/src/features/auth/queries/usePostSignUp.tsx b/src/features/auth/queries/usePostSignUp.tsx new file mode 100644 index 0000000..75aa570 --- /dev/null +++ b/src/features/auth/queries/usePostSignUp.tsx @@ -0,0 +1,15 @@ +import { useMutation } from "@tanstack/react-query"; +import { axiosInstance } from "@/common/libs/axios"; +import { SignUpRequest } from "./dto/sign-up"; + +async function postSignUp(data: SignUpRequest) { + const res = await axiosInstance.post("/app/auth/signup", data); + return res.data; +} + +export function usePostSignUp() { + return useMutation({ + mutationKey: ["signUp"], + mutationFn: postSignUp, + }); +} diff --git a/src/features/form/components/Form/FormLayout/FormLayout.tsx b/src/features/form/components/Form/FormLayout/FormLayout.tsx index 913a17e..ed1b06f 100644 --- a/src/features/form/components/Form/FormLayout/FormLayout.tsx +++ b/src/features/form/components/Form/FormLayout/FormLayout.tsx @@ -24,32 +24,32 @@ export default function FormLayout({ type, onSubmit }: FormProps) { return ( {type === FORM_TYPE.REGISTER && ( - + <> + + + )} - {type === FORM_TYPE.REGISTER && ( - - )} void; }) { const [loginFormData, setLoginFormData] = useState({ - id: "", + email: "", password: "", }); const [registerFormData, setRegisterFormData] = useState({ - name: "", - id: "", + username: "", + userid: "", + email: "", password: "", - check_password: "", + team: -1, + devPart: "", }); const [showError, setShowError] = useState(false); const [errorMessage] = validateForm( type === FORM_TYPE.LOGIN ? loginFormData : registerFormData ); - const handleNameChange = (text: string) => { - setRegisterFormData({ ...registerFormData, name: text }); + const handleUserNameChange = (text: string) => { + setRegisterFormData({ ...registerFormData, username: text }); }; - const handleIdChange = (text: string) => { + const handleUserIdChange = (text: string) => { + setRegisterFormData({ ...registerFormData, userid: text }); + }; + + const handleEmailChange = (text: string) => { if (type === FORM_TYPE.LOGIN) { - setLoginFormData({ ...loginFormData, id: text }); + setLoginFormData({ ...loginFormData, email: text }); } else { - setRegisterFormData({ ...registerFormData, id: text }); + setRegisterFormData({ ...registerFormData, email: text }); } }; @@ -47,10 +53,6 @@ export default function useForm({ } }; - const handleCheckPasswordChange = (text: string) => { - setRegisterFormData({ ...registerFormData, check_password: text }); - }; - const handleSubmit = (e: FormEvent) => { e.preventDefault(); setShowError(true); @@ -81,10 +83,10 @@ export default function useForm({ showError, errorMessage, handlers: { - nameChange: handleNameChange, - idChange: handleIdChange, + userNameChange: handleUserNameChange, + userIdChange: handleUserIdChange, + emailChange: handleEmailChange, passwordChange: handlePasswordChange, - checkPasswordChange: handleCheckPasswordChange, submit: handleSubmit, }, }; diff --git a/src/pages/auth/Login.tsx b/src/pages/auth/Login.tsx index ea35237..4a2a13f 100644 --- a/src/pages/auth/Login.tsx +++ b/src/pages/auth/Login.tsx @@ -4,12 +4,13 @@ import MediaQuery from "@/styles/mediaQuery"; import { styled } from "styled-components"; import { FORM_TYPE } from "@/features/form/constant/form-type"; import { FormState } from "@/features/form/states/form-data-state"; +import { usePostLogin } from "@/features/auth/queries/usePostLogin"; export default function Login() { + const { mutate: postLogin } = usePostLogin(); const { isMobile } = MediaQuery(); const loginFormSubmit = (e: FormState) => { - console.log(e); - console.log("로그인 제출"); + postLogin(e); }; return ( diff --git a/src/pages/auth/Register.tsx b/src/pages/auth/Register.tsx index 89a2d98..c591db9 100644 --- a/src/pages/auth/Register.tsx +++ b/src/pages/auth/Register.tsx @@ -9,7 +9,6 @@ export default function Register() { const { isMobile } = MediaQuery(); const registerFormSubmit = (e: FormState) => { console.log(e); - console.log("회원가입 제출"); }; return ( diff --git a/yarn.lock b/yarn.lock index 61144fa..9df4091 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6541,6 +6541,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.6.2": + version: 1.6.2 + resolution: "axios@npm:1.6.2" + dependencies: + follow-redirects: ^1.15.0 + form-data: ^4.0.0 + proxy-from-env: ^1.1.0 + checksum: 4a7429e2b784be0f2902ca2680964391eae7236faa3967715f30ea45464b98ae3f1c6f631303b13dfe721b17126b01f486c7644b9ef276bfc63112db9fd379f8 + languageName: node + linkType: hard + "axobject-query@npm:^3.2.1": version: 3.2.1 resolution: "axobject-query@npm:3.2.1" @@ -9722,7 +9733,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0": version: 1.15.3 resolution: "follow-redirects@npm:1.15.3" peerDependenciesMeta: @@ -14745,7 +14756,7 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^1.0.0": +"proxy-from-env@npm:^1.0.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 @@ -15253,6 +15264,7 @@ __metadata: "@types/react": ^18.2.39 "@types/react-dom": ^18.2.17 "@vitejs/plugin-react": ^4.2.0 + axios: ^1.6.2 babel-plugin-named-exports-order: ^0.0.2 eslint: ^8.55.0 eslint-config-react-app: ^7.0.1