-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
로그인 정보 저장 방식 변경, 유저 정보 표시 컴포넌트 제작, 회원 정보 수정 페이지 제작
- Loading branch information
Showing
21 changed files
with
478 additions
and
131 deletions.
There are no files selected for viewing
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { useNavigate } from 'react-router-dom'; | ||
import { useState } from 'react'; | ||
import { getCookie, removeCookie, setCookie } from './cookie/cookie'; | ||
|
||
// 로그인 되었을 때 상태를 보여주는 SelectBox 제작 | ||
const UserDropdownBox = () => { | ||
const token = getCookie('loginToken'); | ||
const options = ['My 정보 변경', 'My 보호소 이동', '로그아웃']; | ||
const [isDropdownOpen, setIsDropdownOpen] = useState(false); // 드롭다운 메뉴 열림/닫힘 상태 | ||
const navigate = useNavigate(); | ||
const shelterId = getCookie('userAccountInfo'); | ||
const id = shelterId ? shelterId.split(' ')[1] : ''; | ||
|
||
const toggleDropdown = () => { | ||
setIsDropdownOpen(!isDropdownOpen); | ||
}; | ||
|
||
const removeToken = () => { | ||
removeCookie('loginToken'); | ||
removeCookie('userAccountInfo'); | ||
}; | ||
|
||
const handleOptionClick = (option: string) => { | ||
switch (option) { | ||
case 'My 정보 변경': | ||
navigate(`/shelter/${id}/edit`); // 아직 회원정보 수정 페이지 구현 안됨 | ||
break; | ||
case 'My 보호소 이동': | ||
navigate(`/shelter/${id}/1`); | ||
break; | ||
case '로그아웃': | ||
removeToken(); | ||
setCookie('userAccountInfo', 'Not Login'); | ||
window.location.reload(); | ||
break; | ||
default: | ||
break; | ||
} | ||
setIsDropdownOpen(false); | ||
}; | ||
|
||
if (!token) { | ||
return ( | ||
<div className="flex gap-4 font-bold"> | ||
<button | ||
className="border-2 box-content border-brand-color text-brand-color rounded-md py-1 px-4 transition duration-300 hover:bg-brand-color hover:text-white" | ||
onClick={() => navigate('/login')} | ||
> | ||
로그인 | ||
</button> | ||
<button | ||
className="border-brand-color border-2 bg-brand-color text-white rounded-md py-1 px-4 transition duration-300 hover:bg-white hover:text-brand-color" | ||
onClick={() => navigate('/signup')} | ||
> | ||
회원가입 | ||
</button> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<div className="relative inline-block text-left"> | ||
<div> | ||
<button | ||
onClick={toggleDropdown} | ||
type="button" | ||
className="inline-flex justify-center w-full rounded-full border-2 border-gray-300 hover:border-gray-400 shadow-sm p-2 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100" | ||
id="options-menu" | ||
aria-haspopup="listbox" | ||
aria-expanded="true" | ||
> | ||
<img | ||
src="/assets/images/shelterIcon.png" | ||
alt="유저 정보 아이콘" | ||
className="w-8 h-8" | ||
/> | ||
</button> | ||
</div> | ||
|
||
{isDropdownOpen && ( | ||
<div className="origin-top-right absolute border-2 border-gray-300 hover:border-gray-400 right-0 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5"> | ||
<div | ||
className="py-1" | ||
role="menu" | ||
aria-orientation="vertical" | ||
aria-labelledby="options-menu" | ||
> | ||
{options.map((option, index) => ( | ||
<div | ||
key={index} | ||
className="block px-4 py-2 text-sm font-bold text-gray-500 hover:bg-gray-100 hover:text-black cursor-pointer" | ||
onClick={() => handleOptionClick(option)} | ||
role="menuitem" | ||
> | ||
{option} | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default UserDropdownBox; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { setCookie } from 'commons/cookie/cookie'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { useRecoilState, useRecoilValue } from 'recoil'; | ||
import { tokenCheckState } from 'recoil/shelterState'; | ||
|
||
const LoginGuideModal = () => { | ||
const navigate = useNavigate(); | ||
const [isLogined, setIsLogined] = useRecoilState(tokenCheckState); // default : true | ||
|
||
if (isLogined) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<dialog | ||
className="fixed z-50 flex justify-center w-full h-[20vh] opacity-80 hover:opacity-100 bottom-2 rounded-lg border-2 border-gray-300 text-black" | ||
open={isLogined} | ||
> | ||
<div className="modal-content w-[600px] flex flex-col gap-4 justify-center"> | ||
<div className="font-bold text-center text-lg"> | ||
<div>로그인이 만료되었습니다.</div> | ||
<div>다시 로그인 하시겠습니까?</div> | ||
</div> | ||
<div className="flex justify-evenly font-bold "> | ||
<button | ||
className="border-brand-color text-brand-color border-2 rounded-md px-4 py-1 transition duration-300 hover:bg-brand-color hover:text-white " | ||
onClick={() => { | ||
navigate('/login'); | ||
setIsLogined(true); | ||
}} | ||
> | ||
로그인 하기 | ||
</button> | ||
<button | ||
className="bg-brand-color text-white rounded-md px-4 py-1 transition duration-300 hover:bg-white hover:text-brand-color" | ||
onClick={() => { | ||
setCookie('userAccountInfo', 'Not Login'); | ||
setIsLogined(true); | ||
}} | ||
> | ||
로그아웃 유지하기 | ||
</button> | ||
</div> | ||
</div> | ||
</dialog> | ||
); | ||
}; | ||
|
||
export default LoginGuideModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,44 @@ | ||
import { validateExpiredToken } from 'commons/cookie/getUser'; | ||
import { getCookie } from 'commons/cookie/cookie'; | ||
import LoginGuideModal from 'commons/modals/LoginGuideModal'; | ||
import React, { useEffect } from 'react'; | ||
import { Routes } from 'react-router-dom'; | ||
import { Route, Routes } from 'react-router-dom'; | ||
import { useSetRecoilState } from 'recoil'; | ||
import { tokenCheckState } from 'recoil/shelterState'; | ||
|
||
interface LayoutProps { | ||
children: React.ReactNode; | ||
} | ||
|
||
const ValidateCheckLayout: React.FC<LayoutProps> = ({ children }) => { | ||
useEffect(() => { | ||
validateExpiredToken(); | ||
const intervalId = setInterval(validateExpiredToken, 60000 * 30); // 30분에 한 번 | ||
const setIsLogined = useSetRecoilState(tokenCheckState); | ||
const loginToken = getCookie('loginToken'); | ||
const userAccount = getCookie('userAccountInfo'); | ||
|
||
return () => clearInterval(intervalId); | ||
}, []); | ||
useEffect(() => { | ||
if (!loginToken && !userAccount) { | ||
// loginToken이 없으면 모달 열기 | ||
setIsLogined(false); | ||
} | ||
console.log('token 로직 동작'); | ||
}, [loginToken, userAccount]); | ||
|
||
return <Routes>{children}</Routes>; | ||
return ( | ||
<div> | ||
<Routes> | ||
<Route path="/" element={<LoginGuideModal />} />; | ||
<Route path="/pet/:id" element={<LoginGuideModal />} />; | ||
<Route path="/profile" element={<LoginGuideModal />} />; | ||
<Route path="/shelter/:id/:page" element={<LoginGuideModal />} />; | ||
<Route path="/profile/urgent/:page" element={<LoginGuideModal />} />; | ||
<Route path="/profile/new/:page" element={<LoginGuideModal />} />; | ||
<Route path="/register" element={<LoginGuideModal />} />; | ||
<Route path="/find-shelter" element={<LoginGuideModal />} />; | ||
<Route path="/pet-update/:id" element={<LoginGuideModal />} />; | ||
</Routes> | ||
{/* <LoginGuideModal /> */} | ||
<Routes>{children}</Routes> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ValidateCheckLayout; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.