Files
auto-trade/features/layout/components/header.tsx

94 lines
3.5 KiB
TypeScript

/**
* @file features/layout/components/header.tsx
* @description 애플리케이션 최상단 헤더 컴포넌트 (네비게이션, 테마, 유저 메뉴)
* @remarks
* - [레이어] Components/UI/Layout
* - [사용자 행동] 홈 이동, 테마 변경, 로그인/회원가입 이동, 대시보드 이동
* - [데이터 흐름] User Prop -> UI Conditional Rendering
* - [연관 파일] layout.tsx, session-timer.tsx, user-menu.tsx
*/
import Link from "next/link";
import { User } from "@supabase/supabase-js";
import { AUTH_ROUTES } from "@/features/auth/constants";
import { UserMenu } from "@/features/layout/components/user-menu";
import { ThemeToggle } from "@/components/theme-toggle";
import { Button } from "@/components/ui/button";
import { SessionTimer } from "@/features/auth/components/session-timer";
interface HeaderProps {
/** 현재 로그인한 사용자 정보 (없으면 null) */
user: User | null;
/** 대시보드 링크 표시 여부 */
showDashboardLink?: boolean;
}
/**
* 글로벌 헤더 컴포넌트
* @param user Supabase User 객체
* @param showDashboardLink 대시보드 바로가기 버튼 노출 여부
* @returns Header JSX
* @see layout.tsx - RootLayout에서 데이터 주입하여 호출
*/
export function Header({ user, showDashboardLink = false }: HeaderProps) {
return (
<header className="fixed top-0 z-40 w-full border-b border-border/40 bg-background/80 backdrop-blur-xl supports-backdrop-filter:bg-background/60">
<div className="flex h-16 w-full items-center justify-between px-4 md:px-6">
{/* ========== 좌측: 로고 영역 ========== */}
<Link href={AUTH_ROUTES.HOME} className="flex items-center gap-2 group">
<div className="flex h-9 w-9 items-center justify-center rounded-xl bg-primary/10 transition-transform duration-200 group-hover:scale-110">
<div className="h-5 w-5 rounded-lg bg-linear-to-br from-indigo-500 to-purple-600" />
</div>
<span className="text-xl font-bold tracking-tight text-foreground transition-colors group-hover:text-primary">
AutoTrade
</span>
</Link>
{/* ========== 우측: 액션 버튼 영역 ========== */}
<div className="flex items-center gap-4">
{/* 테마 토글 */}
<ThemeToggle />
{user ? (
// [Case 1] 로그인 상태
<>
{/* 세션 타임아웃 타이머 */}
<SessionTimer />
{showDashboardLink && (
<Button
asChild
variant="ghost"
size="sm"
className="hidden sm:inline-flex"
>
<Link href={AUTH_ROUTES.DASHBOARD}></Link>
</Button>
)}
{/* 사용자 드롭다운 메뉴 */}
<UserMenu user={user} />
</>
) : (
// [Case 2] 비로그인 상태
<div className="flex items-center gap-2">
<Button
asChild
variant="ghost"
size="sm"
className="hidden sm:inline-flex"
>
<Link href={AUTH_ROUTES.LOGIN}></Link>
</Button>
<Button asChild size="sm" className="rounded-full px-6">
<Link href={AUTH_ROUTES.SIGNUP}></Link>
</Button>
</div>
)}
</div>
</div>
</header>
);
}