154 lines
5.1 KiB
TypeScript
154 lines
5.1 KiB
TypeScript
/**
|
|
* @file features/layout/components/header.tsx
|
|
* @description 애플리케이션 상단 헤더 컴포넌트
|
|
*/
|
|
|
|
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";
|
|
import { cn } from "@/lib/utils";
|
|
import { Logo } from "@/features/layout/components/Logo";
|
|
|
|
|
|
import { MarketIndices } from "@/features/layout/components/market-indices";
|
|
|
|
interface HeaderProps {
|
|
/** 현재 로그인 사용자 정보(null 가능) */
|
|
user: User | null;
|
|
/** 대시보드 링크 버튼 노출 여부 */
|
|
showDashboardLink?: boolean;
|
|
/** 홈 랜딩에서 배경과 자연스럽게 섞이는 헤더 모드 */
|
|
blendWithBackground?: boolean;
|
|
}
|
|
|
|
/**
|
|
* 글로벌 헤더 컴포넌트
|
|
* @param user Supabase User 객체
|
|
* @param showDashboardLink 대시보드 버튼 노출 여부
|
|
* @param blendWithBackground 홈 랜딩 전용 반투명 모드
|
|
* @returns Header JSX
|
|
* @see app/(home)/page.tsx 홈 랜딩에서 blendWithBackground=true로 호출
|
|
*/
|
|
export function Header({
|
|
user,
|
|
showDashboardLink = false,
|
|
blendWithBackground = false,
|
|
}: HeaderProps) {
|
|
return (
|
|
<header
|
|
className={cn(
|
|
"fixed inset-x-0 top-0 z-50 w-full",
|
|
blendWithBackground
|
|
? "text-white"
|
|
: "border-b border-border/40 bg-background/80 backdrop-blur-xl supports-backdrop-filter:bg-background/60",
|
|
)}
|
|
>
|
|
{blendWithBackground && (
|
|
<div
|
|
aria-hidden="true"
|
|
className="pointer-events-none absolute inset-x-0 top-0 h-24 bg-linear-to-b from-black/70 via-black/35 to-transparent"
|
|
/>
|
|
)}
|
|
|
|
<div
|
|
className={cn(
|
|
"relative z-10 flex h-16 w-full items-center justify-between px-4 md:px-6",
|
|
blendWithBackground
|
|
? "bg-black/30 backdrop-blur-xl supports-backdrop-filter:bg-black/20"
|
|
: "",
|
|
)}
|
|
>
|
|
{/* ========== LEFT: LOGO SECTION ========== */}
|
|
<Link href={AUTH_ROUTES.HOME} className="group flex items-center gap-2">
|
|
<Logo
|
|
variant="full"
|
|
className="h-10 text-xl transition-transform duration-200 group-hover:scale-105"
|
|
blendWithBackground={blendWithBackground}
|
|
/>
|
|
</Link>
|
|
|
|
{/* ========== CENTER: MARKET INDICES ========== */}
|
|
{!blendWithBackground && user && (
|
|
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
|
|
<MarketIndices />
|
|
</div>
|
|
)}
|
|
|
|
{/* ========== RIGHT: ACTION SECTION ========== */}
|
|
<div
|
|
className={cn(
|
|
"flex items-center gap-2 sm:gap-3",
|
|
blendWithBackground ? "text-white" : "",
|
|
)}
|
|
>
|
|
<ThemeToggle
|
|
className={cn(
|
|
blendWithBackground
|
|
? "rounded-full border border-white/40 bg-black/50 text-white! backdrop-blur-md hover:bg-black/65 focus-visible:ring-white/80"
|
|
: "",
|
|
)}
|
|
iconClassName={blendWithBackground ? "text-white!" : undefined}
|
|
/>
|
|
|
|
{user ? (
|
|
<>
|
|
<SessionTimer blendWithBackground={blendWithBackground} />
|
|
|
|
{showDashboardLink && (
|
|
<Button
|
|
asChild
|
|
variant="ghost"
|
|
size="sm"
|
|
className={cn(
|
|
"hidden font-medium sm:inline-flex",
|
|
blendWithBackground
|
|
? "rounded-full border border-white/40 bg-black/50 text-white! backdrop-blur-md [text-shadow:0_1px_8px_rgba(0,0,0,0.45)] hover:bg-black/65 hover:text-white!"
|
|
: "",
|
|
)}
|
|
>
|
|
<Link href={AUTH_ROUTES.DASHBOARD}>시작하기</Link>
|
|
</Button>
|
|
)}
|
|
|
|
<UserMenu user={user} blendWithBackground={blendWithBackground} />
|
|
</>
|
|
) : (
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
asChild
|
|
variant="ghost"
|
|
size="sm"
|
|
className={cn(
|
|
"hidden sm:inline-flex",
|
|
blendWithBackground
|
|
? "rounded-full border border-white/40 bg-black/50 text-white! backdrop-blur-md hover:bg-black/65 hover:text-white!"
|
|
: "",
|
|
)}
|
|
>
|
|
<Link href={AUTH_ROUTES.LOGIN}>로그인</Link>
|
|
</Button>
|
|
<Button
|
|
asChild
|
|
size="sm"
|
|
className={cn(
|
|
"rounded-full px-6",
|
|
blendWithBackground
|
|
? "bg-brand-500/90 text-white shadow-lg shadow-brand-700/40 hover:bg-brand-400"
|
|
: "",
|
|
)}
|
|
>
|
|
<Link href={AUTH_ROUTES.SIGNUP}>회원가입</Link>
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|
|
|