Skip to content

Commit

Permalink
feat: 로그인 api 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
gogumalatte committed Nov 29, 2024
1 parent 408def0 commit 8f17e12
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// 로그인 하지 않은 사용자의 메인 페이지 컴포넌트
import { useState, useEffect, useRef } from "react";
import { MessageInput } from "./MessageInput/MessageInput";
import { MessageList } from "./messageList/MessageList";
Expand All @@ -10,7 +11,7 @@ import tutorial3 from "@/assets/tutorial3.svg";
import tutorial4 from "@/assets/tutorial4.svg";
import tutorial5 from "@/assets/tutorial5.svg";

const MainPage = () => {
const GuestPage = () => {
const [messages, setMessages] = useState<string[]>([]);
const [inputMessage, setInputMessage] = useState("");
const [isSidebarOpen, setSidebarOpen] = useState(false);
Expand Down Expand Up @@ -330,4 +331,4 @@ const MainPage = () => {
);
};

export default MainPage;
export default GuestPage;
1 change: 1 addition & 0 deletions src/pages/MainPage/IntroModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// 서비스의 사용 설명서를 보여주는 모달 컴포넌트
import React from "react";
import {
Modal,
Expand Down
1 change: 1 addition & 0 deletions src/pages/MainPage/UserPage
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// 로그인을 한 사용자의 메인 페이지 컴포넌트
165 changes: 147 additions & 18 deletions src/pages/SignupPage/SignupPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,130 @@ import {
Text,
Image,
IconButton,
useToast,
InputGroup,
InputRightElement,
} from "@chakra-ui/react";
import { ArrowBackIcon } from "@chakra-ui/icons";
import { useNavigate } from "react-router-dom"; // React Router 사용
import { ArrowBackIcon, ViewIcon, ViewOffIcon } from "@chakra-ui/icons";
import { useNavigate } from "react-router-dom";

import welcomeHobanu from "./assets/signupHobanu.svg"; // 이미지 경로를 맞게 설정하세요

const baseURL = import.meta.env.VITE_BASE_URL; // 환경 변수에서 baseURL 가져오기

const SignupPage: React.FC = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [nickname, setNickname] = useState("");
const [showPassword, setShowPassword] = useState(false); // 비밀번호 보이기/숨기기 상태
const [emailCheckMessage, setEmailCheckMessage] = useState("");
const [emailCheckDone, setEmailCheckDone] = useState(false); // 이메일 중복 검사 완료 여부
const toast = useToast(); // Toast 인스턴스
const navigate = useNavigate();

const handleEmailCheck = () => {
// 이메일 중복 확인 로직
if (email === "[email protected]") {
setEmailCheckMessage("이미 사용 중인 이메일입니다.");
} else {
setEmailCheckMessage("가입 가능한 이메일입니다.");
// 이메일 중복 확인
const handleEmailCheck = async () => {
try {
const response = await fetch(
`${baseURL}/api/member/check-email?email=${email}`,
{
method: "GET",
}
);

if (response.status === 200) {
const data = await response.json();
if (data.email_check) {
setEmailCheckDone(false);
setEmailCheckMessage("이미 사용 중인 이메일입니다.");
} else {
setEmailCheckDone(true); // 이메일 중복 검사 성공
setEmailCheckMessage("가입 가능한 이메일입니다.");
}
} else if (response.status === 400) {
setEmailCheckDone(false);
setEmailCheckMessage("이메일에 공란이 있습니다.");
} else {
setEmailCheckDone(false);
setEmailCheckMessage("오류가 발생했습니다. 다시 시도해주세요.");
}
} catch (error) {
console.error("Error checking email:", error);
setEmailCheckDone(false);
setEmailCheckMessage(
"서버와 연결할 수 없습니다. 나중에 다시 시도해주세요."
);
}
};

// 회원가입 요청
const handleSignup = async () => {
// 이메일 중복 검사 완료 여부 확인
if (!emailCheckDone) {
toast({
title: "이메일 중복 검사를 먼저 해주세요.",
status: "warning",
position: "top",
duration: 1500,
isClosable: true,
});
return;
}

try {
const response = await fetch(`${baseURL}/api/member/signup`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email,
password,
nickname,
}),
});

if (response.status === 201) {
toast({
title: "회원가입에 성공했습니다.",
status: "success",
position: "top",
duration: 1500,
isClosable: true,
});
navigate("/login"); // 회원가입 성공 후 로그인 페이지로 이동
} else if (response.status === 500) {
toast({
title: "내부 서버 오류가 발생했습니다.",
status: "error",
position: "top",
duration: 1500,
isClosable: true,
});
} else {
toast({
title: "회원가입에 실패했습니다. 다시 시도해주세요.",
status: "error",
position: "top",
duration: 1500,
isClosable: true,
});
}
} catch (error) {
console.error("Error during signup:", error);
toast({
title: "서버와 연결할 수 없습니다. 나중에 다시 시도해주세요.",
status: "error",
position: "top",
duration: 1500,
isClosable: true,
});
}
};

// 이전 페이지로 이동
const handleBack = () => {
navigate(-1); // 이전 페이지로 이동
navigate(-1);
};

return (
Expand Down Expand Up @@ -59,7 +161,13 @@ const SignupPage: React.FC = () => {
fontSize={"xl"}
focusBorderColor="#DCD8C8"
value={email}
onChange={(e) => setEmail(e.target.value)}
onChange={(e) => {
setEmail(e.target.value);
setEmailCheckDone(false); // 이메일 변경 시 중복 검사 초기화
setEmailCheckMessage(
"이메일이 변경되었습니다. 중복 검사를 다시 수행해주세요."
);
}}
/>
<Button
bg="#AAA282"
Expand All @@ -74,25 +182,45 @@ const SignupPage: React.FC = () => {
</Stack>
{/* 이메일 중복 확인 메시지 */}
{emailCheckMessage && (
<Text fontSize={"xl"} color="#8B8469" mt={2} textAlign={"center"}>
<Text fontSize={"lg"} color="#8B8469" mt={2} textAlign={"center"}>
{emailCheckMessage}
</Text>
)}
</Box>

{/* 비밀번호 입력 */}
<Input
placeholder="비밀번호"
type="password"
bg="white"
fontSize={"xl"}
focusBorderColor="#DCD8C8"
/>
<InputGroup size="md">
<Input
placeholder="비밀번호"
type={showPassword ? "text" : "password"} // 비밀번호 보이기/숨기기
bg="white"
color="black"
fontSize={"xl"}
focusBorderColor="#DCD8C8"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<InputRightElement>
<IconButton
aria-label={
showPassword ? "비밀번호 숨기기" : "비밀번호 보이기"
}
icon={showPassword ? <ViewOffIcon /> : <ViewIcon />}
onClick={() => setShowPassword(!showPassword)} // 상태 토글
bg="transparent"
_hover={{ bg: "transparent" }}
/>
</InputRightElement>
</InputGroup>

{/* 닉네임 입력 */}
<Input
placeholder="닉네임"
bg="white"
fontSize={"xl"}
focusBorderColor="#DCD8C8"
value={nickname}
onChange={(e) => setNickname(e.target.value)}
/>
{/* 회원가입 버튼 */}
<Button
Expand All @@ -103,6 +231,7 @@ const SignupPage: React.FC = () => {
fontWeight={"light"}
letterSpacing={"0.1em"}
_hover={{ bg: "#AAA282" }}
onClick={handleSignup}
>
가입하기
</Button>
Expand Down
4 changes: 2 additions & 2 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import MainPage from "@/pages/MainPage/MainPage";
import GuestPage from "@/pages/MainPage/GuestPage";
import LoginPage from "@/pages/LoginPage/LoginPage";
import SignupPage from "@/pages/SignupPage/SignupPage";
import { RouterPath } from "./path"; // 경로 상수 가져오기
Expand All @@ -8,7 +8,7 @@ import { RouterPath } from "./path"; // 경로 상수 가져오기
const router = createBrowserRouter([
{
path: RouterPath.root,
element: <MainPage />, // 메인 페이지를 직접 렌더링
element: <GuestPage />, // 메인 페이지를 직접 렌더링
},
{
path: RouterPath.login,
Expand Down
2 changes: 1 addition & 1 deletion src/routes/path.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const RouterPath = {
root: "/",
main: "/",
user: "/user",
login: "/login",
signup: "/signup",
};

0 comments on commit 8f17e12

Please sign in to comment.