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
80 lines
3 KiB
TypeScript
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>
|
|
);
|
|
}
|