From 5836cd4256614359cb6df7fd0e69853135b3619b Mon Sep 17 00:00:00 2001 From: kiyeong Date: Mon, 2 Dec 2024 18:46:23 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=EC=A4=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/LoginPage/LoginPage.tsx | 71 +++++++++++++++++--------- src/pages/MainPage/GuestPage.tsx | 6 ++- src/pages/MainPage/Sidebar/Sidebar.tsx | 7 ++- src/pages/MainPage/UserPage.tsx | 4 +- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/pages/LoginPage/LoginPage.tsx b/src/pages/LoginPage/LoginPage.tsx index d21ddb0..cf7de22 100644 --- a/src/pages/LoginPage/LoginPage.tsx +++ b/src/pages/LoginPage/LoginPage.tsx @@ -10,31 +10,30 @@ import { Box, IconButton, useToast, + Spinner, } from "@chakra-ui/react"; import { ArrowBackIcon } from "@chakra-ui/icons"; -import { useNavigate } from "react-router-dom"; // React Router 사용 +import { useNavigate } from "react-router-dom"; -import loginHobanu from "./assets/loginHobanu.svg"; // 이미지 경로를 맞게 설정하세요 +import loginHobanu from "./assets/loginHobanu.svg"; -const baseURL = import.meta.env.VITE_BASE_URL; // 환경 변수에서 baseURL 가져오기 +const baseURL = import.meta.env.VITE_BASE_URL; const LoginPage: React.FC = () => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); - const toast = useToast(); // Toast 사용 + const [isLoading, setIsLoading] = useState(false); // 로딩 상태 관리 + const toast = useToast(); const navigate = useNavigate(); - // 이전 페이지로 이동 const handleBack = () => { navigate(-1); }; - // 회원가입 페이지로 이동 const handleSignup = () => { navigate("/signup"); }; - // 로그인 API 요청 const handleLogin = async () => { if (!email || !password) { toast({ @@ -47,6 +46,8 @@ const LoginPage: React.FC = () => { return; } + setIsLoading(true); // 로딩 상태 활성화 + try { const response = await fetch(`${baseURL}/api/member/login`, { method: "POST", @@ -58,7 +59,7 @@ const LoginPage: React.FC = () => { if (response.status === 200) { const data = await response.json(); - localStorage.setItem("accessToken", data.accessToken); // access token 저장 + localStorage.setItem("accessToken", data.accessToken); toast({ title: "로그인 성공!", status: "success", @@ -66,7 +67,7 @@ const LoginPage: React.FC = () => { isClosable: true, position: "top", }); - navigate("/"); // 로그인 성공 후 대시보드로 이동 + navigate("/"); } else if (response.status === 400) { toast({ title: "이메일과 비밀번호를 모두 입력해주세요.", @@ -101,12 +102,40 @@ const LoginPage: React.FC = () => { isClosable: true, position: "top", }); + } finally { + setIsLoading(false); // 로딩 상태 비활성화 + } + }; + + const handleKeyPress = (event: React.KeyboardEvent) => { + if (event.key === "Enter" && !isLoading) { + handleLogin(); } }; return ( - {/* 상단 왼쪽에 이전 페이지 버튼 */} + {/* 로딩 중일 때 화면 전체를 덮는 로딩 레이어 */} + {isLoading && ( + + + + 로딩 중... + + + )} + { bg="#DCD8C8" color="black" _hover={{ bg: "#AAA282" }} + isDisabled={isLoading} // 로딩 중 비활성화 />
- {/* 상단 캐릭터 이미지 */} - Character - {/* 이메일 입력 */} + Character { fontFamily={"mono"} focusBorderColor="#DCD8C8" value={email} - onChange={(e) => setEmail(e.target.value)} // 이메일 상태 업데이트 + onChange={(e) => setEmail(e.target.value)} + isDisabled={isLoading} // 로딩 중 비활성화 /> - {/* 비밀번호 입력 */} { fontFamily={"mono"} focusBorderColor="#DCD8C8" value={password} - onChange={(e) => setPassword(e.target.value)} // 비밀번호 상태 업데이트 + onChange={(e) => setPassword(e.target.value)} + onKeyDown={handleKeyPress} + isDisabled={isLoading} // 로딩 중 비활성화 /> - {/* 로그인 버튼 */} - {/* 회원가입 링크 */} 아직 회원이 아니신가요?{" "} diff --git a/src/pages/MainPage/GuestPage.tsx b/src/pages/MainPage/GuestPage.tsx index 5e9eabc..e5b479b 100644 --- a/src/pages/MainPage/GuestPage.tsx +++ b/src/pages/MainPage/GuestPage.tsx @@ -260,9 +260,11 @@ const GuestPage = () => { fontWeight="medium" bg="#EAE6DA" _hover={{ bg: "#DDD8C6", transform: "scale(1.05)" }} - onClick={() => handleSendMessage("참여가능한 대회 알려줘")} + onClick={() => + handleSendMessage("정설영 교수님 이메일 알려줘") + } > - 참여가능한 대회 알려줘 + 정설영 교수님 이메일 알려줘 - {" "} + {" "} {/* 버튼 간 구분선 */}