mirror of
https://github.com/OwethuManagedServices/oms-website-nextjs.git
synced 2025-12-17 19:08:09 +00:00
shwo active page
This commit is contained in:
@ -157,20 +157,44 @@ const Footer = () => {
|
|||||||
</p>
|
</p>
|
||||||
<form className="flex flex-col sm:flex-row gap-2">
|
<form className="flex flex-col sm:flex-row gap-2">
|
||||||
{/* Input needs dark background styles */}
|
{/* Input needs dark background styles */}
|
||||||
|
<div className="relative">
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Enter your email"
|
placeholder="Enter your email"
|
||||||
aria-label="Email for newsletter"
|
aria-label="Email for newsletter"
|
||||||
// Use dark variable for input bg/border, bright for text
|
className="
|
||||||
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
|
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)]
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
{/* Keep button styling primary */}
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
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
|
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
|
Subscribe
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{/* Badges - Use a subtle dark bg */}
|
{/* Badges - Use a subtle dark bg */}
|
||||||
<div className="mt-6 space-x-2 sm:space-x-4">
|
<div className="mt-6 space-x-2 sm:space-x-4">
|
||||||
|
|||||||
@ -1,22 +1,13 @@
|
|||||||
// components/Header.tsx (Server Component)
|
// components/Header.tsx (Server Component)
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { auth } from "@/auth"; // Only need auth (for session) from here now
|
|
||||||
|
|
||||||
import HeaderClient from "./HeaderClient";
|
import HeaderClient from "./HeaderClient";
|
||||||
import { handleSignInAction, handleSignOutAction } from "@/actions/auth-action";
|
|
||||||
|
|
||||||
const Header = async () => {
|
const Header = async () => {
|
||||||
// Fetch session data on the server
|
// Fetch session data on the server
|
||||||
const session = await auth();
|
|
||||||
|
|
||||||
// Pass the session data and YOUR Server Actions as props
|
// Pass the session data and YOUR Server Actions as props
|
||||||
return (
|
return <HeaderClient />;
|
||||||
<HeaderClient
|
|
||||||
session={session}
|
|
||||||
handleSignIn={handleSignInAction} // Pass YOUR sign-in Server Action
|
|
||||||
handleSignOut={handleSignOutAction} // Pass YOUR sign-out Server Action
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { usePathname } from "next/navigation"; // Import usePathname
|
||||||
import {
|
import {
|
||||||
FiChevronDown,
|
FiChevronDown,
|
||||||
FiClipboard,
|
FiClipboard,
|
||||||
@ -54,6 +55,20 @@ const HeaderClient = () => {
|
|||||||
const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
|
const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
|
||||||
const handleJoinUsMouseLeave = () => setJoinUsDropdownOpen(false);
|
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 = `
|
const megaMenuTriggerClasses = `
|
||||||
relative inline-flex items-center text-sm font-medium text-primary-foreground
|
relative inline-flex items-center text-sm font-medium text-primary-foreground
|
||||||
hover:opacity-90 transition-opacity duration-150 ease-in-out pb-1
|
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">
|
<nav className="hidden md:flex items-center space-x-6 lg:space-x-8">
|
||||||
<Link
|
<Link
|
||||||
href="/"
|
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
|
Home
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/tech-talk"
|
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
|
Tech Talk
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/about"
|
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
|
About Us
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/contact"
|
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
|
Contact Us
|
||||||
</Link>
|
</Link>
|
||||||
@ -153,14 +184,22 @@ const HeaderClient = () => {
|
|||||||
<div className="bg-primary relative">
|
<div className="bg-primary relative">
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="hidden md:flex justify-between items-center h-12">
|
<div className="hidden md:flex justify-between items-center h-12">
|
||||||
|
{/* 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">
|
<nav className="flex items-center space-x-8 lg:space-x-10">
|
||||||
{/* Services */}
|
{/* Services */}
|
||||||
<div
|
<div
|
||||||
className="group"
|
className={`group ${isActive("/services") ? "active" : ""}`} // Add active class to group
|
||||||
onMouseEnter={handleServicesMouseEnter}
|
onMouseEnter={handleServicesMouseEnter}
|
||||||
onMouseLeave={handleServicesMouseLeave}
|
onMouseLeave={handleServicesMouseLeave}
|
||||||
>
|
>
|
||||||
<button className={megaMenuTriggerClasses}>
|
<button
|
||||||
|
className={`${megaMenuTriggerClasses} ${
|
||||||
|
isActive("/services") ? "after:w-full" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{/* Apply underline based on active state */}
|
||||||
Services
|
Services
|
||||||
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
||||||
</button>
|
</button>
|
||||||
@ -181,7 +220,11 @@ const HeaderClient = () => {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6">
|
||||||
<Link
|
<Link
|
||||||
href="/services/resource-augmentation"
|
href="/services/resource-augmentation"
|
||||||
className={megaMenuItemClasses}
|
className={`${megaMenuItemClasses} ${
|
||||||
|
isActive("/services/resource-augmentation")
|
||||||
|
? "text-primary"
|
||||||
|
: ""
|
||||||
|
}`} // Apply active class
|
||||||
>
|
>
|
||||||
<FiUsers className={megaMenuIconClasses} />
|
<FiUsers className={megaMenuIconClasses} />
|
||||||
<div className={megaMenuTextWrapperClasses}>
|
<div className={megaMenuTextWrapperClasses}>
|
||||||
@ -192,7 +235,11 @@ const HeaderClient = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/services/project-management"
|
href="/services/project-management"
|
||||||
className={megaMenuItemClasses}
|
className={`${megaMenuItemClasses} ${
|
||||||
|
isActive("/services/project-management")
|
||||||
|
? "text-primary"
|
||||||
|
: ""
|
||||||
|
}`} // Apply active class
|
||||||
>
|
>
|
||||||
<FiBriefcase className={megaMenuIconClasses} />
|
<FiBriefcase className={megaMenuIconClasses} />
|
||||||
<div className={megaMenuTextWrapperClasses}>
|
<div className={megaMenuTextWrapperClasses}>
|
||||||
@ -203,7 +250,11 @@ const HeaderClient = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/services/product-development"
|
href="/services/product-development"
|
||||||
className={megaMenuItemClasses}
|
className={`${megaMenuItemClasses} ${
|
||||||
|
isActive("/services/product-development")
|
||||||
|
? "text-primary"
|
||||||
|
: ""
|
||||||
|
}`} // Apply active class
|
||||||
>
|
>
|
||||||
<FiCpu className={megaMenuIconClasses} />
|
<FiCpu className={megaMenuIconClasses} />
|
||||||
<div className={megaMenuTextWrapperClasses}>
|
<div className={megaMenuTextWrapperClasses}>
|
||||||
@ -213,25 +264,22 @@ const HeaderClient = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</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>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Products */}
|
{/* Products */}
|
||||||
<div
|
<div
|
||||||
className="group"
|
className={`group ${isActive("/obse") ? "active" : ""}`} // Add active class to group
|
||||||
onMouseEnter={handleProductsMouseEnter}
|
onMouseEnter={handleProductsMouseEnter}
|
||||||
onMouseLeave={handleProductsMouseLeave}
|
onMouseLeave={handleProductsMouseLeave}
|
||||||
>
|
>
|
||||||
<button className={megaMenuTriggerClasses}>
|
<button
|
||||||
|
className={`${megaMenuTriggerClasses} ${
|
||||||
|
isActive("/obse") ? "after:w-full" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{/* Apply underline based on active state */}
|
||||||
Products
|
Products
|
||||||
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
||||||
</button>
|
</button>
|
||||||
@ -250,10 +298,19 @@ const HeaderClient = () => {
|
|||||||
>
|
>
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
||||||
<div className="max-w-md">
|
<div className="max-w-md">
|
||||||
<Link href="/obse" className={megaMenuItemClasses}>
|
<Link
|
||||||
|
href="/obse"
|
||||||
|
className={`${megaMenuItemClasses} ${
|
||||||
|
isActive("/obse") ? "text-primary" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{/* Apply active class */}
|
||||||
<FiBox className={megaMenuIconClasses} />
|
<FiBox className={megaMenuIconClasses} />
|
||||||
<div className={megaMenuTextWrapperClasses}>
|
<div className={megaMenuTextWrapperClasses}>
|
||||||
<p className={megaMenuTitleClasses}>OBSE Platform</p>
|
<p className={megaMenuTitleClasses}>
|
||||||
|
OBSE Platform
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -262,11 +319,27 @@ const HeaderClient = () => {
|
|||||||
</div>
|
</div>
|
||||||
{/* Join Our Team */}
|
{/* Join Our Team */}
|
||||||
<div
|
<div
|
||||||
className="group"
|
className={`group ${
|
||||||
|
isActive("/join-us") ||
|
||||||
|
isActive("/vacancies") ||
|
||||||
|
isActive("/portal")
|
||||||
|
? "active"
|
||||||
|
: ""
|
||||||
|
}`} // Add active class to group (check all related paths)
|
||||||
onMouseEnter={handleJoinUsMouseEnter}
|
onMouseEnter={handleJoinUsMouseEnter}
|
||||||
onMouseLeave={handleJoinUsMouseLeave}
|
onMouseLeave={handleJoinUsMouseLeave}
|
||||||
>
|
>
|
||||||
<button className={megaMenuTriggerClasses}>
|
<button
|
||||||
|
className={`${megaMenuTriggerClasses} ${
|
||||||
|
isActive("/join-us") ||
|
||||||
|
isActive("/vacancies") ||
|
||||||
|
isActive("/portal")
|
||||||
|
? "after:w-full"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{/* Apply underline based on active state */}
|
||||||
Join Our Team
|
Join Our Team
|
||||||
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
|
||||||
</button>
|
</button>
|
||||||
@ -285,7 +358,14 @@ const HeaderClient = () => {
|
|||||||
>
|
>
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
|
<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">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 max-w-xl">
|
||||||
<Link href="/vacancies" className={megaMenuItemClasses}>
|
<Link
|
||||||
|
href="/vacancies"
|
||||||
|
className={`${megaMenuItemClasses} ${
|
||||||
|
isActive("/vacancies") ? "text-primary" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{/* Apply active class */}
|
||||||
<FiFileText className={megaMenuIconClasses} />
|
<FiFileText className={megaMenuIconClasses} />
|
||||||
<div className={megaMenuTextWrapperClasses}>
|
<div className={megaMenuTextWrapperClasses}>
|
||||||
<p className={megaMenuTitleClasses}>
|
<p className={megaMenuTitleClasses}>
|
||||||
@ -293,7 +373,14 @@ const HeaderClient = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/portal" className={megaMenuItemClasses}>
|
<Link
|
||||||
|
href="/portal"
|
||||||
|
className={`${megaMenuItemClasses} ${
|
||||||
|
isActive("/portal") ? "text-primary" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{/* Apply active class */}
|
||||||
<FiUserCheck className={megaMenuIconClasses} />
|
<FiUserCheck className={megaMenuIconClasses} />
|
||||||
<div className={megaMenuTextWrapperClasses}>
|
<div className={megaMenuTextWrapperClasses}>
|
||||||
<p className={megaMenuTitleClasses}>
|
<p className={megaMenuTitleClasses}>
|
||||||
@ -309,12 +396,18 @@ const HeaderClient = () => {
|
|||||||
|
|
||||||
{/* ← Here’s the Explore Our Offerings link, back in its original spot */}
|
{/* ← Here’s the Explore Our Offerings link, back in its original spot */}
|
||||||
<Link
|
<Link
|
||||||
href="/services"
|
href="/services" // Assuming this link goes to the main services page
|
||||||
className="flex items-center text-sm font-medium text-primary-foreground hover:opacity-80 transition-opacity group"
|
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
|
Explore Our Offerings
|
||||||
<FiArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" />
|
<FiArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" />
|
||||||
</Link>
|
</Link>
|
||||||
|
</div>{" "}
|
||||||
|
{/* Close the new flex container */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user