Files
vfxreview/components/layout/Header.tsx
twotalesanimation 40b99f3add
Deploy / deploy (push) Successful in 3m19s
feat(ui): usable on phones without changing the desktop layout
At phone width the sidebar stayed 240px wide, leaving pages a ~135px strip.
Below md it is now hidden behind a menu button in the header and opens as a
drawer (closes on navigation, backdrop, X or Escape); from md up the sidebar
is unchanged. Page wrappers use p-4 on phones and keep p-6/p-8 from md.

Shot detail: on phones the thumbnail takes the full width with the details
below it instead of pushing them off screen, the action buttons wrap, and
the tab bar scrolls sideways. Desktop sizing is kept as it was.

Every change is behind a md: breakpoint, so the desktop layout is the same.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 06:56:38 +02:00

118 lines
4.3 KiB
TypeScript

"use client";
import { useSession, signOut } from "next-auth/react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { NotificationBell } from "@/components/notifications/NotificationBell";
import { getInitials } from "@/lib/utils";
import { LogOut, User, Settings, Menu } from "lucide-react";
import Link from "next/link";
import { useMobileNav } from "@/components/layout/MobileNav";
interface HeaderProps {
title?: string;
breadcrumbs?: { label: string; href?: string }[];
}
export function Header({ title, breadcrumbs }: HeaderProps) {
const { data: session } = useSession();
const user = session?.user;
const { setOpen: setMobileNavOpen } = useMobileNav();
return (
<header className="flex h-14 items-center justify-between border-b border-zinc-800 bg-zinc-950 px-4 md:px-6">
{/* Left: Title / Breadcrumbs */}
<div className="flex items-center gap-2 min-w-0">
{/* Phones only: the sidebar is hidden below md and opens as a drawer. */}
<button
type="button"
onClick={() => setMobileNavOpen(true)}
className="md:hidden -ml-2 rounded-md p-2 text-zinc-400 hover:bg-zinc-800 hover:text-white"
aria-label="Open menu"
>
<Menu className="h-5 w-5" />
</button>
{breadcrumbs ? (
<nav className="flex items-center gap-1.5 text-sm">
{breadcrumbs.map((crumb, i) => (
<span key={i} className="flex items-center gap-1.5">
{i > 0 && <span className="text-muted-foreground">/</span>}
{crumb.href ? (
<Link
href={crumb.href}
className="text-muted-foreground hover:text-foreground transition-colors"
>
{crumb.label}
</Link>
) : (
<span className="text-foreground font-medium truncate">
{crumb.label}
</span>
)}
</span>
))}
</nav>
) : (
title && (
<h1 className="text-sm font-semibold truncate">{title}</h1>
)
)}
</div>
{/* Right: Notifications + User menu */}
<div className="flex items-center gap-3">
<NotificationBell />
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-secondary transition-colors">
<Avatar className="h-7 w-7">
{user?.image && <AvatarImage src={user.image} alt={user.name ?? ""} />}
<AvatarFallback className="text-xs">
{getInitials(user?.name)}
</AvatarFallback>
</Avatar>
<div className="hidden sm:block text-left">
<p className="text-xs font-medium leading-none">{user?.name ?? user?.email}</p>
<p className="text-xs text-muted-foreground capitalize">
{user?.role?.toLowerCase()}
</p>
</div>
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48">
<DropdownMenuLabel>
<p className="font-medium truncate">{user?.name}</p>
<p className="text-xs text-muted-foreground font-normal truncate">
{user?.email}
</p>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link href="/settings" className="flex items-center gap-2 cursor-pointer">
<Settings className="h-4 w-4" />
Settings
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-destructive focus:text-destructive cursor-pointer"
onClick={() => signOut({ callbackUrl: "/login" })}
>
<LogOut className="h-4 w-4 mr-2" />
Sign out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>
);
}