94 lines
3.5 KiB
TypeScript
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-brand-500 to-brand-700" />
|
|
</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>
|
|
);
|
|
}
|