"use client"; import { useState, useEffect } from "react"; import { motion, AnimatePresence, Variants } from "framer-motion"; import { useNavigate } from "react-router-dom"; import { useAuthUser } from "@/shared/hooks/useAuthUser"; import { useTranslation } from "react-i18next"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/shared/common/ui/select"; import { toast } from "sonner"; import { ChevronDown, FileText, Menu, X, User, UserPlus as UserPen, Key, LogOut, Cog, Bolt, Globe, Moon, Sun, } from "lucide-react"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/shared/common/ui/dropdown-menu"; import { Button } from "@/shared/common/ui/button"; import { useTheme } from "@/user-management/web-Management/hooks/useTheme"; import { useLocalizedName } from "@/shared/common/localizedName"; import { useModules } from "@/user-management/web-Management/hooks/useModules"; import { useDarkMode } from "@/shared/hooks/useDarkMode"; import { useTenantConfig, resolveModuleConfig, } from "@/layout/components/TenantConfig"; import { UI_LANGUAGE_OPTIONS, resolveUiLanguage, } from "@/shared/i18n/uiLanguages"; interface NavItem { id: string; label?: string; path?: string; link?: string; requiresCompleteRegistration?: true; children?: NavItem[]; name?: { am: string; en: string; }; description?: string; } const languageOptions = UI_LANGUAGE_OPTIONS; const Header = () => { const [activeTab, setActiveTab] = useState("overview"); const [scrolled, setScrolled] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [openDropdown, setOpenDropdown] = useState(null); const navigate = useNavigate(); const { items: item } = useTheme(); const { userDetails, logout } = useAuthUser(); const { t, i18n } = useTranslation(); const currentLanguage = resolveUiLanguage(i18n.language); const { config: tenantConfig } = useTenantConfig(); const moduleConfig = resolveModuleConfig(tenantConfig); const localizedName = useLocalizedName(); const hasCompletedRegistration = userDetails?.hasFinishedRegistration; const baseParams = { isActive: true, }; const { items: modules } = useModules(baseParams); const fullName = localizedName(userDetails?.name) || t("header.user"); const splittedName = fullName.trim().split(" "); const initials = splittedName.length === 1 ? splittedName[0][0] : `${splittedName[0][0]}${splittedName[1][0]}`; const changeLanguage = (lng: string) => { i18n.changeLanguage(lng); }; const handleLogout = () => { logout(); }; const { isDarkMode, toggleDarkMode } = useDarkMode(); useEffect(() => { if (!localStorage.getItem("i18nextLng")) { i18n.changeLanguage("am"); localStorage.setItem("i18nextLng", "am"); } }, [i18n]); useEffect(() => { const handleScroll = () => { setScrolled(window.scrollY > 10); }; window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); const isSuperAdmin = userDetails?.roles?.some( (role) => role.key === "super_admin", ); const isOrgAdmin = userDetails?.roles?.some( (role) => role.key === "unit_admin" || role.key === "organization_admin", ); const navItems: NavItem[] = [ { id: "Modules", label: t("nav.modules"), children: [ ...(moduleConfig.recordManagement ? [ { id: "recordManagement", label: t("nav.Record Management"), path: "/record-management/dashboard", description: t("msg.recordDes"), }, ] : []), ...(moduleConfig.performance ? [ { id: "performanceManagement", label: t("nav.PerformanceManagement"), path: "/performance-management/plan-years", description: t("nav.PerformanceManagement"), }, ] : []), ...(moduleConfig.objective ? [ { id: "objectiveManagement", label: t("nav.objectiveManagement"), path: "/objective-management/plan-years", description: t("nav.objectiveManagement"), }, ] : []), ...(moduleConfig.dms ? [ { id: "documentManagement", label: t("nav.DocumentManagement"), path: "/dms/dashboard", description: t("nav.DocumentManagement"), }, ] : []), ...(isOrgAdmin && moduleConfig.siteManagement ? [ { id: "orgAdmin", label: t("nav.admin"), path: "/user-management/user_management-dashboard", description: t("msg.orgAdminDes"), }, ] : []), ...(isSuperAdmin ? [ { id: "superAdmin", label: t("OrganizationAdmin"), path: "/user-management/dashboard", }, ] : []), ], }, { id: "OfficeHeadMessage", label: t("nav.officeHeadMessage") }, { id: "DeputyMessage", label: t("nav.deputyMessage") }, { id: "OrganizationGoal", label: t("nav.orgGoal"), }, { id: "NewsSection", label: t("nav.news") }, ...(modules && modules.length > 0 ? [ { id: "Other", label: t("nav.other"), children: modules?.map((i) => ({ id: i.id, name: i.label, link: i.link, description: localizedName(i.description), })) || [], }, ] : []), ]; const handleNavClick = (item: NavItem) => { if (item.requiresCompleteRegistration && !hasCompletedRegistration) { toast.error(t("registration.registrationRequired")); return; } if (item.path) { navigate(item.path); setMobileMenuOpen(false); return; } if (item.link) { let url = item.link.trim(); // 🧹 Fix common typos like "https//:" or "http//:" url = url.replace(/^https?\/\/:/i, "https://"); // 🌐 If it doesn't start with http/https, add https:// if (!/^https?:\/\//i.test(url)) { url = `https://${url.replace(/^\/+/, "")}`; // remove leading slashes } // ✅ Finally open the link safely in a new tab window.open(url, "_blank", "noopener,noreferrer"); setMobileMenuOpen(false); } }; const mobileMenuVariants = { hidden: { opacity: 0, height: 0, transition: { duration: 0.3, when: "afterChildren" }, }, visible: { opacity: 1, height: "auto", transition: { duration: 0.3, when: "beforeChildren", staggerChildren: 0.08, }, }, }; const mobileItemVariants: Variants = { hidden: { x: -20, opacity: 0 }, visible: { x: 0, opacity: 1, transition: { type: "spring" as const, stiffness: 300, damping: 30 }, }, }; const servicesVariants = { hidden: { opacity: 0, y: -15, scale: 0.92 }, visible: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.25, staggerChildren: 0.06 }, }, }; const serviceItemVariants = { hidden: { opacity: 0, x: -10 }, visible: { opacity: 1, x: 0 }, }; const getServiceIcon = (id: string, isOrgAdmin: any, isSuperAdmin: any) => { switch (id) { case "recordManagement": return ; case "orgAdmin": return isOrgAdmin ? : null; case "superAdmin": return isSuperAdmin ? : null; default: return ; } }; const getCurrentLanguageDisplay = () => { const currentLang = languageOptions.find( (lang) => lang.value === currentLanguage, ); return currentLang ? currentLang.label : "English"; }; return ( <> ); }; export default Header;