54 Commits

Author SHA1 Message Date
26e3d0975f Merge pull request #34 from OwethuManagedServices/09-09-2025-/Please-add-a-scroller-onTrusted-By-Industry-Leaders
Fix : Added a scroller on ClientLogoSection
2025-09-17 10:47:20 +02:00
4e6d0a5512 Fix : Added a scroller on ClientLogoSection 2025-09-17 10:44:00 +02:00
f0c68f549d Merge pull request #33 from OwethuManagedServices/09-09-2025-/Please-add-a-scroller-onTrusted-By-Industry-Leaders
feat: enhance ClientLogosSection with scrolling functionality and con…
2025-09-16 16:52:11 +02:00
2fade93bf7 feat: enhance ClientLogosSection with scrolling functionality and controls 2025-09-16 16:47:39 +02:00
33008c17f9 Merge pull request #32 from OwethuManagedServices/29-08-2025/Add-CVEvolve-Link-Under-OMS-Website-Products-Menu
29 08 2025/add cv evolve link under oms website products menu
2025-09-08 12:09:05 +02:00
8e889d5e53 fix: update product link and improve dropdown layout in HeaderClient 2025-09-08 11:49:23 +02:00
0530c9c943 fix:cvevolve link+seo+sm links 2025-09-04 15:39:37 +02:00
8d40a10e02 fix: updated tracking code 2025-06-11 16:54:02 +02:00
985c4b5a85 Merge branch 'dev' of https://github.com/OwethuManagedServices/oms-website-nextjs into dev 2025-06-11 16:42:18 +02:00
755eea55a4 feature: added umami 2025-06-11 16:42:02 +02:00
98f581b348 Merge pull request #31 from OwethuManagedServices/dev
Dev
2025-05-28 10:19:35 +02:00
8f828a374c Merge pull request #30 from OwethuManagedServices/25-05-2025/New-Changes
update contact phone number and button variant in CallToActionSection
2025-05-28 10:19:03 +02:00
944066c42f update contact phone number and button variant in CallToActionSection 2025-05-28 10:18:17 +02:00
45822f9af8 Merge pull request #29 from OwethuManagedServices/dev
Dev
2025-05-28 09:07:43 +02:00
3d5417852c Merge pull request #28 from OwethuManagedServices/25-05-2025/New-Changes
update default speed for client logos animation and modify footer con…
2025-05-28 09:06:01 +02:00
5c2714b202 update default speed for client logos animation and modify footer contact address 2025-05-28 09:04:35 +02:00
af917f3484 Merge pull request #26 from OwethuManagedServices/dev
Dev
2025-05-27 16:45:09 +02:00
0658c1ce28 Merge pull request #27 from OwethuManagedServices/25-05-2025/New-Changes
refactor newsletter subscription form layout for better responsiveness
2025-05-27 16:44:24 +02:00
ae6e2b020c refactor newsletter subscription form layout for better responsiveness 2025-05-27 16:43:21 +02:00
7ba4ef1872 Merge pull request #25 from OwethuManagedServices/25-05-2025/New-Changes
update section component structure
2025-05-27 16:16:11 +02:00
b908926912 update section component structure 2025-05-27 16:15:22 +02:00
2044f7207e Merge pull request #24 from OwethuManagedServices/dev
Dev
2025-05-27 15:45:27 +02:00
61ce1848d2 Merge pull request #23 from OwethuManagedServices/25-05-2025/New-Changes
knew changs
2025-05-27 15:44:59 +02:00
db391c833a knew changs 2025-05-27 15:44:07 +02:00
4f71f687d6 Merge pull request #22 from OwethuManagedServices/dev
Dev
2025-05-27 15:33:02 +02:00
91e2f34a63 Merge pull request #21 from OwethuManagedServices/25-05-2025/New-Changes
25-05-2025
2025-05-27 15:32:18 +02:00
91081f2f9d 25-05-2025 2025-05-27 15:31:07 +02:00
78e74dfc7d Merge pull request #20 from OwethuManagedServices/dev
Dev
2025-05-27 02:57:45 +02:00
be8a2fe95d Merge pull request #19 from OwethuManagedServices/25-05-2025/New-Changes
new colors and some minor fixes
2025-05-27 02:57:03 +02:00
860a895e45 new colors and some minor fixes 2025-05-27 02:56:04 +02:00
9949158d31 Merge pull request #18 from OwethuManagedServices/dev
Dev
2025-05-26 22:32:33 +02:00
6188a7ffbc Merge pull request #17 from OwethuManagedServices/25-05-2025/New-Changes
new changes
2025-05-26 22:32:00 +02:00
735f98f564 new changes 2025-05-26 22:30:04 +02:00
985f5c43ba Merge pull request #16 from OwethuManagedServices/dev
Dev
2025-05-26 16:42:30 +02:00
25691d6a2e Merge pull request #15 from OwethuManagedServices/25-05-2025/New-Changes
25-05-2025/For Oms cv evolve
2025-05-26 16:41:42 +02:00
5baa62e86d 25-05-2025/For Oms cv evolve 2025-05-26 16:40:46 +02:00
6f3c946845 Merge pull request #14 from OwethuManagedServices/dev
Dev
2025-05-26 11:29:34 +02:00
b84b287dc1 Merge pull request #13 from OwethuManagedServices/25-05-2025/New-Changes
removed contact us page
2025-05-26 11:28:32 +02:00
54b3b73657 removed contact us page 2025-05-26 11:26:58 +02:00
b1f701e55d replaced URL 2025-05-26 10:30:55 +02:00
d1c497c936 Merge pull request #12 from OwethuManagedServices/dev
Dev
2025-05-26 10:02:29 +02:00
6d2a8c1a59 Merge pull request #11 from OwethuManagedServices/25-05-2025/New-Changes
26-05-2025/Fixed Used Variables and Icons
2025-05-26 10:01:36 +02:00
feac643754 26-05-2025/Fixed Used Variables and Icons 2025-05-26 10:00:35 +02:00
af744bd192 Merge pull request #10 from OwethuManagedServices/dev
Dev
2025-05-26 09:53:57 +02:00
2eb3e35cdb Merge pull request #9 from OwethuManagedServices/25-05-2025/New-Changes
25 05 2025/new changes
2025-05-26 09:53:06 +02:00
782e887ff8 Merge branch '25-05-2025/New-Changes' of https://github.com/OwethuManagedServices/oms-website-nextjs into 25-05-2025/New-Changes 2025-05-26 09:51:44 +02:00
9c14197f0c 26-05-2025/Removed ChatWidget 2025-05-26 09:51:20 +02:00
b6bbf9b54d Merge pull request #8 from OwethuManagedServices/25-05-2025/New-Changes
25 05 2025/new changes
2025-05-26 09:49:53 +02:00
e9c8d25eb6 Merge branch 'dev' into 25-05-2025/New-Changes 2025-05-26 09:49:34 +02:00
62192ab8fb Merge pull request #6 from OwethuManagedServices/updated-site
fix: deployment issue
2025-05-19 16:40:04 +02:00
7175ef9821 fix: deployment issue 2025-05-19 16:38:31 +02:00
d93d3348f3 Merge pull request #5 from OwethuManagedServices/updated-site
Updated site
2025-05-19 16:13:42 +02:00
3f702a7592 05-19-2025/ update site 2025-05-19 16:01:33 +02:00
730dc51629 Merge pull request #2 from OwethuManagedServices/05-05-2025/Add-Toyota-on-Trusted-by-Partners
05 05 2025/add toyota on trusted by partners
2025-05-08 13:48:18 +02:00
24 changed files with 491 additions and 337 deletions

View File

@ -17,7 +17,7 @@ const CallToActionSection: React.FC<CallToActionSectionProps> = ({
}) => {
return (
// Use primary background, primary-foreground for text
<section className="bg-primary text-primary-foreground py-16 md:py-20">
<section className="bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-primary-foreground py-16 md:py-20">
{" "}
{/* Adjusted padding */}
<div className="container mx-auto px-4 sm:px-6 lg:px-8 text-center">
@ -30,7 +30,7 @@ const CallToActionSection: React.FC<CallToActionSectionProps> = ({
</p>{" "}
{/* Slightly less emphasis */}
{/* Button needs contrast on primary bg. Use a secondary/outline/custom variant */}
<Button href={buttonHref} variant="secondary" size="lg">
<Button href={buttonHref} variant="black" size="lg" >
{/* Example: Using 'secondary' which uses light/dark gray bg defined in globals */}
{/* OR custom class: className="bg-background text-foreground hover:bg-background/90" */}
{buttonText}

View File

@ -1,42 +1,87 @@
// components/ClientLogosSection.tsx
import React from "react";
"use client";
import { useRef, useEffect, useState } from "react";
import Image from "next/image";
// Define structure for client data - focusing on logos now
type Client = {
name: string;
logoUrl: string; // Expecting actual logo URLs now
logoUrl: string;
};
type ClientLogosSectionProps = {
title: string;
description?: string;
clients: Client[];
/** Control animation speed (lower number = faster). Default: 40s */
speed?: number;
/** Size of the square background container in pixels. Default: 120 */
speed?: number; // pixels per frame
squareSize?: number;
};
const ClientLogosSection: React.FC<ClientLogosSectionProps> = ({
const ClientLogosSection = ({
title,
description,
clients = [], // Default to empty array
speed = 50, //Default speed in seconds for one full cycle
squareSize = 120, // Default size for the square container (e.g., 120px)
}) => {
// Need at least one client to render the marquee
if (clients.length === 0) {
return null; // Or render a placeholder message if preferred
}
// Duplicate the clients for a seamless loop effect
clients = [],
speed = 1,
squareSize = 120,
}: ClientLogosSectionProps) => {
const extendedClients = [...clients, ...clients];
const squareDim = `${squareSize}px`; // Convert size to string for inline style
const padding = Math.round(squareSize / 6); // Calculate padding based on size (adjust divisor as needed)
const squareDim = `${squareSize}px`;
const padding = Math.round(squareSize / 6);
const paddingDim = `${padding}px`;
const scrollRef = useRef<HTMLDivElement>(null);
const [direction, setDirection] = useState<"left" | "right">("left");
const [paused, setPaused] = useState(false);
let resumeTimeout: NodeJS.Timeout;
const pauseAndScroll = (dir: "left" | "right") => {
if (!scrollRef.current) return;
setPaused(true);
scrollRef.current.scrollBy({
left: dir === "left" ? -200 : 200,
behavior: "smooth",
});
clearTimeout(resumeTimeout);
resumeTimeout = setTimeout(() => {
setPaused(false);
}, 3000);
setDirection(dir === "left" ? "right" : "left");
};
useEffect(() => {
const container = scrollRef.current;
if (!container) return;
let animationFrame: number;
const step = () => {
if (!paused) {
if (direction === "left") {
container.scrollLeft += speed;
if (container.scrollLeft >= container.scrollWidth / 2) {
container.scrollLeft = 0;
}
} else {
container.scrollLeft -= speed;
if (container.scrollLeft <= 0) {
container.scrollLeft = container.scrollWidth / 2;
}
}
}
animationFrame = requestAnimationFrame(step);
};
animationFrame = requestAnimationFrame(step);
return () => cancelAnimationFrame(animationFrame);
}, [direction, paused, speed]);
// ✅ Safe early return after hooks
if (clients.length === 0) return null;
return (
<section className="py-16 md:py-20 bg-background overflow-hidden">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 text-center">
@ -45,19 +90,17 @@ const ClientLogosSection: React.FC<ClientLogosSectionProps> = ({
</h2>
</div>
{/* Marquee container - group allows pausing animation on hover */}
<div className="relative w-full overflow-hidden group">
{/* Inner container that will animate */}
{/* Logos Container */}
<div className="relative w-full overflow-hidden">
<div
className="flex flex-nowrap animate-marquee-continuous"
style={{ animationDuration: `${speed}s` }}
ref={scrollRef}
className="flex flex-nowrap overflow-x-hidden scrollbar-hide"
>
{extendedClients.map((client, index) => (
<div
key={`${client.name}-${index}`}
className="flex-shrink-0 mx-12 md:mx-16 py-4"
>
{/* Square Background Container */}
<div
title={client.name}
className="
@ -73,23 +116,35 @@ const ClientLogosSection: React.FC<ClientLogosSectionProps> = ({
style={{
width: squareDim,
height: squareDim,
padding: paddingDim, // Add padding inside the square
padding: paddingDim,
}}
>
<Image
src={client.logoUrl}
alt={`${client.name} Logo`}
layout="fill" // Let image fill the relative container
objectFit="contain" // Maintain aspect ratio within the container
fill
style={{ objectFit: "contain" }}
/>
</div>
</div>
))}
</div>
</div>
{/* Optional: Add fade effect at the edges */}
<div className="absolute inset-y-0 left-0 w-16 md:w-24 bg-gradient-to-r from-background to-transparent pointer-events-none z-10"></div>
<div className="absolute inset-y-0 right-0 w-16 md:w-24 bg-gradient-to-l from-background to-transparent pointer-events-none z-10"></div>
{/* Arrow Controls */}
<div className="flex justify-center mt-8 space-x-6">
<button
onClick={() => pauseAndScroll("right")}
className="px-4 py-2 rounded-full bg-muted hover:bg-muted/70 transition"
>
</button>
<button
onClick={() => pauseAndScroll("left")}
className="px-4 py-2 rounded-full bg-muted hover:bg-muted/70 transition"
>
</button>
</div>
{description && (
@ -103,6 +158,8 @@ const ClientLogosSection: React.FC<ClientLogosSectionProps> = ({
);
};
export default ClientLogosSection;
export const defaultClients: Client[] = [
{ name: "ABSA", logoUrl: "/images/absa.png" },
{ name: "SYBRIN", logoUrl: "/images/sybrin.svg" },
@ -113,4 +170,4 @@ export const defaultClients: Client[] = [
{ name: "TOYOTA", logoUrl: "/images/toyota-logo.png" },
];
export default ClientLogosSection;

View File

@ -16,15 +16,15 @@ const HeroSection: React.FC<HeroSectionProps> = ({
title,
subtitle,
buttonText,
buttonHref,
//buttonHref,
imageUrl = "/hero-bg-2.jpg", // Default background image
}) => {
return (
<section className="relative h-[70vh] md:h-[85vh] flex items-center justify-center text-center bg-gradient-to-b from-black/10 to-black/40 text-white overflow-hidden">
<section className="relative h-[70vh] md:h-[85vh] flex items-center justify-center text-center text-white overflow-hidden">
{" "}
{/* Adjusted background */}
{/* Adjusted background bg-gradient-to-b from-black/10 to-black/40*/}
{/* Background Image/Video */}
<div className="absolute inset-0 z-0 opacity-40 dark:opacity-30">
<div className="absolute inset-0 z-0 opacity-100 dark:opacity-30">
{" "}
{/* Adjusted opacity */}
{imageUrl && (
@ -52,7 +52,7 @@ const HeroSection: React.FC<HeroSectionProps> = ({
{subtitle}
</p>
<Button
href={buttonHref}
href="/obse"
variant="primary" // Use primary variant defined in Button component
size="lg"
className="animate-fade-in-up animation-delay-600"

View File

@ -21,6 +21,7 @@ const HeroSectionModern: React.FC<HeroSectionProps> = ({
}) => {
return (
// Use min-h-screen for full viewport height adjust if needed
//bg-[linear-gradient(to_right,#f0e18a,#f9f4c3,#ecd973)]
<section className="relative flex flex-col md:flex-row items-center bg-background min-h-[80vh] md:min-h-screen overflow-hidden">
{/* Background Image/Video Layer */}
<div className="absolute inset-0 z-0">

View File

@ -15,6 +15,8 @@ import {
FaUserCheck,
FaProjectDiagram,
} from "react-icons/fa";
import { Metadata } from "next";
// const leadershipTeam = [
// {
@ -42,6 +44,23 @@ import {
// linkedinUrl: "#",
// },
// ];
export const metadata: Metadata = {
title: "About Us | Owethu Managed Services (OMS)",
description: "Learn about OMS, our mission, vision, and the values that drive us to deliver exceptional IT solutions and services.",
keywords: [
"Owethu Managed Services",
"About OMS",
"OMS",
"Black-owned ",
"Women-owned",
"Tech company",
"bank statement reader",
"fintech solutions" ,
],
}
const coreValues = [
{
@ -228,7 +247,7 @@ export default function AboutUsPage() {
</h3>
<p className="text-gray-700 dark:text-gray-300 leading-relaxed font-poppins flex-grow">
&quot;To be global leaders in delivering cutting-edge IT
solutions, pushing the boundaries of what&apos;s possible, and
solutions, pushing the boundaries of what&apos;s possible,and
transforming industries for the better.&quot;
</p>
</div>
@ -247,7 +266,7 @@ export default function AboutUsPage() {
<p className="text-gray-700 dark:text-gray-300 leading-relaxed font-poppins flex-grow">
&quot;Our purpose is to help our clients drive transformative
growth and innovation to propel their business forward
redefining what&apos;s possible.&quot;
redefining whats possible.&quot;
</p>
</div>
</div>
@ -511,7 +530,7 @@ export default function AboutUsPage() {
*/}
{/* Section 10: Commitment to Impact (Optional, but adds value) */}
<section
className="py-16 md:py-24 bg-gold-500 text-gray-900 dark:bg-gold-600 dark:text-gray-900"
className="py-16 md:py-24 bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900 dark:bg-gold-600 dark:text-gray-900"
style={{ backgroundColor: "#e1c44a" }}
>
<div className="container mx-auto px-6 text-center">
@ -522,7 +541,7 @@ export default function AboutUsPage() {
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed font-poppins text-gray-800">
Ultimately, our success is measured by yours. We are committed to
creating solutions that ignite momentum, unlock potential, and turn
ambition into achievement,empowering you to rise above challenges
ambition into achievement empowering you to rise above challenges
and lead with confidence into the future. Together, let&apos;s build
a future where your success is not just a possibility, but a
reality.

View File

@ -12,6 +12,7 @@ import {
import { COLORS } from "@/constants"; // Using COLORS constant
import ContactForm from "@/components/ContactForm";
// Define the structure for FAQ items
interface FAQItem {
id: number;
@ -130,10 +131,10 @@ export default function ContactPage() {
Phone
</h3>
<a
href="tel:+27120513282"
href="tel:+27684855721"
className="text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm font-poppins"
>
(012) 051 3282
+27 68 485 5721
</a>
</div>
</div>

View File

@ -2,11 +2,9 @@ import Image from "next/image";
import Link from "next/link";
import { Metadata } from "next"; // Added import
import {
FaArrowRight,
FaCheckCircle,
FaCogs,
FaDatabase,
FaEnvelope,
FaExclamationTriangle,
FaFileAlt,
FaFileInvoiceDollar,
@ -16,7 +14,6 @@ import {
FaLaptopCode,
FaLayerGroup,
FaLightbulb,
FaPhone,
FaPlayCircle,
FaPuzzlePiece,
FaSearchDollar,
@ -31,7 +28,7 @@ import {
FaWrench,
} from "react-icons/fa";
import { COLORS } from "@/constants"; // Assuming COLORS constant is available
import ContactForm from "@/components/ContactForm"; // Assuming ContactForm is available
// import ContactForm from "@/components/ContactForm"; // Assuming ContactForm is available
// SEO Metadata
export const metadata: Metadata = {
@ -110,16 +107,16 @@ const keyFeatures: FeatureItem[] = [
},
{
icon: FaSearchDollar,
title: "Intelligent Income Detection",
title: "Intelligent Income & Salaried Detection",
description:
"Identifies salaried/non-salaried income, provides explanations, and filters out transfers.",
"Accurately detects both salaried and non-salaried income, explains findings, and intelligently filters out internal transfers for clearer financial insights. ",
},
{
icon: FaFingerprint,
title: "Enhanced Fraud Detection",
description:
"Detects document tampering, fraudulent insertions, and developing behavioral profiling.",
isComingSoon: true,
isComingSoon: false,
},
{
icon: FaSyncAlt,
@ -245,9 +242,10 @@ export default function ObsePage() {
{/* <Image src="/oms-logo-white.png" alt="OMS Logo" width={150} height={50} className="mx-auto mb-6" /> */}
<h1
className="text-3xl md:text-5xl lg:text-6xl font-bold mb-4 font-poppins drop-shadow-md leading-tight"
style={{ color: COLORS.primary }} // Use gold color
style={{ color: COLORS.primary }}
>
Revolutionize Your Lending and <br />Credit Processes with OBSE
Revolutionize Your Lending and <br />
Credit Processes with OBSE
</h1>
<p className="text-lg md:text-xl max-w-4xl mx-auto leading-relaxed text-gray-200 dark:text-gray-300 mb-8">
Automate data extraction, enhance accuracy, detect fraud, and
@ -256,13 +254,14 @@ export default function ObsePage() {
</p>
<div className="flex flex-col sm:flex-row justify-center items-center gap-4">
<Link
href="#how-it-works" // Link to the "How it Works" section
className="inline-flex items-center justify-center bg-gold-500 text-gray-900 font-bold py-3 px-8 rounded-md hover:bg-gold-600 transition-colors duration-300"
href="https://youtu.be/Sd3TnvoLtDA?si=UOeXScbosM5LZxbg" // Link to the "How it Works" section
className="inline-flex items-center justify-center bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900 font-bold py-3 px-8 rounded-md hover:bg-gold-600 transition-colors duration-300"
style={{ backgroundColor: COLORS.primary }}
>
<FaPlayCircle className="inline mr-2 text-red-400" /> See How It
Works
</Link>
{/* Optional Mini-CTA */}
{/* <Link href="#overview-video" className="inline-flex items-center text-gold-400 hover:text-gold-300 transition-colors duration-300">
<FaPlayCircle className="mr-2" /> Watch a Quick Overview
@ -693,10 +692,10 @@ export default function ObsePage() {
</div>
</section>
{/* 11. About OMS Section (Brief) */}
{/* 11. About OMS Section (Brief)
<section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6 text-center">
{/* Optional: OMS Logo */}
{ Optional: OMS Logo }
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 dark:text-white mb-4">
Your Experienced Partner in Financial Technology
</h2>
@ -716,10 +715,11 @@ export default function ObsePage() {
</Link>
</div>
</section>
/}
{/* 12. Call to Action (CTA) Section */}
<section
className="py-16 md:py-24 bg-gold-500 text-gray-900"
className="py-16 md:py-24 bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900"
style={{ backgroundColor: COLORS.primary }}
>
<div className="container mx-auto px-6 text-center">
@ -733,13 +733,13 @@ export default function ObsePage() {
</p>
<div className="flex flex-col sm:flex-row justify-center items-center gap-4">
<Link
href="/contact?subject=OBSE Demo Request" // Pre-fill subject for contact form
href="/contact" // Pre-fill subject for contact form
className="inline-block bg-gray-800 text-white font-bold py-3 px-8 rounded-md hover:bg-gray-900 dark:bg-gray-900 dark:hover:bg-black transition-colors duration-300"
>
Request a Personalized Demo
</Link>
<Link
href="/contact?subject=OBSE Sales Inquiry" // Pre-fill subject
href="/contact" // Pre-fill subject
className="inline-block bg-transparent border-2 border-gray-800 text-gray-800 font-bold py-3 px-8 rounded-md hover:bg-gray-800 hover:text-white transition-colors duration-300"
>
Contact Sales Team
@ -755,6 +755,7 @@ export default function ObsePage() {
</section>
{/* 13. Contact Information Section */}
{/*}
<section className="py-16 md:py-24 bg-gray-100 dark:bg-gray-800">
<div className="container mx-auto px-6">
<div className="text-center mb-12">
@ -769,7 +770,10 @@ export default function ObsePage() {
</p>
</div>
<div className="max-w-4xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-8 items-center">
{/* Contact Details */}
{ -----Contact Details */}
{/* Optional: Add a contact form component here if available ---
<div className="space-y-6">
<div className="flex items-center space-x-4">
<FaPhone
@ -805,7 +809,9 @@ export default function ObsePage() {
</a>
</div>
</div>
{/* Optional: Link to main contact page */}
{--- Optional: Link to main contact page */}
{/* --- comment out if not needed}
<Link
href="/contact"
className="inline-flex items-center text-gold-600 dark:text-gold-400 hover:text-gold-700 dark:hover:text-gold-300 font-semibold transition-colors duration-300"
@ -814,6 +820,7 @@ export default function ObsePage() {
Go to Full Contact Page <FaArrowRight className="ml-2" />
</Link>
</div>
*/}
{/* Optional: Simple Contact Form (if ContactForm component is not used/available) */}
{/* <form className="space-y-4">
@ -834,7 +841,7 @@ export default function ObsePage() {
</button>
</form> */}
{/* OR Use the ContactForm Component */}
{/* OR Use the ContactForm Component
<div className="bg-white dark:bg-gray-700 p-6 rounded-lg shadow-md">
<h3 className="text-xl font-semibold font-poppins text-gray-900 dark:text-white mb-4">
Send a Quick Inquiry
@ -844,6 +851,9 @@ export default function ObsePage() {
</div>
</div>
</section>
*/}
{/* 14. Footer Section */}
</div>
);
}

View File

@ -29,6 +29,7 @@ export const metadata: Metadata = {
"fintech solutions",
"IT consulting",
"OMS",
"CVEvolve",
"Owethu Managed Services",
"Centurion",
"Gauteng",

View File

@ -14,6 +14,7 @@ import FeaturedProductSection, {
} from "./_components/FeaturedProductSection";
import { getHome } from "@/lib/query/home";
export default async function HomePage() {
// Explicitly type the data variable, assuming getHome returns HeroSectionType or null/undefined
const data = await getHome();
@ -62,7 +63,7 @@ export default async function HomePage() {
description="Our advanced Optimized Bank Statement Extractor automates data aggregation, reduces errors, and provides deep financial insights."
features={defaultObseFeatures}
buttonText="Learn More & Demo"
buttonHref="/products/obse" // Link to the OBSE product page
buttonHref="/obse" // Link to the OBSE product page
imageUrl="/images/obse.svg" // **IMPORTANT: Create or find a relevant image**
imageAlt="OBSE Product Interface Mockup"
/>

View File

@ -8,6 +8,7 @@ export const metadata: Metadata = {
description:
"Our recruitment portal is currently under development. Stay tuned for updates on career opportunities at Owethu Managed Services.",
robots: "noindex, nofollow", // Prevent indexing of the coming soon page
};
export default function RecruitmentPortalPage() {

View File

@ -25,6 +25,8 @@ export const metadata: Metadata = {
"IT resource augmentation",
"managed IT services",
"OBSE",
"CVEvolve",
"bank statement extractor",
"bank statement automation",
"fintech solutions",
"IT consulting",

View File

@ -24,11 +24,11 @@ import {
FaChartLine, // For Growth/Scalability
FaTasks, // For QA
FaComments, // For Feedback
FaPhone,
FaEnvelope,
//FaPhone,
//FaEnvelope,
} from "react-icons/fa";
import { COLORS } from "@/constants";
import ContactForm from "@/components/ContactForm";
//import ContactForm from "@/components/ContactForm";
// SEO Metadata
export const metadata: Metadata = {
@ -312,24 +312,24 @@ export default function ProductDevelopmentPage() {
Product Development
</h1>
<p className="text-lg md:text-xl max-w-4xl mx-auto leading-relaxed text-gray-200 dark:text-gray-300 mb-8">
At OMS, we dont just create productswe build digital solutions
that accelerate business growth and transform industries. We
understand that great products are the result of careful planning,
technical expertise, and a deep understanding of user needs. From
concept to launch, our product development services deliver
innovative, tailored solutions that help businesses enhance
At OMS, we don&apos;t just create productswe build digital
solutions that accelerate business growth and transform industries.
We understand that great products are the result of careful
planning, technical expertise, and a deep understanding of user
needs. From concept to launch, our product development services
deliver innovative, tailored solutions that help businesses enhance
efficiency, reduce complexity, and unlock new revenue streams.
</p>
<div className="flex flex-col sm:flex-row justify-center items-center gap-4">
<Link
href="#how-we-deliver"
className="inline-flex items-center justify-center bg-gold-500 text-gray-900 font-bold py-3 px-8 rounded-md hover:bg-gold-600 transition-colors duration-300"
className="inline-flex items-center justify-center bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900 font-bold py-3 px-8 rounded-md hover:bg-gold-600 transition-colors duration-300"
style={{ backgroundColor: COLORS.primary }}
>
How We Deliver
</Link>
<Link
href="#contact"
href="/contact"
className="inline-flex items-center text-gold-400 hover:text-gold-300 transition-colors duration-300"
style={{ color: COLORS.primary }}
>
@ -511,7 +511,7 @@ export default function ProductDevelopmentPage() {
{/* 10. Call to Action (CTA) Section */}
<section
className="py-16 md:py-24 bg-gold-500 text-gray-900"
className="py-16 md:py-24 bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900"
style={{ backgroundColor: COLORS.primary }}
>
<div className="container mx-auto px-6 text-center">
@ -525,13 +525,13 @@ export default function ProductDevelopmentPage() {
</p>
<div className="flex flex-col sm:flex-row justify-center items-center gap-4">
<Link
href="/contact?subject=Product Development Inquiry" // Pre-fill subject
href="/contact" // Pre-fill subject
className="inline-block bg-gray-800 text-white font-bold py-3 px-8 rounded-md hover:bg-gray-900 dark:bg-gray-900 dark:hover:bg-black transition-colors duration-300"
>
Request a Consultation
</Link>
<Link
href="#contact" // Link to contact section below
href="/contact" // Link to contact section below
className="inline-block bg-transparent border-2 border-gray-800 text-gray-800 font-bold py-3 px-8 rounded-md hover:bg-gray-800 hover:text-white transition-colors duration-300"
>
Contact Us
@ -541,7 +541,7 @@ export default function ProductDevelopmentPage() {
</section>
{/* 11. Contact Information Section */}
<section
{/* <section
id="contact"
className="py-16 md:py-24 bg-gray-100 dark:bg-gray-800"
>
@ -556,7 +556,7 @@ export default function ProductDevelopmentPage() {
</p>
</div>
<div className="max-w-4xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-8 items-start">
{/* Contact Details */}
<div className="space-y-6">
<div className="flex items-center space-x-4">
<FaPhone
@ -601,7 +601,7 @@ export default function ProductDevelopmentPage() {
</Link>
</div>
{/* Contact Form */}
<div className="bg-white dark:bg-gray-700 p-6 rounded-lg shadow-md">
<h3 className="text-xl font-semibold font-poppins text-gray-900 dark:text-white mb-4">
Send Us Your Inquiry
@ -610,7 +610,9 @@ export default function ProductDevelopmentPage() {
</div>
</div>
</div>
</section>
</section> */}
</div>
);
}

View File

@ -4,7 +4,6 @@ import Link from "next/link";
import { Metadata } from "next";
import {
FaArrowRight,
FaBriefcase,
FaCheckCircle,
FaClipboardList, // For BA
FaClock, // For Time & Material
@ -13,15 +12,12 @@ import {
FaPaintBrush, // For UX/UI Design
FaProjectDiagram, // For Architecture/Milestones
FaPuzzlePiece, // For Integration/Solutions
FaRegHandshake, // For Partnership/Client Relations
FaShieldAlt, // For Reliability/QA
FaSitemap, // For Process/Architecture
FaSyncAlt, // For Agile/Flexibility
FaTasks, // For Project Management/Milestones
FaVial, // For Testing
FaUsers, // For Teams/Resources
FaChartLine, // For Reporting/MI
FaLightbulb, // For Innovation/Solutions
FaTools, // General Capabilities
FaLayerGroup, // Frameworks (SAFe, etc.)
FaFileInvoiceDollar, // Cost/Pricing
@ -46,7 +42,7 @@ export const metadata: Metadata = {
"UX/UI Designer",
"Process Engineer",
"Salesforce Partner",
"time and material IT",
// "time and material IT",
"milestone-based projects",
"IT outsourcing",
"flexible IT resources",
@ -295,62 +291,62 @@ const capabilities: Capability[] = [
},
];
interface Benefit {
icon: React.ElementType;
title: string;
description: string;
}
// interface Benefit {
// icon: React.ElementType;
// title: string;
// description: string;
// }
const augmentationBenefits: Benefit[] = [
{
icon: FaSyncAlt,
title: "Ultimate Flexibility",
description:
"Scale your team up or down quickly based on project demands and budget.",
},
{
icon: FaUsers,
title: "Access to Expertise",
description:
"Gain immediate access to specialized IT skills that may not be available in-house.",
},
{
icon: FaFileInvoiceDollar,
title: "Cost-Effectiveness",
description:
"Reduce recruitment costs, overheads, and long-term commitments associated with FTEs.",
},
{
icon: FaChartLine,
title: "Increased Productivity",
description:
"Focus your core team on strategic initiatives while OMS resources handle specific tasks or projects.",
},
{
icon: FaShieldAlt,
title: "Reduced Hiring Burden",
description:
"Avoid the time-consuming process of sourcing, vetting, hiring, and onboarding new employees.",
},
{
icon: FaTasks,
title: "Focus on Core Business",
description:
"Outsource IT project execution or specific roles, allowing you to concentrate on your primary objectives.",
},
{
icon: FaCheckCircle,
title: "Quality Assurance",
description:
"Benefit from experienced professionals and managed delivery (in Milestone model) for high-quality outcomes.",
},
{
icon: FaLightbulb,
title: "Faster Project Delivery",
description:
"Accelerate project timelines by quickly filling skill gaps and adding capacity.",
},
];
// const augmentationBenefits: Benefit[] = [
// {
// icon: FaSyncAlt,
// title: "Ultimate Flexibility",
// description:
// "Scale your team up or down quickly based on project demands and budget.",
// },
// {
// icon: FaUsers,
// title: "Access to Expertise",
// description:
// "Gain immediate access to specialized IT skills that may not be available in-house.",
// },
// {
// icon: FaFileInvoiceDollar,
// title: "Cost-Effectiveness",
// description:
// "Reduce recruitment costs, overheads, and long-term commitments associated with FTEs.",
// },
// {
// icon: FaChartLine,
// title: "Increased Productivity",
// description:
// "Focus your core team on strategic initiatives while OMS resources handle specific tasks or projects.",
// },
// {
// icon: FaShieldAlt,
// title: "Reduced Hiring Burden",
// description:
// "Avoid the time-consuming process of sourcing, vetting, hiring, and onboarding new employees.",
// },
// {
// icon: FaTasks,
// title: "Focus on Core Business",
// description:
// "Outsource IT project execution or specific roles, allowing you to concentrate on your primary objectives.",
// },
// {
// icon: FaCheckCircle,
// title: "Quality Assurance",
// description:
// "Benefit from experienced professionals and managed delivery (in Milestone model) for high-quality outcomes.",
// },
// {
// icon: FaLightbulb,
// title: "Faster Project Delivery",
// description:
// "Accelerate project timelines by quickly filling skill gaps and adding capacity.",
// },
// ];
const methodologies = [
{ name: "Agile (SCRUM)", icon: FaSyncAlt },
@ -380,6 +376,7 @@ export default function ResourceAugmentationPage() {
{/* Consider adding OMS Logo here if desired */}
{/* <Image src="/oms-logo-white.png" alt="OMS Logo" width={150} height={50} className="mx-auto mb-6" /> */}
<h1
className="text-3xl md:text-5xl lg:text-6xl font-bold mb-4 font-poppins drop-shadow-md leading-<1.5>"
style={{ color: COLORS.primary }} // Use gold color
>
@ -393,7 +390,7 @@ export default function ResourceAugmentationPage() {
<div className="flex flex-col sm:flex-row justify-center items-center gap-4">
<Link
href="#service-models" // Link to the service models section
className="inline-flex items-center justify-center bg-gold-500 text-gray-900 font-bold py-3 px-8 rounded-md hover:bg-gold-600 transition-colors duration-300"
className="inline-flex items-center justify-center bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900 font-bold py-3 px-8 rounded-md hover:bg-gold-600 transition-colors duration-300"
style={{ backgroundColor: COLORS.primary }}
>
Explore Our Models <FaArrowRight className="ml-2" />
@ -486,7 +483,7 @@ export default function ResourceAugmentationPage() {
Your Strategic Partner for IT Talent
</h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4">
Owethu Managed Services (OMS) provides high-caliber IT
Owethu Managed Services provides high-caliber IT
professionals through flexible engagement models tailored to
your specific project requirements and business objectives. As a
100% Black female-owned organization based in Centurion,
@ -722,7 +719,7 @@ export default function ResourceAugmentationPage() {
</h4>
<p className="text-sm text-gray-600 dark:text-gray-300">
Crafting seamless, data-driven onboarding experiences through
straight-through processing, enhanced customer journeys,
straight-through processing, enhanced customer journeys,<br/>
real-time insights, and a 360-degree customer view.
</p>
</div>
@ -810,7 +807,7 @@ export default function ResourceAugmentationPage() {
{/* 10. Call to Action (CTA) Section */}
<section
className="py-16 md:py-24 bg-gold-500 text-gray-900"
className="py-16 md:py-24 bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-gray-900"
style={{ backgroundColor: COLORS.primary }}
>
<div className="container mx-auto px-6 text-center">

View File

@ -11,6 +11,7 @@ export const metadata: Metadata = {
alternates: {
canonical: "/tech-talk",
},
openGraph: {
title: "OMS TechTalk | Insights & Innovation",
description: "Stay updated with tech insights from OMS.",
@ -50,7 +51,7 @@ const TechTalkPage = async () => {
</p>
</div>
{/* Blog Post Grid */}
{posts.length > 0 ? (
{false && posts.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 md:gap-10">
{posts.map((post: Post) => (
<BlogPostCard

View File

@ -12,7 +12,7 @@ interface ExtendedVacancy extends Vacancy {
}
async function getVacancy(slug: string): Promise<ExtendedVacancy | null> {
const res = await fetch(`http://localhost:3000/api/vacancies/${slug}`, {
const res = await fetch(`${process.env.WEBSITE_URL}/api/vacancies/${slug}`, {
cache: "no-store",
});
if (!res.ok) {

View File

@ -208,18 +208,16 @@
} /* Added longer delay */
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.animate-fade-in-up {
animation: fadeInUp 0.8s ease-out forwards;
opacity: 0; /* Start hidden */
.animate-marquee-continuous {
animation: marquee linear infinite;
}
.paused {
animation-play-state: paused !important;
}

View File

@ -3,8 +3,8 @@ import { Poppins } from "next/font/google";
import "./globals.css";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
import ChatbotWidget from "@/components/ChatbotWidget";
import { ThemeProvider } from "@/providers/theme-provider";
import Script from "next/script";
const poppins = Poppins({
subsets: ["latin"],
@ -20,6 +20,7 @@ export const metadata: Metadata = {
"Owethu Managed Services (OMS) provides expert IT solutions in Centurion & South Africa, including resource augmentation, project management, custom software development, and the OBSE financial analysis tool.", // Include Keywords, Location, USP
keywords: [
"Owethu Managed Services",
"OMS",
"OBSE",
"IT solutions South Africa",
"resource augmentation",
@ -28,6 +29,7 @@ export const metadata: Metadata = {
"OBSE",
"financial data analysis",
"IT services Centurion",
"digital transformation",
], // Add relevant keywords
alternates: {
canonical: "/", // Assuming this is the root URL
@ -95,8 +97,15 @@ export default function RootLayout({
<Header />
<main>{children}</main>
<Footer />
<ChatbotWidget />
</ThemeProvider>
<Script
src="https://umami.obse.africa/script.js"
data-website-id={
process.env.NEXT_PUBLIC_UMAMI_WEB_ID ||
"d9f0e4d7-0f0a-45e4-91bf-62e0e65e25d2"
}
strategy="afterInteractive"
/>
</body>
</html>
);

View File

@ -1,22 +0,0 @@
// components/ChatbotWidget.tsx
import React from "react";
import { FaComments } from "react-icons/fa";
const ChatbotWidget = () => {
// TODO: Implement actual chat functionality (e.g., integrate a service)
// const handleChatOpen = () => {
// alert("Chatbot functionality to be implemented!");
// };
return (
<button
// onClick={handleChatOpen}
className="fixed bottom-6 right-6 bg-primary text-dark p-4 rounded-full shadow-lg hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 transition-all duration-300 z-50"
aria-label="Open Chat"
>
<FaComments size={24} />
</button>
);
};
export default ChatbotWidget;

View File

@ -1,9 +1,10 @@
// components/Footer.tsx
import React from "react";
import Link from "next/link";
import { FaLinkedin, FaInstagram } from "react-icons/fa";
import { FaLinkedin, FaInstagram, FaYoutube } from "react-icons/fa";
import Image from "next/image";
const omsLogoUrl = "/oms-logo.svg"; // Ensure this exists in /public
// const omsLogoDarkUrl = "/oms-logo-dark.svg"; // Optional dark mode logo
@ -69,7 +70,7 @@ const Footer = () => {
</li>
<li>
<Link
href="/services"
href="/services/resource-augmentation"
className="text-sm text-[var(--oms-white)]/80 hover:text-primary transition-colors"
>
Services
@ -77,20 +78,20 @@ const Footer = () => {
</li>
<li>
<Link
href="/products"
href="/obse"
className="text-sm text-[var(--oms-white)]/80 hover:text-primary transition-colors"
>
Products
</Link>
</li>
<li>
{/* <li>
<Link
href="/join-us"
className="text-sm text-[var(--oms-white)]/80 hover:text-primary transition-colors"
>
Join Our Team
</Link>
</li>
</li> */}
<li>
<Link
href="/contact"
@ -106,16 +107,16 @@ const Footer = () => {
<div>
<h5 className="text-lg font-semibold mb-4 text-primary">Contact</h5>
<address className="text-sm text-[var(--oms-white)]/80 mb-2 not-italic">
Unit 10 B Centuria Park
<br />
265 Von Willich Avenue
<br />
Die Hoewes, Centurion, 0159
<br />
(Unit 10 B Centuria Park)
</address>
<p className="text-sm text-[var(--oms-white)]/80 mb-2">
Phone:{" "}
<a href="tel:+27120513282" className="hover:text-primary">
(012) 051 3282
<a href="tel:+27684855721" className="hover:text-primary">
+27 68 485 5721
</a>
</p>
<p className="text-sm text-[var(--oms-white)]/80 mb-2">
@ -127,7 +128,7 @@ const Footer = () => {
{/* Social Icons - Use muted bright color, primary on hover */}
<div className="flex space-x-4 mt-4">
<a
href="https://linkedin.com"
href="https://www.linkedin.com/company/owethu-managed-services-oms"
target="_blank"
rel="noopener noreferrer"
className="text-[var(--oms-white)]/70 hover:text-primary transition-colors"
@ -135,8 +136,9 @@ const Footer = () => {
>
<FaLinkedin size={24} />
</a>
<a
href="https://instagram.com"
href="https://www.instagram.com/owethumanagedservices_oms"
target="_blank"
rel="noopener noreferrer"
className="text-[var(--oms-white)]/70 hover:text-primary transition-colors"
@ -144,6 +146,17 @@ const Footer = () => {
>
<FaInstagram size={24} />
</a>
<a
href="https://www.youtube.com/@OwethuManagedServices-africa"
target="_blank"
rel="noopener noreferrer"
className="text-[var(--oms-white)]/70 hover:text-primary transition-colors"
aria-label="YouTube"
>
<FaYoutube size={24} />
</a>
</div>
</div>
@ -157,7 +170,7 @@ const Footer = () => {
</p>
<form className="flex flex-col sm:flex-row gap-2">
{/* Input needs dark background styles */}
<div className="relative">
<div className="relative max-w-md mx-auto w-full">
<input
type="email"
placeholder="Enter your email"
@ -165,7 +178,6 @@ const Footer = () => {
className="
w-full
pr-24
px-4 py-2
rounded-lg
bg-[var(--dark-input)]
@ -183,7 +195,7 @@ const Footer = () => {
h-full
px-4
rounded-r-lg
bg-primary
bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)]
text-primary-foreground
font-semibold
hover:bg-opacity-90
@ -217,19 +229,29 @@ const Footer = () => {
</p>
<div className="flex space-x-4">
{/* Links still hover to primary */}
<Link
{/* <Link
href="/privacy-policy"
className="hover:text-primary transition-colors"
>
Privacy Policy
</Link>
<Link
href="/paia-popia"
</Link> */}
<a
href="/Privacy-Policy/Recruitment-Privacy-Policy.pdf"
className="hover:text-primary transition-colors"
>
Privacy Policy
</a>
<a
href="/Privacy-Policy/Data-Privacy-Statement-for-Candidates.pdf"
className="hover:text-primary transition-colors"
>
PAIA & POPIA
</Link>
</a>
</div>
</div>
</div>
</footer>
@ -237,3 +259,4 @@ const Footer = () => {
};
export default Footer;
//Data-Privacy-Statement-for-Candidates

View File

@ -8,15 +8,12 @@ import { usePathname } from "next/navigation"; // Import usePathname
import {
FiChevronDown,
FiClipboard,
FiArrowRight,
FiMenu,
FiX,
FiUsers,
FiBriefcase,
FiCpu,
FiBox,
FiFileText,
FiUserCheck,
FiLayers
} from "react-icons/fi";
import ThemeToggle from "./ThemeToggle";
@ -44,8 +41,7 @@ const HeaderClient = () => {
const [servicesDropdownOpen, setServicesDropdownOpen] = useState(false);
const [productsDropdownOpen, setProductsDropdownOpen] = useState(false);
const [joinUsDropdownOpen, setJoinUsDropdownOpen] = useState(false);
const [offeringsDropdownOpen, setOfferingsDropdownOpen] = useState(false);
//const [joinUsDropdownOpen, setJoinUsDropdownOpen] = useState(false);
const handleServicesMouseEnter = () => setServicesDropdownOpen(true);
const handleServicesMouseLeave = () => setServicesDropdownOpen(false);
@ -53,11 +49,8 @@ const HeaderClient = () => {
const handleProductsMouseEnter = () => setProductsDropdownOpen(true);
const handleProductsMouseLeave = () => setProductsDropdownOpen(false);
const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
const handleJoinUsMouseLeave = () => setJoinUsDropdownOpen(false);
const handleOfferingsMouseEnter = () => setOfferingsDropdownOpen(true);
const handleOfferingsMouseLeave = () => setOfferingsDropdownOpen(false);
// const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
// const handleJoinUsMouseLeave = () => setJoinUsDropdownOpen(false);
const pathname = usePathname(); // Get current path
@ -156,8 +149,8 @@ const HeaderClient = () => {
<div className="hidden md:flex items-center space-x-4">
<ThemeToggle />
<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"
href="/contact"
className="flex items-center text-sm font-medium bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] 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" />
@ -185,7 +178,7 @@ const HeaderClient = () => {
</div>
{/* Secondary Row w/ Mega Menus */}
<div className="bg-primary relative">
<div className="bg-[linear-gradient(to_right,#dec750,#f0de7e,#e1c44a)] 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">
{/* Wrap nav and link in a flex container */}
@ -273,15 +266,16 @@ const HeaderClient = () => {
</div>
</div>
</div>
{/* Products */}
<div
className={`group ${isActive("/obse") ? "active" : ""}`} // Add active class to group
className={`group ${isActive("/products") ? "active" : ""}`} // Add active class to group
onMouseEnter={handleProductsMouseEnter}
onMouseLeave={handleProductsMouseLeave}
>
<button
className={`${megaMenuTriggerClasses} ${
isActive("/obse") ? "after:w-full" : ""
isActive("/products") ? "after:w-full" : ""
}`}
>
{" "}
@ -291,7 +285,7 @@ const HeaderClient = () => {
</button>
<div
className={`
absolute left-0 top-full w-full shadow-lg z-1000
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]
${
@ -303,7 +297,7 @@ const HeaderClient = () => {
`}
>
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
<div className="max-w-md">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 max-w-xl">
<Link
href="/obse"
className={`${megaMenuItemClasses} ${
@ -315,7 +309,44 @@ const HeaderClient = () => {
<FiBox className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}>
<p className={megaMenuTitleClasses}>
OBSE Platform
</p>
</div>
</Link>
{/* Add more service links here
<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="https://cvevolve.com/"
target="_blank"
className={`${megaMenuItemClasses} ${
isActive("/obse") ? "text-primary" : ""
}`}
>
{" "}
{/* Apply active class */}
<FiLayers className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}>
<p className={megaMenuTitleClasses}>
CVEvolve
</p>
</div>
</Link>
@ -323,82 +354,12 @@ const HeaderClient = () => {
</div>
</div>
</div>
{/* Join Our Team */}
<div
className={`group ${
isActive("/join-us") ||
isActive("/vacancies") ||
isActive("/portal")
? "active"
: ""
}`} // Add active class to group (check all related paths)
onMouseEnter={handleJoinUsMouseEnter}
onMouseLeave={handleJoinUsMouseLeave}
>
<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
{/* <div
className={`group ${isActive("/offerings") ? "active" : ""}`}
onMouseEnter={handleOfferingsMouseEnter}
onMouseLeave={handleOfferingsMouseLeave}
@ -438,7 +399,7 @@ const HeaderClient = () => {
</div>
</div>
</div>
</div>
</div> */}
</nav>
{/* ← Heres the Explore Our Offerings link, back in its original spot
@ -472,11 +433,16 @@ const HeaderClient = () => {
<nav className="container mx-auto px-4 sm:px-6 lg:px-8 flex flex-col space-y-1 text-foreground">
<DropdownLink href="/" onClick={handleMobileLinkClick}>
Home
</DropdownLink>
<DropdownLink href="/tech-talk" onClick={handleMobileLinkClick}>
Tech Talk
</DropdownLink>
<DropdownLink href="/about" onClick={handleMobileLinkClick}>
About Us
</DropdownLink>
<DropdownLink href="/contact" onClick={handleMobileLinkClick}>
Contact Us
</DropdownLink>
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
Services
</span>
@ -500,7 +466,12 @@ const HeaderClient = () => {
OBSE
</DropdownLink>
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
{/* small screen investigation */}
<DropdownLink href="https://cvevolve.com" onClick={handleMobileLinkClick}>
CVEvolve
</DropdownLink>
{/* <span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
Join Us
</span>
<DropdownLink href="/vacancies" onClick={handleMobileLinkClick}>
@ -508,24 +479,21 @@ const HeaderClient = () => {
</DropdownLink>
<DropdownLink href="/portal" onClick={handleMobileLinkClick}>
Recruitment Portal
</DropdownLink>
<DropdownLink href="/contact" onClick={handleMobileLinkClick}>
Contact Us
</DropdownLink>
</DropdownLink> */}
{/*
<span className="pt-3 pb-1 text-xs uppercase text-muted-foreground">
Explore Our Offerings
</span>
<DropdownLink href="/offerings" onClick={handleMobileLinkClick}>
Our Offerings
</DropdownLink>
</DropdownLink> */}
<div className="pt-4">
<Link
href="/request-demo"
href="/contact"
onClick={handleMobileLinkClick}
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"
className="flex w-full justify-center items-center text-sm font-medium bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] 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 OBSE Demo
@ -540,3 +508,77 @@ const HeaderClient = () => {
};
export default HeaderClient;
// <div
// className={`group ${
// isActive("/join-us") ||
// isActive("/vacancies") ||
// isActive("/portal")
// ? "active"
// : ""
// }`} // Add active class to group (check all related paths)
// onMouseEnter={handleJoinUsMouseEnter}
// onMouseLeave={handleJoinUsMouseLeave}
// >
// <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>

View File

@ -4,7 +4,7 @@ import Link from "next/link";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
href?: string;
variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive"; // Added more variants
variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive" | "black";
size?: "sm" | "md" | "lg";
children: React.ReactNode;
className?: string;
@ -24,13 +24,17 @@ const Button: React.FC<ButtonProps> = ({
// Variant styles using semantic vars (Tailwind classes generated via @theme)
const variantStyles = {
primary: "bg-primary text-primary-foreground hover:bg-primary/90", // bg-primary generated from --primary
//primary: "bg-primary text-primary-foreground hover:bg-primary/90", // bg-primary generated from --primary
primary: "bg-[linear-gradient(to_right,#e6cd4b,#fff8b3,#e0b843)] text-primary-foreground hover:bg-primary/90",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
outline:
"border border-border bg-transparent hover:bg-accent hover:text-accent-foreground",
ghost: "hover:bg-accent hover:text-accent-foreground",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
//linear-gradient(to right, #ead566, #e0be45) created using Tailwind's gradient utilities
//i want that variant
black:"inline-block bg-gray-800 text-white font-bold py-3 px-8 rounded-md hover:bg-gray-900 dark:bg-gray-900 dark:hover:bg-black transition-colors duration-300 font-poppins",
};
const sizeStyles = {

View File

@ -0,0 +1,7 @@
{
"folders": [
{
"path": "."
}
]
}

Binary file not shown.