mirror of
https://github.com/OwethuManagedServices/oms-website-nextjs.git
synced 2025-12-17 18:58:10 +00:00
shwo active page
This commit is contained in:
@ -157,20 +157,44 @@ const Footer = () => {
|
||||
</p>
|
||||
<form className="flex flex-col sm:flex-row gap-2">
|
||||
{/* Input needs dark background styles */}
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Enter your email"
|
||||
aria-label="Email for newsletter"
|
||||
// Use dark variable for input bg/border, bright for text
|
||||
className="flex-grow px-4 py-2 rounded-lg bg-[var(--dark-input)] border border-[var(--dark-border)] text-[var(--dark-foreground)] placeholder:text-[var(--dark-muted-foreground)] focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]" // Ring offset needs dark bg
|
||||
/>
|
||||
{/* Keep button styling primary */}
|
||||
<button
|
||||
type="submit"
|
||||
className="bg-primary text-primary-foreground px-4 py-2 rounded-lg font-semibold hover:bg-opacity-90 transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]" // Ring offset needs dark bg
|
||||
>
|
||||
Subscribe
|
||||
</button>
|
||||
<div className="relative">
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Enter your email"
|
||||
aria-label="Email for newsletter"
|
||||
className="
|
||||
w-full
|
||||
pr-24
|
||||
|
||||
px-4 py-2
|
||||
rounded-lg
|
||||
bg-[var(--dark-input)]
|
||||
border border-[var(--dark-border)]
|
||||
text-[var(--dark-foreground)]
|
||||
placeholder:text-[var(--dark-muted-foreground)]
|
||||
focus:outline-none focus:ring-2 focus:ring-ring
|
||||
focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]
|
||||
"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="
|
||||
absolute top-0 right-0
|
||||
h-full
|
||||
px-4
|
||||
rounded-r-lg
|
||||
bg-primary
|
||||
text-primary-foreground
|
||||
font-semibold
|
||||
hover:bg-opacity-90
|
||||
transition-colors
|
||||
focus:outline-none focus:ring-2 focus:ring-ring
|
||||
focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]
|
||||
"
|
||||
>
|
||||
Subscribe
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{/* Badges - Use a subtle dark bg */}
|
||||
<div className="mt-6 space-x-2 sm:space-x-4">
|
||||
|
||||
@ -1,22 +1,13 @@
|
||||
// components/Header.tsx (Server Component)
|
||||
import React from "react";
|
||||
import { auth } from "@/auth"; // Only need auth (for session) from here now
|
||||
|
||||
import HeaderClient from "./HeaderClient";
|
||||
import { handleSignInAction, handleSignOutAction } from "@/actions/auth-action";
|
||||
|
||||
const Header = async () => {
|
||||
// Fetch session data on the server
|
||||
const session = await auth();
|
||||
|
||||
// Pass the session data and YOUR Server Actions as props
|
||||
return (
|
||||
<HeaderClient
|
||||
session={session}
|
||||
handleSignIn={handleSignInAction} // Pass YOUR sign-in Server Action
|
||||
handleSignOut={handleSignOutAction} // Pass YOUR sign-out Server Action
|
||||
/>
|
||||
);
|
||||
return <HeaderClient />;
|
||||
};
|
||||
|
||||
export default Header;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
import React, { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { usePathname } from "next/navigation"; // Import usePathname
|
||||
import {
|
||||
FiChevronDown,
|
||||
FiClipboard,
|
||||
@ -54,6 +55,20 @@ const HeaderClient = () => {
|
||||
const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
|
||||
const handleJoinUsMouseLeave = () => setJoinUsDropdownOpen(false);
|
||||
|
||||
const pathname = usePathname(); // Get current path
|
||||
|
||||
// Helper function to check if a path is active (exact match for simple links, startsWith for base paths)
|
||||
const isActive = (href: string, exact = false) => {
|
||||
if (exact) {
|
||||
return pathname === href;
|
||||
}
|
||||
// Handle root path specifically
|
||||
if (href === "/") {
|
||||
return pathname === "/";
|
||||
}
|
||||
return pathname.startsWith(href);
|
||||
};
|
||||
|
||||
const megaMenuTriggerClasses = `
|
||||
relative inline-flex items-center text-sm font-medium text-primary-foreground
|
||||
hover:opacity-90 transition-opacity duration-150 ease-in-out pb-1
|
||||
@ -94,25 +109,41 @@ const HeaderClient = () => {
|
||||
<nav className="hidden md:flex items-center space-x-6 lg:space-x-8">
|
||||
<Link
|
||||
href="/"
|
||||
className="text-sm font-medium text-foreground/80 hover:text-primary transition"
|
||||
className={`text-sm font-medium transition ${
|
||||
isActive("/")
|
||||
? "text-primary"
|
||||
: "text-foreground/80 hover:text-primary"
|
||||
}`} // Apply active class
|
||||
>
|
||||
Home
|
||||
</Link>
|
||||
<Link
|
||||
href="/tech-talk"
|
||||
className="text-sm font-medium text-foreground/80 hover:text-primary transition"
|
||||
className={`text-sm font-medium transition ${
|
||||
isActive("/tech-talk")
|
||||
? "text-primary"
|
||||
: "text-foreground/80 hover:text-primary"
|
||||
}`} // Apply active class
|
||||
>
|
||||
Tech Talk
|
||||
</Link>
|
||||
<Link
|
||||
href="/about"
|
||||
className="text-sm font-medium text-foreground/80 hover:text-primary transition"
|
||||
className={`text-sm font-medium transition ${
|
||||
isActive("/about")
|
||||
? "text-primary"
|
||||
: "text-foreground/80 hover:text-primary"
|
||||
}`} // Apply active class
|
||||
>
|
||||
About Us
|
||||
</Link>
|
||||
<Link
|
||||
href="/contact"
|
||||
className="text-sm font-medium text-foreground/80 hover:text-primary transition"
|
||||
className={`text-sm font-medium transition ${
|
||||
isActive("/contact")
|
||||
? "text-primary"
|
||||
: "text-foreground/80 hover:text-primary"
|
||||
}`} // Apply active class
|
||||
>
|
||||
Contact Us
|
||||
</Link>
|
||||
@ -153,168 +184,230 @@ const HeaderClient = () => {
|
||||
<div className="bg-primary relative">
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<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"
|
||||
onMouseEnter={handleServicesMouseEnter}
|
||||
onMouseLeave={handleServicesMouseLeave}
|
||||
>
|
||||
<button className={megaMenuTriggerClasses}>
|
||||
Services
|
||||
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
||||
</button>
|
||||
{/* Wrap nav and link in a flex container */}
|
||||
<div className="flex items-center space-x-8 lg:space-x-10">
|
||||
<nav className="flex items-center space-x-8 lg:space-x-10">
|
||||
{/* Services */}
|
||||
<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]
|
||||
${
|
||||
servicesDropdownOpen
|
||||
? "opacity-100 visible translate-y-0"
|
||||
: ""
|
||||
}
|
||||
transition-all duration-300 ease-out transform
|
||||
`}
|
||||
className={`group ${isActive("/services") ? "active" : ""}`} // Add active class to group
|
||||
onMouseEnter={handleServicesMouseEnter}
|
||||
onMouseLeave={handleServicesMouseLeave}
|
||||
>
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6">
|
||||
<Link
|
||||
href="/services/resource-augmentation"
|
||||
className={megaMenuItemClasses}
|
||||
>
|
||||
<FiUsers className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Resource Augmentation
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/services/project-management"
|
||||
className={megaMenuItemClasses}
|
||||
>
|
||||
<FiBriefcase className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Project Management
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/services/product-development"
|
||||
className={megaMenuItemClasses}
|
||||
>
|
||||
<FiCpu className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Product Development
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="mt-6 pt-4 border-t border-border flex justify-end">
|
||||
<Link
|
||||
href="/services"
|
||||
className="flex items-center text-sm font-medium text-primary hover:underline"
|
||||
>
|
||||
Explore All Services
|
||||
<FiArrowRight className="w-4 h-4 ml-1" />
|
||||
</Link>
|
||||
<button
|
||||
className={`${megaMenuTriggerClasses} ${
|
||||
isActive("/services") ? "after:w-full" : ""
|
||||
}`}
|
||||
>
|
||||
{" "}
|
||||
{/* Apply underline based on active state */}
|
||||
Services
|
||||
<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]
|
||||
${
|
||||
servicesDropdownOpen
|
||||
? "opacity-100 visible translate-y-0"
|
||||
: ""
|
||||
}
|
||||
transition-all duration-300 ease-out transform
|
||||
`}
|
||||
>
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6">
|
||||
<Link
|
||||
href="/services/resource-augmentation"
|
||||
className={`${megaMenuItemClasses} ${
|
||||
isActive("/services/resource-augmentation")
|
||||
? "text-primary"
|
||||
: ""
|
||||
}`} // Apply active class
|
||||
>
|
||||
<FiUsers className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Resource Augmentation
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/services/project-management"
|
||||
className={`${megaMenuItemClasses} ${
|
||||
isActive("/services/project-management")
|
||||
? "text-primary"
|
||||
: ""
|
||||
}`} // Apply active class
|
||||
>
|
||||
<FiBriefcase className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Project Management
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/services/product-development"
|
||||
className={`${megaMenuItemClasses} ${
|
||||
isActive("/services/product-development")
|
||||
? "text-primary"
|
||||
: ""
|
||||
}`} // Apply active class
|
||||
>
|
||||
<FiCpu className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Product Development
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Products */}
|
||||
<div
|
||||
className="group"
|
||||
onMouseEnter={handleProductsMouseEnter}
|
||||
onMouseLeave={handleProductsMouseLeave}
|
||||
>
|
||||
<button className={megaMenuTriggerClasses}>
|
||||
Products
|
||||
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
||||
</button>
|
||||
{/* Products */}
|
||||
<div
|
||||
className={`
|
||||
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]
|
||||
${
|
||||
productsDropdownOpen
|
||||
? "opacity-100 visible translate-y-0"
|
||||
: ""
|
||||
}
|
||||
transition-all duration-300 ease-out transform
|
||||
`}
|
||||
className={`group ${isActive("/obse") ? "active" : ""}`} // Add active class to group
|
||||
onMouseEnter={handleProductsMouseEnter}
|
||||
onMouseLeave={handleProductsMouseLeave}
|
||||
>
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||
<div className="max-w-md">
|
||||
<Link href="/obse" className={megaMenuItemClasses}>
|
||||
<FiBox className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>OBSE Platform</p>
|
||||
</div>
|
||||
</Link>
|
||||
<button
|
||||
className={`${megaMenuTriggerClasses} ${
|
||||
isActive("/obse") ? "after:w-full" : ""
|
||||
}`}
|
||||
>
|
||||
{" "}
|
||||
{/* Apply underline based on active state */}
|
||||
Products
|
||||
<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-1000
|
||||
bg-card border-x border-b border-border rounded-b-lg
|
||||
opacity-0 invisible translate-y-[-10px]
|
||||
${
|
||||
productsDropdownOpen
|
||||
? "opacity-100 visible translate-y-0"
|
||||
: ""
|
||||
}
|
||||
transition-all duration-300 ease-out transform
|
||||
`}
|
||||
>
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||
<div className="max-w-md">
|
||||
<Link
|
||||
href="/obse"
|
||||
className={`${megaMenuItemClasses} ${
|
||||
isActive("/obse") ? "text-primary" : ""
|
||||
}`}
|
||||
>
|
||||
{" "}
|
||||
{/* Apply active class */}
|
||||
<FiBox className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
OBSE Platform
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Join Our Team */}
|
||||
<div
|
||||
className="group"
|
||||
onMouseEnter={handleJoinUsMouseEnter}
|
||||
onMouseLeave={handleJoinUsMouseLeave}
|
||||
>
|
||||
<button className={megaMenuTriggerClasses}>
|
||||
Join Our Team
|
||||
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
||||
</button>
|
||||
{/* Join Our Team */}
|
||||
<div
|
||||
className={`
|
||||
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]
|
||||
${
|
||||
joinUsDropdownOpen
|
||||
? "opacity-100 visible translate-y-0"
|
||||
: ""
|
||||
}
|
||||
transition-all duration-300 ease-out transform
|
||||
`}
|
||||
className={`group ${
|
||||
isActive("/join-us") ||
|
||||
isActive("/vacancies") ||
|
||||
isActive("/portal")
|
||||
? "active"
|
||||
: ""
|
||||
}`} // Add active class to group (check all related paths)
|
||||
onMouseEnter={handleJoinUsMouseEnter}
|
||||
onMouseLeave={handleJoinUsMouseLeave}
|
||||
>
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 max-w-xl">
|
||||
<Link href="/vacancies" className={megaMenuItemClasses}>
|
||||
<FiFileText className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Current Vacancies
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="/portal" className={megaMenuItemClasses}>
|
||||
<FiUserCheck className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Recruitment Portal
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<button
|
||||
className={`${megaMenuTriggerClasses} ${
|
||||
isActive("/join-us") ||
|
||||
isActive("/vacancies") ||
|
||||
isActive("/portal")
|
||||
? "after:w-full"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{" "}
|
||||
{/* Apply underline based on active state */}
|
||||
Join Our Team
|
||||
<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-1000
|
||||
bg-card border-x border-b border-border rounded-b-lg
|
||||
opacity-0 invisible translate-y-[-10px]
|
||||
${
|
||||
joinUsDropdownOpen
|
||||
? "opacity-100 visible translate-y-0"
|
||||
: ""
|
||||
}
|
||||
transition-all duration-300 ease-out transform
|
||||
`}
|
||||
>
|
||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 max-w-xl">
|
||||
<Link
|
||||
href="/vacancies"
|
||||
className={`${megaMenuItemClasses} ${
|
||||
isActive("/vacancies") ? "text-primary" : ""
|
||||
}`}
|
||||
>
|
||||
{" "}
|
||||
{/* Apply active class */}
|
||||
<FiFileText className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Current Vacancies
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/portal"
|
||||
className={`${megaMenuItemClasses} ${
|
||||
isActive("/portal") ? "text-primary" : ""
|
||||
}`}
|
||||
>
|
||||
{" "}
|
||||
{/* Apply active class */}
|
||||
<FiUserCheck className={megaMenuIconClasses} />
|
||||
<div className={megaMenuTextWrapperClasses}>
|
||||
<p className={megaMenuTitleClasses}>
|
||||
Recruitment Portal
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</nav>
|
||||
|
||||
{/* ← Here’s the Explore Our Offerings link, back in its original spot */}
|
||||
<Link
|
||||
href="/services"
|
||||
className="flex items-center text-sm font-medium text-primary-foreground hover:opacity-80 transition-opacity group"
|
||||
>
|
||||
Explore Our Offerings
|
||||
<FiArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" />
|
||||
</Link>
|
||||
{/* ← Here’s the Explore Our Offerings link, back in its original spot */}
|
||||
<Link
|
||||
href="/services" // Assuming this link goes to the main services page
|
||||
className={`flex items-center text-sm font-medium hover:opacity-80 transition-opacity group ${
|
||||
isActive("/services")
|
||||
? "text-primary"
|
||||
: "text-primary-foreground"
|
||||
}`} // Apply active class
|
||||
>
|
||||
Explore Our Offerings
|
||||
<FiArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" />
|
||||
</Link>
|
||||
</div>{" "}
|
||||
{/* Close the new flex container */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user