-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #63 from FRIED-NOTE/58-improvement-add-userprofile…
…-component 58 improvement add userprofile component
- Loading branch information
Showing
16 changed files
with
246 additions
and
30 deletions.
There are no files selected for viewing
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,3 @@ | ||
import axios from 'axios'; | ||
|
||
export default axios.create({}); |
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,46 @@ | ||
import { useContext, useEffect } from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { AuthContext } from '.'; | ||
import { UserSetPropType, useUserState } from './stores'; | ||
|
||
export const useAuth = () => { | ||
const { removeUser, setUser } = useUserState(); | ||
const { token, setToken } = useContext(AuthContext); | ||
|
||
const setLogin = (user: UserSetPropType & { token: string }) => { | ||
setUser(user); | ||
setToken(user.token); | ||
}; | ||
|
||
const setLogout = () => { | ||
removeUser(); | ||
setToken(undefined); | ||
}; | ||
|
||
const updateToken = (token: string) => setToken(token); | ||
|
||
return { token, setLogin, setLogout, updateToken }; | ||
}; | ||
|
||
export const useCurrentUser = ({ | ||
redirectTo = '', | ||
redirectIfFound = false, | ||
} = {}) => { | ||
const { user } = useUserState(); | ||
const navigate = useNavigate(); | ||
|
||
useEffect(() => { | ||
if (!redirectTo || !user) return; | ||
|
||
if ( | ||
// If redirectTo is set, redirect if the user was not found. | ||
(redirectTo && !redirectIfFound && !user?.isLoggedIn) || | ||
// If redirectIfFound is also set, redirect if the user was found | ||
(redirectIfFound && user?.isLoggedIn) | ||
) { | ||
navigate(redirectTo); | ||
} | ||
}, [user, redirectIfFound, redirectTo]); | ||
|
||
return { user }; | ||
}; |
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,62 @@ | ||
import { ReactNode, createContext, useEffect, useMemo, useState } from 'react'; | ||
import instance from '../apis/instance'; | ||
import { useUserState } from './stores'; | ||
|
||
export const AuthContext = createContext<{ | ||
token: string | undefined; | ||
setToken: (token: string | undefined) => void; | ||
}>({ | ||
token: undefined, | ||
setToken: () => { | ||
throw new Error('setToken function must be overridden'); | ||
}, | ||
}); | ||
|
||
export interface AuthProviderProps { | ||
children: ReactNode; | ||
} | ||
|
||
const mockAuthUser = (token: string) => ({ | ||
name: 'hi', | ||
email: '', | ||
profileImage: '', | ||
}); | ||
|
||
function AuthProvider({ children, ...props }: AuthProviderProps) { | ||
const [token, setToken_] = useState( | ||
localStorage.getItem('token') || undefined, | ||
); | ||
|
||
const { removeUser, setUser } = useUserState(); | ||
|
||
const setToken = (token: string | undefined) => { | ||
setToken_(token); | ||
}; | ||
|
||
useEffect(() => { | ||
if (token) { | ||
instance.defaults.headers.common['Authorization'] = `Bearer ${token}`; | ||
localStorage.setItem('token', token); | ||
} else { | ||
delete instance.defaults.headers.common['Authorization']; | ||
localStorage.removeItem('token'); | ||
} | ||
}, [token]); | ||
|
||
useEffect(() => { | ||
if (!token) { | ||
removeUser(); | ||
return; | ||
} | ||
const userData = mockAuthUser(token); | ||
if (userData) setUser(userData); | ||
}, []); | ||
|
||
const contextValue = useMemo(() => ({ token, setToken }), [token]); | ||
|
||
return ( | ||
<AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider> | ||
); | ||
} | ||
|
||
export default AuthProvider; |
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,38 @@ | ||
import { create } from 'zustand'; | ||
import { devtools } from 'zustand/middleware'; | ||
|
||
export interface UserType { | ||
name: string | null; | ||
email: string | null; | ||
profileImage: string | null; | ||
isLoggedIn: boolean; | ||
} | ||
|
||
export type UserSetPropType = Omit<UserType, 'isLoggedIn'>; | ||
|
||
interface UserState { | ||
user: UserType; | ||
setUser: (user: UserSetPropType) => void; | ||
removeUser: () => void; | ||
} | ||
|
||
export const useUserState = create<UserState>()( | ||
devtools((set) => ({ | ||
user: { | ||
isLoggedIn: false, | ||
name: null, | ||
email: null, | ||
profileImage: null, | ||
}, | ||
setUser: (user) => set(() => ({ user: { ...user, isLoggedIn: true } })), | ||
removeUser: () => | ||
set(() => ({ | ||
user: { | ||
isLoggedIn: false, | ||
name: null, | ||
email: null, | ||
profileImage: null, | ||
}, | ||
})), | ||
})), | ||
); |
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 |
---|---|---|
|
@@ -10,6 +10,8 @@ const meta: Meta<typeof TopNav> = { | |
user: { | ||
email: '[email protected]', | ||
name: '테스트 유저', | ||
isLoggedIn: true, | ||
profileImage: '', | ||
}, | ||
navBarMenu: [ | ||
{ label: 'MY RECIPE', path: '/mypage' }, | ||
|
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,17 @@ | ||
import DefaultProfile from '@/assets/default-profile.svg'; | ||
import { useCurrentUser } from '@/auth/hooks'; | ||
import { ImgHTMLAttributes } from 'react'; | ||
|
||
export interface UserProfileProps extends ImgHTMLAttributes<HTMLImageElement> { | ||
width?: number; | ||
} | ||
|
||
function UserProfileImg({ width, ...props }: UserProfileProps) { | ||
const { user } = useCurrentUser(); | ||
|
||
return ( | ||
<img src={user.profileImage || DefaultProfile} css={{ width }} {...props} /> | ||
); | ||
} | ||
|
||
export default UserProfileImg; |
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,6 +1,7 @@ | ||
import { useUserData } from '@/utils/hooks'; | ||
import { useAuth } from '@/auth/hooks'; | ||
import { useUserState } from '@/auth/stores'; | ||
import globalStyles from '@/utils/styles'; | ||
import TopNav, { UserType } from '@copmonents/TopNav/TopNav'; | ||
import TopNav from '@copmonents/TopNav/TopNav'; | ||
import { css } from '@emotion/react'; | ||
import { ReactNode } from 'react'; | ||
import { useLocation } from 'react-router-dom'; | ||
|
@@ -24,7 +25,8 @@ export interface LayoutProps { | |
const EXCEPT_PATH = ['/mypage/initial', '/post']; | ||
|
||
function Layout({ children, ...props }: LayoutProps) { | ||
const [user, setUser] = useUserData<UserType>(); | ||
const { user } = useUserState(); | ||
const { setLogin, setLogout } = useAuth(); | ||
const locaton = useLocation(); | ||
|
||
const isExceptPath = EXCEPT_PATH.includes(locaton.pathname); | ||
|
@@ -39,8 +41,15 @@ function Layout({ children, ...props }: LayoutProps) { | |
{ label: 'INVENTORY', path: '/inventory' }, | ||
{ label: 'SEARCH', path: '/search' }, | ||
]} | ||
onLoginClick={() => setUser({ email: '[email protected]', name: 'testUser' })} | ||
onLogoutClick={() => setUser(null)} | ||
onLoginClick={() => | ||
setLogin({ | ||
name: 'hi', | ||
email: '', | ||
profileImage: '', | ||
token: 'temp token', | ||
}) | ||
} | ||
onLogoutClick={setLogout} | ||
/> | ||
<div css={[styles.body.default, !isExceptPath && styles.body.mediaQuery]}> | ||
{children} | ||
|
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
Oops, something went wrong.