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
+
+
+ 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