feature: sign up with github and about page completed
18
actions/auth-action.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// app/actions.ts (or lib/actions.ts)
|
||||||
|
"use server"; // <--- IMPORTANT: This file contains Server Actions
|
||||||
|
|
||||||
|
import { signIn as nextAuthSignIn, signOut as nextAuthSignOut } from "@/auth";
|
||||||
|
|
||||||
|
// Define your server action to handle sign-in
|
||||||
|
export async function handleSignInAction(provider: string = "github") {
|
||||||
|
// You can add any pre-sign-in logic here if needed
|
||||||
|
await nextAuthSignIn(provider);
|
||||||
|
// You can add any post-sign-in logic or revalidates here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define your server action to handle sign-out
|
||||||
|
export async function handleSignOutAction() {
|
||||||
|
// You can add any pre-sign-out logic here if needed
|
||||||
|
await nextAuthSignOut();
|
||||||
|
// You can add any post-sign-out logic or revalidates here
|
||||||
|
}
|
||||||
541
app/(website)/about/page.tsx
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import {
|
||||||
|
FaHandshake,
|
||||||
|
FaBullseye,
|
||||||
|
FaUsers,
|
||||||
|
FaCheckCircle,
|
||||||
|
FaHeart,
|
||||||
|
FaComments,
|
||||||
|
FaShieldAlt,
|
||||||
|
FaCogs,
|
||||||
|
FaChartLine,
|
||||||
|
FaMicrochip,
|
||||||
|
FaBriefcase,
|
||||||
|
FaSyncAlt,
|
||||||
|
FaUserCheck,
|
||||||
|
FaProjectDiagram,
|
||||||
|
} from "react-icons/fa";
|
||||||
|
|
||||||
|
const leadershipTeam = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Michael Shapiro",
|
||||||
|
title: "Managing Director",
|
||||||
|
imageUrl: "/images/profile1.jpg",
|
||||||
|
bio: "A seasoned leader and innovator with over 25 years of experience, driving strategic growth and fostering a culture of excellence within OMS.",
|
||||||
|
linkedinUrl: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Gareth Corbishley",
|
||||||
|
title: "Director",
|
||||||
|
imageUrl: "/images/profile2.jpg",
|
||||||
|
bio: "Expert in operational efficiency and technological implementation, ensuring seamless project delivery and client satisfaction.",
|
||||||
|
linkedinUrl: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Darryl Govender",
|
||||||
|
title: "Director",
|
||||||
|
imageUrl: "/images/profile3.jpg",
|
||||||
|
bio: "Specializes in aligning cutting-edge technology solutions with complex business needs to unlock transformative results.",
|
||||||
|
linkedinUrl: "#",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const coreValues = [
|
||||||
|
{
|
||||||
|
icon: FaCheckCircle,
|
||||||
|
title: "Service",
|
||||||
|
description:
|
||||||
|
"Dedicated to providing outstanding service at every touchpoint, meeting the highest standards, and creating lasting impact for our clients.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaHandshake,
|
||||||
|
title: "Accountability",
|
||||||
|
description:
|
||||||
|
"Taking ownership of our actions and delivering on promises with transparency. Our commitment fosters trust and ensures we consistently meet client expectations.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaHeart,
|
||||||
|
title: "Passion",
|
||||||
|
description:
|
||||||
|
"Driven by a passion for innovation, we embrace new ideas and technologies, constantly seeking ways to improve and deliver creative, boundary-pushing solutions.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaComments,
|
||||||
|
title: "Communication",
|
||||||
|
description:
|
||||||
|
"Clear, consistent, and proactive communication is central. We ensure all stakeholders are aligned, informed, and empowered, fostering collaboration.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaShieldAlt,
|
||||||
|
title: "Trust",
|
||||||
|
description:
|
||||||
|
"Cultivating trust through ethical practices, honesty, and transparency. We uphold the highest integrity for long-term, mutually beneficial relationships.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const ourApproach = [
|
||||||
|
{
|
||||||
|
icon: FaProjectDiagram,
|
||||||
|
title: "Strategic Alignment",
|
||||||
|
description:
|
||||||
|
" We begin by deeply understanding your business objectives, challenges, and long-term vision to ensure every solution delivers strategic value.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaUserCheck,
|
||||||
|
title: "Client-Centric Collaboration",
|
||||||
|
description:
|
||||||
|
"We believe in true partnership. You're involved throughout the process, ensuring transparency, feedback loops, and solutions tailored precisely to your needs.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaSyncAlt,
|
||||||
|
title: "Agile & Adaptive Delivery",
|
||||||
|
description:
|
||||||
|
"Leveraging agile methodologies allows us to be flexible, adapt to changing requirements, and deliver incremental value faster, ensuring projects stay on track and relevant.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaCogs,
|
||||||
|
title: "Technical Excellence",
|
||||||
|
description:
|
||||||
|
"Our commitment to technical excellence means employing best practices, rigorous testing, and seasoned expertise to build robust, scalable, and maintainable solutions.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const industryExpertise = [
|
||||||
|
{
|
||||||
|
icon: FaBriefcase,
|
||||||
|
industry: "Financial Services & Fintech",
|
||||||
|
details:
|
||||||
|
"Deep understanding of regulatory landscapes, security requirements, and digital transformation needs within banking, insurance, and investment sectors. We build secure, compliant, and innovative fintech solutions.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaBriefcase,
|
||||||
|
industry: "Automotive",
|
||||||
|
details:
|
||||||
|
"Experience in optimizing supply chains, developing connected car solutions, enhancing customer experiences, and leveraging data analytics for the automotive industry.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaBriefcase,
|
||||||
|
industry: "Technology",
|
||||||
|
details:
|
||||||
|
"Partnering with tech companies to accelerate product development, provide specialized engineering talent, and build scalable cloud-native applications.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: FaBriefcase,
|
||||||
|
industry: "Retail/E-commerce",
|
||||||
|
details: "Describe experience in this sector.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function AboutUsPage() {
|
||||||
|
return (
|
||||||
|
<div className="bg-white text-gray-800 overflow-x-hidden">
|
||||||
|
{" "}
|
||||||
|
{/* Prevent horizontal scroll */}
|
||||||
|
{/* Section 1: Hero / Company Overview */}
|
||||||
|
<section className="relative bg-gradient-to-r from-gray-800 via-gray-700 to-gray-800 text-white py-24 md:py-40">
|
||||||
|
{/* Optional decorative background elements */}
|
||||||
|
<div className="absolute inset-0 bg-black opacity-30"></div>
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 bg-cover bg-center opacity-10"
|
||||||
|
style={{ backgroundImage: "url('/path/to/abstract-tech-bg.jpg')" }}
|
||||||
|
></div>{" "}
|
||||||
|
{/* Add a subtle background image */}
|
||||||
|
<div className="container mx-auto px-6 text-center relative z-10">
|
||||||
|
<h1
|
||||||
|
className="text-4xl md:text-6xl font-bold mb-4 font-poppins text-gold-500 drop-shadow-md"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
About Owethu Managed Services
|
||||||
|
</h1>
|
||||||
|
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed text-gray-200 font-poppins">
|
||||||
|
Your strategic partner in navigating the digital frontier. We fuse
|
||||||
|
deep technical expertise with a passion for innovation to craft
|
||||||
|
bespoke IT solutions that drive tangible business results and unlock
|
||||||
|
future potential.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 2: Our Genesis & Purpose */}
|
||||||
|
<section className="py-16 md:py-24 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold mb-6 font-poppins text-gray-900 leading-tight">
|
||||||
|
Forged in Innovation, <br className="hidden md:inline" /> Driven
|
||||||
|
by Purpose
|
||||||
|
</h2>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 leading-relaxed mb-4 font-poppins">
|
||||||
|
Expand on the founding story/motivation. E.g., Owethu Managed
|
||||||
|
Services was born from a clear vision: to harness the
|
||||||
|
transformative power of technology not just to solve problems,
|
||||||
|
but to proactively create opportunities for businesses to
|
||||||
|
thrive. We saw a need for a partner who truly understands both
|
||||||
|
technology's potential and the unique challenges modern
|
||||||
|
organizations face.
|
||||||
|
</p>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 leading-relaxed font-poppins">
|
||||||
|
Elaborate on the journey. E.g., Our journey has been defined by
|
||||||
|
a relentless pursuit of knowledge, adaptation to the
|
||||||
|
ever-evolving tech landscape, and an unwavering commitment to
|
||||||
|
client success. This focus has established us as trusted
|
||||||
|
advisors and thought leaders in digital transformation.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg">
|
||||||
|
{/* Replace with a relevant, high-quality image representing innovation or teamwork */}
|
||||||
|
<Image
|
||||||
|
src="/images/team-collaborative.png"
|
||||||
|
alt="Team collaborating on innovative solutions"
|
||||||
|
layout="fill"
|
||||||
|
objectFit="cover"
|
||||||
|
className="transition-transform duration-500 hover:scale-105"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 3: Vision & Mission (Similar layout, refined look) */}
|
||||||
|
<section className="py-16 md:py-24 bg-white">
|
||||||
|
<div className="container mx-auto px-6 text-center mb-12">
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900">
|
||||||
|
Our North Star
|
||||||
|
</h2>
|
||||||
|
<p className="text-md md:text-lg text-gray-600 mt-3 max-w-2xl mx-auto font-poppins">
|
||||||
|
Guiding our strategy, actions, and partnerships.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-10 md:gap-12">
|
||||||
|
{/* Vision Card */}
|
||||||
|
<div
|
||||||
|
className="bg-gray-50 p-8 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 border-t-4 border-gold-500 flex flex-col items-center text-center"
|
||||||
|
style={{ borderColor: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
<FaBullseye
|
||||||
|
className="text-5xl mb-5 text-gold-500"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h3 className="text-2xl font-bold mb-4 font-poppins text-gray-900">
|
||||||
|
Our Vision
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-700 leading-relaxed font-poppins flex-grow">
|
||||||
|
"To be global leaders in delivering cutting-edge IT
|
||||||
|
solutions, pushing the boundaries of what's possible, and
|
||||||
|
transforming industries for the better. We aim to empower
|
||||||
|
organisations to break through technological barriers and
|
||||||
|
achieve greater success."
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/* Mission Card */}
|
||||||
|
<div
|
||||||
|
className="bg-gray-50 p-8 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300 border-t-4 border-gold-500 flex flex-col items-center text-center"
|
||||||
|
style={{ borderColor: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
<FaHandshake
|
||||||
|
className="text-5xl mb-5 text-gold-500"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h3 className="text-2xl font-bold mb-4 font-poppins text-gray-900">
|
||||||
|
Our Mission
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-700 leading-relaxed font-poppins flex-grow">
|
||||||
|
"We are dedicated to creating tailored, innovative
|
||||||
|
solutions that drive business success. By combining expertise
|
||||||
|
with cutting-edge technology, we solve complex problems and
|
||||||
|
enable our clients to achieve outstanding results. We partner
|
||||||
|
closely with clients to ensure every solution aligns with their
|
||||||
|
unique needs for long-term success."
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 4: Our Approach & Methodology */}
|
||||||
|
<section className="py-16 md:py-24 bg-gradient-to-br from-gray-100 to-gray-200">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="text-center mb-14">
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 mb-4">
|
||||||
|
How We Deliver Excellence
|
||||||
|
</h2>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 max-w-3xl mx-auto font-poppins">
|
||||||
|
Our methodology is built on collaboration, precision, and a
|
||||||
|
relentless focus on delivering impactful results. We tailor our
|
||||||
|
process to fit your specific project needs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||||
|
{ourApproach.map((item) => (
|
||||||
|
<div
|
||||||
|
key={item.title}
|
||||||
|
className="bg-white p-6 rounded-lg shadow-md text-center transform transition duration-300 hover:-translate-y-2 hover:shadow-xl"
|
||||||
|
>
|
||||||
|
<item.icon
|
||||||
|
className="text-4xl text-gold-500 mx-auto mb-5"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h4 className="text-xl font-semibold mb-3 font-poppins">
|
||||||
|
{item.title}
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-600 font-poppins text-sm leading-relaxed">
|
||||||
|
{item.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 5: Industry Expertise */}
|
||||||
|
<section className="py-16 md:py-24 bg-white">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-12 items-center">
|
||||||
|
<div className="lg:col-span-1">
|
||||||
|
<FaBriefcase
|
||||||
|
className="text-5xl text-gold-500 mb-4"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold mb-4 font-poppins text-gray-900 leading-tight">
|
||||||
|
Deep Domain Knowledge
|
||||||
|
</h2>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 leading-relaxed font-poppins">
|
||||||
|
We combine broad technological capabilities with specialized
|
||||||
|
expertise across key industries, understanding the unique
|
||||||
|
challenges and opportunities within each sector.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="lg:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
{industryExpertise.map((exp) => (
|
||||||
|
<div
|
||||||
|
key={exp.industry}
|
||||||
|
className="bg-gray-50 p-6 rounded-lg shadow-sm border-l-4 border-gold-500"
|
||||||
|
style={{ borderColor: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
<h4 className="text-lg font-semibold mb-2 font-poppins">
|
||||||
|
{exp.industry}
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-600 font-poppins text-sm leading-relaxed">
|
||||||
|
{exp.details}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 6: Technology Philosophy */}
|
||||||
|
<section className="py-16 md:py-24 bg-gray-800 text-white">
|
||||||
|
<div className="container mx-auto px-6 text-center">
|
||||||
|
<FaMicrochip
|
||||||
|
className="text-5xl text-gold-500 mx-auto mb-5"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold mb-4 font-poppins">
|
||||||
|
Smart Technology, Applied Wisely
|
||||||
|
</h2>
|
||||||
|
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed text-gray-300 mb-8 font-poppins">
|
||||||
|
We don't chase trends; we select and implement technologies
|
||||||
|
strategically. Our focus is on building solutions that are:
|
||||||
|
</p>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-4xl mx-auto">
|
||||||
|
<div className="bg-gray-700 p-6 rounded-lg">
|
||||||
|
<h4
|
||||||
|
className="text-xl font-semibold mb-2 font-poppins text-gold-500"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
Scalable & Future-Proof
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-300 font-poppins text-sm">
|
||||||
|
Designed to grow with your business and adapt to future
|
||||||
|
technological advancements.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="bg-gray-700 p-6 rounded-lg">
|
||||||
|
<h4
|
||||||
|
className="text-xl font-semibold mb-2 font-poppins text-gold-500"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
Robust & Reliable
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-300 font-poppins text-sm">
|
||||||
|
Built with quality and security at the core, ensuring dependable
|
||||||
|
performance.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="bg-gray-700 p-6 rounded-lg">
|
||||||
|
<h4
|
||||||
|
className="text-xl font-semibold mb-2 font-poppins text-gold-500"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
Best-Fit Solutions
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-300 font-poppins text-sm">
|
||||||
|
Chosen based on your specific needs, budget, and existing
|
||||||
|
infrastructure, not just the latest hype.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 7: Core Values (Reusing previous structure, adjusting background) */}
|
||||||
|
<section className="py-16 md:py-24 bg-gray-100">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-poppins text-gray-900">
|
||||||
|
Our Foundational Values
|
||||||
|
</h2>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{coreValues.map((value) => (
|
||||||
|
<div
|
||||||
|
key={value.title}
|
||||||
|
className="bg-white p-6 rounded-lg shadow-sm text-center transition-shadow duration-300 hover:shadow-lg"
|
||||||
|
>
|
||||||
|
<value.icon
|
||||||
|
className="text-4xl text-gold-500 mx-auto mb-4"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h4 className="text-xl font-semibold mb-2 font-poppins">
|
||||||
|
{value.title}
|
||||||
|
</h4>
|
||||||
|
<p className="text-gray-600 font-poppins text-sm leading-relaxed">
|
||||||
|
{value.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 8: The OMS Partnership */}
|
||||||
|
<section className="py-16 md:py-24 bg-white">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||||
|
<div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg order-last md:order-first">
|
||||||
|
{/* Replace with an image representing partnership or client collaboration */}
|
||||||
|
<Image
|
||||||
|
src="/images/partners.jpg"
|
||||||
|
alt="Client partnership and collaboration"
|
||||||
|
layout="fill"
|
||||||
|
objectFit="cover"
|
||||||
|
className="transition-transform duration-500 hover:scale-105"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<FaUsers
|
||||||
|
className="text-5xl text-gold-500 mb-4"
|
||||||
|
style={{ color: "#e1c44a" }}
|
||||||
|
/>
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold mb-6 font-poppins text-gray-900 leading-tight">
|
||||||
|
More Than Vendors, <br className="hidden md:inline" />{" "}
|
||||||
|
We're Partners
|
||||||
|
</h2>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 leading-relaxed mb-4 font-poppins">
|
||||||
|
We believe the best results come from true collaboration. We
|
||||||
|
invest time in understanding your culture, goals, and
|
||||||
|
challenges, working alongside your team as an extension of your
|
||||||
|
own capabilities.
|
||||||
|
</p>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 leading-relaxed font-poppins">
|
||||||
|
This means open communication, shared goals, proactive
|
||||||
|
problem-solving, and a long-term commitment to your success,
|
||||||
|
extending far beyond project completion.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 9: Our Leadership Team */}
|
||||||
|
<section className="py-16 md:py-24 bg-gray-50">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="text-center mb-14">
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 mb-4">
|
||||||
|
Meet Our Leadership
|
||||||
|
</h2>
|
||||||
|
<p className="text-md md:text-lg text-gray-700 max-w-3xl mx-auto font-poppins">
|
||||||
|
Slightly enhance the intro. E.g., Guided by experience and a
|
||||||
|
passion for innovation, our leadership team fosters a culture of
|
||||||
|
excellence and empowers our experts to deliver outstanding results
|
||||||
|
for our clients.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 md:gap-10 justify-center">
|
||||||
|
{/* Added justify-center */}
|
||||||
|
{leadershipTeam.map((member) => (
|
||||||
|
<div
|
||||||
|
key={member.id}
|
||||||
|
className="bg-white rounded-lg shadow-lg overflow-hidden text-center transition-transform duration-300 hover:scale-105 max-w-sm mx-auto"
|
||||||
|
>
|
||||||
|
{/* Added max-width and mx-auto for centering if fewer than 3 items */}
|
||||||
|
<div className="relative h-60 w-full">
|
||||||
|
{/* Slightly taller image */}
|
||||||
|
<Image
|
||||||
|
src={member.imageUrl || "/images/profile1.jpg"}
|
||||||
|
alt={`Photo of ${member.name}`}
|
||||||
|
layout="fill"
|
||||||
|
objectFit="cover"
|
||||||
|
className="bg-gray-200"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="p-6">
|
||||||
|
<h4 className="text-xl font-semibold font-poppins mb-1">
|
||||||
|
{member.name}
|
||||||
|
</h4>
|
||||||
|
<p
|
||||||
|
className="text-gold-600 font-poppins text-sm mb-3"
|
||||||
|
style={{ color: "#c8a93d" }}
|
||||||
|
>
|
||||||
|
{member.title}
|
||||||
|
</p>
|
||||||
|
<p className="text-gray-600 font-poppins text-sm mb-4">
|
||||||
|
{member.bio}
|
||||||
|
</p>
|
||||||
|
{member.linkedinUrl && member.linkedinUrl !== "#" && (
|
||||||
|
<a
|
||||||
|
href={member.linkedinUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-sm font-medium text-blue-600 hover:text-blue-800 transition-colors duration-200 font-poppins"
|
||||||
|
aria-label={`LinkedIn profile of ${member.name}`}
|
||||||
|
>
|
||||||
|
{/* Using a simple text link for cleanliness */}
|
||||||
|
Connect on LinkedIn
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{/* Button removed as requested */}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 10: Commitment to Impact (Optional, but adds value) */}
|
||||||
|
<section
|
||||||
|
className="py-16 md:py-24 bg-gold-500 text-gray-900"
|
||||||
|
style={{ backgroundColor: "#e1c44a" }}
|
||||||
|
>
|
||||||
|
<div className="container mx-auto px-6 text-center">
|
||||||
|
<FaChartLine className="text-5xl mx-auto mb-5" />
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold mb-4 font-poppins">
|
||||||
|
Driving Measurable Impact
|
||||||
|
</h2>
|
||||||
|
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed font-poppins">
|
||||||
|
Ultimately, our success is measured by yours. We are committed to
|
||||||
|
delivering solutions that not only meet technical requirements but
|
||||||
|
also drive efficiency, foster growth, enhance user experiences, and
|
||||||
|
provide a clear return on investment. Let's build a successful
|
||||||
|
future, together.
|
||||||
|
</p>
|
||||||
|
{/* Optional CTA to contact */}
|
||||||
|
<div className="mt-10">
|
||||||
|
<a
|
||||||
|
href="/contact"
|
||||||
|
className="inline-block bg-gray-800 text-white font-bold py-3 px-8 rounded-md hover:bg-gray-900 transition-colors duration-300 font-poppins"
|
||||||
|
>
|
||||||
|
Start the Conversation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
BIN
app/favicon.ico
|
Before Width: | Height: | Size: 25 KiB |
24
app/icon.svg
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<svg width="1005" height="1005" viewBox="0 0 1005 1005" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M502.085 0L1004.09 502L502.085 1004L0.0844712 502L502.085 0Z" fill="white"/>
|
||||||
|
<path d="M502.122 92.0752L912.207 502.16L502.122 912.244L92.0376 502.16L502.122 92.0752Z" fill="url(#paint0_linear_67_245)"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M954.507 502.085L502 49.5779L49.493 502.085L502 954.592L954.507 502.085ZM502 0.0849609L2.81409e-05 502.085L502 1004.08L1004 502.085L502 0.0849609Z" fill="url(#paint1_linear_67_245)"/>
|
||||||
|
<path d="M343.932 579.034C324.45 579.034 309.266 574.083 298.379 564.181C287.492 554.279 281.762 539.57 281.189 520.053C281.046 515.891 280.975 509.792 280.975 501.756C280.975 493.576 281.046 487.405 281.189 483.244C281.762 464.158 287.636 449.52 298.809 439.331C309.982 429.142 325.023 424.048 343.932 424.048C362.841 424.048 377.881 429.142 389.055 439.331C400.371 449.52 406.316 464.158 406.889 483.244C407.176 491.567 407.319 497.738 407.319 501.756C407.319 505.631 407.176 511.73 406.889 520.053C406.173 539.57 400.371 554.279 389.485 564.181C378.598 574.083 363.413 579.034 343.932 579.034ZM343.932 554.279C353.529 554.279 361.193 551.409 366.923 545.669C372.653 539.785 375.733 530.888 376.163 518.977C376.449 510.366 376.592 504.554 376.592 501.541C376.592 498.24 376.449 492.428 376.163 484.105C375.733 472.194 372.653 463.368 366.923 457.628C361.193 451.744 353.529 448.803 343.932 448.803C334.478 448.803 326.885 451.744 321.156 457.628C315.426 463.368 312.346 472.194 311.916 484.105C311.773 488.267 311.701 494.078 311.701 501.541C311.701 508.86 311.773 514.672 311.916 518.977C312.346 530.888 315.354 539.785 320.941 545.669C326.671 551.409 334.334 554.279 343.932 554.279Z" fill="black" fill-opacity="0.87"/>
|
||||||
|
<path d="M440.906 576.881C439.33 576.881 438.041 576.451 437.038 575.59C436.035 574.585 435.534 573.294 435.534 571.715V431.582C435.534 430.003 436.035 428.712 437.038 427.707C438.041 426.703 439.33 426.2 440.906 426.2H457.881C460.889 426.2 463.038 427.564 464.327 430.29L505.797 507.783L547.697 430.29C549.129 427.564 551.278 426.2 554.143 426.2H570.903C572.479 426.2 573.768 426.703 574.771 427.707C575.773 428.712 576.275 430.003 576.275 431.582V571.715C576.275 573.294 575.773 574.585 574.771 575.59C573.768 576.451 572.479 576.881 570.903 576.881H552.854C551.421 576.881 550.204 576.379 549.201 575.374C548.198 574.37 547.697 573.15 547.697 571.715V478.508L517.615 535.982C515.753 539.139 513.317 540.718 510.309 540.718H501.5C498.491 540.718 496.056 539.139 494.194 535.982L464.112 478.508V571.715C464.112 573.15 463.611 574.37 462.608 575.374C461.748 576.379 460.531 576.881 458.955 576.881H440.906Z" fill="black" fill-opacity="0.87"/>
|
||||||
|
<path d="M661.911 579.034C649.162 579.034 638.203 577.096 629.036 573.222C619.868 569.347 612.92 564.253 608.193 557.938C603.466 551.624 600.959 544.808 600.673 537.489C600.673 536.197 601.102 535.121 601.962 534.26C602.821 533.399 603.896 532.968 605.185 532.968H624.308C626.027 532.968 627.317 533.327 628.176 534.045C629.179 534.619 630.11 535.623 630.969 537.058C632.402 541.938 635.697 546.027 640.854 549.328C646.01 552.629 653.03 554.279 661.911 554.279C672.081 554.279 679.745 552.629 684.902 549.328C690.059 545.884 692.637 541.148 692.637 535.121C692.637 531.103 691.277 527.802 688.555 525.219C685.976 522.636 682.037 520.412 676.737 518.546C671.58 516.681 663.845 514.385 653.531 511.658C636.628 507.64 624.237 502.33 616.358 495.729C608.623 488.984 604.755 479.441 604.755 467.099C604.755 458.776 606.975 451.386 611.416 444.928C616 438.47 622.518 433.376 630.969 429.645C639.564 425.913 649.52 424.048 660.837 424.048C672.583 424.048 682.753 426.129 691.348 430.29C699.943 434.452 706.461 439.69 710.901 446.004C715.485 452.175 717.921 458.346 718.207 464.516C718.207 465.808 717.777 466.884 716.918 467.745C716.058 468.606 714.984 469.037 713.695 469.037H693.712C690.704 469.037 688.627 467.674 687.481 464.947C686.621 460.355 683.756 456.552 678.886 453.538C674.015 450.381 667.999 448.803 660.837 448.803C652.815 448.803 646.512 450.309 641.928 453.323C637.344 456.337 635.052 460.713 635.052 466.454C635.052 470.472 636.198 473.772 638.49 476.356C640.782 478.939 644.363 481.235 649.233 483.244C654.247 485.253 661.409 487.477 670.721 489.917C683.326 492.787 693.354 496.016 700.803 499.603C708.395 503.191 713.981 507.712 717.562 513.165C721.144 518.618 722.934 525.578 722.934 534.045C722.934 543.229 720.356 551.265 715.199 558.154C710.185 564.898 703.023 570.065 693.712 573.652C684.544 577.24 673.944 579.034 661.911 579.034Z" fill="black" fill-opacity="0.87"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_67_245" x1="233.025" y1="357.551" x2="595.992" y2="804.51" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.0767781" stop-color="#E1C44A"/>
|
||||||
|
<stop offset="0.290113" stop-color="#E1C44A" stop-opacity="0.7"/>
|
||||||
|
<stop offset="0.463052" stop-color="#E1C44A" stop-opacity="0.26"/>
|
||||||
|
<stop offset="0.675574" stop-color="#E1C44A" stop-opacity="0.71"/>
|
||||||
|
<stop offset="1" stop-color="#E1C44A"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_67_245" x1="346.014" y1="314.556" x2="718.674" y2="491.224" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#E1C44A"/>
|
||||||
|
<stop offset="0.201382" stop-color="#E1C44A" stop-opacity="0.7"/>
|
||||||
|
<stop offset="0.463052" stop-color="#E1C44A" stop-opacity="0.09"/>
|
||||||
|
<stop offset="0.744023" stop-color="#E1C44A" stop-opacity="0.71"/>
|
||||||
|
<stop offset="1" stop-color="#E1C44A"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.3 KiB |
@ -1,303 +1,21 @@
|
|||||||
// components/Header.tsx
|
// components/Header.tsx (Server Component)
|
||||||
"use client";
|
import React from "react";
|
||||||
|
import { auth } from "@/auth"; // Only need auth (for session) from here now
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import HeaderClient from "./HeaderClient";
|
||||||
import Link from "next/link";
|
import { handleSignInAction, handleSignOutAction } from "@/actions/auth-action";
|
||||||
import Image from "next/image";
|
|
||||||
// Use usePathname only if needed for active state logic not shown here
|
|
||||||
// import { usePathname } from "next/navigation";
|
|
||||||
import {
|
|
||||||
FiChevronDown,
|
|
||||||
FiClipboard,
|
|
||||||
FiArrowRight,
|
|
||||||
FiMenu,
|
|
||||||
FiX,
|
|
||||||
} from "react-icons/fi";
|
|
||||||
import ThemeToggle from "./ThemeToggle"; // Assuming ThemeToggle component exists
|
|
||||||
|
|
||||||
const omsLogoUrl = "/oms-logo.svg"; // Ensure this is in your /public folder
|
const Header = async () => {
|
||||||
|
// Fetch session data on the server
|
||||||
// --- Basic Dropdown Component ---
|
const session = await auth();
|
||||||
// Using semantic variables for background, text, and borders
|
|
||||||
type DropdownMenuProps = {
|
|
||||||
trigger: React.ReactNode;
|
|
||||||
children: React.ReactNode;
|
|
||||||
menuClasses?: string;
|
|
||||||
};
|
|
||||||
const DropdownMenu = ({
|
|
||||||
trigger,
|
|
||||||
children,
|
|
||||||
menuClasses = "w-48",
|
|
||||||
}: DropdownMenuProps) => (
|
|
||||||
// Using group-focus-within for better keyboard/touch accessibility
|
|
||||||
<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 {/* USE SEMANTIC VARS */}
|
|
||||||
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>
|
|
||||||
);
|
|
||||||
|
|
||||||
// Dropdown Link component using semantic variables
|
|
||||||
type DropdownLinkProps = {
|
|
||||||
href: string;
|
|
||||||
children: React.ReactNode;
|
|
||||||
onClick?: () => void; // Added onClick for mobile menu closure
|
|
||||||
};
|
|
||||||
const DropdownLink = ({ href, children, onClick }: DropdownLinkProps) => (
|
|
||||||
<Link
|
|
||||||
href={href}
|
|
||||||
onClick={onClick} // Call onClick if provided
|
|
||||||
className="block w-full text-left px-4 py-2 text-sm text-card-foreground hover:bg-secondary hover:text-primary" // USE SEMANTIC VARS
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
// --- End Dropdown Component ---
|
|
||||||
|
|
||||||
const Header = () => {
|
|
||||||
// If you need pathname for active states later:
|
|
||||||
// const pathname = usePathname() || "/";
|
|
||||||
// const isActive = (path: string) => pathname === path;
|
|
||||||
// const isActive = (path: string) => false; // Simple placeholder
|
|
||||||
|
|
||||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
||||||
|
|
||||||
const toggleMenu = () => setIsMenuOpen((open) => !open);
|
|
||||||
// Close menu when a link is clicked
|
|
||||||
const handleMobileLinkClick = () => setIsMenuOpen(false);
|
|
||||||
|
|
||||||
const currentLogo = omsLogoUrl;
|
|
||||||
|
|
||||||
|
// Pass the session data and YOUR Server Actions as props
|
||||||
return (
|
return (
|
||||||
// Use semantic variables for header background and border
|
<HeaderClient
|
||||||
<header className="sticky top-0 z-50 shadow-md bg-background border-b border-border">
|
session={session}
|
||||||
{/* Top Row */}
|
handleSignIn={handleSignInAction} // Pass YOUR sign-in Server Action
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
handleSignOut={handleSignOutAction} // Pass YOUR sign-out Server Action
|
||||||
<div className="flex justify-between items-center h-16">
|
/>
|
||||||
{/* Logo */}
|
|
||||||
<Link
|
|
||||||
href="/"
|
|
||||||
className="flex items-center space-x-2"
|
|
||||||
title="OMS Home"
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
src={currentLogo}
|
|
||||||
alt="OMS Logo"
|
|
||||||
width={40}
|
|
||||||
height={40}
|
|
||||||
priority
|
|
||||||
/>
|
|
||||||
{/* Use semantic variable for text color */}
|
|
||||||
<span className="text-xl font-bold text-foreground hidden sm:inline">
|
|
||||||
Owethu Managed Services
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{/* Desktop Navigation */}
|
|
||||||
<nav className="hidden md:flex items-center space-x-6 lg:space-x-8">
|
|
||||||
{/* Use semantic variables for text, hover uses primary */}
|
|
||||||
<Link
|
|
||||||
href="/"
|
|
||||||
className={`text-sm font-medium text-foreground/80 hover:text-primary`}
|
|
||||||
/* Active state example (requires usePathname) */
|
|
||||||
/* ${isActive("/") ? "text-primary font-semibold" : "text-foreground/80 hover:text-primary"} */
|
|
||||||
>
|
|
||||||
Home
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/about"
|
|
||||||
className={`text-sm font-medium text-foreground/80 hover:text-primary`}
|
|
||||||
/* Active state example */
|
|
||||||
/* ${pathname.startsWith("/about") ? "text-primary font-semibold" : "text-foreground/80 hover:text-primary"} */
|
|
||||||
>
|
|
||||||
About Us
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
href="/contact"
|
|
||||||
className={`text-sm font-medium text-foreground/80 hover:text-primary`}
|
|
||||||
/* Active state example */
|
|
||||||
/* ${isActive("/contact") ? "text-primary font-semibold" : "text-foreground/80 hover:text-primary"} */
|
|
||||||
>
|
|
||||||
Contact Us
|
|
||||||
</Link>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
{/* Right Utilities (Desktop) */}
|
|
||||||
<div className="hidden md:flex items-center space-x-4">
|
|
||||||
<ThemeToggle />
|
|
||||||
|
|
||||||
{/* Use semantic variables for button */}
|
|
||||||
<Link
|
|
||||||
href="/request-demo"
|
|
||||||
className="flex items-center text-sm font-medium bg-primary text-primary-foreground px-3 py-1.5 rounded-lg hover:bg-opacity-90 transition-colors" // Use rounded-lg from radius
|
|
||||||
title="Request a Demo"
|
|
||||||
>
|
|
||||||
<FiClipboard className="w-4 h-4 mr-1.5" />
|
|
||||||
Request Demo
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mobile Buttons */}
|
|
||||||
<div className="md:hidden flex items-center">
|
|
||||||
<ThemeToggle /> {/* Theme toggle appears first */}
|
|
||||||
<button
|
|
||||||
onClick={toggleMenu}
|
|
||||||
className="text-foreground/60 hover:text-primary focus:outline-none ml-3" // Use semantic muted color, hover primary
|
|
||||||
aria-label="Toggle menu"
|
|
||||||
aria-expanded={isMenuOpen}
|
|
||||||
aria-controls="mobile-menu"
|
|
||||||
>
|
|
||||||
{isMenuOpen ? (
|
|
||||||
<FiX className="w-6 h-6" />
|
|
||||||
) : (
|
|
||||||
<FiMenu className="w-6 h-6" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Secondary Row */}
|
|
||||||
<div className="bg-primary">
|
|
||||||
{" "}
|
|
||||||
{/* Keep gold background */}
|
|
||||||
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
|
||||||
{/* Hide on mobile */}
|
|
||||||
<div className="hidden md:flex justify-between items-center h-12">
|
|
||||||
{/* Use primary-foreground for text color */}
|
|
||||||
<nav className="flex items-center space-x-6 lg:space-x-8 text-primary-foreground">
|
|
||||||
{/* Wrap dropdown triggers for consistent hover */}
|
|
||||||
<div className="hover:text-opacity-80 transition-opacity">
|
|
||||||
<DropdownMenu trigger={<span>Services</span>}>
|
|
||||||
<DropdownLink href="/services/resource-augmentation">
|
|
||||||
Resource Augmentation
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink href="/services/project-management">
|
|
||||||
Project Management
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink href="/services/product-development">
|
|
||||||
Product Development
|
|
||||||
</DropdownLink>
|
|
||||||
</DropdownMenu>
|
|
||||||
</div>
|
|
||||||
<div className="hover:text-opacity-80 transition-opacity">
|
|
||||||
<DropdownMenu trigger={<span>Products</span>}>
|
|
||||||
<DropdownLink href="/products/obse">OBSE</DropdownLink>
|
|
||||||
</DropdownMenu>
|
|
||||||
</div>
|
|
||||||
<div className="hover:text-opacity-80 transition-opacity">
|
|
||||||
<DropdownMenu trigger={<span>Join Our Team</span>}>
|
|
||||||
<DropdownLink href="/join-us/vacancies">
|
|
||||||
Vacancies
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink href="/join-us/portal">
|
|
||||||
Recruitment Portal
|
|
||||||
</DropdownLink>
|
|
||||||
</DropdownMenu>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
{/* Use primary-foreground for link */}
|
|
||||||
<Link
|
|
||||||
href="/services"
|
|
||||||
className="flex items-center text-sm font-medium text-primary-foreground hover:text-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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Mobile Menu Panel */}
|
|
||||||
<div
|
|
||||||
id="mobile-menu"
|
|
||||||
// Use semantic variables for background and border
|
|
||||||
className={`md:hidden absolute top-full left-0 w-full shadow-lg transition-all duration-300 ease-in-out overflow-hidden bg-card border-t border-border ${
|
|
||||||
isMenuOpen
|
|
||||||
? "max-h-[calc(100vh-4rem)] py-4 overflow-y-auto"
|
|
||||||
: "max-h-0 py-0" // Animate height, allow scroll
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{/* Use semantic variable for text color */}
|
|
||||||
<nav className="container mx-auto px-4 sm:px-6 lg:px-8 flex flex-col space-y-1 text-foreground">
|
|
||||||
{" "}
|
|
||||||
{/* Reduced space-y */}
|
|
||||||
{/* Simplified mobile links, using DropdownLink component for consistency */}
|
|
||||||
<DropdownLink href="/" onClick={handleMobileLinkClick}>
|
|
||||||
Home
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink href="/about" onClick={handleMobileLinkClick}>
|
|
||||||
About Us
|
|
||||||
</DropdownLink>
|
|
||||||
{/* Maybe use collapsible sections here in a real app, but simple list for now */}
|
|
||||||
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
|
|
||||||
Services
|
|
||||||
</span>
|
|
||||||
<DropdownLink
|
|
||||||
href="/services/resource-augmentation"
|
|
||||||
onClick={handleMobileLinkClick}
|
|
||||||
>
|
|
||||||
Resource Augmentation
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink
|
|
||||||
href="/services/project-management"
|
|
||||||
onClick={handleMobileLinkClick}
|
|
||||||
>
|
|
||||||
Project Management
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink
|
|
||||||
href="/services/product-development"
|
|
||||||
onClick={handleMobileLinkClick}
|
|
||||||
>
|
|
||||||
Product Development
|
|
||||||
</DropdownLink>
|
|
||||||
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
|
|
||||||
Products
|
|
||||||
</span>
|
|
||||||
<DropdownLink href="/products/obse" onClick={handleMobileLinkClick}>
|
|
||||||
OBSE
|
|
||||||
</DropdownLink>
|
|
||||||
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
|
|
||||||
Join Us
|
|
||||||
</span>
|
|
||||||
<DropdownLink
|
|
||||||
href="/join-us/vacancies"
|
|
||||||
onClick={handleMobileLinkClick}
|
|
||||||
>
|
|
||||||
Vacancies
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink href="/join-us/portal" onClick={handleMobileLinkClick}>
|
|
||||||
Recruitment Portal
|
|
||||||
</DropdownLink>
|
|
||||||
<DropdownLink href="/contact" onClick={handleMobileLinkClick}>
|
|
||||||
Contact Us
|
|
||||||
</DropdownLink>
|
|
||||||
{/* Demo button at the bottom */}
|
|
||||||
<div className="pt-4">
|
|
||||||
<Link
|
|
||||||
href="/request-demo"
|
|
||||||
onClick={handleMobileLinkClick}
|
|
||||||
// Use semantic variables for button style
|
|
||||||
className="flex w-full justify-center items-center text-sm font-medium bg-primary text-primary-foreground px-4 py-2 rounded-lg hover:bg-opacity-90 transition-colors"
|
|
||||||
title="Request a Demo"
|
|
||||||
>
|
|
||||||
<FiClipboard className="w-4 h-4 mr-1.5" />
|
|
||||||
Request Demo
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
370
components/HeaderClient.tsx
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
// components/HeaderClient.tsx
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import Image from "next/image";
|
||||||
|
// Use usePathname only if needed for active state logic not shown here
|
||||||
|
// import { usePathname } from "next/navigation";
|
||||||
|
import {
|
||||||
|
FiChevronDown,
|
||||||
|
FiClipboard,
|
||||||
|
FiArrowRight,
|
||||||
|
FiMenu,
|
||||||
|
FiX,
|
||||||
|
FiLogIn, // Import the login icon
|
||||||
|
} from "react-icons/fi";
|
||||||
|
import ThemeToggle from "./ThemeToggle"; // Assuming ThemeToggle component exists
|
||||||
|
import type { Session } from "@auth/core/types"; // Import Session type for props
|
||||||
|
|
||||||
|
const omsLogoUrl = "/oms-logo.svg"; // Ensure this is in your /public folder
|
||||||
|
|
||||||
|
// --- Basic Dropdown Component ---
|
||||||
|
// (Keep the DropdownMenu and DropdownLink component definitions here as before)
|
||||||
|
type DropdownMenuProps = {
|
||||||
|
trigger: React.ReactNode;
|
||||||
|
children: React.ReactNode;
|
||||||
|
menuClasses?: string;
|
||||||
|
};
|
||||||
|
const DropdownMenu = ({
|
||||||
|
trigger,
|
||||||
|
children,
|
||||||
|
menuClasses = "w-48",
|
||||||
|
}: DropdownMenuProps) => (
|
||||||
|
// Using group-focus-within for better keyboard/touch accessibility
|
||||||
|
<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 {/* USE SEMANTIC VARS */}
|
||||||
|
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;
|
||||||
|
onClick?: () => void; // Added onClick for mobile menu closure
|
||||||
|
};
|
||||||
|
const DropdownLink = ({ href, children, onClick }: DropdownLinkProps) => (
|
||||||
|
<Link
|
||||||
|
href={href}
|
||||||
|
onClick={onClick} // Call onClick if provided
|
||||||
|
className="block w-full text-left px-4 py-2 text-sm text-card-foreground hover:bg-secondary hover:text-primary" // USE SEMANTIC VARS
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
// --- End Dropdown Component ---
|
||||||
|
|
||||||
|
// --- Define Props for the Client Component ---
|
||||||
|
type HeaderClientProps = {
|
||||||
|
session: Session | null; // Accept session from the server component
|
||||||
|
handleSignIn: () => void; // Pass sign-in handler
|
||||||
|
handleSignOut: () => void; // Pass sign-out handler
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- The Main Client Component ---
|
||||||
|
const HeaderClient = ({
|
||||||
|
session,
|
||||||
|
handleSignIn,
|
||||||
|
handleSignOut,
|
||||||
|
}: HeaderClientProps) => {
|
||||||
|
// --- Client-side state and hooks ---
|
||||||
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||||
|
// const pathname = usePathname() || "/"; // Uncomment if needed
|
||||||
|
// const isActive = (path: string) => pathname === path; // Uncomment if needed
|
||||||
|
|
||||||
|
const toggleMenu = () => setIsMenuOpen((open) => !open);
|
||||||
|
const handleMobileLinkClick = () => setIsMenuOpen(false);
|
||||||
|
|
||||||
|
const currentLogo = omsLogoUrl;
|
||||||
|
|
||||||
|
return (
|
||||||
|
// Use semantic variables for header background and border
|
||||||
|
<header className="sticky top-0 z-50 shadow-md bg-background border-b border-border">
|
||||||
|
{/* Top Row */}
|
||||||
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div className="flex justify-between items-center h-16">
|
||||||
|
{/* Logo */}
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className="flex items-center space-x-2"
|
||||||
|
title="OMS Home"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={currentLogo}
|
||||||
|
alt="OMS Logo"
|
||||||
|
width={40}
|
||||||
|
height={40}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
{/* Use semantic variable for text color */}
|
||||||
|
<span className="text-xl font-bold text-foreground hidden sm:inline">
|
||||||
|
Owethu Managed Services
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* Desktop Navigation */}
|
||||||
|
<nav className="hidden md:flex items-center space-x-6 lg:space-x-8">
|
||||||
|
{/* Use semantic variables for text, hover uses primary */}
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className={`text-sm font-medium text-foreground/80 hover:text-primary transition`}
|
||||||
|
>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/about"
|
||||||
|
className={`text-sm font-medium text-foreground/80 hover:text-primary transition`}
|
||||||
|
>
|
||||||
|
About Us
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/contact"
|
||||||
|
className={`text-sm font-medium text-foreground/80 hover:text-primary transition`}
|
||||||
|
>
|
||||||
|
Contact Us
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{/* Desktop Utilities */}
|
||||||
|
<div className="hidden md:flex items-center space-x-4">
|
||||||
|
<ThemeToggle />
|
||||||
|
|
||||||
|
{/* Request Demo Button */}
|
||||||
|
<Link
|
||||||
|
href="/request-demo"
|
||||||
|
className="flex items-center text-sm font-medium bg-primary text-primary-foreground px-3 py-1.5 rounded-lg hover:bg-opacity-90 transition-colors"
|
||||||
|
title="Request a Demo"
|
||||||
|
>
|
||||||
|
<FiClipboard className="w-4 h-4 mr-1.5" />
|
||||||
|
Request Demo
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{/* --- Auth Section --- */}
|
||||||
|
{session?.user ? (
|
||||||
|
// Logged In: User Dropdown
|
||||||
|
<DropdownMenu
|
||||||
|
menuClasses="w-40 right-0 left-auto" // Align dropdown to the right
|
||||||
|
trigger={
|
||||||
|
<div className="flex items-center space-x-2 cursor-pointer hover:opacity-80 transition">
|
||||||
|
<Image
|
||||||
|
src={session.user.image || "/default-avatar.png"} // Provide a fallback avatar
|
||||||
|
alt={session.user.name || "User"}
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
className="rounded-full ring-1 ring-primary ring-offset-2 ring-offset-background" // Added offset
|
||||||
|
/>
|
||||||
|
{/* Optionally hide name on smaller desktop screens */}
|
||||||
|
<span className="text-sm font-medium text-foreground hidden lg:inline">
|
||||||
|
{session.user.name?.split(" ")[0]}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{/* Sign Out inside the dropdown */}
|
||||||
|
<button
|
||||||
|
onClick={() => handleSignOut()}
|
||||||
|
className="block w-full text-left px-4 py-2 text-sm text-destructive hover:bg-secondary hover:text-destructive transition" // Destructive color
|
||||||
|
>
|
||||||
|
Sign Out
|
||||||
|
</button>
|
||||||
|
</DropdownMenu>
|
||||||
|
) : (
|
||||||
|
// Logged Out: Icon Button to Sign In
|
||||||
|
<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>
|
||||||
|
)}
|
||||||
|
{/* --- End Auth Section --- */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Buttons */}
|
||||||
|
<div className="md:hidden flex items-center">
|
||||||
|
<ThemeToggle /> {/* Theme toggle remains */}
|
||||||
|
<button
|
||||||
|
onClick={toggleMenu}
|
||||||
|
className="text-foreground/60 hover:text-primary focus:outline-none ml-3" // Use semantic muted color, hover primary
|
||||||
|
aria-label="Toggle menu"
|
||||||
|
aria-expanded={isMenuOpen}
|
||||||
|
aria-controls="mobile-menu"
|
||||||
|
>
|
||||||
|
{isMenuOpen ? (
|
||||||
|
<FiX className="w-6 h-6" />
|
||||||
|
) : (
|
||||||
|
<FiMenu className="w-6 h-6" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Secondary Row (Desktop Only) */}
|
||||||
|
<div className="bg-primary">
|
||||||
|
<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-6 lg:space-x-8 text-primary-foreground">
|
||||||
|
<div className="hover:text-opacity-80 transition-opacity">
|
||||||
|
<DropdownMenu trigger={<span>Services</span>}>
|
||||||
|
<DropdownLink href="/services/resource-augmentation">
|
||||||
|
Resource Augmentation
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink href="/services/project-management">
|
||||||
|
Project Management
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink href="/services/product-development">
|
||||||
|
Product Development
|
||||||
|
</DropdownLink>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
<div className="hover:text-opacity-80 transition-opacity">
|
||||||
|
<DropdownMenu trigger={<span>Products</span>}>
|
||||||
|
<DropdownLink href="/products/obse">OBSE</DropdownLink>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
<div className="hover:text-opacity-80 transition-opacity">
|
||||||
|
<DropdownMenu trigger={<span>Join Our Team</span>}>
|
||||||
|
<DropdownLink href="/join-us/vacancies">
|
||||||
|
Vacancies
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink href="/join-us/portal">
|
||||||
|
Recruitment Portal
|
||||||
|
</DropdownLink>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<Link
|
||||||
|
href="/services"
|
||||||
|
className="flex items-center text-sm font-medium text-primary-foreground hover:text-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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu Panel */}
|
||||||
|
<div
|
||||||
|
id="mobile-menu"
|
||||||
|
// Use semantic variables for background and border
|
||||||
|
className={`md:hidden absolute top-full left-0 w-full shadow-lg transition-all duration-300 ease-in-out overflow-hidden bg-card border-t border-border ${
|
||||||
|
isMenuOpen
|
||||||
|
? "max-h-[calc(100vh-4rem)] py-4 overflow-y-auto"
|
||||||
|
: "max-h-0 py-0" // Animate height, allow scroll
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{/* Use semantic variable for text color */}
|
||||||
|
<nav className="container mx-auto px-4 sm:px-6 lg:px-8 flex flex-col space-y-1 text-foreground">
|
||||||
|
{" "}
|
||||||
|
{/* Reduced space-y */}
|
||||||
|
{/* Mobile Links */}
|
||||||
|
<DropdownLink href="/" onClick={handleMobileLinkClick}>
|
||||||
|
Home
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink href="/about" onClick={handleMobileLinkClick}>
|
||||||
|
About Us
|
||||||
|
</DropdownLink>
|
||||||
|
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
|
||||||
|
Services
|
||||||
|
</span>
|
||||||
|
<DropdownLink
|
||||||
|
href="/services/resource-augmentation"
|
||||||
|
onClick={handleMobileLinkClick}
|
||||||
|
>
|
||||||
|
Resource Augmentation
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink
|
||||||
|
href="/services/project-management"
|
||||||
|
onClick={handleMobileLinkClick}
|
||||||
|
>
|
||||||
|
Project Management
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink
|
||||||
|
href="/services/product-development"
|
||||||
|
onClick={handleMobileLinkClick}
|
||||||
|
>
|
||||||
|
Product Development
|
||||||
|
</DropdownLink>
|
||||||
|
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
|
||||||
|
Products
|
||||||
|
</span>
|
||||||
|
<DropdownLink href="/products/obse" onClick={handleMobileLinkClick}>
|
||||||
|
OBSE
|
||||||
|
</DropdownLink>
|
||||||
|
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
|
||||||
|
Join Us
|
||||||
|
</span>
|
||||||
|
<DropdownLink
|
||||||
|
href="/join-us/vacancies"
|
||||||
|
onClick={handleMobileLinkClick}
|
||||||
|
>
|
||||||
|
Vacancies
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink href="/join-us/portal" onClick={handleMobileLinkClick}>
|
||||||
|
Recruitment Portal
|
||||||
|
</DropdownLink>
|
||||||
|
<DropdownLink href="/contact" onClick={handleMobileLinkClick}>
|
||||||
|
Contact Us
|
||||||
|
</DropdownLink>
|
||||||
|
{/* Demo Button */}
|
||||||
|
<div className="pt-4">
|
||||||
|
<Link
|
||||||
|
href="/request-demo"
|
||||||
|
onClick={handleMobileLinkClick}
|
||||||
|
// Use semantic variables for button style
|
||||||
|
className="flex w-full justify-center items-center text-sm font-medium bg-primary text-primary-foreground px-4 py-2 rounded-lg hover:bg-opacity-90 transition-colors"
|
||||||
|
title="Request a Demo"
|
||||||
|
>
|
||||||
|
<FiClipboard className="w-4 h-4 mr-1.5" />
|
||||||
|
Request Demo
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
{/* Auth Buttons in Mobile Menu */}
|
||||||
|
<div className="pt-4 border-t border-border mt-4">
|
||||||
|
{session?.user ? (
|
||||||
|
// Sign Out Button (Text)
|
||||||
|
<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>
|
||||||
|
) : (
|
||||||
|
// Sign In Button (Text or Icon+Text)
|
||||||
|
<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" /> {/* Added icon here too */}
|
||||||
|
Sign In
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HeaderClient;
|
||||||
@ -1,7 +1,9 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
/* config options here */
|
images: {
|
||||||
|
domains: ["avatars.githubusercontent.com"],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
BIN
public/images/partners.jpg
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
public/images/profile1.jpg
Normal file
|
After Width: | Height: | Size: 603 KiB |
BIN
public/images/profile2.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/images/profile3.jpg
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/images/team-collaborative.png
Normal file
|
After Width: | Height: | Size: 3.1 MiB |