-
Notifications
You must be signed in to change notification settings - Fork 3
fix: 로그아웃 기능 사이드바 내장 기능으로 구현, 마이페이지및 자유게시판 사이드바 드롭다운 사용, 변경시 성공 토스트 구현 #82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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,8 +1,10 @@ | ||
| 'use client'; | ||
|
|
||
| import { type ReactNode, useState, useRef, useEffect } from 'react'; | ||
| import { type ReactNode, useState, useRef, useEffect, useCallback } from 'react'; | ||
| import { useRouter } from 'next/navigation'; | ||
| import Image from 'next/image'; | ||
| import clsx from 'clsx'; | ||
| import MobileDrawer from './MobileDrawer'; | ||
|
|
||
| import styles from './styles/MobileHeader.module.css'; | ||
| import logoSmall from '@/assets/logos/logoSmall.svg'; | ||
|
|
@@ -15,8 +17,10 @@ type MobileHeaderProps = { | |
| isLoggedIn?: boolean; | ||
| /** 프로필 이미지 (ReactNode로 자유롭게 주입, 미전달 시 기본 아이콘) */ | ||
| profileImage?: ReactNode; | ||
| /** 햄버거 메뉴 버튼 클릭 시 호출되는 콜백 */ | ||
| /** @deprecated 내부 드로어로 대체됨. 호환성을 위해 유지 */ | ||
| onMenuClick?: () => void; | ||
| /** 드로어 내부 콘텐츠 (전달 시 햄버거 메뉴 클릭으로 드로어 표시) */ | ||
| drawerContent?: ReactNode; | ||
| /** 프로필 버튼 클릭 시 호출되는 콜백 */ | ||
| onProfileClick?: () => void; | ||
| /** 로그아웃 클릭 시 호출되는 콜백 */ | ||
|
|
@@ -37,16 +41,27 @@ type MobileHeaderProps = { | |
| export default function MobileHeader({ | ||
| isLoggedIn, | ||
| profileImage, | ||
| onMenuClick, | ||
| drawerContent, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| onProfileClick, | ||
| onLogout, | ||
| onLogoClick, | ||
| logoWidth = 102, | ||
| logoHeight = 20, | ||
| }: MobileHeaderProps) { | ||
| const router = useRouter(); | ||
| const [showProfileMenu, setShowProfileMenu] = useState(false); | ||
| const [isDrawerOpen, setIsDrawerOpen] = useState(false); | ||
| const profileMenuRef = useRef<HTMLDivElement>(null); | ||
|
|
||
| const defaultLogout = useCallback(async () => { | ||
| await fetch('/api/auth/logout', { method: 'POST' }); | ||
| router.push('/login'); | ||
| }, [router]); | ||
|
|
||
| const handleLogout = onLogout ?? defaultLogout; | ||
| const handleProfileClick = onProfileClick ?? (() => router.push('/mypage')); | ||
| const handleLogoClick = onLogoClick ?? (() => router.push('/addteam')); | ||
|
Comment on lines
+56
to
+63
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| useEffect(() => { | ||
| if (!showProfileMenu) return; | ||
| const handleClickOutside = (e: MouseEvent) => { | ||
|
|
@@ -61,12 +76,7 @@ export default function MobileHeader({ | |
| if (!isLoggedIn) { | ||
| return ( | ||
| <header className={styles.header}> | ||
| <div | ||
| className={styles.logo} | ||
| onClick={onLogoClick} | ||
| role={onLogoClick ? 'button' : undefined} | ||
| tabIndex={onLogoClick ? 0 : undefined} | ||
| > | ||
| <div className={styles.logo} onClick={handleLogoClick} role="button" tabIndex={0}> | ||
| <Image src={logoSmall} alt="COWORKERS" width={logoWidth} height={logoHeight} /> | ||
| </div> | ||
| </header> | ||
|
|
@@ -79,17 +89,12 @@ export default function MobileHeader({ | |
| <button | ||
| type="button" | ||
| className={styles.menuButton} | ||
| onClick={onMenuClick} | ||
| onClick={() => setIsDrawerOpen(true)} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| aria-label="메뉴 열기" | ||
| > | ||
| <Image src={hamburger} alt="" width={24} height={24} /> | ||
| </button> | ||
| <div | ||
| className={styles.logo} | ||
| onClick={onLogoClick} | ||
| role={onLogoClick ? 'button' : undefined} | ||
| tabIndex={onLogoClick ? 0 : undefined} | ||
| > | ||
| <div className={styles.logo} onClick={handleLogoClick} role="button" tabIndex={0}> | ||
| <Image src={logoIcon} alt="COWORKERS" width={24} height={24} /> | ||
| </div> | ||
| </div> | ||
|
|
@@ -109,7 +114,7 @@ export default function MobileHeader({ | |
| className={styles.profileMenuItem} | ||
| onClick={() => { | ||
| setShowProfileMenu(false); | ||
| onProfileClick?.(); | ||
| handleProfileClick(); | ||
| }} | ||
| > | ||
| 마이페이지 | ||
|
|
@@ -119,14 +124,19 @@ export default function MobileHeader({ | |
| className={`${styles.profileMenuItem} ${styles.profileMenuDanger}`} | ||
| onClick={() => { | ||
| setShowProfileMenu(false); | ||
| onLogout?.(); | ||
| handleLogout(); | ||
| }} | ||
| > | ||
| 로그아웃 | ||
| </button> | ||
| </div> | ||
| )} | ||
| </div> | ||
| {drawerContent && ( | ||
| <MobileDrawer isOpen={isDrawerOpen} onClose={() => setIsDrawerOpen(false)}> | ||
| {drawerContent} | ||
| </MobileDrawer> | ||
| )} | ||
| </header> | ||
| ); | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasChanges에 의한 안내 토스트와successToast가 동시에 활성화될 경우, 두 토스트가 겹쳐서 보일 수 있습니다.toastWrapper의 CSS가 스택 구조를 지원하지 않는다면, 하나의 토스트 상태 변수를 사용하여 메시지 내용만 교체하는 방식으로 개선하는 것을 추천합니다.