product development added

This commit is contained in:
libertyoms
2025-05-18 09:07:14 +02:00
parent 225fbc707e
commit e2347ecc87
2 changed files with 596 additions and 121 deletions

View File

@ -10,47 +10,17 @@ import {
FiArrowRight,
FiMenu,
FiX,
FiLogIn,
FiUsers, // Resource Augmentation
FiBriefcase, // Project Management
FiCpu, // Product Development
FiBox, // OBSE
FiFileText, // Vacancies
FiUserCheck, // Recruitment Portal
FiUsers,
FiBriefcase,
FiCpu,
FiBox,
FiFileText,
FiUserCheck,
} from "react-icons/fi";
import ThemeToggle from "./ThemeToggle";
import type { Session } from "@auth/core/types";
const omsLogoUrl = "/oms-logo.svg";
type DropdownMenuProps = {
trigger: React.ReactNode;
children: React.ReactNode;
menuClasses?: string;
};
const DropdownMenu = ({
trigger,
children,
menuClasses = "w-48",
}: DropdownMenuProps) => (
<div className="relative group">
<button className="flex items-center space-x-1 text-sm font-medium focus:outline-none inherit-color group">
{trigger}
<FiChevronDown className="w-4 h-4 transition-transform duration-200 group-hover:rotate-180 group-focus-within:rotate-180" />
</button>
<div
className={`
absolute left-0 mt-2 ${menuClasses} origin-top-left rounded-md shadow-lg z-50
bg-card border border-border
opacity-0 invisible group-hover:opacity-100 group-hover:visible group-focus-within:opacity-100 group-focus-within:visible
transition-all duration-200
`}
>
<div className="py-1">{children}</div>
</div>
</div>
);
type DropdownLinkProps = {
href: string;
children: React.ReactNode;
@ -66,34 +36,36 @@ const DropdownLink = ({ href, children, onClick }: DropdownLinkProps) => (
</Link>
);
type HeaderClientProps = {
session: Session | null;
handleSignIn: () => void;
handleSignOut: () => void;
};
const HeaderClient = ({
session,
handleSignIn,
handleSignOut,
}: HeaderClientProps) => {
const HeaderClient = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const toggleMenu = () => setIsMenuOpen((open) => !open);
const handleMobileLinkClick = () => setIsMenuOpen(false);
const [servicesDropdownOpen, setServicesDropdownOpen] = useState(false);
const [productsDropdownOpen, setProductsDropdownOpen] = useState(false);
const [joinUsDropdownOpen, setJoinUsDropdownOpen] = useState(false);
const handleServicesMouseEnter = () => setServicesDropdownOpen(true);
const handleServicesMouseLeave = () => setServicesDropdownOpen(false);
const handleProductsMouseEnter = () => setProductsDropdownOpen(true);
const handleProductsMouseLeave = () => setProductsDropdownOpen(false);
const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
const handleJoinUsMouseLeave = () => setJoinUsDropdownOpen(false);
const megaMenuTriggerClasses = `
relative inline-flex items-center text-sm font-medium text-primary-foreground group
relative inline-flex items-center text-sm font-medium text-primary-foreground
hover:opacity-90 transition-opacity duration-150 ease-in-out pb-1
after:content-[''] after:absolute after:left-0 after:bottom-0 after:h-[2px]
after:w-0 after:bg-primary-foreground/80 after:transition-all after:duration-300 after:ease-out
group-hover:after:w-full group-focus-within:after:w-full
`;
const megaMenuItemClasses = `
flex items-center p-3 -m-3 rounded-lg
hover:bg-secondary transition-colors duration-150 ease-in-out group
hover:bg-secondary transition-colors duration-150 ease-in-out
`;
const megaMenuIconClasses = `flex-shrink-0 h-6 w-6 text-primary group-hover:text-primary-focus mr-4`;
const megaMenuIconClasses = `flex-shrink-0 h-6 w-6 text-primary mr-4`;
const megaMenuTextWrapperClasses = `text-sm`;
const megaMenuTitleClasses = `font-semibold text-card-foreground`;
@ -156,42 +128,6 @@ const HeaderClient = ({
<FiClipboard className="w-4 h-4 mr-1.5" />
Request OBSE Demo
</Link>
{session?.user ? (
<DropdownMenu
menuClasses="w-40 right-0 left-auto"
trigger={
<div className="flex items-center space-x-2 cursor-pointer hover:opacity-80 transition">
<Image
src={session.user.image || "/default-avatar.png"}
alt={session.user.name || "User"}
width={32}
height={32}
className="rounded-full ring-1 ring-primary ring-offset-2 ring-offset-background"
/>
<span className="text-sm font-medium text-foreground hidden lg:inline">
{session.user.name?.split(" ")[0]}
</span>
</div>
}
>
<button
onClick={handleSignOut}
className="block w-full text-left px-4 py-2 text-sm text-destructive hover:bg-secondary hover:text-destructive transition"
>
Sign Out
</button>
</DropdownMenu>
) : (
<button
onClick={handleSignIn}
className="p-2 rounded-full text-foreground/70 hover:text-primary hover:bg-secondary focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background transition-colors"
title="Sign In"
aria-label="Sign In"
>
<FiLogIn className="w-5 h-5" />
</button>
)}
</div>
<div className="md:hidden flex items-center">
@ -219,17 +155,25 @@ const HeaderClient = ({
<div className="hidden md:flex justify-between items-center h-12">
<nav className="flex items-center space-x-8 lg:space-x-10">
{/* Services */}
<div className="group">
<div
className="group"
onMouseEnter={handleServicesMouseEnter}
onMouseLeave={handleServicesMouseLeave}
>
<button className={megaMenuTriggerClasses}>
Services
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 group-hover:rotate-180 transition-transform duration-200" />
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
</button>
<div
className={`
absolute left-0 top-full w-full shadow-lg z-40
bg-card border-x border-b border-border rounded-b-lg
opacity-0 invisible translate-y-[-10px]
group-hover:opacity-100 group-hover:visible group-hover:translate-y-0
${
servicesDropdownOpen
? "opacity-100 visible translate-y-0"
: ""
}
transition-all duration-300 ease-out transform
`}
>
@ -282,17 +226,25 @@ const HeaderClient = ({
</div>
</div>
{/* Products */}
<div className="group">
<div
className="group"
onMouseEnter={handleProductsMouseEnter}
onMouseLeave={handleProductsMouseLeave}
>
<button className={megaMenuTriggerClasses}>
Products
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 group-hover:rotate-180 transition-transform duration-200" />
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
</button>
<div
className={`
absolute left-0 top-full w-full shadow-lg z-40
absolute left-0 top-full w-full shadow-lg z-1000
bg-card border-x border-b border-border rounded-b-lg
opacity-0 invisible translate-y-[-10px]
group-hover:opacity-100 group-hover:visible group-hover:translate-y-0
${
productsDropdownOpen
? "opacity-100 visible translate-y-0"
: ""
}
transition-all duration-300 ease-out transform
`}
>
@ -309,17 +261,25 @@ const HeaderClient = ({
</div>
</div>
{/* Join Our Team */}
<div className="group">
<div
className="group"
onMouseEnter={handleJoinUsMouseEnter}
onMouseLeave={handleJoinUsMouseLeave}
>
<button className={megaMenuTriggerClasses}>
Join Our Team
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 group-hover:rotate-180 transition-transform duration-200" />
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
</button>
<div
className={`
absolute left-0 top-full w-full shadow-lg z-40
absolute left-0 top-full w-full shadow-lg z-1000
bg-card border-x border-b border-border rounded-b-lg
opacity-0 invisible translate-y-[-10px]
group-hover:opacity-100 group-hover:visible group-hover:translate-y-0
${
joinUsDropdownOpen
? "opacity-100 visible translate-y-0"
: ""
}
transition-all duration-300 ease-out transform
`}
>
@ -424,29 +384,7 @@ const HeaderClient = ({
<FiClipboard className="w-4 h-4 mr-1.5" /> Request OBSE Demo
</Link>
</div>
<div className="pt-4 border-t border-border mt-4">
{session?.user ? (
<button
onClick={() => {
handleSignOut();
handleMobileLinkClick();
}}
className="flex items-center w-full text-left px-4 py-2 text-sm font-medium text-destructive hover:bg-secondary transition"
>
Sign Out
</button>
) : (
<button
onClick={() => {
handleSignIn();
handleMobileLinkClick();
}}
className="flex items-center w-full text-left px-4 py-2 text-sm font-medium text-foreground hover:bg-secondary hover:text-primary transition"
>
<FiLogIn className="w-4 h-4 mr-2" /> Sign In
</button>
)}
</div>
<div className="pt-4 border-t border-border mt-4"></div>
</nav>
</div>
</header>