From 721f43b8f8a1a5fbf046f17d272aec5455d9625f Mon Sep 17 00:00:00 2001 From: Dongpil Jo <91816664+eastfilmm@users.noreply.github.com> Date: Mon, 22 Jan 2024 15:18:16 +0900 Subject: [PATCH 01/23] feat/issue 16 (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat:FE디렉토리 구조 * Feat:FE 디렉토리 구조 추가 수정 * Chore : 더미 파일 명 수정 * Feat: 라우터 경로 설정 --------- Co-authored-by: Quvid <48755156+KimKyuHoi@users.noreply.github.com> --- .idea/TadakTadak.iml | 9 ++++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 +++ .idea/workspace.xml | 47 ++++++++++++++++ frontend/src/App.tsx | 53 +++++++++---------- frontend/src/components/auth/auth.tsx | 0 frontend/src/components/chat/Chat.tsx | 0 .../chattingRoomList/ChattingRoomList.tsx | 0 frontend/src/components/layout/Layout.tsx | 0 frontend/src/components/video/Video.tsx | 0 frontend/src/hooks/Hook.ts | 0 frontend/src/pages/ChattingListPage.tsx | 5 ++ frontend/src/pages/ChattingRoomPage.tsx | 5 ++ frontend/src/pages/ErrorPage.tsx | 7 +++ frontend/src/pages/RootPage.tsx | 12 +++++ frontend/src/pages/SigninPage.tsx | 7 +++ frontend/src/pages/SignupPage.tsx | 5 ++ frontend/src/pages/WelcomePage.tsx | 7 +++ frontend/src/stores/Store.ts | 0 frontend/src/styles/Style.tsx | 0 20 files changed, 144 insertions(+), 27 deletions(-) create mode 100644 .idea/TadakTadak.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 frontend/src/components/auth/auth.tsx create mode 100644 frontend/src/components/chat/Chat.tsx create mode 100644 frontend/src/components/chattingRoomList/ChattingRoomList.tsx create mode 100644 frontend/src/components/layout/Layout.tsx create mode 100644 frontend/src/components/video/Video.tsx create mode 100644 frontend/src/hooks/Hook.ts create mode 100644 frontend/src/pages/ChattingListPage.tsx create mode 100644 frontend/src/pages/ChattingRoomPage.tsx create mode 100644 frontend/src/pages/ErrorPage.tsx create mode 100644 frontend/src/pages/RootPage.tsx create mode 100644 frontend/src/pages/SigninPage.tsx create mode 100644 frontend/src/pages/SignupPage.tsx create mode 100644 frontend/src/pages/WelcomePage.tsx create mode 100644 frontend/src/stores/Store.ts create mode 100644 frontend/src/styles/Style.tsx diff --git a/.idea/TadakTadak.iml b/.idea/TadakTadak.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/TadakTadak.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e9f2a87 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..9196fa6 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + 1705738328256 + + + + \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 9e051ef..53584a4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,35 +1,34 @@ -import { useState } from 'react'; -import reactLogo from './assets/react.svg'; -import viteLogo from "/vite.svg"; +import { createBrowserRouter, RouterProvider } from 'react-router-dom'; +import RootPage from './pages/RootPage'; +import WelcomePage from './pages/WelcomePage'; +import ErrorPage from './pages/ErrorPage'; +import ChattingListPage from './pages/ChattingListPage'; +import SignupPage from './pages/SignupPage'; +import SigninPage from './pages/SigninPage'; +import ChattingRoomPage from './pages/ChattingRoomPage'; +const router = createBrowserRouter([ + { + path: '/', + element: , + id: 'root', + errorElement: , + children: [ + { index: true, element: }, + { path: 'signin', element: }, + { path: 'signup', element: }, + { path: 'chattinglist', element: }, + { path: 'chatroom/:chatroom_id', element: }, + ], + }, +]); -function App() { - const [count, setCount] = useState(0); - +const App = () => { return ( <> - -

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

+ ); -} +}; export default App; diff --git a/frontend/src/components/auth/auth.tsx b/frontend/src/components/auth/auth.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/chat/Chat.tsx b/frontend/src/components/chat/Chat.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/chattingRoomList/ChattingRoomList.tsx b/frontend/src/components/chattingRoomList/ChattingRoomList.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/layout/Layout.tsx b/frontend/src/components/layout/Layout.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/video/Video.tsx b/frontend/src/components/video/Video.tsx new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/hooks/Hook.ts b/frontend/src/hooks/Hook.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/pages/ChattingListPage.tsx b/frontend/src/pages/ChattingListPage.tsx new file mode 100644 index 0000000..cf5cdaa --- /dev/null +++ b/frontend/src/pages/ChattingListPage.tsx @@ -0,0 +1,5 @@ +const ChattingListPage = () => { + return <>It's ChattingListPage!; +}; + +export default ChattingListPage; diff --git a/frontend/src/pages/ChattingRoomPage.tsx b/frontend/src/pages/ChattingRoomPage.tsx new file mode 100644 index 0000000..0a9dd44 --- /dev/null +++ b/frontend/src/pages/ChattingRoomPage.tsx @@ -0,0 +1,5 @@ +const ChattingRoomPage = () => { + return <>It's Chatting RoomPage!; +}; + +export default ChattingRoomPage; diff --git a/frontend/src/pages/ErrorPage.tsx b/frontend/src/pages/ErrorPage.tsx new file mode 100644 index 0000000..7b01827 --- /dev/null +++ b/frontend/src/pages/ErrorPage.tsx @@ -0,0 +1,7 @@ +const ErrorPage = () => { + return( + <>It's ErrorPage! + ) +}; + +export default ErrorPage; \ No newline at end of file diff --git a/frontend/src/pages/RootPage.tsx b/frontend/src/pages/RootPage.tsx new file mode 100644 index 0000000..f39b6f1 --- /dev/null +++ b/frontend/src/pages/RootPage.tsx @@ -0,0 +1,12 @@ +import { Outlet } from 'react-router-dom'; + +const RootPage = () => { + return <> + +
+ +
+ +}; + +export default RootPage; \ No newline at end of file diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx new file mode 100644 index 0000000..e1031c3 --- /dev/null +++ b/frontend/src/pages/SigninPage.tsx @@ -0,0 +1,7 @@ +const SigninPage = () => { + return( + <>It's SigninPage! + ) +}; + +export default SigninPage; diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx new file mode 100644 index 0000000..ea4f828 --- /dev/null +++ b/frontend/src/pages/SignupPage.tsx @@ -0,0 +1,5 @@ +const SignupPage = () => { + return
It's SignupPage!
; +}; + +export default SignupPage; diff --git a/frontend/src/pages/WelcomePage.tsx b/frontend/src/pages/WelcomePage.tsx new file mode 100644 index 0000000..83658d4 --- /dev/null +++ b/frontend/src/pages/WelcomePage.tsx @@ -0,0 +1,7 @@ +const WelcomePage = () => { + return( + <>It's Home! + ) +}; + +export default WelcomePage; \ No newline at end of file diff --git a/frontend/src/stores/Store.ts b/frontend/src/stores/Store.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/styles/Style.tsx b/frontend/src/styles/Style.tsx new file mode 100644 index 0000000..e69de29 From b7386e7987643494892dbd0d6e0aa3c6b1097130 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 22 Jan 2024 16:20:48 +0900 Subject: [PATCH 02/23] =?UTF-8?q?Feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=8A=A4=EC=BC=88=EB=A0=88?= =?UTF-8?q?=ED=86=A4=20=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 3 ++ frontend/src/pages/SignUpKakaoPage.tsx | 5 +++ frontend/src/pages/SigninPage.tsx | 62 +++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 frontend/src/pages/SignUpKakaoPage.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 53584a4..efacefc 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,6 +6,7 @@ import ChattingListPage from './pages/ChattingListPage'; import SignupPage from './pages/SignupPage'; import SigninPage from './pages/SigninPage'; import ChattingRoomPage from './pages/ChattingRoomPage'; +import SignUpKakaoPage from './pages/SignUpKaKaoPage'; const router = createBrowserRouter([ { @@ -19,6 +20,8 @@ const router = createBrowserRouter([ { path: 'signup', element: }, { path: 'chattinglist', element: }, { path: 'chatroom/:chatroom_id', element: }, + { path: 'signupkakao', element: }, + ], }, ]); diff --git a/frontend/src/pages/SignUpKakaoPage.tsx b/frontend/src/pages/SignUpKakaoPage.tsx new file mode 100644 index 0000000..828b623 --- /dev/null +++ b/frontend/src/pages/SignUpKakaoPage.tsx @@ -0,0 +1,5 @@ +const SignUpKakaoPage = () => { + return
It's SignUpKakaoPage!
; +}; + +export default SignUpKakaoPage; diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx index e1031c3..0a619e1 100644 --- a/frontend/src/pages/SigninPage.tsx +++ b/frontend/src/pages/SigninPage.tsx @@ -1,6 +1,66 @@ +import React,{useState} from "react"; +import { useNavigate } from "react-router-dom"; + const SigninPage = () => { + const [inputs,setInputs] = useState({ + email: '', + password : '', + }); + + const {email,password} = inputs + const navigate = useNavigate(); + + const onChange = (e) => { + const {value, name} = e.target; + setInputs({ + ...inputs, + [name]: value, + }); + console.log(inputs); + } + + const onSignin = (e) =>{ + console.log("값확정",inputs) + setTimeout(() => navigate("/"), 2000); + } + + const onSignUp = (e) =>{ + console.log("회원가입",inputs) + setTimeout(() => navigate("/signup"), 2000); + } + + const onSignKaKaoUp = (e) =>{ + console.log("카카오 회원가입",inputs) + setTimeout(() => navigate("/signupkakao"), 2000); + } + return( - <>It's SigninPage! +
+
+

TadakTadak Logo

+ <>It's SigninPage! + +
+ + {/* email input */} + 이메일 + + +
+ + {/* pw input */} + 비밀번호 + + +
+ +
+ +
+ + +
) }; From 8221415fd41aad7ce83ced1158f1fe4d4b17f2b1 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 22 Jan 2024 16:53:14 +0900 Subject: [PATCH 03/23] =?UTF-8?q?Feat:=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=ED=99=94,=20=EC=9E=AC=EC=82=AC=EC=9A=A9=EC=84=B1=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Button.tsx | 7 ++++ frontend/src/components/InputForm.tsx | 12 +++++++ frontend/src/pages/SigninPage.tsx | 49 ++++++++++++++------------- 3 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 frontend/src/components/Button.tsx create mode 100644 frontend/src/components/InputForm.tsx diff --git a/frontend/src/components/Button.tsx b/frontend/src/components/Button.tsx new file mode 100644 index 0000000..65df1ec --- /dev/null +++ b/frontend/src/components/Button.tsx @@ -0,0 +1,7 @@ +export const Button = ({onClick,label,...rest})=>{ + return( + + ) +} \ No newline at end of file diff --git a/frontend/src/components/InputForm.tsx b/frontend/src/components/InputForm.tsx new file mode 100644 index 0000000..60f3283 --- /dev/null +++ b/frontend/src/components/InputForm.tsx @@ -0,0 +1,12 @@ +export const InputForm = ({type, onChange, placeholder,title, ...rest}) =>{ + return(<> + {title} + + + ) +} \ No newline at end of file diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx index 0a619e1..8072124 100644 --- a/frontend/src/pages/SigninPage.tsx +++ b/frontend/src/pages/SigninPage.tsx @@ -1,14 +1,16 @@ import React,{useState} from "react"; import { useNavigate } from "react-router-dom"; +import { InputForm } from "../components/InputForm"; +import { Button } from "../components/Button"; const SigninPage = () => { + const navigate = useNavigate(); const [inputs,setInputs] = useState({ email: '', password : '', }); - const {email,password} = inputs - const navigate = useNavigate(); + const onChange = (e) => { const {value, name} = e.target; @@ -19,19 +21,21 @@ const SigninPage = () => { console.log(inputs); } - const onSignin = (e) =>{ - console.log("값확정",inputs) - setTimeout(() => navigate("/"), 2000); - } - - const onSignUp = (e) =>{ - console.log("회원가입",inputs) - setTimeout(() => navigate("/signup"), 2000); - } - - const onSignKaKaoUp = (e) =>{ - console.log("카카오 회원가입",inputs) - setTimeout(() => navigate("/signupkakao"), 2000); + const onButtonClick = (action) => { + console.log(action ,inputs); + switch(action){ + case "onSignIn": + setTimeout(()=> navigate("/"),2000); + break; + case "onSignUp": + setTimeout(()=> navigate("/signup"),2000); + break; + case "onSignUpKakao": + setTimeout(()=> navigate("/signupkakao"),2000); + break; + default: + console.error("error") + } } return( @@ -43,22 +47,21 @@ const SigninPage = () => { {/* email input */} - 이메일 - +
{/* pw input */} - 비밀번호 - +
- +
- +
- + + ) From a6bed5d4741fb27e9fb555b7ac13347ce009fd04 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 22 Jan 2024 17:36:24 +0900 Subject: [PATCH 04/23] =?UTF-8?q?Feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=B3=B8=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/auth/KakaoButton.tsx | 70 ++++++++++++++++++++ frontend/src/pages/SigninPage.tsx | 15 +++-- 2 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 frontend/src/components/auth/KakaoButton.tsx diff --git a/frontend/src/components/auth/KakaoButton.tsx b/frontend/src/components/auth/KakaoButton.tsx new file mode 100644 index 0000000..8195d21 --- /dev/null +++ b/frontend/src/components/auth/KakaoButton.tsx @@ -0,0 +1,70 @@ +import styled from '@emotion/styled'; + +const REST_API_KEY = import.meta.env.VITE_APP_REST_API_KEY; + +export const KakaoButton = () => { + + const REDIRECT_URI = "http://127.0.0.1:5173/SignUpKakaoPage"; + const KAKAO_AUTH_URI = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`; + + + return( + + + + ) +} + +const KakaoButtonStyles = styled.div` + .KakaoLoginBtn-wrapper { + display: flex; + justify-content: center; + } + + .btn-kakao { + width: 300px; + height: 46px; + background: #FEE500; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + transition: background-color 0.3s; + } + + .text { + font-family: 'Noto Sans', sans-serif; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: 24px; + text-align: center; + color: #000000; + } + + .btn-kakao:hover { + background-color: #fff7ac; + } +`; \ No newline at end of file diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx index 8072124..8477435 100644 --- a/frontend/src/pages/SigninPage.tsx +++ b/frontend/src/pages/SigninPage.tsx @@ -2,6 +2,7 @@ import React,{useState} from "react"; import { useNavigate } from "react-router-dom"; import { InputForm } from "../components/InputForm"; import { Button } from "../components/Button"; +import { KakaoButton } from "../components/auth/KakaoButton"; const SigninPage = () => { const navigate = useNavigate(); @@ -24,13 +25,13 @@ const SigninPage = () => { const onButtonClick = (action) => { console.log(action ,inputs); switch(action){ - case "onSignIn": + case "onSignin": setTimeout(()=> navigate("/"),2000); break; - case "onSignUp": + case "onSignup": setTimeout(()=> navigate("/signup"),2000); break; - case "onSignUpKakao": + case "onSignupKakao": setTimeout(()=> navigate("/signupkakao"),2000); break; default: @@ -56,13 +57,15 @@ const SigninPage = () => { type = 'password' title="비밀번호" name="password" value={password} placeholder="비밀번호을 입력해주세요"/>
- +
- +
- + + + ) }; From fa6e9d7dd8db7625f51057ecb4874c4132f8669f Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 22 Jan 2024 17:36:45 +0900 Subject: [PATCH 05/23] =?UTF-8?q?Chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignUpKakaoPage.tsx | 6 +++--- frontend/src/pages/SigninPage.tsx | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/SignUpKakaoPage.tsx b/frontend/src/pages/SignUpKakaoPage.tsx index 828b623..6825965 100644 --- a/frontend/src/pages/SignUpKakaoPage.tsx +++ b/frontend/src/pages/SignUpKakaoPage.tsx @@ -1,5 +1,5 @@ -const SignUpKakaoPage = () => { - return
It's SignUpKakaoPage!
; +const SignupKakaoPage = () => { + return
It's SignupKakaoPage!
; }; -export default SignUpKakaoPage; +export default SignupKakaoPage; diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx index 8477435..b799beb 100644 --- a/frontend/src/pages/SigninPage.tsx +++ b/frontend/src/pages/SigninPage.tsx @@ -61,10 +61,6 @@ const SigninPage = () => {

- - - - ) From 1ed510bdd8326e40716d36fb05edf52eed811afd Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 22 Jan 2024 17:38:54 +0900 Subject: [PATCH 06/23] =?UTF-8?q?Feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20API?= =?UTF-8?q?=ED=82=A4=20=EA=B0=9C=EC=9D=B8=EC=A0=95=EB=B3=B4=EB=B3=B4?= =?UTF-8?q?=ED=98=B8=EA=B4=80=EB=A0=A8=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.gitignore | 6 ++++++ frontend/tsconfig.json | 1 + 2 files changed, 7 insertions(+) diff --git a/frontend/.gitignore b/frontend/.gitignore index a547bf3..69258c8 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -22,3 +22,9 @@ dist-ssr *.njsproj *.sln *.sw? + +.env +.env.local +.env.development.local +.env.test.local +.env.production.local \ No newline at end of file diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index a7fc6fb..66eda50 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -5,6 +5,7 @@ "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, + "types": ["vite/client"], /* Bundler mode */ "moduleResolution": "bundler", From fd4b5c09ab6d29d1be0923dcc94861939174c0c4 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Fri, 26 Jan 2024 17:26:57 +0900 Subject: [PATCH 07/23] =?UTF-8?q?Feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=ED=8E=98=EC=9D=B4=EC=A7=80(SignUp)=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=88=EB=A0=88=ED=86=A4=20=EC=BD=94=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.gitignore | 6 ++ frontend/src/components/Button.tsx | 7 +++ frontend/src/components/InputForm.tsx | 16 ++++++ frontend/src/pages/SignupPage.tsx | 81 ++++++++++++++++++++++++++- frontend/src/stores/UserInfoStore.ts | 31 ++++++++++ 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/Button.tsx create mode 100644 frontend/src/components/InputForm.tsx create mode 100644 frontend/src/stores/UserInfoStore.ts diff --git a/frontend/.gitignore b/frontend/.gitignore index a547bf3..69258c8 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -22,3 +22,9 @@ dist-ssr *.njsproj *.sln *.sw? + +.env +.env.local +.env.development.local +.env.test.local +.env.production.local \ No newline at end of file diff --git a/frontend/src/components/Button.tsx b/frontend/src/components/Button.tsx new file mode 100644 index 0000000..f7733d2 --- /dev/null +++ b/frontend/src/components/Button.tsx @@ -0,0 +1,7 @@ +export const Button = ({onClick,label,...rest})=>{ + return( + + ) + } \ No newline at end of file diff --git a/frontend/src/components/InputForm.tsx b/frontend/src/components/InputForm.tsx new file mode 100644 index 0000000..10a71df --- /dev/null +++ b/frontend/src/components/InputForm.tsx @@ -0,0 +1,16 @@ +export const InputForm = ({ type, name, value, onChange, placeholder, title, ...rest }) => { + return ( + <> + {title} + + + ); + }; + \ No newline at end of file diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index ea4f828..eabe019 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -1,5 +1,84 @@ +import { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { InputForm } from "../components/InputForm"; +import { Button } from "../components/Button"; +import { useStore, create } from "zustand"; +import { UserInfoStore } from "../stores/UserInfoStore"; +import { devtools } from 'zustand/middleware' + const SignupPage = () => { - return
It's SignupPage!
; + const navigate = useNavigate(); + const userInfo = useStore(UserInfoStore); + let passwordCheck:string; + + const onChange = (e: React.ChangeEvent) => { + const { value, name } = e.target; + + if (name === 'email') { + userInfo.updateEmail(value); + } else if (name === 'password') { + userInfo.updatePassword(value); + } + else if (name === 'password-check') { + if(userInfo.password === value){ + console.log("비밀번호가 동일합니다.") + } + } + else if (name === 'username') { + userInfo.updateUsername(value); + } + } + + const onButtonClick = (action:string) => { + switch(action){ + case "onSignupEmail": + console.log(`API 통신 ${userInfo.email}`) + break; + case "onSetNickname": + console.log(`API 통신 ${userInfo.username}`) + break; + case "onSignup": + console.log(`회원가입 ${userInfo.email}, ${userInfo.password}, ${userInfo.username}`); + setTimeout(()=> navigate("/"),2000); + break; + default: + console.error("error") + } + } + + + return( +
+
+ <>It's SignupPage! +
+ + {/* email input */} + + +
+ + {/* pw input */} + +
+ {/* password duplicate check */} + + +
+ + {/* username input */} + + +
+
+ +
+
+
+ ) }; export default SignupPage; diff --git a/frontend/src/stores/UserInfoStore.ts b/frontend/src/stores/UserInfoStore.ts new file mode 100644 index 0000000..1eed850 --- /dev/null +++ b/frontend/src/stores/UserInfoStore.ts @@ -0,0 +1,31 @@ +import { create } from "zustand"; +import { devtools, persist } from "zustand/middleware"; + +interface UserInfo { + email: string; + password: string; + username: string; + updateEmail: (email: UserInfo['email']) => void; + updatePassword: (password: UserInfo['password']) => void; + updateUsername: (username: UserInfo['username']) => void; +} + +export const UserInfoStore = create()( + devtools( + (set, get) => ({ + email: '', + password: '', + username: '', + updateEmail: (email) => set({ email }), + updatePassword: (password) => set({ password }), + updateUsername: (username) => set({ username }), + }), + { + name: 'userInfo' + } + ) +); + +if (import.meta.env.PROD) { + devtools(UserInfoStore); +} \ No newline at end of file From 36eee0cdc06fe1f4d9b910089595ed7ecd8a98d7 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Fri, 26 Jan 2024 17:49:32 +0900 Subject: [PATCH 08/23] =?UTF-8?q?Feat:=20API=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20/=20URL=20=EC=97=B0=EA=B2=B0=ED=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignupPage.tsx | 52 ++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index eabe019..10cff4b 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -5,23 +5,29 @@ import { Button } from "../components/Button"; import { useStore, create } from "zustand"; import { UserInfoStore } from "../stores/UserInfoStore"; import { devtools } from 'zustand/middleware' +import axios from 'axios'; + + const SignupPage = () => { const navigate = useNavigate(); const userInfo = useStore(UserInfoStore); let passwordCheck:string; + let message:string; const onChange = (e: React.ChangeEvent) => { const { value, name } = e.target; if (name === 'email') { - userInfo.updateEmail(value); + userInfo.updateEmail(value); } else if (name === 'password') { userInfo.updatePassword(value); } else if (name === 'password-check') { if(userInfo.password === value){ - console.log("비밀번호가 동일합니다.") + console.log("일치하는 비밀번호 입니다.") + }else{ + console.log("비밀번호가 일치하지 않습니다.") } } else if (name === 'username') { @@ -29,20 +35,37 @@ const SignupPage = () => { } } + // 통신코드 + const checkEmailDuplicate = async () => { + try { + const response = await axios.post('/api/v1/signup', { + username: userInfo.username, + email: userInfo.email, + password: userInfo.password + }); + + const data = response.data; + + } catch (error) { + console.error("API 통신 에러:", error); + } + }; + const onButtonClick = (action:string) => { switch(action){ - case "onSignupEmail": + case "onSetEmailCheck": console.log(`API 통신 ${userInfo.email}`) break; - case "onSetNickname": - console.log(`API 통신 ${userInfo.username}`) - break; - case "onSignup": - console.log(`회원가입 ${userInfo.email}, ${userInfo.password}, ${userInfo.username}`); - setTimeout(()=> navigate("/"),2000); - break; - default: - console.error("error") + case "onSetNicknameCheck": + console.log(`API 통신 ${userInfo.username}`) + break; + case "onSignup": + console.log(`회원가입 ${userInfo.email}, ${userInfo.password}, ${userInfo.username}`); + checkEmailDuplicate(); + setTimeout(()=> navigate("/"),2000); + break; + default: + console.error("error") } } @@ -55,7 +78,8 @@ const SignupPage = () => { {/* email input */} - + + {/* {message} */}
{/* pw input */} @@ -71,7 +95,7 @@ const SignupPage = () => { {/* username input */} - +

From 3f5275752cf1d7b204e669e231d7781b7893a61f Mon Sep 17 00:00:00 2001 From: DingX2 Date: Fri, 26 Jan 2024 17:53:03 +0900 Subject: [PATCH 09/23] =?UTF-8?q?Feat:=20API=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20/=20URL=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignupPage.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 10cff4b..73962e4 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -38,11 +38,11 @@ const SignupPage = () => { // 통신코드 const checkEmailDuplicate = async () => { try { - const response = await axios.post('/api/v1/signup', { - username: userInfo.username, - email: userInfo.email, - password: userInfo.password - }); + const response = await axios.post('http://localhost:8001/user-service/login', { + username: userInfo.username, + email: userInfo.email, + password: userInfo.password + }); const data = response.data; From be1221a9c2dd598a5702e0198fd5d9495d0c9fae Mon Sep 17 00:00:00 2001 From: DingX2 Date: Sun, 28 Jan 2024 23:06:48 +0900 Subject: [PATCH 10/23] =?UTF-8?q?Feat:=20=EA=B0=9D=EC=B2=B4=ED=99=94?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20=ED=95=9C=20=EB=B2=88=EC=97=90=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignupPage.tsx | 117 +++++++++++++++++++++++++----- 1 file changed, 100 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 0f4e9b7..33b326f 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -5,38 +5,94 @@ import { Button } from "../components/Button"; import { useStore, create } from "zustand"; import { UserInfoStore } from "../stores/UserInfoStore"; import { devtools } from 'zustand/middleware' +import styled from '@emotion/styled'; import axios from 'axios'; +type isValid = { + passwordIsValid: boolean; + passwordCheckIsValid: boolean; + emailIsValid: boolean; + usernameIsValid: boolean; + messageValidPw1Color: 'black' | 'blue'; + messageValidPw2Color: 'black' | 'blue'; +}; + const SignupPage = () => { const navigate = useNavigate(); const userInfo = useStore(UserInfoStore); + const [messageValidPw1, setMessageValidPw1] = useState('숫자/영어/특수문자를 혼용하여 3종류를 사용하세요.'); + const [messageValidPw2, setMessageValidPw2] = useState('비밀번호는 1자 이상 20자 이하로 입력하세요.'); + const [messagePw, setMessagePw] = useState(""); const [messageEmail, setMessageEmail] = useState(""); const [messageUsername, setMessageUsername] = useState(""); const [passwordConfirm, setPasswordConfirm] = useState(""); - let emailIsValid:boolean = true; - let usernameIsValid:boolean = true; + + const [isValid, setIsValid] = useState({ + passwordIsValid: false, + passwordCheckIsValid: false, + emailIsValid: false, + usernameIsValid: false, + messageValidPw1Color: 'black', + messageValidPw2Color: 'black', + }); + + // 확인용 코드 + useEffect(()=>{ + console.log(isValid); + },[isValid]) + // 중복확인 예외 코드 // 중복확인을 받아놓고 값을 바꾸는 경우 + useEffect(()=>{ + // email + + // username + console.log(isValid); + },[isValid]) + + //inputForm 코드 const onChange = (e: React.ChangeEvent) => { const { value, name } = e.target; if (name === 'email') { userInfo.updateEmail(value); } else if (name === 'password') { - userInfo.updatePassword(value); - } + userInfo.updatePassword(value); + checkValidPassword(value); + if(isValid.passwordIsValid) + console.log("사용가능한 비밀번호입니다"); + } else if (name === 'password-check') { - setPasswordConfirm(value) - if(userInfo.password === value) - setMessagePw("일치하는 비밀번호 입니다.") - else + setPasswordConfirm(value); + if(userInfo.password === value){ + isValid.passwordCheckIsValid= true; + setMessagePw("일치하는 비밀번호 입니다.")} + else{ + isValid.passwordCheckIsValid= false; setMessagePw("비밀번호가 일치하지 않습니다.") + } } else if (name === 'username') { userInfo.updateUsername(value); } } + // 비밀번호 예외처리 + const checkValidPassword = (password: string) => { + // 숫자/영어/특수문자를 혼용했는가 + const pattern = /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]+$/; + + // 1~20자내인가 + const isValidLength = password.length >= 1 && password.length <= 20; + setIsValid(prevState => ({ + ...prevState, + messageValidPw1Color: pattern.test(password) ? 'blue' : 'black', + messageValidPw2Color: isValidLength ? 'blue' : 'black', + passwordIsValid: pattern.test(password) && isValidLength, + })); + }; + + // 통신코드 const checkEmailDuplicate = async () => { try { @@ -53,28 +109,46 @@ const SignupPage = () => { } }; + // 버튼코드 const onButtonClick = (action:string) => { switch(action){ case "onSetEmailCheck": console.log(`API 통신 ${userInfo.email}`) - if(!emailIsValid) + // 해서 중복확인을 받는다. 코드 수정 필요 + setIsValid(prevState => ({ + ...prevState, + emailIsValid: true, + })); + if(!isValid.emailIsValid) setMessageEmail('중복된 이메일입니다') - else + else{ setMessageEmail('사용 가능한 이메일입니다') + } - break; + break; case "onSetNicknameCheck": console.log(`API 통신 ${userInfo.username}`) - if(!usernameIsValid) + // 해서 중복확인을 받는다. 코드 수정 필요 + setIsValid(prevState => ({ + ...prevState, + usernameIsValid: true, + })); + if(!isValid.usernameIsValid) setMessageUsername('중복된 닉네임입니다') - else + else{ setMessageUsername('사용 가능한 닉네임입니다') - + } break; case "onSignup": console.log(`회원가입 ${userInfo.email}, ${userInfo.password},${passwordConfirm}, ${userInfo.username}`); - checkEmailDuplicate(); - setTimeout(()=> navigate("/"),1000); + + if (isValid.passwordIsValid && isValid.passwordCheckIsValid && isValid.emailIsValid && isValid.usernameIsValid) { + console.log("성공"); + checkEmailDuplicate(); + setTimeout(()=> navigate("/"),1000); + } + else + console.log("조건이 안맞음"); break; default: console.error("error") @@ -96,7 +170,10 @@ const SignupPage = () => { {/* pw input */} + type = 'password' title="비밀번호" name="password" value={userInfo?.password} placeholder="비밀번호을 입력해주세요"/>
+ {messageValidPw1}
+
+ {messageValidPw2}

{/* password duplicate check */} { }; export default SignupPage; + + +// 스타일 적용 +const MessageValidPw = styled.p<{ color: string }>` + color: ${(props) => props.color}; +`; \ No newline at end of file From 289de915bdd787a4df0ee7586e6762536aa7b6da Mon Sep 17 00:00:00 2001 From: DingX2 Date: Sun, 28 Jan 2024 23:47:10 +0900 Subject: [PATCH 11/23] =?UTF-8?q?Feat:=20=EC=98=88=EC=99=B8=20:=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=ED=99=95=EC=9D=B8=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=EB=B3=80=EA=B2=BD=ED=95=98=EB=A9=B4=20fal?= =?UTF-8?q?se=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignupPage.tsx | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 33b326f..dd01e47 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -1,10 +1,9 @@ -import { useState, useEffect } from "react"; +import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { InputForm } from "../components/InputForm"; import { Button } from "../components/Button"; -import { useStore, create } from "zustand"; +import { useStore } from "zustand"; import { UserInfoStore } from "../stores/UserInfoStore"; -import { devtools } from 'zustand/middleware' import styled from '@emotion/styled'; import axios from 'axios'; @@ -37,31 +36,19 @@ const SignupPage = () => { messageValidPw2Color: 'black', }); - // 확인용 코드 - useEffect(()=>{ - console.log(isValid); - },[isValid]) - - // 중복확인 예외 코드 // 중복확인을 받아놓고 값을 바꾸는 경우 - useEffect(()=>{ - // email - - // username - console.log(isValid); - },[isValid]) - //inputForm 코드 const onChange = (e: React.ChangeEvent) => { const { value, name } = e.target; if (name === 'email') { - userInfo.updateEmail(value); + setIsValid((prev) => ({ ...prev, emailIsValid: false })); + userInfo.updateEmail(value); } else if (name === 'password') { userInfo.updatePassword(value); checkValidPassword(value); if(isValid.passwordIsValid) - console.log("사용가능한 비밀번호입니다"); - } + console.log("사용가능한 비밀번호입니다"); + } else if (name === 'password-check') { setPasswordConfirm(value); if(userInfo.password === value){ @@ -73,6 +60,7 @@ const SignupPage = () => { } } else if (name === 'username') { + setIsValid((prev) => ({ ...prev, usernameIsValid: false })); userInfo.updateUsername(value); } } From ac919dd12e56cc719015002c82615d46ffd60714 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Sun, 28 Jan 2024 23:50:41 +0900 Subject: [PATCH 12/23] =?UTF-8?q?Chore:=20=EB=8C=80=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=ED=86=B5=EC=9D=BC=20commit=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/stores/UserInfoStore.ts | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 frontend/src/stores/UserInfoStore.ts diff --git a/frontend/src/stores/UserInfoStore.ts b/frontend/src/stores/UserInfoStore.ts new file mode 100644 index 0000000..7a18483 --- /dev/null +++ b/frontend/src/stores/UserInfoStore.ts @@ -0,0 +1,31 @@ +import { create } from "zustand"; +import { devtools, persist } from "zustand/middleware"; + +interface UserInfo { + email: string; + password: string; + username: string; + updateEmail: (email: UserInfo['email']) => void; + updatePassword: (password: UserInfo['password']) => void; + updateUsername: (username: UserInfo['username']) => void; +} + +const createUserInfoStore = (set) => ({ + email: '', + password: '', + username: '', + updateEmail: (email: string) => set({ email }), + updatePassword: (password: string) => set({ password }), + updateUsername: (username: string) => set({ username }), +}); + +let userInfoStoreTemp; + +//devtools +if (import.meta.env.DEV) { + userInfoStoreTemp = create()(devtools(createUserInfoStore, { name: 'userInfo' })); +} else { + userInfoStoreTemp = create()(createUserInfoStore); +} + +export const UserInfoStore = userInfoStoreTemp; \ No newline at end of file From 09d8fe183f8a2daf19564955292930c8db131672 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 29 Jan 2024 00:14:32 +0900 Subject: [PATCH 13/23] =?UTF-8?q?Feat:=20=EA=B8=B0=EB=B3=B8=20API=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignupPage.tsx | 135 +++++++++++++++++------------- 1 file changed, 78 insertions(+), 57 deletions(-) diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index dd01e47..730fa9b 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -78,66 +78,87 @@ const SignupPage = () => { messageValidPw2Color: isValidLength ? 'blue' : 'black', passwordIsValid: pattern.test(password) && isValidLength, })); - }; - + }; // 통신코드 - const checkEmailDuplicate = async () => { + const signup = async () => { try { const response = await axios.post('http://localhost:8001/user-service/login', { username: userInfo.username, email: userInfo.email, password: userInfo.password, passwordConfirm: passwordConfirm, - }); - const data = response.data; - + }); + const data = response.data; + const jwtToken = data.token; + localStorage.setItem('jwtToken', jwtToken); } catch (error) { - console.error("API 통신 에러:", error); + console.error("API 통신 에러:", error); + } + }; + + // 통신코드 + const checkEmailDuplicate = async () => { + try { + const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.email}`, { + email: userInfo.email, + }); + const data = response.data; + if(data) setIsValid((prev)=>({...prev, emailIsValid:true })); + } catch (error) { + console.error("API 통신 에러:", error); + } + }; + + // 통신코드 + const checkUsernameDuplicate = async () => { + try { + const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.username}`, { + username: userInfo.username, + }); + const data = response.data; + if(data) setIsValid((prev)=>({...prev, usernameIsValid:true })); + } catch (error) { + console.error("API 통신 에러:", error); } - }; + }; + + + // 버튼코드 const onButtonClick = (action:string) => { switch(action){ - case "onSetEmailCheck": + case "onSetEmailCheck": console.log(`API 통신 ${userInfo.email}`) - // 해서 중복확인을 받는다. 코드 수정 필요 - setIsValid(prevState => ({ - ...prevState, - emailIsValid: true, - })); + checkEmailDuplicate(); if(!isValid.emailIsValid) setMessageEmail('중복된 이메일입니다') - else{ + else setMessageEmail('사용 가능한 이메일입니다') - } - break; + case "onSetNicknameCheck": console.log(`API 통신 ${userInfo.username}`) - // 해서 중복확인을 받는다. 코드 수정 필요 - setIsValid(prevState => ({ - ...prevState, - usernameIsValid: true, - })); + checkUsernameDuplicate(); if(!isValid.usernameIsValid) setMessageUsername('중복된 닉네임입니다') - else{ + else setMessageUsername('사용 가능한 닉네임입니다') - } break; + case "onSignup": console.log(`회원가입 ${userInfo.email}, ${userInfo.password},${passwordConfirm}, ${userInfo.username}`); if (isValid.passwordIsValid && isValid.passwordCheckIsValid && isValid.emailIsValid && isValid.usernameIsValid) { console.log("성공"); - checkEmailDuplicate(); - setTimeout(()=> navigate("/"),1000); + signup(); + navigate("/"); } else console.log("조건이 안맞음"); break; + default: console.error("error") } @@ -146,39 +167,39 @@ const SignupPage = () => { return(
-
- <>It's SignupPage! -
+
+ <>It's SignupPage! +
- {/* email input */} - - - {messageEmail} -
+ {/* email input */} + + + {messageEmail} +
- {/* pw input */} -
- {messageValidPw1}
-
- {messageValidPw2}
-
- {/* password duplicate check */} - - {messagePw} -
- - {/* username input */} - - - {messageUsername} -
-
- -
-
+ {/* pw input */} +
+ {messageValidPw1}
+
+ {messageValidPw2}
+
+ {/* password duplicate check */} + + {messagePw} +
+ + {/* username input */} + + + {messageUsername} +
+
+ +
+
) }; From 74227fe4a261ccd19fa3b50f5c87a3ef6850fa24 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 29 Jan 2024 00:46:52 +0900 Subject: [PATCH 14/23] =?UTF-8?q?Refactor:=20API=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 54 +++++++++++++++++++++++++ frontend/src/pages/SignupPage.tsx | 64 +++++++++--------------------- 2 files changed, 72 insertions(+), 46 deletions(-) create mode 100644 frontend/src/hooks/useAuthQuery.ts diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts new file mode 100644 index 0000000..07d4fa5 --- /dev/null +++ b/frontend/src/hooks/useAuthQuery.ts @@ -0,0 +1,54 @@ +import axios from 'axios'; +import { UserInfoStore } from '../stores/UserInfoStore'; +import { useStore } from 'zustand'; + +export const AuthApis = () => { + const userInfo = useStore(UserInfoStore); + + // 통신코드 + const signup = async (passwordConfirm: string) => { + try { + const response = await axios.post('http://localhost:8001/user-service/login', { + username: userInfo.username, + email: userInfo.email, + password: userInfo.password, + passwordConfirm: passwordConfirm, + }); + const data = response.data; + const jwtToken = data.token; + localStorage.setItem('jwtToken', jwtToken); + } catch (error) { + console.error("API 통신 에러:", error); + } + }; + + // 통신코드 + const checkEmailDuplicate = async () => { + try { + const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.email}`, { + email: userInfo.email, + }); + const data = response.data; + return data === true; + } catch (error) { + console.error("API 통신 에러:", error); + return false; + } + }; + + // 통신코드 + const checkUsernameDuplicate = async () => { + try { + const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.username}`, { + username: userInfo.username, + }); + const data = response.data; + return data === true; + } catch (error) { + console.error("API 통신 에러:", error); + return false; + } + }; + + return { signup, checkEmailDuplicate, checkUsernameDuplicate }; +}; diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 730fa9b..dede2db 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -7,6 +7,8 @@ import { UserInfoStore } from "../stores/UserInfoStore"; import styled from '@emotion/styled'; import axios from 'axios'; +import { AuthApis } from "../hooks/useAuthQuery"; + type isValid = { passwordIsValid: boolean; passwordCheckIsValid: boolean; @@ -26,7 +28,7 @@ const SignupPage = () => { const [messageEmail, setMessageEmail] = useState(""); const [messageUsername, setMessageUsername] = useState(""); const [passwordConfirm, setPasswordConfirm] = useState(""); - + const [isValid, setIsValid] = useState({ passwordIsValid: false, passwordCheckIsValid: false, @@ -34,7 +36,9 @@ const SignupPage = () => { usernameIsValid: false, messageValidPw1Color: 'black', messageValidPw2Color: 'black', - }); + }); + + const authApis = AuthApis(); //inputForm 코드 const onChange = (e: React.ChangeEvent) => { @@ -80,58 +84,26 @@ const SignupPage = () => { })); }; - // 통신코드 - const signup = async () => { - try { - const response = await axios.post('http://localhost:8001/user-service/login', { - username: userInfo.username, - email: userInfo.email, - password: userInfo.password, - passwordConfirm: passwordConfirm, - }); - const data = response.data; - const jwtToken = data.token; - localStorage.setItem('jwtToken', jwtToken); - } catch (error) { - console.error("API 통신 에러:", error); + // API 반환값 설정 + const handleCheckEmailDuplicate = async () => { + if (await authApis.checkEmailDuplicate()) { + setIsValid((prev) => ({ ...prev, emailIsValid: true })); } }; - // 통신코드 - const checkEmailDuplicate = async () => { - try { - const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.email}`, { - email: userInfo.email, - }); - const data = response.data; - if(data) setIsValid((prev)=>({...prev, emailIsValid:true })); - } catch (error) { - console.error("API 통신 에러:", error); + // API 반환값 설정 + const handlecheckUsernameDuplicate = async () => { + if (await authApis.checkUsernameDuplicate()) { + setIsValid((prev) => ({ ...prev, usernameIsValid: true })); } }; - // 통신코드 - const checkUsernameDuplicate = async () => { - try { - const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.username}`, { - username: userInfo.username, - }); - const data = response.data; - if(data) setIsValid((prev)=>({...prev, usernameIsValid:true })); - } catch (error) { - console.error("API 통신 에러:", error); - } - }; - - - - // 버튼코드 const onButtonClick = (action:string) => { switch(action){ case "onSetEmailCheck": console.log(`API 통신 ${userInfo.email}`) - checkEmailDuplicate(); + handleCheckEmailDuplicate(); if(!isValid.emailIsValid) setMessageEmail('중복된 이메일입니다') else @@ -140,7 +112,7 @@ const SignupPage = () => { case "onSetNicknameCheck": console.log(`API 통신 ${userInfo.username}`) - checkUsernameDuplicate(); + handlecheckUsernameDuplicate(); if(!isValid.usernameIsValid) setMessageUsername('중복된 닉네임입니다') else @@ -151,8 +123,8 @@ const SignupPage = () => { console.log(`회원가입 ${userInfo.email}, ${userInfo.password},${passwordConfirm}, ${userInfo.username}`); if (isValid.passwordIsValid && isValid.passwordCheckIsValid && isValid.emailIsValid && isValid.usernameIsValid) { - console.log("성공"); - signup(); + console.log("로그인 성공"); + authApis.signup(passwordConfirm); navigate("/"); } else From 2b92c05e481e51b7b87ea13c43657d14a0e2a544 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 29 Jan 2024 02:40:01 +0900 Subject: [PATCH 15/23] =?UTF-8?q?Refactor:=20=EB=AA=A8=EB=93=88=EC=B5=9C?= =?UTF-8?q?=EC=A0=81=ED=99=94=ED=95=B4=EC=84=9C=20=EA=B0=81=EC=9E=90=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 102 +++++++++++++++++++---------- frontend/src/pages/SignupPage.tsx | 16 +++-- 2 files changed, 80 insertions(+), 38 deletions(-) diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts index 07d4fa5..2d43732 100644 --- a/frontend/src/hooks/useAuthQuery.ts +++ b/frontend/src/hooks/useAuthQuery.ts @@ -1,14 +1,33 @@ import axios from 'axios'; import { UserInfoStore } from '../stores/UserInfoStore'; import { useStore } from 'zustand'; +import { useQuery, useMutation } from '@tanstack/react-query'; -export const AuthApis = () => { - const userInfo = useStore(UserInfoStore); +export const AuthApis = { + instance: axios.create({ + baseURL: "http://localhost:8001/user-service/", + withCredentials: true, + }), - // 통신코드 - const signup = async (passwordConfirm: string) => { + checkEmailDuplicate: async (userInfo) => { + const response = await AuthApis.instance.post(`/signup/exists/${userInfo.email}`, { + email: userInfo.email, + }); + const data = response.data; + return response.data === true; + }, + + checkUsernameDuplicate: async (userInfo) => { + const response = await AuthApis.instance.post(`/signup/exists/${userInfo.username}`, { + username: userInfo.username, + }); + const data = response.data; + return response.data === true; + }, + + signup: async (userInfo, passwordConfirm: string) => { try { - const response = await axios.post('http://localhost:8001/user-service/login', { + const response = await AuthApis.instance.post('/login', { username: userInfo.username, email: userInfo.email, password: userInfo.password, @@ -17,38 +36,55 @@ export const AuthApis = () => { const data = response.data; const jwtToken = data.token; localStorage.setItem('jwtToken', jwtToken); + return data; } catch (error) { console.error("API 통신 에러:", error); } - }; - - // 통신코드 - const checkEmailDuplicate = async () => { - try { - const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.email}`, { - email: userInfo.email, - }); - const data = response.data; - return data === true; - } catch (error) { - console.error("API 통신 에러:", error); - return false; + } +, + fetchData: async (endpoint: string, type: string, data?: any) => { + let response; + + switch (type) { + case 'get': + response = await axios.get(`http://localhost:8001/user-service/${endpoint}`); + break; + case 'post': + response = await axios.post(`http://localhost:8001/user-service/${endpoint}`, data); + break; + default: + console.error("Invalid type:", type); } - }; + return response; + } + +}; + // 통신코드 - const checkUsernameDuplicate = async () => { - try { - const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.username}`, { - username: userInfo.username, - }); - const data = response.data; - return data === true; - } catch (error) { - console.error("API 통신 에러:", error); - return false; - } - }; + // const checkEmailDuplicate = async (userInfo) => { + // try { + // const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.email}`, { + // email: userInfo.email, + // }); + // const data = response.data; + // return data === true; + // } catch (error) { + // console.error("API 통신 에러:", error); + // return false; + // } + // }; - return { signup, checkEmailDuplicate, checkUsernameDuplicate }; -}; + // // 통신코드 + // const checkUsernameDuplicate = async (userInfo) => { + // try { + // const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.username}`, { + // username: userInfo.username, + // }); + // const data = response.data; + // return data === true; + // } catch (error) { + // console.error("API 통신 에러:", error); + // return false; + // } + // }; \ No newline at end of file diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index dede2db..24a34c2 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { InputForm } from "../components/InputForm"; import { Button } from "../components/Button"; @@ -38,7 +38,11 @@ const SignupPage = () => { messageValidPw2Color: 'black', }); - const authApis = AuthApis(); + // const authApis = AuthApis(userInfo); + + useEffect(()=>{ + console.log(isValid) + },[isValid]) //inputForm 코드 const onChange = (e: React.ChangeEvent) => { @@ -86,14 +90,16 @@ const SignupPage = () => { // API 반환값 설정 const handleCheckEmailDuplicate = async () => { - if (await authApis.checkEmailDuplicate()) { + const data = await AuthApis.checkEmailDuplicate(userInfo); + if (data) { setIsValid((prev) => ({ ...prev, emailIsValid: true })); } }; // API 반환값 설정 const handlecheckUsernameDuplicate = async () => { - if (await authApis.checkUsernameDuplicate()) { + const data = await AuthApis.checkUsernameDuplicate(userInfo) + if (data) { setIsValid((prev) => ({ ...prev, usernameIsValid: true })); } }; @@ -124,7 +130,7 @@ const SignupPage = () => { if (isValid.passwordIsValid && isValid.passwordCheckIsValid && isValid.emailIsValid && isValid.usernameIsValid) { console.log("로그인 성공"); - authApis.signup(passwordConfirm); + AuthApis.signup(userInfo,passwordConfirm); navigate("/"); } else From 1c929c7669e76d223367812d3554006f0bedefce Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 29 Jan 2024 03:42:36 +0900 Subject: [PATCH 16/23] =?UTF-8?q?Feat:=20query=EB=AC=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 68 +++++++++++++--------------- frontend/src/pages/SignupPage.tsx | 4 +- frontend/src/stores/UserInfoStore.ts | 2 +- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts index 2d43732..3dbc094 100644 --- a/frontend/src/hooks/useAuthQuery.ts +++ b/frontend/src/hooks/useAuthQuery.ts @@ -1,7 +1,8 @@ import axios from 'axios'; -import { UserInfoStore } from '../stores/UserInfoStore'; +import { UserInfo, UserInfoStore } from '../stores/UserInfoStore'; import { useStore } from 'zustand'; -import { useQuery, useMutation } from '@tanstack/react-query'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; + export const AuthApis = { instance: axios.create({ @@ -9,23 +10,37 @@ export const AuthApis = { withCredentials: true, }), - checkEmailDuplicate: async (userInfo) => { + checkEmailDuplicate: async (userInfo: UserInfo): Promise => { const response = await AuthApis.instance.post(`/signup/exists/${userInfo.email}`, { email: userInfo.email, }); - const data = response.data; return response.data === true; }, - checkUsernameDuplicate: async (userInfo) => { + useCheckEmailDuplicateQuery: (userInfo: UserInfo) => { + const { data, isLoading, error } = useQuery({ + queryKey: ['checkEmailDuplicateQuery', userInfo.email], + queryFn: () => AuthApis.checkEmailDuplicate(userInfo), + }); + return { data, isLoading, error }; + }, + + checkUsernameDuplicate: async (userInfo:UserInfo): Promise => { const response = await AuthApis.instance.post(`/signup/exists/${userInfo.username}`, { username: userInfo.username, }); - const data = response.data; return response.data === true; }, - signup: async (userInfo, passwordConfirm: string) => { + checkUsernameDuplicateQuery: (userInfo: UserInfo) => { + const { data, isLoading, error } = useQuery({ + queryKey: ['checkUsernameDuplicateQuery', userInfo.username], + queryFn: () => AuthApis.checkUsernameDuplicate(userInfo), + }); + return { data, isLoading, error }; + }, + + signup: async (userInfo:UserInfo, passwordConfirm: string) => { try { const response = await AuthApis.instance.post('/login', { username: userInfo.username, @@ -40,8 +55,16 @@ export const AuthApis = { } catch (error) { console.error("API 통신 에러:", error); } - } -, + }, + + signupQuery: (userInfo: UserInfo,passwordConfirm:string) => { + const { data, isLoading, error } = useQuery({ + queryKey: ['signupQuery', userInfo,passwordConfirm], + queryFn: () => AuthApis.signup(userInfo, passwordConfirm), + }); + return { data, isLoading, error }; + }, + fetchData: async (endpoint: string, type: string, data?: any) => { let response; @@ -61,30 +84,3 @@ export const AuthApis = { }; - // 통신코드 - // const checkEmailDuplicate = async (userInfo) => { - // try { - // const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.email}`, { - // email: userInfo.email, - // }); - // const data = response.data; - // return data === true; - // } catch (error) { - // console.error("API 통신 에러:", error); - // return false; - // } - // }; - - // // 통신코드 - // const checkUsernameDuplicate = async (userInfo) => { - // try { - // const response = await axios.post(`http://localhost:8001/user-service/signup/exists/${userInfo.username}`, { - // username: userInfo.username, - // }); - // const data = response.data; - // return data === true; - // } catch (error) { - // console.error("API 통신 에러:", error); - // return false; - // } - // }; \ No newline at end of file diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 24a34c2..c5ec8ce 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -90,12 +90,14 @@ const SignupPage = () => { // API 반환값 설정 const handleCheckEmailDuplicate = async () => { - const data = await AuthApis.checkEmailDuplicate(userInfo); + const { data, isLoading } = await AuthApis.useCheckEmailDuplicateQuery(userInfo); // react-query: true/false date로 반환 + // const data = await AuthApis.checkEmailDuplicate(userInfo); if (data) { setIsValid((prev) => ({ ...prev, emailIsValid: true })); } }; + // API 반환값 설정 const handlecheckUsernameDuplicate = async () => { const data = await AuthApis.checkUsernameDuplicate(userInfo) diff --git a/frontend/src/stores/UserInfoStore.ts b/frontend/src/stores/UserInfoStore.ts index 7a18483..b4dfcc5 100644 --- a/frontend/src/stores/UserInfoStore.ts +++ b/frontend/src/stores/UserInfoStore.ts @@ -1,7 +1,7 @@ import { create } from "zustand"; import { devtools, persist } from "zustand/middleware"; -interface UserInfo { +export interface UserInfo { email: string; password: string; username: string; From d1fc500eaa4007d1e12a6aecc4ec746b09c6fa59 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 29 Jan 2024 03:49:51 +0900 Subject: [PATCH 17/23] =?UTF-8?q?Refactor:=20type=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SignupPage.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index c5ec8ce..1e66961 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -18,7 +18,7 @@ type isValid = { messageValidPw2Color: 'black' | 'blue'; }; -const SignupPage = () => { +const SignupPage: React.FC = () => { const navigate = useNavigate(); const userInfo = useStore(UserInfoStore); const [messageValidPw1, setMessageValidPw1] = useState('숫자/영어/특수문자를 혼용하여 3종류를 사용하세요.'); @@ -74,7 +74,7 @@ const SignupPage = () => { } // 비밀번호 예외처리 - const checkValidPassword = (password: string) => { + const checkValidPassword = (password: string): void => { // 숫자/영어/특수문자를 혼용했는가 const pattern = /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]+$/; @@ -89,9 +89,9 @@ const SignupPage = () => { }; // API 반환값 설정 - const handleCheckEmailDuplicate = async () => { - const { data, isLoading } = await AuthApis.useCheckEmailDuplicateQuery(userInfo); // react-query: true/false date로 반환 - // const data = await AuthApis.checkEmailDuplicate(userInfo); + const handleCheckEmailDuplicate = async (): Promise => { + // const { data, isLoading } = await AuthApis.useCheckEmailDuplicateQuery(userInfo); + const data = await AuthApis.checkEmailDuplicate(userInfo); if (data) { setIsValid((prev) => ({ ...prev, emailIsValid: true })); } @@ -99,7 +99,7 @@ const SignupPage = () => { // API 반환값 설정 - const handlecheckUsernameDuplicate = async () => { + const handlecheckUsernameDuplicate = async (): Promise => { const data = await AuthApis.checkUsernameDuplicate(userInfo) if (data) { setIsValid((prev) => ({ ...prev, usernameIsValid: true })); @@ -107,7 +107,7 @@ const SignupPage = () => { }; // 버튼코드 - const onButtonClick = (action:string) => { + const onButtonClick = (action:string): void => { switch(action){ case "onSetEmailCheck": console.log(`API 통신 ${userInfo.email}`) @@ -136,7 +136,7 @@ const SignupPage = () => { navigate("/"); } else - console.log("조건이 안맞음"); + console.log("4가지 조건이 안맞음 ex)중복확인x, 비밀번호다름"); break; default: From ceef46e0711b9de69848248f921d08c90ed6cca0 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Mon, 29 Jan 2024 04:04:37 +0900 Subject: [PATCH 18/23] =?UTF-8?q?Feat:=20refreshToken=20interceptor=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 76 ++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts index 3dbc094..57651dc 100644 --- a/frontend/src/hooks/useAuthQuery.ts +++ b/frontend/src/hooks/useAuthQuery.ts @@ -1,4 +1,4 @@ -import axios from 'axios'; +import axios,{ AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import { UserInfo, UserInfoStore } from '../stores/UserInfoStore'; import { useStore } from 'zustand'; import { useQuery, UseQueryResult } from '@tanstack/react-query'; @@ -42,7 +42,7 @@ export const AuthApis = { signup: async (userInfo:UserInfo, passwordConfirm: string) => { try { - const response = await AuthApis.instance.post('/login', { + const response = await AuthApis.instance.post('/signup', { username: userInfo.username, email: userInfo.email, password: userInfo.password, @@ -50,7 +50,11 @@ export const AuthApis = { }); const data = response.data; const jwtToken = data.token; + const refreshToken = data.refreshToken; + localStorage.setItem('jwtToken', jwtToken); + localStorage.setItem('refreshToken', refreshToken); + return data; } catch (error) { console.error("API 통신 에러:", error); @@ -65,21 +69,83 @@ export const AuthApis = { return { data, isLoading, error }; }, + + signin: async (userInfo:UserInfo, passwordConfirm: string) => { + try { + const response = await AuthApis.instance.post('/login', { + email: userInfo.email, + password: userInfo.password, + }); + const data = response.data; + const jwtToken = data.token; + const refreshToken = data.refreshToken; + + localStorage.setItem('jwtToken', jwtToken); + localStorage.setItem('refreshToken', refreshToken); + + return data; + } catch (error) { + console.error("API 통신 에러:", error); + } + }, + + //refreshToken + setupInterceptors: () => { + AuthApis.instance.interceptors.response.use( + (response: AxiosResponse) => response, + async (error) => { + const originalRequest = error.config; + + if (error.response.status === 401 && !originalRequest._retry) { + originalRequest._retry = true; + + try { + const refreshToken = localStorage.getItem('refreshToken'); + // 재발급받는 경로 + const response = await AuthApis.instance.post<{ accessToken: string }>('/login', { refreshToken }); + + const newAccessToken = response.data.accessToken; + + originalRequest.headers['Authorization'] = `Bearer ${newAccessToken}`; + + return AuthApis.instance(originalRequest); + } catch (refreshError) { + console.error("토큰 갱신 실패:", refreshError); + localStorage.removeItem('jwtToken'); + localStorage.removeItem('refreshToken'); + window.location.href = '/signin'; + } + } + + return Promise.reject(error); + } + ); + }, + + + // 리팩토링용 코드 fetchData: async (endpoint: string, type: string, data?: any) => { let response; switch (type) { case 'get': - response = await axios.get(`http://localhost:8001/user-service/${endpoint}`); + response = await AuthApis.instance.get(`http://localhost:8001/user-service/${endpoint}`, { + headers: { Authorization: `Bearer ${localStorage.getItem('jwtToken')}` }, + }); break; + case 'post': - response = await axios.post(`http://localhost:8001/user-service/${endpoint}`, data); + response = await AuthApis.instance.post(`http://localhost:8001/user-service/${endpoint}`, data, { + headers: { Authorization: `Bearer ${localStorage.getItem('jwtToken')}` }, + }); break; + default: console.error("Invalid type:", type); } + return response; - } + }, }; From f1712806a0778dcd1329417e4a4128395c0a8221 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Tue, 30 Jan 2024 14:37:38 +0900 Subject: [PATCH 19/23] =?UTF-8?q?Feat:=20UX=20=EA=B0=9C=EC=84=A0=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A4=91=EB=B3=B5=EC=8B=9C=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 32 +++++++++++++----------------- frontend/src/pages/SignupPage.tsx | 23 +++++++++++---------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts index 57651dc..37b437c 100644 --- a/frontend/src/hooks/useAuthQuery.ts +++ b/frontend/src/hooks/useAuthQuery.ts @@ -1,7 +1,6 @@ import axios,{ AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; -import { UserInfo, UserInfoStore } from '../stores/UserInfoStore'; -import { useStore } from 'zustand'; -import { useQuery, UseQueryResult } from '@tanstack/react-query'; +import { UserInfo } from '../stores/UserInfoStore'; +import { useQuery } from '@tanstack/react-query'; export const AuthApis = { @@ -10,11 +9,11 @@ export const AuthApis = { withCredentials: true, }), - checkEmailDuplicate: async (userInfo: UserInfo): Promise => { - const response = await AuthApis.instance.post(`/signup/exists/${userInfo.email}`, { + checkEmailDuplicate: async (userInfo: UserInfo): Promise => { + const response = await AuthApis.instance.get(`/signup/exists-email/${userInfo.email}`, { email: userInfo.email, }); - return response.data === true; + return response.data.valid === true; }, useCheckEmailDuplicateQuery: (userInfo: UserInfo) => { @@ -26,10 +25,10 @@ export const AuthApis = { }, checkUsernameDuplicate: async (userInfo:UserInfo): Promise => { - const response = await AuthApis.instance.post(`/signup/exists/${userInfo.username}`, { + const response = await AuthApis.instance.get(`/signup/exists-username/${userInfo.username}`, { username: userInfo.username, }); - return response.data === true; + return response.data.valid === true; }, checkUsernameDuplicateQuery: (userInfo: UserInfo) => { @@ -49,11 +48,6 @@ export const AuthApis = { passwordConfirm: passwordConfirm, }); const data = response.data; - const jwtToken = data.token; - const refreshToken = data.refreshToken; - - localStorage.setItem('jwtToken', jwtToken); - localStorage.setItem('refreshToken', refreshToken); return data; } catch (error) { @@ -70,17 +64,18 @@ export const AuthApis = { }, - signin: async (userInfo:UserInfo, passwordConfirm: string) => { + signin: async (userInfo:UserInfo) => { try { const response = await AuthApis.instance.post('/login', { email: userInfo.email, password: userInfo.password, }); const data = response.data; - const jwtToken = data.token; + console.log(data); + const accessToken = data.accessToken; const refreshToken = data.refreshToken; - localStorage.setItem('jwtToken', jwtToken); + localStorage.setItem('accessToken', accessToken); localStorage.setItem('refreshToken', refreshToken); return data; @@ -100,9 +95,10 @@ export const AuthApis = { originalRequest._retry = true; try { + console.log("토큰 갱신 :",); const refreshToken = localStorage.getItem('refreshToken'); // 재발급받는 경로 - const response = await AuthApis.instance.post<{ accessToken: string }>('/login', { refreshToken }); + const response = await AuthApis.instance.post<{ accessToken: string }>('/hello', { refreshToken }); const newAccessToken = response.data.accessToken; @@ -111,7 +107,7 @@ export const AuthApis = { return AuthApis.instance(originalRequest); } catch (refreshError) { console.error("토큰 갱신 실패:", refreshError); - localStorage.removeItem('jwtToken'); + localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); window.location.href = '/signin'; } diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 1e66961..1bc4906 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -89,30 +89,33 @@ const SignupPage: React.FC = () => { }; // API 반환값 설정 - const handleCheckEmailDuplicate = async (): Promise => { + const handleCheckEmailDuplicate = async (): Promise => { // const { data, isLoading } = await AuthApis.useCheckEmailDuplicateQuery(userInfo); const data = await AuthApis.checkEmailDuplicate(userInfo); if (data) { setIsValid((prev) => ({ ...prev, emailIsValid: true })); } + return data; }; // API 반환값 설정 - const handlecheckUsernameDuplicate = async (): Promise => { + const handlecheckUsernameDuplicate = async (): Promise => { const data = await AuthApis.checkUsernameDuplicate(userInfo) if (data) { setIsValid((prev) => ({ ...prev, usernameIsValid: true })); } + return data; }; // 버튼코드 - const onButtonClick = (action:string): void => { + const onButtonClick = async (action: string): Promise => { switch(action){ case "onSetEmailCheck": console.log(`API 통신 ${userInfo.email}`) - handleCheckEmailDuplicate(); - if(!isValid.emailIsValid) + const res1 = await handleCheckEmailDuplicate(); + + if(!res1) setMessageEmail('중복된 이메일입니다') else setMessageEmail('사용 가능한 이메일입니다') @@ -120,8 +123,8 @@ const SignupPage: React.FC = () => { case "onSetNicknameCheck": console.log(`API 통신 ${userInfo.username}`) - handlecheckUsernameDuplicate(); - if(!isValid.usernameIsValid) + const res2 = await handlecheckUsernameDuplicate(); + if(!res2) setMessageUsername('중복된 닉네임입니다') else setMessageUsername('사용 가능한 닉네임입니다') @@ -131,12 +134,12 @@ const SignupPage: React.FC = () => { console.log(`회원가입 ${userInfo.email}, ${userInfo.password},${passwordConfirm}, ${userInfo.username}`); if (isValid.passwordIsValid && isValid.passwordCheckIsValid && isValid.emailIsValid && isValid.usernameIsValid) { - console.log("로그인 성공"); + alert("회원가입 성공"); AuthApis.signup(userInfo,passwordConfirm); - navigate("/"); + navigate("/signin"); } else - console.log("4가지 조건이 안맞음 ex)중복확인x, 비밀번호다름"); + alert("회원가입에 실패했습니다. 입력 정보를 다시 확인해주세요."); break; default: From d55b67b123514e3beb31682d56d4fa8bc5f84ec2 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Tue, 30 Jan 2024 15:36:56 +0900 Subject: [PATCH 20/23] =?UTF-8?q?Feat:=20Header=20=EC=A0=80=EC=9E=A5/=20?= =?UTF-8?q?=EC=9E=AC=EB=B0=9C=EA=B8=89=20=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 39 ++++++--- frontend/src/pages/SigninPage.tsx | 126 +++++++++++++++++------------ 2 files changed, 102 insertions(+), 63 deletions(-) diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts index 37b437c..3a803ad 100644 --- a/frontend/src/hooks/useAuthQuery.ts +++ b/frontend/src/hooks/useAuthQuery.ts @@ -71,12 +71,17 @@ export const AuthApis = { password: userInfo.password, }); const data = response.data; - console.log(data); - const accessToken = data.accessToken; - const refreshToken = data.refreshToken; + + const rawAccessToken = response.headers.get('Accesstoken'); + const rawRefreshToken = response.headers.get('RefreshToken'); + + const Accesstoken = rawAccessToken ? rawAccessToken.replace(/^Bearer\s+/i, '') : null; + const Refreshtoken = rawRefreshToken ? rawRefreshToken.replace(/^Bearer\s+/i, '') : null; + + console.log(`토큰 발급\n Accesstoken:${Accesstoken}\n Refreshtoken:${Refreshtoken}`) - localStorage.setItem('accessToken', accessToken); - localStorage.setItem('refreshToken', refreshToken); + localStorage.setItem('Accesstoken', Accesstoken); + localStorage.setItem('Refreshtoken', Refreshtoken); return data; } catch (error) { @@ -95,20 +100,30 @@ export const AuthApis = { originalRequest._retry = true; try { - console.log("토큰 갱신 :",); const refreshToken = localStorage.getItem('refreshToken'); // 재발급받는 경로 - const response = await AuthApis.instance.post<{ accessToken: string }>('/hello', { refreshToken }); + const response = await AuthApis.instance.get('/hello', { + headers: {Refreshtoken : `Bearer ${localStorage.getItem('Refreshtoken')}`} + }); + + const rawAccessToken = response.headers.get('Accesstoken'); + const rawRefreshToken = response.headers.get('Refreshtoken'); + + const newAccesstoken = rawAccessToken ? rawAccessToken.replace(/^Bearer\s+/i, '') : null; + const newRefreshtoken = rawRefreshToken ? rawRefreshToken.replace(/^Bearer\s+/i, '') : null; + + console.log(`토큰 갱신\n newAccesstoken:${newAccesstoken}\n newRefreshtoken:${newRefreshtoken}`) - const newAccessToken = response.data.accessToken; + localStorage.setItem('Accesstoken',newAccesstoken); + localStorage.setItem('Refreshtoken',newRefreshtoken); - originalRequest.headers['Authorization'] = `Bearer ${newAccessToken}`; + originalRequest.headers['Authorization'] = `Bearer ${newAccesstoken}`; return AuthApis.instance(originalRequest); } catch (refreshError) { - console.error("토큰 갱신 실패:", refreshError); - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); + console.error("토큰 갱신 실패", refreshError); + localStorage.removeItem('Accesstoken'); + localStorage.removeItem('Refreshtoken'); window.location.href = '/signin'; } } diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx index b799beb..13d454f 100644 --- a/frontend/src/pages/SigninPage.tsx +++ b/frontend/src/pages/SigninPage.tsx @@ -1,69 +1,93 @@ -import React,{useState} from "react"; +import { useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { InputForm } from "../components/InputForm"; import { Button } from "../components/Button"; import { KakaoButton } from "../components/auth/KakaoButton"; +import { useStore } from "zustand"; +import { UserInfoStore } from "../stores/UserInfoStore"; -const SigninPage = () => { - const navigate = useNavigate(); - const [inputs,setInputs] = useState({ - email: '', - password : '', - }); - const {email,password} = inputs +import { AuthApis } from "../hooks/useAuthQuery"; +import axios from "axios"; - const onChange = (e) => { - const {value, name} = e.target; - setInputs({ - ...inputs, - [name]: value, - }); - console.log(inputs); - } +const fetchDataExample = async () => { + instance: axios.create({ + baseURL: "http://localhost:8001/user-service/", + withCredentials: true, + }) - const onButtonClick = (action) => { - console.log(action ,inputs); - switch(action){ - case "onSignin": - setTimeout(()=> navigate("/"),2000); - break; - case "onSignup": - setTimeout(()=> navigate("/signup"),2000); - break; - case "onSignupKakao": - setTimeout(()=> navigate("/signupkakao"),2000); - break; - default: - console.error("error") + try { + AuthApis.setupInterceptors(); + const response = await AuthApis.instance.get('/hello', { + headers: { Accesstoken: `Bearer ${localStorage.getItem('Accesstoken')}` }, + }); + const data = response.data; + console.log("로그인 성공") + return data; + } catch (error) { + } + }; + +const SigninPage:React.FC = () => { + const navigate = useNavigate(); + const userInfo = useStore(UserInfoStore); + + const onChange = (e: React.ChangeEvent) => { + const { value, name } = e.target; + + if (name === 'email') { + userInfo.updateEmail(value); + } else if (name === 'password') { + userInfo.updatePassword(value); } + }; + + const onButtonClick = (action:string) => { + switch(action){ + case "onSignin": + AuthApis.signin(userInfo); + navigate("/"); + break; + case "onSignup": + navigate("/signup") + break; + case "onSignupKakao": + fetchDataExample(); + // navigate("/signupkakao") + break; + default: + console.error("error") + } } return( -
-
-

TadakTadak Logo

- <>It's SigninPage! - -
+
+
+

TadakTadak Logo

+ <>It's SigninPage! +
- {/* email input */} - + {/* email input */} + -
+
- {/* pw input */} - + {/* pw input */} + -
- -
- -
- -
- ) +
+ +
+ +
+ +
+ + +
+ ) + }; -export default SigninPage; +export default SigninPage; \ No newline at end of file From 29c1d5f98433749a32e905de50b3dd01fdadfacc Mon Sep 17 00:00:00 2001 From: DingX2 Date: Thu, 1 Feb 2024 23:16:18 +0900 Subject: [PATCH 21/23] =?UTF-8?q?Feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useAuthQuery.ts | 4 +- frontend/src/pages/SignupPage.tsx | 103 +++++++++++++++++++---------- 2 files changed, 69 insertions(+), 38 deletions(-) diff --git a/frontend/src/hooks/useAuthQuery.ts b/frontend/src/hooks/useAuthQuery.ts index 3a803ad..b5e5cc0 100644 --- a/frontend/src/hooks/useAuthQuery.ts +++ b/frontend/src/hooks/useAuthQuery.ts @@ -39,16 +39,16 @@ export const AuthApis = { return { data, isLoading, error }; }, - signup: async (userInfo:UserInfo, passwordConfirm: string) => { + signup: async (userInfo:UserInfo, passwordConfirm: string, authCode: string) => { try { const response = await AuthApis.instance.post('/signup', { username: userInfo.username, email: userInfo.email, password: userInfo.password, + authCode: authCode, passwordConfirm: passwordConfirm, }); const data = response.data; - return data; } catch (error) { console.error("API 통신 에러:", error); diff --git a/frontend/src/pages/SignupPage.tsx b/frontend/src/pages/SignupPage.tsx index 1bc4906..50ee2ea 100644 --- a/frontend/src/pages/SignupPage.tsx +++ b/frontend/src/pages/SignupPage.tsx @@ -1,11 +1,10 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState, useMemo } from "react"; import { useNavigate } from "react-router-dom"; import { InputForm } from "../components/InputForm"; import { Button } from "../components/Button"; import { useStore } from "zustand"; import { UserInfoStore } from "../stores/UserInfoStore"; import styled from '@emotion/styled'; -import axios from 'axios'; import { AuthApis } from "../hooks/useAuthQuery"; @@ -14,32 +13,34 @@ type isValid = { passwordCheckIsValid: boolean; emailIsValid: boolean; usernameIsValid: boolean; + authCode: string; messageValidPw1Color: 'black' | 'blue'; messageValidPw2Color: 'black' | 'blue'; }; const SignupPage: React.FC = () => { const navigate = useNavigate(); - const userInfo = useStore(UserInfoStore); const [messageValidPw1, setMessageValidPw1] = useState('숫자/영어/특수문자를 혼용하여 3종류를 사용하세요.'); const [messageValidPw2, setMessageValidPw2] = useState('비밀번호는 1자 이상 20자 이하로 입력하세요.'); - const [messagePw, setMessagePw] = useState(""); const [messageEmail, setMessageEmail] = useState(""); const [messageUsername, setMessageUsername] = useState(""); const [passwordConfirm, setPasswordConfirm] = useState(""); + const userInfo = useStore(UserInfoStore); const [isValid, setIsValid] = useState({ passwordIsValid: false, passwordCheckIsValid: false, emailIsValid: false, usernameIsValid: false, + authCode: '', messageValidPw1Color: 'black', messageValidPw2Color: 'black', }); // const authApis = AuthApis(userInfo); + // 값 보존을 위한 코드 -> 값 변경되면 false 처리 useEffect(()=>{ console.log(isValid) },[isValid]) @@ -51,35 +52,35 @@ const SignupPage: React.FC = () => { if (name === 'email') { setIsValid((prev) => ({ ...prev, emailIsValid: false })); userInfo.updateEmail(value); + } else if (name === 'authCode'){ + setIsValid((prev)=>({...prev, authCode: value})) } else if (name === 'password') { userInfo.updatePassword(value); checkValidPassword(value); - if(isValid.passwordIsValid) + if (isValid.passwordIsValid) console.log("사용가능한 비밀번호입니다"); - } - else if (name === 'password-check') { + } else if (name === 'password-check') { setPasswordConfirm(value); - if(userInfo.password === value){ + if (userInfo.password === value){ isValid.passwordCheckIsValid= true; setMessagePw("일치하는 비밀번호 입니다.")} else{ isValid.passwordCheckIsValid= false; setMessagePw("비밀번호가 일치하지 않습니다.") } - } - else if (name === 'username') { + } else if (name === 'username') { setIsValid((prev) => ({ ...prev, usernameIsValid: false })); userInfo.updateUsername(value); } } - // 비밀번호 예외처리 + // 비밀번호 예외처리 -> 색 변경 const checkValidPassword = (password: string): void => { // 숫자/영어/특수문자를 혼용했는가 const pattern = /^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]+$/; - // 1~20자내인가 - const isValidLength = password.length >= 1 && password.length <= 20; + // 1~15자내인가 + const isValidLength = password.length >= 1 && password.length <= 15; setIsValid(prevState => ({ ...prevState, messageValidPw1Color: pattern.test(password) ? 'blue' : 'black', @@ -88,23 +89,27 @@ const SignupPage: React.FC = () => { })); }; - // API 반환값 설정 + // 이메일중복 및 형식체크 -> t/f const handleCheckEmailDuplicate = async (): Promise => { // const { data, isLoading } = await AuthApis.useCheckEmailDuplicateQuery(userInfo); const data = await AuthApis.checkEmailDuplicate(userInfo); - if (data) { - setIsValid((prev) => ({ ...prev, emailIsValid: true })); - } return data; }; + // 닉네임 글자수 체크 -> t/f + const checkValidUsername = (username: string): boolean =>{ + //2~15자내인가 + const isValidLength = username.length >= 2 && username.length <= 15; + setIsValid(prevState => ({ + ...prevState, + usernameIsValid: isValidLength + })) + return isValidLength; + } - // API 반환값 설정 + // 닉네임중복체크 -> t/f const handlecheckUsernameDuplicate = async (): Promise => { const data = await AuthApis.checkUsernameDuplicate(userInfo) - if (data) { - setIsValid((prev) => ({ ...prev, usernameIsValid: true })); - } return data; }; @@ -116,27 +121,40 @@ const SignupPage: React.FC = () => { const res1 = await handleCheckEmailDuplicate(); if(!res1) - setMessageEmail('중복된 이메일입니다') - else - setMessageEmail('사용 가능한 이메일입니다') + setMessageEmail('이메일 형식이 잘못됐거나 중복된 이메일입니다.') + else{ + + setMessageEmail('이메일로 전송된 인증코드를 입력해주세요.') + setIsValid((prev) => ({ ...prev, emailIsValid: true })); break; + } case "onSetNicknameCheck": + const res3 = checkValidUsername(userInfo.username); console.log(`API 통신 ${userInfo.username}`) const res2 = await handlecheckUsernameDuplicate(); if(!res2) setMessageUsername('중복된 닉네임입니다') - else + else if(!res3){ + setMessageUsername('닉네임은 2~15자이내입니다.') + } + else if(res2 && res3){ setMessageUsername('사용 가능한 닉네임입니다') + setIsValid((prev) => ({ ...prev, usernameIsValid: true })); + } break; case "onSignup": - console.log(`회원가입 ${userInfo.email}, ${userInfo.password},${passwordConfirm}, ${userInfo.username}`); + console.log(`회원가입 ${userInfo.email}, ${userInfo.password},${passwordConfirm}, ${userInfo.username}, ${isValid.authCode}`); if (isValid.passwordIsValid && isValid.passwordCheckIsValid && isValid.emailIsValid && isValid.usernameIsValid) { - alert("회원가입 성공"); - AuthApis.signup(userInfo,passwordConfirm); - navigate("/signin"); + const res = await AuthApis.signup(userInfo,passwordConfirm,isValid.authCode); + console.log(res,res); + if (res.id){ + navigate("/signin"); + alert(`${res.username}님 가입을 환영합니다`);} + else + alert(res.message) } else alert("회원가입에 실패했습니다. 입력 정보를 다시 확인해주세요."); @@ -155,32 +173,45 @@ const SignupPage: React.FC = () => {
{/* email input */} - - + + {messageEmail}
- + {/* emailToggle */} + { isValid.emailIsValid ?
+ + 이메일을 받지 못하셨나요? + +
: null} + {/* pw input */}
+ type = 'password' title="비밀번호" name="password" value={userInfo?.password} placeholder="비밀번호"/>
{messageValidPw1}

{messageValidPw2}

{/* password duplicate check */} + type = 'password' title="비밀번호 확인" name="password-check" value={passwordConfirm} placeholder="비밀번호 확인"/> {messagePw}
{/* username input */} + type = 'text' title="닉네임" name="username" value={userInfo?.username} placeholder="닉네임 (2~15자)"/> {messageUsername}

- +
From 0474411028234945764def2d6275ae63cdac8a19 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Sun, 4 Feb 2024 21:20:17 +0900 Subject: [PATCH 22/23] =?UTF-8?q?Chore:=20=EC=98=9B=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/auth/KakaoButton.tsx | 70 -------------------- frontend/src/pages/SignUpKakaoPage.tsx | 5 -- 2 files changed, 75 deletions(-) delete mode 100644 frontend/src/components/auth/KakaoButton.tsx delete mode 100644 frontend/src/pages/SignUpKakaoPage.tsx diff --git a/frontend/src/components/auth/KakaoButton.tsx b/frontend/src/components/auth/KakaoButton.tsx deleted file mode 100644 index 8195d21..0000000 --- a/frontend/src/components/auth/KakaoButton.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import styled from '@emotion/styled'; - -const REST_API_KEY = import.meta.env.VITE_APP_REST_API_KEY; - -export const KakaoButton = () => { - - const REDIRECT_URI = "http://127.0.0.1:5173/SignUpKakaoPage"; - const KAKAO_AUTH_URI = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`; - - - return( - - - - ) -} - -const KakaoButtonStyles = styled.div` - .KakaoLoginBtn-wrapper { - display: flex; - justify-content: center; - } - - .btn-kakao { - width: 300px; - height: 46px; - background: #FEE500; - border-radius: 12px; - display: flex; - align-items: center; - justify-content: center; - gap: 1rem; - transition: background-color 0.3s; - } - - .text { - font-family: 'Noto Sans', sans-serif; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 24px; - text-align: center; - color: #000000; - } - - .btn-kakao:hover { - background-color: #fff7ac; - } -`; \ No newline at end of file diff --git a/frontend/src/pages/SignUpKakaoPage.tsx b/frontend/src/pages/SignUpKakaoPage.tsx deleted file mode 100644 index 6825965..0000000 --- a/frontend/src/pages/SignUpKakaoPage.tsx +++ /dev/null @@ -1,5 +0,0 @@ -const SignupKakaoPage = () => { - return
It's SignupKakaoPage!
; -}; - -export default SignupKakaoPage; From b541b27e7c416b9048191e0881e15ef581ecacb6 Mon Sep 17 00:00:00 2001 From: DingX2 Date: Sun, 4 Feb 2024 21:30:58 +0900 Subject: [PATCH 23/23] =?UTF-8?q?Chore:=20=ED=99=95=EC=9D=B8=EC=99=84?= =?UTF-8?q?=EB=A3=8C,=20=EC=B6=A9=EB=8F=8C=EB=B0=A9=EC=A7=80=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 4 -- frontend/src/components/InputForm.tsx | 27 ++++---- frontend/src/pages/SigninPage.tsx | 93 --------------------------- 3 files changed, 15 insertions(+), 109 deletions(-) delete mode 100644 frontend/src/pages/SigninPage.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 052e8d9..97caf88 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4,9 +4,7 @@ import WelcomePage from './pages/WelcomePage'; import ErrorPage from './pages/ErrorPage'; import ChattingListPage from './pages/ChattingListPage'; import SignupPage from './pages/SignupPage'; -import SigninPage from './pages/SigninPage'; import ChattingRoomPage from './pages/ChattingRoomPage'; -import SignUpKakaoPage from './pages/SignUpKaKaoPage'; import TestPage from './test/TestPage'; const router = createBrowserRouter([ @@ -17,11 +15,9 @@ const router = createBrowserRouter([ errorElement: , children: [ { index: true, element: }, - { path: 'signin', element: }, { path: 'signup', element: }, { path: 'chattinglist', element: }, { path: 'chatroom/:chatroom_id', element: }, - { path: 'signupkakao', element: }, { path: 'test', element: }, ], }, diff --git a/frontend/src/components/InputForm.tsx b/frontend/src/components/InputForm.tsx index 60f3283..6b5d0a2 100644 --- a/frontend/src/components/InputForm.tsx +++ b/frontend/src/components/InputForm.tsx @@ -1,12 +1,15 @@ -export const InputForm = ({type, onChange, placeholder,title, ...rest}) =>{ - return(<> - {title} - - - ) -} \ No newline at end of file +export const InputForm = ({ type, name, value, onChange, placeholder, title, ...rest }) => { + return ( + <> + {title} + + + ); +}; \ No newline at end of file diff --git a/frontend/src/pages/SigninPage.tsx b/frontend/src/pages/SigninPage.tsx deleted file mode 100644 index 13d454f..0000000 --- a/frontend/src/pages/SigninPage.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { useEffect } from "react"; -import { useNavigate } from "react-router-dom"; -import { InputForm } from "../components/InputForm"; -import { Button } from "../components/Button"; -import { KakaoButton } from "../components/auth/KakaoButton"; -import { useStore } from "zustand"; -import { UserInfoStore } from "../stores/UserInfoStore"; - -import { AuthApis } from "../hooks/useAuthQuery"; -import axios from "axios"; - - -const fetchDataExample = async () => { - instance: axios.create({ - baseURL: "http://localhost:8001/user-service/", - withCredentials: true, - }) - - try { - AuthApis.setupInterceptors(); - const response = await AuthApis.instance.get('/hello', { - headers: { Accesstoken: `Bearer ${localStorage.getItem('Accesstoken')}` }, - }); - const data = response.data; - console.log("로그인 성공") - return data; - } catch (error) { - } - }; - -const SigninPage:React.FC = () => { - const navigate = useNavigate(); - const userInfo = useStore(UserInfoStore); - - const onChange = (e: React.ChangeEvent) => { - const { value, name } = e.target; - - if (name === 'email') { - userInfo.updateEmail(value); - } else if (name === 'password') { - userInfo.updatePassword(value); - } - }; - - const onButtonClick = (action:string) => { - switch(action){ - case "onSignin": - AuthApis.signin(userInfo); - navigate("/"); - break; - case "onSignup": - navigate("/signup") - break; - case "onSignupKakao": - fetchDataExample(); - // navigate("/signupkakao") - break; - default: - console.error("error") - } - } - - return( -
-
-

TadakTadak Logo

- <>It's SigninPage! -
- - {/* email input */} - - -
- - {/* pw input */} - - -
- -
- -
- -
- -
-
- ) - -}; - -export default SigninPage; \ No newline at end of file