updated other pages

This commit is contained in:
libertyoms
2025-05-01 11:48:37 +02:00
parent 41d2db9383
commit 4119a2d3ef
19 changed files with 469 additions and 103 deletions

View File

@ -1,84 +1,115 @@
// components/ClientLogosSection.tsx // components/ClientLogosSection.tsx
import React from "react"; import React from "react";
import Image from "next/image"; // For actual logos import Image from "next/image";
import { FaBuilding, FaCar, FaLaptopCode, FaUsers } from "react-icons/fa"; // For placeholders
// Define structure for client data (adapt as needed) // Define structure for client data - focusing on logos now
type Client = { type Client = {
name: string; name: string;
logoUrl?: string; // URL to actual logo image logoUrl: string; // Expecting actual logo URLs now
icon?: React.ElementType; // Placeholder icon component
}; };
type ClientLogosSectionProps = { type ClientLogosSectionProps = {
title: string; title: string;
description?: string; description?: string;
clients: Client[]; clients: Client[];
/** Control animation speed (lower number = faster). Default: 40s */
speed?: number;
/** Size of the square background container in pixels. Default: 120 */
squareSize?: number;
}; };
const ClientLogosSection: React.FC<ClientLogosSectionProps> = ({ const ClientLogosSection: React.FC<ClientLogosSectionProps> = ({
title, title,
description, description,
clients, 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
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 paddingDim = `${padding}px`;
return ( return (
// Use semantic background <section className="py-16 md:py-20 bg-background overflow-hidden">
<section className="py-16 md:py-20 bg-background">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 text-center"> <div className="container mx-auto px-4 sm:px-6 lg:px-8 text-center">
{" "}
{/* Use container */}
{/* Use semantic foreground */}
<h2 className="text-3xl md:text-4xl font-bold mb-12 text-foreground"> <h2 className="text-3xl md:text-4xl font-bold mb-12 text-foreground">
{title} {title}
</h2> </h2>
{/* TODO: Implement Auto-Sliding Panel (e.g., using Swiper.js or Embla Carousel) */} </div>
<div className="flex flex-wrap justify-center items-center gap-10 md:gap-16 opacity-70 dark:opacity-60">
{" "} {/* Marquee container - group allows pausing animation on hover */}
{/* Adjust opacity */} <div className="relative w-full overflow-hidden group">
{clients.map((client, index) => ( {/* Inner container that will animate */}
<div <div
key={index} className="flex flex-nowrap animate-marquee-continuous"
title={client.name} style={{ animationDuration: `${speed}s` }}
className="transition-opacity hover:opacity-100" >
{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="
relative flex items-center justify-center
bg-muted/30 dark:bg-muted/20
rounded-lg shadow-sm
overflow-hidden
grayscale hover:grayscale-0
opacity-70 hover:opacity-100
transition-all duration-300 ease-in-out
cursor-pointer
"
style={{
width: squareDim,
height: squareDim,
padding: paddingDim, // Add padding inside the square
}}
> >
{client.logoUrl ? (
<Image <Image
src={client.logoUrl} src={client.logoUrl}
alt={`${client.name} Logo`} alt={`${client.name} Logo`}
width={120} // Adjust size as needed layout="fill" // Let image fill the relative container
height={40} // Adjust size as needed objectFit="contain" // Maintain aspect ratio within the container
objectFit="contain"
className="dark:invert dark:filter" // Example: Invert logo colors in dark mode if needed
/> />
) : client.icon ? ( </div>
// Use semantic muted foreground for icons, primary on hover
React.createElement(client.icon, {
className:
"text-5xl text-muted-foreground/80 hover:text-primary transition-colors",
})
) : (
<span className="text-muted-foreground">{client.name}</span> // Fallback text
)}
</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>
</div>
{description && ( {description && (
<p className="mt-8 text-muted-foreground italic text-sm"> <div className="container mx-auto px-4 sm:px-6 lg:px-8 text-center">
<p className="mt-10 text-muted-foreground italic text-sm">
{description} {description}
</p> </p>
)}
</div> </div>
)}
</section> </section>
); );
}; };
// Example default data matching the original page (using placeholders)
export const defaultClients: Client[] = [ export const defaultClients: Client[] = [
{ name: "Financial Services Client", icon: FaBuilding }, { name: "ABSA", logoUrl: "/images/absa.png" },
{ name: "Automotive Client", icon: FaCar }, { name: "SYBRIN", logoUrl: "/images/sybrin.svg" },
{ name: "Tech Industry Client", icon: FaLaptopCode }, { name: "SASOL", logoUrl: "/images/sasol.png" },
{ name: "Generic Client 1", icon: FaUsers }, { name: "JACARANDA", logoUrl: "/images/jacaranda.png" },
{ name: "Generic Client 2", icon: FaBuilding }, { name: "SALESFORCE", logoUrl: "/images/salesforce.png" },
{ name: "BCX", logoUrl: "/images/bcx.png" },
]; ];
export default ClientLogosSection; export default ClientLogosSection;

View File

@ -16,32 +16,32 @@ import {
FaProjectDiagram, FaProjectDiagram,
} from "react-icons/fa"; } from "react-icons/fa";
const leadershipTeam = [ // const leadershipTeam = [
{ // {
id: 1, // id: 1,
name: "Michael Shapiro", // name: "Michael Shapiro",
title: "Managing Director", // title: "Managing Director",
imageUrl: "/images/profile1.jpg", // 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.", // bio: "A seasoned leader and innovator with over 25 years of experience, driving strategic growth and fostering a culture of excellence within OMS.",
linkedinUrl: "#", // linkedinUrl: "#",
}, // },
{ // {
id: 2, // id: 2,
name: "Gareth Corbishley", // name: "Gareth Corbishley",
title: "Director", // title: "Director",
imageUrl: "/images/profile2.jpg", // imageUrl: "/images/profile2.jpg",
bio: "Expert in operational efficiency and technological implementation, ensuring seamless project delivery and client satisfaction.", // bio: "Expert in operational efficiency and technological implementation, ensuring seamless project delivery and client satisfaction.",
linkedinUrl: "#", // linkedinUrl: "#",
}, // },
{ // {
id: 3, // id: 3,
name: "Darryl Govender", // name: "Darryl Govender",
title: "Director", // title: "Director",
imageUrl: "/images/profile3.jpg", // imageUrl: "/images/profile3.jpg",
bio: "Specializes in aligning cutting-edge technology solutions with complex business needs to unlock transformative results.", // bio: "Specializes in aligning cutting-edge technology solutions with complex business needs to unlock transformative results.",
linkedinUrl: "#", // linkedinUrl: "#",
}, // },
]; // ];
const coreValues = [ const coreValues = [
{ {
@ -187,7 +187,7 @@ export default function AboutUsPage() {
<div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg"> <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 */} {/* Replace with a relevant, high-quality image representing innovation or teamwork */}
<Image <Image
src="/images/team-collaborative.png" src="/images/team.svg"
alt="Team collaborating on innovative solutions" alt="Team collaborating on innovative solutions"
layout="fill" layout="fill"
objectFit="cover" objectFit="cover"
@ -412,7 +412,7 @@ export default function AboutUsPage() {
<div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg order-last md:order-first"> <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 */} {/* Replace with an image representing partnership or client collaboration */}
<Image <Image
src="/images/partners.jpg" src="/images/meeting.svg"
alt="Client partnership and collaboration" alt="Client partnership and collaboration"
layout="fill" layout="fill"
objectFit="cover" objectFit="cover"
@ -443,7 +443,7 @@ export default function AboutUsPage() {
</div> </div>
</div> </div>
</section> </section>
{/* Section 9: Our Leadership Team */} {/* Section 9: Our Leadership Team
<section className="py-16 md:py-24 bg-gray-50 dark:bg-gray-800"> <section className="py-16 md:py-24 bg-gray-50 dark:bg-gray-800">
<div className="container mx-auto px-6"> <div className="container mx-auto px-6">
<div className="text-center mb-14"> <div className="text-center mb-14">
@ -459,15 +459,12 @@ export default function AboutUsPage() {
</div> </div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 md:gap-10 justify-center"> <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) => ( {leadershipTeam.map((member) => (
<div <div
key={member.id} key={member.id}
className="bg-white dark:bg-gray-700 rounded-lg shadow-lg overflow-hidden text-center transition-transform duration-300 hover:scale-105 max-w-sm mx-auto dark:hover:shadow-gold-500/20" className="bg-white dark:bg-gray-700 rounded-lg shadow-lg overflow-hidden text-center transition-transform duration-300 hover:scale-105 max-w-sm mx-auto dark:hover:shadow-gold-500/20"
> >
{/* Added max-width and mx-auto for centering if fewer than 3 items */}
<div className="relative h-60 w-full"> <div className="relative h-60 w-full">
{/* Slightly taller image */}
<Image <Image
src={member.imageUrl || "/images/profile1.jpg"} src={member.imageUrl || "/images/profile1.jpg"}
alt={`Photo of ${member.name}`} alt={`Photo of ${member.name}`}
@ -497,7 +494,6 @@ export default function AboutUsPage() {
className="text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 transition-colors duration-200 font-poppins" className="text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 transition-colors duration-200 font-poppins"
aria-label={`LinkedIn profile of ${member.name}`} aria-label={`LinkedIn profile of ${member.name}`}
> >
{/* Using a simple text link for cleanliness */}
Connect on LinkedIn Connect on LinkedIn
</a> </a>
)} )}
@ -505,9 +501,9 @@ export default function AboutUsPage() {
</div> </div>
))} ))}
</div> </div>
{/* Button removed as requested */}
</div> </div>
</section> </section>
*/}
{/* Section 10: Commitment to Impact (Optional, but adds value) */} {/* Section 10: Commitment to Impact (Optional, but adds value) */}
<section <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-gold-500 text-gray-900 dark:bg-gold-600 dark:text-gray-900"

View File

@ -39,7 +39,7 @@ export const metadata: Metadata = {
description: description:
"Revolutionize lending with OBSE: Automated bank statement data extraction, OCR, fraud detection, and analysis for South African financial institutions. Improve accuracy, speed, and decision-making.", "Revolutionize lending with OBSE: Automated bank statement data extraction, OCR, fraud detection, and analysis for South African financial institutions. Improve accuracy, speed, and decision-making.",
keywords: [ keywords: [
"Optical Bank Statement Extractor", "Optimised Bank Statement Extractor",
"OBSE", "OBSE",
"bank statement extraction", "bank statement extraction",
"OCR bank statements", "OCR bank statements",
@ -347,7 +347,7 @@ export default function ObsePage() {
OBSE: Automated Accuracy, Speed, and Insight OBSE: Automated Accuracy, Speed, and Insight
</h2> </h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4"> <p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4">
Optical Bank Statement Extractor (OBSE) is an advanced OCR and Optimised Bank Statement Extractor (OBSE) is an advanced OCR and
data aggregation platform designed specifically for the South data aggregation platform designed specifically for the South
African financial landscape. It seamlessly extracts African financial landscape. It seamlessly extracts
comprehensive, accurate data from any bank statement (individual comprehensive, accurate data from any bank statement (individual
@ -364,7 +364,7 @@ export default function ObsePage() {
<div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg"> <div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg">
{/* Placeholder for UI Screenshot */} {/* Placeholder for UI Screenshot */}
<Image <Image
src="/images/obse-ui-upload.png" // Replace with actual path src="/images/obse.svg" // Replace with actual path
alt="OBSE Upload Interface" alt="OBSE Upload Interface"
layout="fill" layout="fill"
objectFit="cover" objectFit="cover"
@ -532,7 +532,7 @@ export default function ObsePage() {
<div className="relative h-64 md:h-96 rounded-lg overflow-hidden shadow-lg"> <div className="relative h-64 md:h-96 rounded-lg overflow-hidden shadow-lg">
{/* Placeholder for Dashboard Example */} {/* Placeholder for Dashboard Example */}
<Image <Image
src="/images/obse-dashboard-example.png" // Replace with actual path src="/images/dashboard.png" // Replace with actual path
alt="OBSE Dashboard Insights" alt="OBSE Dashboard Insights"
layout="fill" layout="fill"
objectFit="contain" // Use contain if showing a full dashboard objectFit="contain" // Use contain if showing a full dashboard

View File

@ -58,11 +58,11 @@ export default async function HomePage() {
eyebrow="Featured Product" eyebrow="Featured Product"
title="Streamline Financial Analysis with" title="Streamline Financial Analysis with"
productName="OBSE" productName="OBSE"
description="Our advanced Optical Bank Statement Extractor automates data aggregation, reduces errors, and provides deep financial insights." description="Our advanced Optimised Bank Statement Extractor automates data aggregation, reduces errors, and provides deep financial insights."
features={defaultObseFeatures} features={defaultObseFeatures}
buttonText="Learn More & Demo" buttonText="Learn More & Demo"
buttonHref="/products/obse" // Link to the OBSE product page buttonHref="/products/obse" // Link to the OBSE product page
imageUrl="/obse-mockup.png" // **IMPORTANT: Create or find a relevant image** imageUrl="/images/obse.svg" // **IMPORTANT: Create or find a relevant image**
imageAlt="OBSE Product Interface Mockup" imageAlt="OBSE Product Interface Mockup"
/> />
<ClientLogosSection <ClientLogosSection

View File

@ -0,0 +1,284 @@
import Image from "next/image";
import Link from "next/link";
import { Metadata } from "next";
import {
FaArrowRight,
FaBriefcase,
FaCogs,
FaHandshake,
FaLaptopCode,
FaProjectDiagram,
FaUsers,
FaWrench,
FaShippingFast,
} from "react-icons/fa";
import { COLORS } from "@/constants"; // Assuming COLORS constant is available
// SEO Metadata
export const metadata: Metadata = {
title: "IT Services & Solutions | OMS South Africa",
description:
"Explore IT services by Owethu Managed Services (OMS): Custom Software Development, IT Resource Augmentation, and the OBSE Bank Statement Extractor. Partner with us for innovative solutions.",
keywords: [
"IT services South Africa",
"custom software development",
"IT resource augmentation",
"managed IT services",
"OBSE",
"bank statement automation",
"fintech solutions",
"IT consulting",
"OMS",
"Owethu Managed Services",
"Centurion",
"Gauteng",
],
openGraph: {
title: "Comprehensive IT Services & Solutions | OMS South Africa",
description:
"OMS offers tailored IT solutions including custom development, resource augmentation, and specialized products like OBSE.",
url: "https://oms.africa/services", // Update with the final URL
images: [
{
url: "/images/oms-services-og.png", // Replace with an appropriate OG image URL
width: 1200,
height: 630,
alt: "OMS IT Services",
},
],
locale: "en_ZA",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Comprehensive IT Services & Solutions | OMS South Africa",
description:
"Partner with OMS for expert IT services, from custom builds to resource scaling.",
// images: ['/images/oms-services-twitter.png'], // Replace if needed
},
};
// Data for Service Areas
const serviceAreas = [
{
title: "Custom Software Development & Consulting",
icon: FaLaptopCode,
description:
"We design, build, and implement bespoke software solutions tailored to your unique business challenges and objectives. Our consulting services help align technology with your strategic goals.",
imageUrl: "/images/team.svg", // Reusing image from About
link: "/contact?subject=Custom Development Inquiry", // Link to contact or a future dedicated page
linkText: "Discuss Your Project",
},
{
title: "IT Resource Augmentation",
icon: FaUsers,
description:
"Scale your team effectively with our flexible resource augmentation model. Access skilled IT professionals (BAs, Testers, Developers, Designers) on demand or via managed milestone-based projects.",
imageUrl: "/images/team-collaborative.png", // Reusing image from Resource Augmentation
link: "/services/resource-augmentation",
linkText: "Explore Augmentation",
},
{
title: "OBSE - Bank Statement Extractor",
icon: FaShippingFast,
description:
"Automate bank statement processing with OBSE. Our intelligent OCR solution extracts data accurately and quickly, enhancing efficiency, reducing risk, and speeding up financial assessments.",
imageUrl: "/images/obse.svg", // Reusing image from OBSE
link: "/obse",
linkText: "Learn About OBSE",
},
];
const ourApproachItems = [
{
icon: FaProjectDiagram,
title: "Strategic Alignment",
description: "Understanding your goals to ensure solutions deliver value.",
},
{
icon: FaHandshake,
title: "Client-Centric Collaboration",
description: "Working as true partners, involving you throughout.",
},
{
icon: FaCogs,
title: "Agile & Adaptive Delivery",
description: "Flexible methodologies for faster, relevant results.",
},
{
icon: FaWrench,
title: "Technical Excellence",
description: "Building robust, scalable, and maintainable solutions.",
},
];
export default function ServicesPage() {
return (
<div className="bg-white text-gray-800 overflow-x-hidden dark:bg-gray-900 dark:text-gray-200 font-poppins">
{/* 1. Hero Section */}
<section className="relative bg-gradient-to-r from-gray-800 via-gray-700 to-gray-900 text-white py-20 md:py-32">
<div className="absolute inset-0 bg-black opacity-50 dark:opacity-70"></div>
<div className="container mx-auto px-6 text-center relative z-10">
<h1
className="text-3xl md:text-5xl lg:text-6xl font-bold mb-4 font-poppins drop-shadow-md"
style={{ color: COLORS.primary }}
>
Tailored IT Services & Solutions
</h1>
<p className="text-lg md:text-xl max-w-4xl mx-auto leading-relaxed text-gray-200 dark:text-gray-300 mb-8">
Owethu Managed Services empowers businesses through innovative
technology solutions, strategic consulting, flexible resource
augmentation, and specialized product offerings.
</p>
<Link
href="#core-services"
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"
style={{ backgroundColor: COLORS.primary }}
>
Explore Our Services <FaArrowRight className="ml-2" />
</Link>
</div>
</section>
{/* 2. Core Service Areas Section */}
<section
id="core-services"
className="py-16 md:py-24 bg-white dark:bg-gray-900"
>
<div className="container mx-auto px-6">
<div className="text-center mb-12 md:mb-16">
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 dark:text-white mb-4">
Our Expertise, Your Advantage
</h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto">
We offer a comprehensive suite of services designed to address
your specific IT needs and drive business growth.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{serviceAreas.map((service) => (
<div
key={service.title}
className="flex flex-col bg-gray-50 dark:bg-gray-800 rounded-lg shadow-md overflow-hidden transform transition duration-300 hover:shadow-xl hover:-translate-y-1"
>
<div className="relative h-48 w-full">
<Image
src={service.imageUrl}
alt={`${service.title} illustration`}
layout="fill"
objectFit="contain" // Changed to contain for SVG/Illustrations
className="p-4 bg-gray-100 dark:bg-gray-700" // Added padding and bg
/>
</div>
<div className="p-6 flex flex-col flex-grow">
<div className="flex items-center mb-3">
<service.icon
className="text-2xl mr-3 flex-shrink-0"
style={{ color: COLORS.primary }}
/>
<h3 className="text-xl font-semibold font-poppins text-gray-900 dark:text-white">
{service.title}
</h3>
</div>
<p className="text-gray-600 dark:text-gray-300 text-sm mb-4 flex-grow">
{service.description}
</p>
<Link
href={service.link}
className="inline-flex items-center mt-auto text-gold-600 dark:text-gold-400 hover:text-gold-700 dark:hover:text-gold-300 font-semibold transition-colors duration-300 text-sm"
style={{ color: COLORS.primary }}
>
{service.linkText} <FaArrowRight className="ml-2" />
</Link>
</div>
</div>
))}
</div>
</div>
</section>
{/* 3. Our Approach Section */}
<section className="py-16 md:py-24 bg-gradient-to-br from-gray-100 to-gray-200 dark:from-gray-800 dark:to-gray-700">
<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 dark:text-white mb-4">
How We Deliver Excellence
</h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto font-poppins">
Our methodology ensures collaboration, precision, and impactful
results tailored to your project needs.
</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8">
{ourApproachItems.map((item) => (
<div
key={item.title}
className="bg-white dark:bg-gray-700 p-6 rounded-lg shadow-md text-center transform transition duration-300 hover:-translate-y-2 hover:shadow-xl dark:hover:shadow-gold-500/20"
>
<item.icon
className="text-4xl text-gold-500 mx-auto mb-5"
style={{ color: COLORS.primary }}
/>
<h4 className="text-xl font-semibold mb-3 font-poppins dark:text-white">
{item.title}
</h4>
<p className="text-gray-600 dark:text-gray-300 font-poppins text-sm leading-relaxed">
{item.description}
</p>
</div>
))}
</div>
</div>
</section>
{/* 4. Industry Expertise Snippet (Optional) */}
<section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6 text-center">
<FaBriefcase
className="text-5xl text-gold-500 mx-auto mb-4"
style={{ color: COLORS.primary }}
/>
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 dark:text-white mb-4">
Serving Diverse Industries
</h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto mb-8">
We apply our technical expertise across various sectors,
understanding the unique challenges and opportunities within each.
Key areas include Financial Services, Automotive, Technology, and
more.
</p>
<Link
href="/about#industry-expertise" // Assuming you add an ID to the section in about page
className="text-gold-600 dark:text-gold-400 hover:text-gold-700 dark:hover:text-gold-300 font-semibold transition-colors duration-300 inline-flex items-center"
style={{ color: COLORS.primary }}
>
Learn More About Our Industry Focus{" "}
<FaArrowRight className="ml-2" />
</Link>
</div>
</section>
{/* 5. Call to Action (CTA) Section */}
<section
className="py-16 md:py-24 bg-gold-500 text-gray-900"
style={{ backgroundColor: COLORS.primary }}
>
<div className="container mx-auto px-6 text-center">
<h2 className="text-3xl md:text-4xl font-bold mb-4 font-poppins">
Let&apos;s Build Your Solution
</h2>
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed mb-8 font-poppins text-gray-800">
Ready to discuss how OMS can help you achieve your technology goals?
Contact us today for a consultation.
</p>
<Link
href="/contact"
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"
>
Get in Touch
</Link>
</div>
</section>
</div>
);
}

View File

@ -363,17 +363,10 @@ const methodologies = [
]; ];
const clientLogos = [ const clientLogos = [
{ src: "/clients/absa-logo.png", alt: "Absa Bank Logo" }, // Replace with actual paths { src: "/images/absa.png", alt: "Absa Bank Logo" }, // Replace with actual paths
{ src: "/clients/african-bank-logo.png", alt: "African Bank Logo" }, { src: "/images/sybrin.svg", alt: "Sybrin Logo" },
{ src: "/clients/sybrin-logo.png", alt: "Sybrin Logo" }, { src: "/images/bcx.png", alt: "BCX Logo" },
{ src: "/clients/telkom-logo.png", alt: "Telkom Logo" }, { src: "/images/sasol.png", alt: "Sasol Logo" },
{ src: "/clients/fnb-logo.png", alt: "FNB Logo" },
{ src: "/clients/bcx-logo.png", alt: "BCX Logo" },
{
src: "/clients/ssd-logo.png",
alt: "Shapiro Shaik Defries & Associates Logo",
},
{ src: "/clients/flysafair-logo.png", alt: "FlySafair Logo" },
]; ];
// --- Page Component --- // --- Page Component ---
@ -517,7 +510,7 @@ export default function ResourceAugmentationPage() {
<div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg"> <div className="relative h-64 md:h-80 rounded-lg overflow-hidden shadow-lg">
{/* Placeholder Image - Replace with a relevant image (e.g., team collaboration, office) */} {/* Placeholder Image - Replace with a relevant image (e.g., team collaboration, office) */}
<Image <Image
src="/images/team-meeting.jpg" // Replace with actual path src="/images/team-collaborative.png" // Replace with actual path
alt="OMS Team Collaboration" alt="OMS Team Collaboration"
layout="fill" layout="fill"
objectFit="cover" objectFit="cover"

View File

@ -130,6 +130,21 @@
.animation-delay-600 { .animation-delay-600 {
animation-delay: 0.6s; animation-delay: 0.6s;
} }
@keyframes marquee-continuous {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(-50%);
}
}
.animate-marquee-continuous {
animation: marquee-continuous linear infinite;
will-change: transform;
}
.group:hover .animate-marquee-continuous {
animation-play-state: paused;
}
} }
/* Optional scale animation for background */ /* Optional scale animation for background */
@keyframes floatSlightly { @keyframes floatSlightly {

View File

@ -9,8 +9,8 @@ export const demoVacancies: Vacancy[] = [
"We are looking for a talented Senior Frontend Engineer to join our growing team. You will be responsible for building and maintaining our user-facing web applications, ensuring high performance and responsiveness.", "We are looking for a talented Senior Frontend Engineer to join our growing team. You will be responsible for building and maintaining our user-facing web applications, ensuring high performance and responsiveness.",
department: "Engineering", department: "Engineering",
location: { location: {
city: "Amsterdam", city: "Cape Town",
country: "Netherlands", country: "South Africa",
remote: false, remote: false,
}, },
employmentType: "Full-time", employmentType: "Full-time",
@ -18,7 +18,7 @@ export const demoVacancies: Vacancy[] = [
salary: { salary: {
min: 70000, min: 70000,
max: 90000, max: 90000,
currency: "EUR", currency: "ZAR",
period: "Annual", period: "Annual",
}, },
responsibilities: [ responsibilities: [
@ -74,8 +74,8 @@ export const demoVacancies: Vacancy[] = [
"Seeking an experienced Product Marketing Manager to lead the go-to-market strategy for our innovative products. You will craft compelling messaging and positioning, drive demand, and enable sales.", "Seeking an experienced Product Marketing Manager to lead the go-to-market strategy for our innovative products. You will craft compelling messaging and positioning, drive demand, and enable sales.",
department: "Marketing", department: "Marketing",
location: { location: {
city: "London", city: "Pretoria",
country: "UK", country: "South Africa",
remote: true, remote: true,
}, },
employmentType: "Full-time", employmentType: "Full-time",
@ -83,7 +83,7 @@ export const demoVacancies: Vacancy[] = [
salary: { salary: {
min: 60000, min: 60000,
max: 80000, max: 80000,
currency: "GBP", currency: "ZAR",
period: "Annual", period: "Annual",
}, },
responsibilities: [ responsibilities: [
@ -122,8 +122,8 @@ export const demoVacancies: Vacancy[] = [
"Join our backend team to design, develop, and maintain server-side logic, databases, and APIs for our platform. Focus on scalability, performance, and reliability.", "Join our backend team to design, develop, and maintain server-side logic, databases, and APIs for our platform. Focus on scalability, performance, and reliability.",
department: "Engineering", department: "Engineering",
location: { location: {
city: "Berlin", city: "Johannesburg",
country: "Germany", country: "South Africa",
remote: false, remote: false,
}, },
employmentType: "Full-time", employmentType: "Full-time",

BIN
public/images/absa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
public/images/bcx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
public/images/dashboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

BIN
public/images/jacaranda.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.8 MiB

16
public/images/obse.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 731 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
public/images/sasol.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

13
public/images/sybrin.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 228 KiB

9
public/images/team.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.2 MiB