inogen/app/components/dashboard/header.tsx
2025-09-14 17:25:30 +03:30

155 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useState } from "react";
import { useAuth } from "~/contexts/auth-context";
import { Link } from "react-router";
import { cn } from "~/lib/utils";
import { Button } from "~/components/ui/button";
import {
PanelLeft,
Settings,
User,
Menu,
ChevronDown,
Server,
} from "lucide-react";
import apiService from "~/lib/api";
interface HeaderProps {
onToggleSidebar?: () => void;
className?: string;
title?: string;
}
export function Header({
onToggleSidebar,
className,
title = "صفحه اول",
}: HeaderProps) {
const { user } = useAuth();
const [isProfileMenuOpen, setIsProfileMenuOpen] = useState(false);
const [isNotificationOpen, setIsNotificationOpen] = useState(false);
const redirectHandler = async () => {
try {
const getData = await apiService.post('/GenerateSsoCode')
// const url = `http://localhost:3000/redirect/${getData.data}`;
const url = `https://inogen-bpms.pelekan.org/redirect/${getData.data}`;
window.open(url, "_blank");
} catch (error) {
console.log(error);
}
}
return (
<header
className={cn(
"backdrop-blur-sm border-b border-gray-400/30 h-16 flex items-center justify-between px-4 lg:px-6 shadow-sm relative z-30",
className,
)}
>
{/* Left Section */}
<div className="flex items-center gap-4">
{/* Mobile Menu Toggle */}
{onToggleSidebar && (
<Button
variant="ghost"
size="sm"
onClick={onToggleSidebar}
className="lg:hidden"
>
<Menu className="h-5 w-5" />
</Button>
)}
{/* Page Title */}
<h1 className="text-xl flex items-center justify-center gap-4 font-bold text-white font-persian">
<PanelLeft /> {title}
</h1>
</div>
{/* Right Section */}
<div className="flex items-center gap-2">
{/* User Menu */}
<div className="relative">
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="sm"
onClick={() => setIsProfileMenuOpen(!isProfileMenuOpen)}
className="flex items-center gap-2 text-gray-300"
>
<div className="w-8 h-8 bg-gradient-to-r from-emerald-500/20 to-teal-500/20 text-emerald-400 rounded-full flex items-center justify-center">
<User className="h-4 w-4" />
</div>
<div className="hidden sm:block text-right">
<div className="text-sm font-medium font-persian">
{user?.name} {user?.family}
</div>
<div className="text-xs text-gray-400 font-persian">
{user?.username}
</div>
</div>
<ChevronDown className="h-3 w-3" />
</Button>
<button
className="flex w-full items-center gap-2 px-3 py-2 text-sm text-gray-300 hover:bg-gradient-to-r hover:from-emerald-500/10 hover:to-teal-500/10 hover:text-emerald-300 font-persian"
onClick={redirectHandler}>
<Server className="h-4 w-4" />
ورود به سامانه BPMS
</button>
</div>
{/* Profile Dropdown */}
{isProfileMenuOpen && (
<div className="absolute left-1/2 top-full mt-2 w-48 bg-gray-800 border border-emerald-500/30 rounded-lg shadow-lg z-50">
<div className="p-3 border-b border-emerald-500/30">
<div className="text-sm font-medium text-white font-persian">
{user?.name} {user?.family}
</div>
<div className="text-xs text-gray-400 font-persian">
{user?.email}
</div>
</div>
<div className="py-1">
<Link
to="/dashboard/profile"
className="flex items-center gap-2 px-3 py-2 text-sm text-gray-300 hover:bg-gradient-to-r hover:from-emerald-500/10 hover:to-teal-500/10 hover:text-emerald-300 font-persian"
onClick={() => setIsProfileMenuOpen(false)}
>
<User className="h-4 w-4" />
پروفایل کاربری
</Link>
<Link
to="/dashboard/settings"
className="flex items-center gap-2 px-3 py-2 text-sm text-gray-300 hover:bg-gradient-to-r hover:from-emerald-500/10 hover:to-teal-500/10 hover:text-emerald-300 font-persian"
onClick={() => setIsProfileMenuOpen(false)}
>
<Settings className="h-4 w-4" />
تنظیمات
</Link>
</div>
</div>
)}
</div>
</div>
{/* Click outside to close dropdowns */}
{(isProfileMenuOpen || isNotificationOpen) && (
<div
className="fixed inset-0 z-40"
onClick={() => {
setIsProfileMenuOpen(false);
setIsNotificationOpen(false);
}}
/>
)}
</header>
);
}
export default Header;