124 lines
3.1 KiB
TypeScript
124 lines
3.1 KiB
TypeScript
import { useState } from 'react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import Logo from '../common/Logo'
|
|
import SideMenu from './SideMenu'
|
|
import styles from './Header.module.css'
|
|
|
|
interface HeaderProps {
|
|
showMenu?: boolean
|
|
showBackButton?: boolean
|
|
logoPosition?: 'left' | 'center'
|
|
title?: string
|
|
onMenuClick?: () => void
|
|
onBackClick?: () => void
|
|
}
|
|
|
|
export default function Header({
|
|
showMenu = false,
|
|
showBackButton = false,
|
|
logoPosition = 'center',
|
|
title,
|
|
onMenuClick,
|
|
onBackClick
|
|
}: HeaderProps) {
|
|
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
|
const navigate = useNavigate()
|
|
|
|
const handleMenuClick = () => {
|
|
if (onMenuClick) {
|
|
onMenuClick()
|
|
} else {
|
|
setIsMenuOpen(true)
|
|
}
|
|
}
|
|
|
|
const handleBackClick = () => {
|
|
if (onBackClick) {
|
|
onBackClick()
|
|
} else {
|
|
navigate(-1)
|
|
}
|
|
}
|
|
|
|
// MK-002 layout: Logo left, Menu right
|
|
if (logoPosition === 'left') {
|
|
return (
|
|
<>
|
|
<header className={styles.header}>
|
|
<Logo variant="light" />
|
|
<div className={styles.spacer} />
|
|
{showMenu && (
|
|
<button
|
|
className={styles.iconButton}
|
|
onClick={handleMenuClick}
|
|
aria-label="메뉴 열기"
|
|
>
|
|
<HamburgerIcon />
|
|
</button>
|
|
)}
|
|
</header>
|
|
<SideMenu isOpen={isMenuOpen} onClose={() => setIsMenuOpen(false)} />
|
|
</>
|
|
)
|
|
}
|
|
|
|
// MK-003 layout: Back button left, Logo center, Menu right
|
|
return (
|
|
<>
|
|
<header className={styles.header}>
|
|
{/* Left: Back button or spacer */}
|
|
{showBackButton ? (
|
|
<button
|
|
className={styles.iconButton}
|
|
onClick={handleBackClick}
|
|
aria-label="뒤로 가기"
|
|
>
|
|
<BackIcon />
|
|
</button>
|
|
) : (
|
|
<div className={styles.spacer} />
|
|
)}
|
|
|
|
{/* Center: Logo or Title */}
|
|
{title ? (
|
|
<h1 className={styles.title}>{title}</h1>
|
|
) : (
|
|
<Logo variant="light" />
|
|
)}
|
|
|
|
{/* Right: Menu button or spacer */}
|
|
{showMenu ? (
|
|
<button
|
|
className={styles.iconButton}
|
|
onClick={handleMenuClick}
|
|
aria-label="메뉴 열기"
|
|
>
|
|
<HamburgerIcon />
|
|
</button>
|
|
) : (
|
|
<div className={styles.spacer} />
|
|
)}
|
|
</header>
|
|
<SideMenu isOpen={isMenuOpen} onClose={() => setIsMenuOpen(false)} />
|
|
</>
|
|
)
|
|
}
|
|
|
|
function HamburgerIcon() {
|
|
return (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M21 5H3" stroke="white" strokeWidth="2" strokeLinecap="round"/>
|
|
<path d="M21 12H3" stroke="white" strokeWidth="2" strokeLinecap="round"/>
|
|
<path d="M21 19H3" stroke="white" strokeWidth="2" strokeLinecap="round"/>
|
|
</svg>
|
|
)
|
|
}
|
|
|
|
function BackIcon() {
|
|
return (
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M15 19L8 12L15 5" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
</svg>
|
|
)
|
|
}
|