Files
hellojewellers/src/components/TopNavBar.tsx
priyanshuvish d58c08ce28 first commit
2025-10-14 12:07:18 +05:30

156 lines
5.7 KiB
TypeScript

import { useState } from "react";
import { Search, Bell, ChevronDown, Moon, Sun } from "lucide-react";
import { Input } from "./ui/input";
import { Avatar, AvatarFallback } from "./ui/avatar";
import { Button } from "./ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "./ui/dropdown-menu";
import { Badge } from "./ui/badge";
interface TopNavBarProps {
userName: string;
userEmail: string;
currentTenant: string;
tenants: { id: string; name: string; role: string }[];
onTenantSwitch: (tenantId: string) => void;
notificationCount?: number;
theme: "light" | "dark";
onThemeToggle: () => void;
}
export function TopNavBar({
userName,
userEmail,
currentTenant,
tenants,
onTenantSwitch,
notificationCount = 0,
theme,
onThemeToggle,
}: TopNavBarProps) {
const [searchOpen, setSearchOpen] = useState(false);
const initials = userName
.split(" ")
.map((n) => n[0])
.join("")
.toUpperCase();
return (
<div className="sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="container mx-auto px-4 lg:px-8">
<div className="flex h-16 items-center justify-between gap-4">
{/* Logo */}
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-[10px] bg-primary flex items-center justify-center">
<span className="text-primary-foreground">H</span>
</div>
<span className="hidden sm:inline">Hello Jewellers</span>
</div>
{/* Search */}
<div className="flex-1 max-w-md hidden md:block">
<div className="relative">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
<Input
placeholder="Global search..."
className="pl-10"
onFocus={() => setSearchOpen(true)}
/>
</div>
</div>
{/* Right side */}
<div className="flex items-center gap-2">
{/* Tenant Switcher */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="hidden lg:flex items-center gap-2">
<span className="text-[14px] max-w-[150px] truncate">{currentTenant}</span>
<ChevronDown className="w-4 h-4 text-muted-foreground" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[280px]">
<DropdownMenuLabel>Switch Tenant</DropdownMenuLabel>
<DropdownMenuSeparator />
{tenants.map((tenant) => (
<DropdownMenuItem
key={tenant.id}
onClick={() => onTenantSwitch(tenant.id)}
className="flex items-center justify-between"
>
<div className="flex flex-col gap-1">
<span className="text-[14px]">{tenant.name}</span>
<span className="text-[12px] text-muted-foreground">{tenant.role}</span>
</div>
{tenant.name === currentTenant && (
<Badge variant="secondary" className="text-[10px]">
Active
</Badge>
)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
{/* Theme Toggle */}
<Button
variant="ghost"
size="icon"
onClick={onThemeToggle}
className="hidden sm:flex"
>
{theme === "light" ? (
<Moon className="w-5 h-5" />
) : (
<Sun className="w-5 h-5" />
)}
</Button>
{/* Notifications */}
<Button variant="ghost" size="icon" className="relative">
<Bell className="w-5 h-5" />
{notificationCount > 0 && (
<span className="absolute -top-1 -right-1 w-5 h-5 bg-destructive text-destructive-foreground rounded-full flex items-center justify-center text-[10px]">
{notificationCount > 9 ? "9+" : notificationCount}
</span>
)}
</Button>
{/* User Menu */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="flex items-center gap-2">
<Avatar className="w-8 h-8">
<AvatarFallback>{initials}</AvatarFallback>
</Avatar>
<ChevronDown className="w-4 h-4 text-muted-foreground hidden sm:block" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[240px]">
<DropdownMenuLabel>
<div className="flex flex-col gap-1">
<span>{userName}</span>
<span className="text-[12px] text-muted-foreground">{userEmail}</span>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile Settings</DropdownMenuItem>
<DropdownMenuItem>Preferences</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-destructive">Sign Out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</div>
</div>
);
}