diff --git a/frontend/src/context/AuthProvider.tsx b/frontend/src/context/AuthProvider.tsx index 0b9bafb1a..baa57a1ed 100644 --- a/frontend/src/context/AuthProvider.tsx +++ b/frontend/src/context/AuthProvider.tsx @@ -1,7 +1,7 @@ import { useState, createContext, ReactElement } from 'react'; export type AuthUser = { - userId: string; + userId: number; userName: string; profileImg: string; accessToken: string; @@ -9,6 +9,7 @@ export type AuthUser = { export type AuthContextType = { auth: AuthUser | null; + isAuthenticated: boolean; setAuth: React.Dispatch>; login: (authUser: AuthUser) => void; logout: () => void; @@ -17,18 +18,33 @@ export type AuthContextType = { export const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactElement }) { - const [auth, setAuth] = useState(null); + const [isAuthenticated, setIsAuthenticated] = useState( + localStorage.getItem('userId') ? true : false + ); + const [auth, setAuth] = useState( + localStorage.getItem('userId') + ? { + userId: JSON.parse(localStorage.getItem('userId')!) as number, + userName: localStorage.getItem('userName') as string, + profileImg: localStorage.getItem('profileImg') as string, + accessToken: localStorage.getItem('accessToken') as string, + } + : null + ); const login = (authUser: AuthUser) => { + setIsAuthenticated(true); setAuth(authUser); }; const logout = () => { + setIsAuthenticated(false); setAuth(null); }; return ( - + {children} ); diff --git a/frontend/src/pages/Issues.tsx b/frontend/src/pages/Issues.tsx index a771949f3..05c27cab8 100644 --- a/frontend/src/pages/Issues.tsx +++ b/frontend/src/pages/Issues.tsx @@ -1,5 +1,7 @@ import { useContext, useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import { AppContext } from '../main'; +import useAuth from '../hooks/useAuth'; import Header from '../components/landmark/Header'; import IssueTable from '../components/issues/IssueTable'; import Main from '../components/landmark/Main'; @@ -16,7 +18,9 @@ import useAxiosPrivate from '../hooks/useAxiosPrivate'; export default function Issues() { const { util } = useContext(AppContext); + const { auth, logout } = useAuth(); const logo = (util.getLogoByTheme() as ContextLogo).medium; + const navigate = useNavigate(); const axiosPrivate = useAxiosPrivate(); const [data, setData] = useState({ @@ -99,6 +103,28 @@ export default function Issues() { // }; // fetchData(); // }, []); + const handleLogout = async () => { + if (!auth) { + return; + } + + try { + const res = await axiosPrivate.post('/api/logout', null, { + headers: { 'Content-Type': 'application/json' }, + withCredentials: true, + }); + + if (res.status === 200) { + localStorage.clear(); + logout(); + navigate('/login'); + } else { + console.error('로그아웃 실패:', res.status); + } + } catch (err) { + console.error('로그아웃 에러:', err); + } + }; return ( @@ -106,6 +132,9 @@ export default function Issues() { 이슈트래커 +
{/* profile */} popopo diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index 3f5cbbb80..ca85f0053 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -49,6 +49,9 @@ export default function Login() { ); if (res.status === 200) { + localStorage.setItem('userId', res.data.message.userId); + localStorage.setItem('userName', res.data.message.userName); + localStorage.setItem('profileImg', res.data.message.profileImgUrl); localStorage.setItem('accessToken', res.data.message.accessToken); localStorage.setItem('refreshToken', res.data.message.refreshToken); login({ @@ -105,7 +108,7 @@ export default function Login() { ) : (