RJBULK-APP/components/shell/top-bar.tsx
SJCoetz 1efa979443 feat: initial setup of rj bulk supplies backoffice app
Adds complete initial codebase for the RJ Bulk Supplies fuel delivery backoffice:
- Authentication pages and protected route layouts
- Customer, supplier, fuel purchase, and delivery note management
- Custom reporting and customer statement sending tools
- Full UI component library and Tailwind styling
- Server actions, API routes, and PocketBase integration
- Development scripts and project configuration updates
- Updated README and package metadata
2026-07-19 20:38:16 +02:00

80 lines
3 KiB
TypeScript

"use client";
import { useRouter } from "next/navigation";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { LogOut, User as UserIcon, Moon, Sun } from "lucide-react";
import { logoutAction } from "@/actions/auth";
import { Button } from "@/components/ui/button";
import { MobileNav } from "./mobile-nav";
interface TopBarProps {
user: { name?: string; email: string };
}
export function TopBar({ user }: TopBarProps) {
const router = useRouter();
function toggleDark() {
const html = document.documentElement;
html.classList.toggle("dark");
localStorage.setItem("theme", html.classList.contains("dark") ? "dark" : "light");
}
return (
<header className="sticky top-0 z-20 flex h-16 items-center justify-between gap-2 border-b bg-background/95 px-4 md:px-6 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="flex items-center gap-2">
<MobileNav />
</div>
<div className="hidden md:block text-sm text-muted-foreground">
{user.name || user.email}
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="icon" onClick={toggleDark} aria-label="Toggle theme">
<Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm" className="gap-2">
<div className="flex h-7 w-7 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-semibold">
{(user.name || user.email).charAt(0).toUpperCase()}
</div>
<span className="hidden sm:inline text-sm">{user.name || user.email}</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
<DropdownMenuLabel>
<div className="flex flex-col">
<span className="text-sm font-medium">{user.name || "User"}</span>
<span className="text-xs text-muted-foreground">{user.email}</span>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => router.push("/profile")}>
<UserIcon className="mr-2 h-4 w-4" />
Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<form action={logoutAction}>
<DropdownMenuItem asChild>
<button type="submit" className="w-full text-left">
<LogOut className="mr-2 h-4 w-4" />
Log out
</button>
</DropdownMenuItem>
</form>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>
);
}