Merge pull request #5 from OwethuManagedServices/updated-site

Updated site
This commit is contained in:
libertyoms
2025-05-19 16:13:42 +02:00
committed by GitHub
9 changed files with 1003 additions and 430 deletions

View File

@ -48,31 +48,31 @@ const coreValues = [
icon: FaCheckCircle, icon: FaCheckCircle,
title: "Service", title: "Service",
description: description:
"Dedicated to providing outstanding service at every touchpoint, meeting the highest standards, and creating lasting impact for our clients.", "We strive to elevate every experience — from client interactions to internal collaborations. With unwavering dedication, we deliver excellence that inspires growth, fosters partnerships, and creates a lasting, positive impact on everyone we touch.",
}, },
{ {
icon: FaHandshake, icon: FaHandshake,
title: "Accountability", title: "Accountability",
description: description:
"Taking ownership of our actions and delivering on promises with transparency. Our commitment fosters trust and ensures we consistently meet client expectations.", "We embrace ownership with pride, holding ourselves and each other to the highest standards. Our transparency and commitment to our promises build the trust that strengthens relationships, propels progress, and empowers everyone to thrive.",
}, },
{ {
icon: FaHeart, icon: FaHeart,
title: "Passion", title: "Passion",
description: description:
"Driven by a passion for innovation, we embrace new ideas and technologies, constantly seeking ways to improve and deliver creative, boundary-pushing solutions.", "Driven by a relentless passion for innovation, we embrace challenges as opportunities. We inspire creativity, ignite new ideas, and fuel transformation — always seeking to push the limits of whats possible and make a difference in everything we do.",
}, },
{ {
icon: FaComments, icon: FaComments,
title: "Communication", title: "Communication",
description: description:
"Clear, consistent, and proactive communication is central. We ensure all stakeholders are aligned, informed, and empowered, fostering collaboration.", "Open, honest, and proactive communication is the bridge that connects us all. We believe in the power of dialogue to align, inspire, and drive collaboration — ensuring that every voice is heard and every idea has the opportunity to flourish.",
}, },
{ {
icon: FaShieldAlt, icon: FaShieldAlt,
title: "Trust", title: "Trust",
description: description:
"Cultivating trust through ethical practices, honesty, and transparency. We uphold the highest integrity for long-term, mutually beneficial relationships.", "At the heart of our work lies unwavering trust. Built on integrity, honesty, and respect, we nurture strong, meaningful relationships that create a foundation for long-term success — together, as partners, as a team, and as a community.",
}, },
]; ];
@ -168,20 +168,24 @@ export default function AboutUsPage() {
by Purpose by Purpose
</h2> </h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4 font-poppins"> <p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4 font-poppins">
Expand on the founding story/motivation. E.g., Owethu Managed Owethu Managed Services wasnt built in a boardroom it was
Services was born from a clear vision: to harness the born from a deeper calling: a desire to do more than simply
transformative power of technology not just to solve problems, exist in the tech space. We set out to use innovation not as a
but to proactively create opportunities for businesses to buzzword, but as a lifeline pulling businesses out of
thrive. We saw a need for a partner who truly understands both stagnation and into a future full of possibility.
technology&apos;s potential and the unique challenges modern </p>
organizations face. <p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4 font-poppins">
From day one, weve challenged the status quo. We dont just fix
problems we anticipate them, reimagine them, and turn them
into powerful stepping stones for growth. Our mission is simple:
break what seems impossible, and rebuild it into something
extraordinary.
</p> </p>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed font-poppins"> <p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed font-poppins">
Elaborate on the journey. E.g., Our journey has been defined by Today, OMS is more than a service provider. We are trusted
a relentless pursuit of knowledge, adaptation to the digital transformation partners, creative problem-solvers, and
ever-evolving tech landscape, and an unwavering commitment to passionate believers in human-driven innovation. This isnt just
client success. This focus has established us as trusted business. This is our purpose.
advisors and thought leaders in digital transformation.
</p> </p>
</div> </div>
<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">
@ -224,9 +228,7 @@ export default function AboutUsPage() {
<p className="text-gray-700 dark:text-gray-300 leading-relaxed font-poppins flex-grow"> <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 &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. We aim to empower transforming industries for the better.&quot;
organisations to break through technological barriers and
achieve greater success.&quot;
</p> </p>
</div> </div>
{/* Mission Card */} {/* Mission Card */}
@ -242,12 +244,9 @@ export default function AboutUsPage() {
Our Mission Our Mission
</h3> </h3>
<p className="text-gray-700 dark:text-gray-300 leading-relaxed font-poppins flex-grow"> <p className="text-gray-700 dark:text-gray-300 leading-relaxed font-poppins flex-grow">
&quot;We are dedicated to creating tailored, innovative &quot;Our purpose is to help our clients drive transformative
solutions that drive business success. By combining expertise growth and innovation to propel their business forward
with cutting-edge technology, we solve complex problems and redefining whats possible.&quot;
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.&quot;
</p> </p>
</div> </div>
</div> </div>
@ -300,9 +299,10 @@ export default function AboutUsPage() {
Deep Domain Knowledge Deep Domain Knowledge
</h2> </h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed font-poppins"> <p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed font-poppins">
We combine broad technological capabilities with specialized Retail/E-commerce: Experience in building scalable e-commerce
expertise across key industries, understanding the unique platforms, optimizing digital customer journeys, enabling secure
challenges and opportunities within each sector. payment integrations, and leveraging data analytics to drive
personalized shopping experiences and operational efficiency.
</p> </p>
</div> </div>
<div className="lg:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6"> <div className="lg:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6">
@ -430,7 +430,7 @@ export default function AboutUsPage() {
</h2> </h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4 font-poppins"> <p className="text-md md:text-lg text-gray-700 dark:text-gray-300 leading-relaxed mb-4 font-poppins">
We believe the best results come from true collaboration. We We believe the best results come from true collaboration. We
invest time in understanding your culture, goals, and invest time in understanding your culture, processes, goals, and
challenges, working alongside your team as an extension of your challenges, working alongside your team as an extension of your
own capabilities. own capabilities.
</p> </p>
@ -516,10 +516,11 @@ export default function AboutUsPage() {
</h2> </h2>
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed font-poppins text-gray-800"> <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 Ultimately, our success is measured by yours. We are committed to
delivering solutions that not only meet technical requirements but creating solutions that ignite momentum, unlock potential, and turn
also drive efficiency, foster growth, enhance user experiences, and ambition into achievement empowering you to rise above challenges
provide a clear return on investment. Let&apos;s build a successful and lead with confidence into the future. Together, let&apos;s build
future, together. a future where your success is not just a possibility, but a
reality.
</p> </p>
{/* Optional CTA to contact */} {/* Optional CTA to contact */}
<div className="mt-10"> <div className="mt-10">

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: [
"Optimised Bank Statement Extractor", "Optimized Bank Statement Extractor",
"OBSE", "OBSE",
"bank statement extraction", "bank statement extraction",
"OCR bank statements", "OCR bank statements",
@ -110,16 +110,16 @@ const keyFeatures: FeatureItem[] = [
}, },
{ {
icon: FaSearchDollar, icon: FaSearchDollar,
title: "Intelligent Income Detection", title: "Intelligent Income & Salaried Detection",
description: 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, icon: FaFingerprint,
title: "Enhanced Fraud Detection", title: "Enhanced Fraud Detection",
description: description:
"Detects document tampering, fraudulent insertions, and developing behavioral profiling.", "Detects document tampering, fraudulent insertions, and developing behavioral profiling.",
isComingSoon: true, isComingSoon: false,
}, },
{ {
icon: FaSyncAlt, icon: FaSyncAlt,
@ -244,10 +244,11 @@ export default function ObsePage() {
{/* Consider adding OMS Logo here */} {/* Consider adding OMS Logo here */}
{/* <Image src="/oms-logo-white.png" alt="OMS Logo" width={150} height={50} className="mx-auto mb-6" /> */} {/* <Image src="/oms-logo-white.png" alt="OMS Logo" width={150} height={50} className="mx-auto mb-6" /> */}
<h1 <h1
className="text-3xl md:text-5xl lg:text-6xl font-bold mb-4 font-poppins drop-shadow-md" 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 Credit Processes with OBSE Revolutionize Your Lending
and Credit Processes with OBSE
</h1> </h1>
<p className="text-lg md:text-xl max-w-4xl mx-auto leading-relaxed text-gray-200 dark:text-gray-300 mb-8"> <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 Automate data extraction, enhance accuracy, detect fraud, and
@ -347,7 +348,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">
Optimised Bank Statement Extractor (OBSE) is an advanced OCR and Optimized 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
@ -691,10 +692,10 @@ export default function ObsePage() {
</div> </div>
</section> </section>
{/* 11. About OMS Section (Brief) */} {/* 11. About OMS Section (Brief)
<section className="py-16 md:py-24 bg-white dark:bg-gray-900"> <section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6 text-center"> <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"> <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 Your Experienced Partner in Financial Technology
</h2> </h2>
@ -714,6 +715,7 @@ export default function ObsePage() {
</Link> </Link>
</div> </div>
</section> </section>
/}
{/* 12. Call to Action (CTA) Section */} {/* 12. Call to Action (CTA) Section */}
<section <section
@ -753,6 +755,7 @@ export default function ObsePage() {
</section> </section>
{/* 13. Contact Information Section */} {/* 13. Contact Information Section */}
{/*}
<section className="py-16 md:py-24 bg-gray-100 dark:bg-gray-800"> <section className="py-16 md:py-24 bg-gray-100 dark:bg-gray-800">
<div className="container mx-auto px-6"> <div className="container mx-auto px-6">
<div className="text-center mb-12"> <div className="text-center mb-12">
@ -767,7 +770,10 @@ export default function ObsePage() {
</p> </p>
</div> </div>
<div className="max-w-4xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-8 items-center"> <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="space-y-6">
<div className="flex items-center space-x-4"> <div className="flex items-center space-x-4">
<FaPhone <FaPhone
@ -803,7 +809,9 @@ export default function ObsePage() {
</a> </a>
</div> </div>
</div> </div>
{/* Optional: Link to main contact page */}
{--- Optional: Link to main contact page */}
{/* --- comment out if not needed}
<Link <Link
href="/contact" 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" 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"
@ -812,6 +820,7 @@ export default function ObsePage() {
Go to Full Contact Page <FaArrowRight className="ml-2" /> Go to Full Contact Page <FaArrowRight className="ml-2" />
</Link> </Link>
</div> </div>
*/}
{/* Optional: Simple Contact Form (if ContactForm component is not used/available) */} {/* Optional: Simple Contact Form (if ContactForm component is not used/available) */}
{/* <form className="space-y-4"> {/* <form className="space-y-4">
@ -832,7 +841,7 @@ export default function ObsePage() {
</button> </button>
</form> */} </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"> <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"> <h3 className="text-xl font-semibold font-poppins text-gray-900 dark:text-white mb-4">
Send a Quick Inquiry Send a Quick Inquiry
@ -842,6 +851,9 @@ export default function ObsePage() {
</div> </div>
</div> </div>
</section> </section>
*/}
{/* 14. Footer Section */}
</div> </div>
); );
} }

View File

@ -58,7 +58,7 @@ 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 Optimised Bank Statement Extractor automates data aggregation, reduces errors, and provides deep financial insights." description="Our advanced Optimized 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

View File

@ -0,0 +1,597 @@
import Link from "next/link";
import { Metadata } from "next";
import {
FaArrowRight,
FaDraftingCompass,
FaHandshake,
FaHeadset,
FaLaptopCode, // For Web App Dev, Backend
FaLightbulb, // For Ideation, Innovation
FaPuzzlePiece, // For Custom Software Solutions
FaRocket, // For Product Launch, Scalable Tech
FaSearch, // For User Research
FaShieldAlt, // For Security Testing
FaSyncAlt, // For Agile, Iteration
FaUserCheck, // For User-Centred Design, Usability Testing
FaUsersCog, // For Dedicated Teams
// Additional icons that might be useful for the new content:
FaMobileAlt, // For Mobile Apps
FaDesktop, // For Desktop Apps
FaBrain, // For AI & ML
FaCubes, // For Blockchain (alternative: FaLink)
FaNetworkWired, // For IoT (alternative: FaBroadcastTower)
FaBullseye, // For Market Strategy
FaChartLine, // For Growth/Scalability
FaTasks, // For QA
FaComments, // For Feedback
FaPhone,
FaEnvelope,
} from "react-icons/fa";
import { COLORS } from "@/constants";
import ContactForm from "@/components/ContactForm";
// SEO Metadata
export const metadata: Metadata = {
title: "Product Development Services | Digital Solutions by OMS",
description:
"OMS delivers innovative, tailored digital solutions. Explore our end-to-end product development services, from ideation to launch and beyond.",
keywords: [
"product development",
"custom software solutions",
"user-centred design",
"agile development",
"cross-platform solutions",
"mobile app development",
"web app development",
"tech stack",
"quality assurance",
"OMS",
"Owethu Management Services",
],
openGraph: {
title: "Product Development Services | Digital Solutions by OMS",
description:
"Transform your ideas into market-ready products with OMS's comprehensive development expertise.",
url: "https://www.oms.africa/services/product-development", // Replace with your actual URL
images: [
{
url: "/images/product-dev-og-image.png", // Replace with an appropriate OG image URL
width: 1200,
height: 630,
alt: "OMS Product Development Services",
},
],
locale: "en_ZA",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Product Development Services | Digital Solutions by OMS",
description:
"Build innovative digital products with OMS. We cover the full lifecycle from concept to continuous improvement.",
// images: ['/images/product-dev-twitter-image.png'], // Replace if needed
},
};
interface FeatureItem {
icon?: React.ElementType; // Icon is optional for some lists like tech stack
title: string;
description: string;
}
const SectionTitle: React.FC<{ children: React.ReactNode }> = ({
children,
}) => (
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 dark:text-white mb-4 text-center">
{children}
</h2>
);
const SectionParagraph: React.FC<{ children: React.ReactNode }> = ({
children,
}) => (
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto text-center mb-10 md:mb-12">
{children}
</p>
);
const FeatureGrid: React.FC<{ items: FeatureItem[]; iconColor?: string }> = ({
items,
iconColor = COLORS.primary,
}) => (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{items.map((item) => (
<div
key={item.title}
className="bg-white dark:bg-gray-700 p-6 rounded-lg shadow-md"
>
{item.icon && (
<item.icon className="text-3xl mb-3" style={{ color: iconColor }} />
)}
<h4 className="text-xl font-semibold mb-2 font-poppins dark:text-white">
{item.title}
</h4>
<p className="text-gray-600 dark:text-gray-300 text-sm leading-relaxed">
{item.description}
</p>
</div>
))}
</div>
);
export default function ProductDevelopmentPage() {
const howOmsDeliversItems: FeatureItem[] = [
{
icon: FaPuzzlePiece,
title: "Custom Software Solutions",
description:
"We craft bespoke applications designed to solve your unique business challenges, ensuring alignment with your goals and processes.",
},
{
icon: FaUserCheck,
title: "User-Centred Design",
description:
"We prioritise seamless functionality with an intuitive user experience, creating products that are not only powerful but also easy to use.",
},
{
icon: FaRocket,
title: "Scalable & Future-Proof Technology",
description:
"Our solutions are built with long-term growth in mind, ensuring adaptability to future demands and changes in technology.",
},
{
icon: FaSyncAlt,
title: "Agile Development Approach",
description:
"Through iterative development, we ensure faster time-to-market, with continuous feedback from users driving improvements along the way.",
},
];
const endToEndItems: FeatureItem[] = [
{
icon: FaLightbulb,
title: "Ideation & Concept Development",
description:
"We collaborate with you to transform your ideas into a clear product vision and roadmap.",
},
{
icon: FaDraftingCompass,
title: "Prototyping & MVP Development",
description:
"We build prototypes and minimum viable products to validate concepts early, gather feedback, and ensure alignment with user needs.",
},
{
icon: FaBullseye,
title: "Product Launch & Market Strategy",
description:
"Our team helps with the go-to-market strategy, ensuring a successful product launch with strong market positioning and customer adoption.",
},
{
icon: FaHeadset,
title: "Post-Launch Support & Continuous Improvement",
description:
"We provide ongoing support, monitoring, and iterative enhancements based on user feedback and market trends.",
},
];
const crossPlatformItems: FeatureItem[] = [
{
icon: FaMobileAlt,
title: "Mobile Application Development",
description:
"We create intuitive mobile apps for both iOS and Android, ensuring seamless performance and a high-quality user experience.",
},
{
icon: FaLaptopCode,
title: "Web Application Development",
description:
"Tailored web applications that are scalable, secure, and optimized for the best user interaction.",
},
{
icon: FaDesktop,
title: "Desktop Applications",
description:
"For businesses requiring more complex or resource-heavy solutions, we build powerful desktop applications with smooth integration.",
},
];
const techStackItems: FeatureItem[] = [
{ title: "Frontend Development", description: "React, Angular, Vue.js" },
{
title: "Backend Development",
description: "Node.js, Python, Java, Ruby on Rails",
},
{
title: "Database Technologies",
description: "MySQL, PostgreSQL, MongoDB, NoSQL",
},
{
title: "Cloud Services & DevOps",
description: "AWS, Azure, Google Cloud Platform",
},
{
title: "AI & Machine Learning",
description: "TensorFlow, PyTorch, Scikit-learn",
},
];
const qualityAssuranceItems: FeatureItem[] = [
{
icon: FaTasks,
title: "Manual & Automated Testing",
description:
"Comprehensive testing to ensure the product meets all requirements and functions seamlessly.",
},
{
icon: FaChartLine, // Or FaTachometerAlt if you add it
title: "Performance & Load Testing",
description:
"We simulate high traffic and performance scenarios to ensure your product can scale and handle user demands.",
},
{
icon: FaShieldAlt,
title: "Security Testing",
description:
"Proactive identification and mitigation of potential security vulnerabilities to safeguard your product and user data.",
},
];
const collaborativeProcessItems: FeatureItem[] = [
{
icon: FaSyncAlt,
title: "Agile Methodology",
description:
"Our flexible and iterative approach ensures that your product evolves based on real-time feedback, reducing risk and accelerating time-to-market.",
},
{
icon: FaHandshake,
title: "Client Involvement",
description:
"Regular check-ins, demos, and sprint reviews keep you involved and aligned with project progress, making sure we are building the product you envisioned.",
},
{
icon: FaUsersCog,
title: "Dedicated Development Teams",
description:
"Our dedicated teams work closely with your business to ensure that every decision aligns with your strategic goals and product vision.",
},
];
const userCentredApproachItems: FeatureItem[] = [
{
icon: FaSearch,
title: "User Research & Personas",
description:
"We conduct thorough user research to understand the needs, behaviours, and challenges of your target audience.",
},
{
icon: FaUserCheck,
title: "Usability Testing",
description:
"Regular usability tests are conducted to ensure that your product is easy to navigate, efficient, and enjoyable to use.",
},
{
icon: FaComments,
title: "User Feedback & Iteration",
description:
"We continuously gather user feedback and iterate on product features to improve usability and customer satisfaction.",
},
];
const innovationItems: FeatureItem[] = [
{
icon: FaBrain,
title: "Artificial Intelligence & Machine Learning",
description:
"We integrate AI and machine learning to create smarter, data-driven products that can adapt and scale as user needs evolve.",
},
{
icon: FaCubes,
title: "Blockchain Solutions",
description:
"We incorporate blockchain for secure, transparent, and decentralized applications.",
},
{
icon: FaNetworkWired,
title: "Internet of Things (IoT)",
description:
"We build IoT-enabled products that connect the physical and digital worlds for enhanced business intelligence and automation.",
},
];
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-800 text-white py-24 md:py-40">
<div className="absolute inset-0 bg-black opacity-40 dark:opacity-60"></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 }}
>
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 don'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"
style={{ backgroundColor: COLORS.primary }}
>
How We Deliver
</Link>
<Link
href="#contact"
className="inline-flex items-center text-gold-400 hover:text-gold-300 transition-colors duration-300"
style={{ color: COLORS.primary }}
>
Discuss Your Project <FaArrowRight className="ml-2" />
</Link>
</div>
</div>
</section>
{/* 2. How OMS Delivers Market-Ready Products Section */}
<section
id="how-we-deliver"
className="py-16 md:py-24 bg-gray-50 dark:bg-gray-800"
>
<div className="container mx-auto px-6">
<SectionTitle>How OMS Delivers Market-Ready Products</SectionTitle>
{/* No intro paragraph provided for this specific subtitle in the source */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-5xl mx-auto">
{howOmsDeliversItems.map((item) => (
<div
key={item.title}
className="bg-white dark:bg-gray-700 p-6 rounded-lg shadow-md flex items-start space-x-4"
>
{item.icon && (
<item.icon
className="text-3xl text-gold-500 dark:text-gold-400 mt-1 flex-shrink-0"
style={{ color: COLORS.primary }}
/>
)}
<div>
<h4 className="text-lg font-semibold mb-1 font-poppins dark:text-white">
{item.title}
</h4>
<p className="text-gray-600 dark:text-gray-300 text-sm leading-relaxed">
{item.description}
</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* 3. End-to-End Product Development Section */}
<section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6">
<SectionTitle>End-to-End Product Development</SectionTitle>
<SectionParagraph>
We support businesses throughout the entire product lifecycle, from
ideation to post-launch support. Our comprehensive services cover
every phase of development, ensuring that your product is not only
designed and built to meet your current needs, but is also ready for
future growth and evolution.
</SectionParagraph>
<FeatureGrid items={endToEndItems} />
</div>
</section>
{/* 4. Cross-Platform Solutions Section */}
<section className="py-16 md:py-24 bg-gray-50 dark:bg-gray-800">
<div className="container mx-auto px-6">
<SectionTitle>Cross-Platform Solutions</SectionTitle>
<SectionParagraph>
We deliver cross-platform products that work seamlessly across web,
mobile, and desktop environments. This ensures your product is
accessible to a wider audience and provides a consistent user
experience, regardless of the device or platform.
</SectionParagraph>
<FeatureGrid items={crossPlatformItems} />
</div>
</section>
{/* 5. Tech Stack Expertise Section */}
<section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6">
<SectionTitle>Tech Stack Expertise</SectionTitle>
<SectionParagraph>
Our product development solutions are powered by a diverse range of
technologies. Whether you need a high-performance web app, a mobile
solution, or a complex enterprise application, our team uses the
latest and most suitable technologies to ensure the product is
reliable, secure, and future-ready.
</SectionParagraph>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{techStackItems.map((item) => (
<div
key={item.title}
className="bg-gray-100 dark:bg-gray-800 p-6 rounded-lg shadow-sm"
>
<h4
className="text-lg font-semibold mb-2 font-poppins text-gold-600 dark:text-gold-400"
style={{ color: COLORS.primary }}
>
{item.title}
</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm">
{item.description}
</p>
</div>
))}
</div>
</div>
</section>
{/* 6. Quality Assurance & Testing Section */}
<section className="py-16 md:py-24 bg-gray-50 dark:bg-gray-800">
<div className="container mx-auto px-6">
<SectionTitle>Quality Assurance & Testing</SectionTitle>
<SectionParagraph>
Our product development approach includes robust testing and quality
assurance to ensure that your product is error-free, secure, and
optimized for performance. We conduct thorough testing at each stage
of the development process to deliver a high-quality final product.
</SectionParagraph>
<FeatureGrid items={qualityAssuranceItems} />
</div>
</section>
{/* 7. Collaborative Development Process Section */}
<section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6">
<SectionTitle>Collaborative Development Process</SectionTitle>
<SectionParagraph>
We believe that collaboration is key to successful product
development. Our agile and transparent development process ensures
that you are always in the loop, from initial discussions to final
delivery.
</SectionParagraph>
<FeatureGrid items={collaborativeProcessItems} />
</div>
</section>
{/* 8. User-Centred Approach Section */}
<section className="py-16 md:py-24 bg-gray-50 dark:bg-gray-800">
<div className="container mx-auto px-6">
<SectionTitle>User-Centred Approach</SectionTitle>
<SectionParagraph>
We design products with the end-user in mind, focusing on creating
intuitive, engaging, and valuable experiences that delight customers
and drive retention.
</SectionParagraph>
<FeatureGrid items={userCentredApproachItems} />
</div>
</section>
{/* 9. Innovation & Emerging Technologies Section */}
<section className="py-16 md:py-24 bg-white dark:bg-gray-900">
<div className="container mx-auto px-6">
<SectionTitle>Innovation & Emerging Technologies</SectionTitle>
<SectionParagraph>
At OMS, we believe in staying ahead of the curve by leveraging the
latest innovations and emerging technologies to build
next-generation products. We are constantly exploring new ways to
incorporate cutting-edge solutions into our product development
process.
</SectionParagraph>
<FeatureGrid items={innovationItems} />
</div>
</section>
{/* 10. 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">
Ready to Transform Your Ideas into Reality?
</h2>
<p className="text-lg md:text-xl max-w-3xl mx-auto leading-relaxed mb-8 font-poppins text-gray-800">
Let&apos;s discuss your product vision and explore how OMS can
develop innovative digital solutions to drive your business forward.
Schedule a consultation with our experts today.
</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
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
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
</Link>
</div>
</div>
</section>
{/* 11. Contact Information Section */}
<section
id="contact"
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">
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 dark:text-white mb-4">
Get in Touch
</h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto">
Have a project in mind or need more information about our product
development services? Reach out today.
</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
className="w-6 h-6 text-gold-500 dark:text-gold-400 flex-shrink-0"
style={{ color: COLORS.primary }}
/>
<div>
<h3 className="text-lg font-semibold font-poppins text-gray-800 dark:text-gray-100">
Phone
</h3>
<a
href="tel:+27120513281"
className="text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm"
>
(012) 051 3281
</a>
</div>
</div>
<div className="flex items-center space-x-4">
<FaEnvelope
className="w-6 h-6 text-gold-500 dark:text-gold-400 flex-shrink-0"
style={{ color: COLORS.primary }}
/>
<div>
<h3 className="text-lg font-semibold font-poppins text-gray-800 dark:text-gray-100">
Email
</h3>
<a
href="mailto:info@oms.africa?subject=Product Development Inquiry"
className="text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm"
>
info@oms.africa
</a>
</div>
</div>
<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"
style={{ color: COLORS.primary }}
>
Go to Full Contact Page <FaArrowRight className="ml-2" />
</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
</h3>
<ContactForm />
</div>
</div>
</div>
</section>
</div>
);
}

View File

@ -22,15 +22,12 @@ import {
FaUsers, // For Teams/Resources FaUsers, // For Teams/Resources
FaChartLine, // For Reporting/MI FaChartLine, // For Reporting/MI
FaLightbulb, // For Innovation/Solutions FaLightbulb, // For Innovation/Solutions
FaPhone, // Contact
FaEnvelope, // Contact
FaTools, // General Capabilities FaTools, // General Capabilities
FaLayerGroup, // Frameworks (SAFe, etc.) FaLayerGroup, // Frameworks (SAFe, etc.)
FaFileInvoiceDollar, // Cost/Pricing FaFileInvoiceDollar, // Cost/Pricing
FaBusinessTime, // Experience/Past Projects FaBusinessTime, // Experience/Past Projects
} from "react-icons/fa"; } from "react-icons/fa";
import { COLORS } from "@/constants"; // Assuming COLORS constant is available import { COLORS } from "@/constants"; // Assuming COLORS constant is available
import ContactForm from "@/components/ContactForm"; // Assuming ContactForm is available
// SEO Metadata // SEO Metadata
export const metadata: Metadata = { export const metadata: Metadata = {
@ -49,7 +46,7 @@ export const metadata: Metadata = {
"UX/UI Designer", "UX/UI Designer",
"Process Engineer", "Process Engineer",
"Salesforce Partner", "Salesforce Partner",
"time and material IT", // "time and material IT",
"milestone-based projects", "milestone-based projects",
"IT outsourcing", "IT outsourcing",
"flexible IT resources", "flexible IT resources",
@ -98,7 +95,7 @@ interface ServiceModel {
const serviceModels: ServiceModel[] = [ const serviceModels: ServiceModel[] = [
{ {
icon: FaClock, icon: FaClock,
title: "Resource Augmentation Model (Time & Material)", title: "Resource Augmentation Model",
description: description:
"Access skilled IT professionals on demand to supplement your existing team.", "Access skilled IT professionals on demand to supplement your existing team.",
details: [ details: [
@ -111,15 +108,14 @@ const serviceModels: ServiceModel[] = [
}, },
{ {
icon: FaTasks, icon: FaTasks,
title: "Milestone-Based Model (Managed Service)", title: "Milestone-Based Model",
description: description:
"OMS takes full responsibility for delivering specific IT project phases or entire projects.", "OMS takes full responsibility for delivering specific IT project phases or entire projects.",
details: [ details: [
"Includes Project Planning & Management.", "Includes Project Planning & Management.",
"Covers End-to-end Process Design (Requirements, BPD, Arch, UX/UI).", "Covers End-to-end Process Design (Requirements, Business Process Design, Architecture, User Experience/User Interface, Data Architecture, Transformation, and Business Intelligence).",
"Includes Data & MI Design (Architecture, Transformation, BI).", "Change Management & Training ",
"Comprehensive Testing & QA (Strategy, Implementation, Management).", "Comprehensive Testing and Quality Assurance.",
"OMS manages all deployed team members, deliverables, and velocity.",
], ],
pricingModel: pricingModel:
"Milestone-Based pricing, payable on delivery of key milestones.", "Milestone-Based pricing, payable on delivery of key milestones.",
@ -384,10 +380,11 @@ export default function ResourceAugmentationPage() {
{/* Consider adding OMS Logo here if desired */} {/* 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" /> */} {/* <Image src="/oms-logo-white.png" alt="OMS Logo" width={150} height={50} className="mx-auto mb-6" /> */}
<h1 <h1
className="text-3xl md:text-5xl lg:text-6xl font-bold mb-4 font-poppins drop-shadow-md" 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 }} // Use gold color
> >
Flexible IT Resource Augmentation & Managed Services Flexible IT Resource <br />
Augmentation & Managed Services
</h1> </h1>
<p className="text-lg md:text-xl max-w-4xl mx-auto leading-relaxed text-gray-200 dark:text-gray-300 mb-8"> <p className="text-lg md:text-xl max-w-4xl mx-auto leading-relaxed text-gray-200 dark:text-gray-300 mb-8">
Scale your IT capabilities effectively with Owethu Managed Services. Scale your IT capabilities effectively with Owethu Managed Services.
@ -487,7 +484,7 @@ export default function ResourceAugmentationPage() {
Your Strategic Partner for IT Talent Your Strategic Partner for IT Talent
</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">
Owethu Managed Services (OMS) provides high-caliber IT Owethu Managed Services provides high-caliber IT
professionals through flexible engagement models tailored to professionals through flexible engagement models tailored to
your specific project requirements and business objectives. As a your specific project requirements and business objectives. As a
100% Black female-owned organization based in Centurion, 100% Black female-owned organization based in Centurion,
@ -553,7 +550,7 @@ export default function ResourceAugmentationPage() {
{model.title} {model.title}
</h3> </h3>
</div> </div>
<p className="text-gray-600 dark:text-gray-300 mb-4 text-sm flex-grow"> <p className="text-gray-600 dark:text-gray-300 mb-4 text-sm">
{model.description} {model.description}
</p> </p>
<ul className="space-y-2 mb-4"> <ul className="space-y-2 mb-4">
@ -566,17 +563,19 @@ export default function ResourceAugmentationPage() {
</li> </li>
))} ))}
</ul> </ul>
{/* Add the sentence as a separate paragraph for the Milestone model */}
{model.title === "Milestone-Based Model" && (
<p className="text-sm text-gray-700 dark:text-gray-300 mb-4 italic">
OMS manages all deployed team members, deliverables, and
velocity.
</p>
)}
<p className="text-sm font-semibold text-gray-800 dark:text-gray-200 mt-auto pt-4 border-t border-gray-200 dark:border-gray-600"> <p className="text-sm font-semibold text-gray-800 dark:text-gray-200 mt-auto pt-4 border-t border-gray-200 dark:border-gray-600">
{model.pricingModel} {model.pricingModel}
</p> </p>
</div> </div>
))} ))}
</div> </div>
<p className="text-center text-md text-gray-700 dark:text-gray-300 mt-12 max-w-3xl mx-auto">
OMS operates using both <span className="font-semibold">AGILE</span>{" "}
and <span className="font-semibold">Waterfall</span> Frameworks,
depending on client preference and project suitability.
</p>
</div> </div>
</section> </section>
@ -704,8 +703,10 @@ export default function ResourceAugmentationPage() {
Financial Services & Compliance Financial Services & Compliance
</h4> </h4>
<p className="text-sm text-gray-600 dark:text-gray-300"> <p className="text-sm text-gray-600 dark:text-gray-300">
FIC/KYC Remediation (Data Architecture, MI), Core Banking Expertise in FIC/KYC remediation, including data architecture
Systems, Lending/Credit Process Optimisation. and management information design, as well as core banking
systems and end-to-end optimisation of lending and credit
processes.
</p> </p>
</div> </div>
<div className="bg-gray-50 dark:bg-gray-800 p-6 rounded-lg shadow-sm"> <div className="bg-gray-50 dark:bg-gray-800 p-6 rounded-lg shadow-sm">
@ -717,8 +718,9 @@ export default function ResourceAugmentationPage() {
Customer Management & Onboarding Customer Management & Onboarding
</h4> </h4>
<p className="text-sm text-gray-600 dark:text-gray-300"> <p className="text-sm text-gray-600 dark:text-gray-300">
Design, Testing, Requirements, Process Engineering, UX/UI for Crafting seamless, data-driven onboarding experiences through
customer-facing platforms. straight-through processing, enhanced customer journeys,<br/>
real-time insights, and a 360-degree customer view.
</p> </p>
</div> </div>
<div className="bg-gray-50 dark:bg-gray-800 p-6 rounded-lg shadow-sm"> <div className="bg-gray-50 dark:bg-gray-800 p-6 rounded-lg shadow-sm">
@ -730,8 +732,10 @@ export default function ResourceAugmentationPage() {
Platform & Process Automation Platform & Process Automation
</h4> </h4>
<p className="text-sm text-gray-600 dark:text-gray-300"> <p className="text-sm text-gray-600 dark:text-gray-300">
Straight-Through Processing (STP) on Banking Platforms, API Specialising in Straight-Through Processing (STP) for banking
Integration, Salesforce implementations. platforms, seamless API integration, and end-to-end Salesforce
implementations to drive efficiency and reduce manual
intervention.
</p> </p>
</div> </div>
</div> </div>
@ -831,100 +835,6 @@ export default function ResourceAugmentationPage() {
</div> </div>
</div> </div>
</section> </section>
{/* 11. 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">
<h2 className="text-3xl md:text-4xl font-bold font-poppins text-gray-900 dark:text-white mb-4">
Get in Touch
</h2>
<p className="text-md md:text-lg text-gray-700 dark:text-gray-300 max-w-3xl mx-auto">
We&apos;re ready to assist you. Reach out via phone, email, or use
the form below to start the conversation about your IT resource
needs.
</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 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">
Contact Information
</h3>
<div className="flex items-center space-x-4">
<FaPhone
className="w-6 h-6 flex-shrink-0"
style={{ color: COLORS.primary }}
/>
<div>
<h4 className="text-lg font-semibold font-poppins text-gray-800 dark:text-gray-100">
Phone
</h4>
{/* Using specific numbers from PDF */}
<a
href="tel:+27120513281"
className="block text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm"
>
Zanele: (012) 051 3281
</a>
<a
href="tel:+27120513282"
className="block text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm"
>
Lindiwe: (012) 051 3282
</a>
</div>
</div>
<div className="flex items-center space-x-4">
<FaEnvelope
className="w-6 h-6 flex-shrink-0"
style={{ color: COLORS.primary }}
/>
<div>
<h4 className="text-lg font-semibold font-poppins text-gray-800 dark:text-gray-100">
Email
</h4>
{/* Using specific emails from PDF */}
<a
href="mailto:Zanelem@oms.africa"
className="block text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm"
>
Zanelem@oms.africa
</a>
<a
href="mailto:Lindiwes@oms.africa"
className="block text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm"
>
Lindiwes@oms.africa
</a>
<a
href="mailto:admin@oms.africa"
className="block text-gray-600 hover:text-gray-800 dark:text-gray-300 dark:hover:text-gray-100 transition text-sm mt-1"
>
admin@oms.africa (General)
</a>
</div>
</div>
{/* Optional: Link to main contact page */}
<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 mt-4"
style={{ color: COLORS.primary }}
>
Go to Full Contact Page <FaArrowRight className="ml-2" />
</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 a Quick Inquiry
</h3>
<ContactForm /> {/* Reuse your existing contact form */}
</div>
</div>
</div>
</section>
</div> </div>
); );
} }

View File

@ -157,20 +157,44 @@ const Footer = () => {
</p> </p>
<form className="flex flex-col sm:flex-row gap-2"> <form className="flex flex-col sm:flex-row gap-2">
{/* Input needs dark background styles */} {/* Input needs dark background styles */}
<div className="relative">
<input <input
type="email" type="email"
placeholder="Enter your email" placeholder="Enter your email"
aria-label="Email for newsletter" aria-label="Email for newsletter"
// Use dark variable for input bg/border, bright for text className="
className="flex-grow px-4 py-2 rounded-lg bg-[var(--dark-input)] border border-[var(--dark-border)] text-[var(--dark-foreground)] placeholder:text-[var(--dark-muted-foreground)] focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]" // Ring offset needs dark bg w-full
pr-24
px-4 py-2
rounded-lg
bg-[var(--dark-input)]
border border-[var(--dark-border)]
text-[var(--dark-foreground)]
placeholder:text-[var(--dark-muted-foreground)]
focus:outline-none focus:ring-2 focus:ring-ring
focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]
"
/> />
{/* Keep button styling primary */}
<button <button
type="submit" type="submit"
className="bg-primary text-primary-foreground px-4 py-2 rounded-lg font-semibold hover:bg-opacity-90 transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]" // Ring offset needs dark bg className="
absolute top-0 right-0
h-full
px-4
rounded-r-lg
bg-primary
text-primary-foreground
font-semibold
hover:bg-opacity-90
transition-colors
focus:outline-none focus:ring-2 focus:ring-ring
focus:ring-offset-2 focus:ring-offset-[var(--oms-black)]
"
> >
Subscribe Subscribe
</button> </button>
</div>
</form> </form>
{/* Badges - Use a subtle dark bg */} {/* Badges - Use a subtle dark bg */}
<div className="mt-6 space-x-2 sm:space-x-4"> <div className="mt-6 space-x-2 sm:space-x-4">

View File

@ -1,22 +1,13 @@
// components/Header.tsx (Server Component) // components/Header.tsx (Server Component)
import React from "react"; import React from "react";
import { auth } from "@/auth"; // Only need auth (for session) from here now
import HeaderClient from "./HeaderClient"; import HeaderClient from "./HeaderClient";
import { handleSignInAction, handleSignOutAction } from "@/actions/auth-action";
const Header = async () => { const Header = async () => {
// Fetch session data on the server // Fetch session data on the server
const session = await auth();
// Pass the session data and YOUR Server Actions as props // Pass the session data and YOUR Server Actions as props
return ( return <HeaderClient />;
<HeaderClient
session={session}
handleSignIn={handleSignInAction} // Pass YOUR sign-in Server Action
handleSignOut={handleSignOutAction} // Pass YOUR sign-out Server Action
/>
);
}; };
export default Header; export default Header;

View File

@ -4,53 +4,24 @@
import React, { useState } from "react"; import React, { useState } from "react";
import Link from "next/link"; import Link from "next/link";
import Image from "next/image"; import Image from "next/image";
import { usePathname } from "next/navigation"; // Import usePathname
import { import {
FiChevronDown, FiChevronDown,
FiClipboard, FiClipboard,
FiArrowRight, FiArrowRight,
FiMenu, FiMenu,
FiX, FiX,
FiLogIn, FiUsers,
FiUsers, // Resource Augmentation FiBriefcase,
FiBriefcase, // Project Management FiCpu,
FiCpu, // Product Development FiBox,
FiBox, // OBSE FiFileText,
FiFileText, // Vacancies FiUserCheck,
FiUserCheck, // Recruitment Portal
} from "react-icons/fi"; } from "react-icons/fi";
import ThemeToggle from "./ThemeToggle"; import ThemeToggle from "./ThemeToggle";
import type { Session } from "@auth/core/types";
const omsLogoUrl = "/oms-logo.svg"; const omsLogoUrl = "/oms-logo.svg";
type DropdownMenuProps = {
trigger: React.ReactNode;
children: React.ReactNode;
menuClasses?: string;
};
const DropdownMenu = ({
trigger,
children,
menuClasses = "w-48",
}: DropdownMenuProps) => (
<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
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 = { type DropdownLinkProps = {
href: string; href: string;
children: React.ReactNode; children: React.ReactNode;
@ -66,34 +37,50 @@ const DropdownLink = ({ href, children, onClick }: DropdownLinkProps) => (
</Link> </Link>
); );
type HeaderClientProps = { const HeaderClient = () => {
session: Session | null;
handleSignIn: () => void;
handleSignOut: () => void;
};
const HeaderClient = ({
session,
handleSignIn,
handleSignOut,
}: HeaderClientProps) => {
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
const toggleMenu = () => setIsMenuOpen((open) => !open); const toggleMenu = () => setIsMenuOpen((open) => !open);
const handleMobileLinkClick = () => setIsMenuOpen(false); const handleMobileLinkClick = () => setIsMenuOpen(false);
const [servicesDropdownOpen, setServicesDropdownOpen] = useState(false);
const [productsDropdownOpen, setProductsDropdownOpen] = useState(false);
const [joinUsDropdownOpen, setJoinUsDropdownOpen] = useState(false);
const handleServicesMouseEnter = () => setServicesDropdownOpen(true);
const handleServicesMouseLeave = () => setServicesDropdownOpen(false);
const handleProductsMouseEnter = () => setProductsDropdownOpen(true);
const handleProductsMouseLeave = () => setProductsDropdownOpen(false);
const handleJoinUsMouseEnter = () => setJoinUsDropdownOpen(true);
const handleJoinUsMouseLeave = () => setJoinUsDropdownOpen(false);
const pathname = usePathname(); // Get current path
// Helper function to check if a path is active (exact match for simple links, startsWith for base paths)
const isActive = (href: string, exact = false) => {
if (exact) {
return pathname === href;
}
// Handle root path specifically
if (href === "/") {
return pathname === "/";
}
return pathname.startsWith(href);
};
const megaMenuTriggerClasses = ` const megaMenuTriggerClasses = `
relative inline-flex items-center text-sm font-medium text-primary-foreground group relative inline-flex items-center text-sm font-medium text-primary-foreground
hover:opacity-90 transition-opacity duration-150 ease-in-out pb-1 hover:opacity-90 transition-opacity duration-150 ease-in-out pb-1
after:content-[''] after:absolute after:left-0 after:bottom-0 after:h-[2px] after:content-[''] after:absolute after:left-0 after:bottom-0 after:h-[2px]
after:w-0 after:bg-primary-foreground/80 after:transition-all after:duration-300 after:ease-out after:w-0 after:bg-primary-foreground/80 after:transition-all after:duration-300 after:ease-out
group-hover:after:w-full group-focus-within:after:w-full
`; `;
const megaMenuItemClasses = ` const megaMenuItemClasses = `
flex items-center p-3 -m-3 rounded-lg flex items-center p-3 -m-3 rounded-lg
hover:bg-secondary transition-colors duration-150 ease-in-out group hover:bg-secondary transition-colors duration-150 ease-in-out
`; `;
const megaMenuIconClasses = `flex-shrink-0 h-6 w-6 text-primary group-hover:text-primary-focus mr-4`; const megaMenuIconClasses = `flex-shrink-0 h-6 w-6 text-primary mr-4`;
const megaMenuTextWrapperClasses = `text-sm`; const megaMenuTextWrapperClasses = `text-sm`;
const megaMenuTitleClasses = `font-semibold text-card-foreground`; const megaMenuTitleClasses = `font-semibold text-card-foreground`;
@ -122,25 +109,41 @@ const HeaderClient = ({
<nav className="hidden md:flex items-center space-x-6 lg:space-x-8"> <nav className="hidden md:flex items-center space-x-6 lg:space-x-8">
<Link <Link
href="/" href="/"
className="text-sm font-medium text-foreground/80 hover:text-primary transition" className={`text-sm font-medium transition ${
isActive("/")
? "text-primary"
: "text-foreground/80 hover:text-primary"
}`} // Apply active class
> >
Home Home
</Link> </Link>
<Link <Link
href="/tech-talk" href="/tech-talk"
className="text-sm font-medium text-foreground/80 hover:text-primary transition" className={`text-sm font-medium transition ${
isActive("/tech-talk")
? "text-primary"
: "text-foreground/80 hover:text-primary"
}`} // Apply active class
> >
Tech Talk Tech Talk
</Link> </Link>
<Link <Link
href="/about" href="/about"
className="text-sm font-medium text-foreground/80 hover:text-primary transition" className={`text-sm font-medium transition ${
isActive("/about")
? "text-primary"
: "text-foreground/80 hover:text-primary"
}`} // Apply active class
> >
About Us About Us
</Link> </Link>
<Link <Link
href="/contact" href="/contact"
className="text-sm font-medium text-foreground/80 hover:text-primary transition" className={`text-sm font-medium transition ${
isActive("/contact")
? "text-primary"
: "text-foreground/80 hover:text-primary"
}`} // Apply active class
> >
Contact Us Contact Us
</Link> </Link>
@ -156,42 +159,6 @@ const HeaderClient = ({
<FiClipboard className="w-4 h-4 mr-1.5" /> <FiClipboard className="w-4 h-4 mr-1.5" />
Request OBSE Demo Request OBSE Demo
</Link> </Link>
{session?.user ? (
<DropdownMenu
menuClasses="w-40 right-0 left-auto"
trigger={
<div className="flex items-center space-x-2 cursor-pointer hover:opacity-80 transition">
<Image
src={session.user.image || "/default-avatar.png"}
alt={session.user.name || "User"}
width={32}
height={32}
className="rounded-full ring-1 ring-primary ring-offset-2 ring-offset-background"
/>
<span className="text-sm font-medium text-foreground hidden lg:inline">
{session.user.name?.split(" ")[0]}
</span>
</div>
}
>
<button
onClick={handleSignOut}
className="block w-full text-left px-4 py-2 text-sm text-destructive hover:bg-secondary hover:text-destructive transition"
>
Sign Out
</button>
</DropdownMenu>
) : (
<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>
)}
</div> </div>
<div className="md:hidden flex items-center"> <div className="md:hidden flex items-center">
@ -217,19 +184,35 @@ const HeaderClient = ({
<div className="bg-primary relative"> <div className="bg-primary relative">
<div className="container mx-auto px-4 sm:px-6 lg:px-8"> <div className="container mx-auto px-4 sm:px-6 lg:px-8">
<div className="hidden md:flex justify-between items-center h-12"> <div className="hidden md:flex justify-between items-center h-12">
{/* Wrap nav and link in a flex container */}
<div className="flex items-center space-x-8 lg:space-x-10">
<nav className="flex items-center space-x-8 lg:space-x-10"> <nav className="flex items-center space-x-8 lg:space-x-10">
{/* Services */} {/* Services */}
<div className="group"> <div
<button className={megaMenuTriggerClasses}> className={`group ${isActive("/services") ? "active" : ""}`} // Add active class to group
onMouseEnter={handleServicesMouseEnter}
onMouseLeave={handleServicesMouseLeave}
>
<button
className={`${megaMenuTriggerClasses} ${
isActive("/services") ? "after:w-full" : ""
}`}
>
{" "}
{/* Apply underline based on active state */}
Services Services
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 group-hover:rotate-180 transition-transform duration-200" /> <FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
</button> </button>
<div <div
className={` className={`
absolute left-0 top-full w-full shadow-lg z-40 absolute left-0 top-full w-full shadow-lg z-40
bg-card border-x border-b border-border rounded-b-lg bg-card border-x border-b border-border rounded-b-lg
opacity-0 invisible translate-y-[-10px] opacity-0 invisible translate-y-[-10px]
group-hover:opacity-100 group-hover:visible group-hover:translate-y-0 ${
servicesDropdownOpen
? "opacity-100 visible translate-y-0"
: ""
}
transition-all duration-300 ease-out transform transition-all duration-300 ease-out transform
`} `}
> >
@ -237,7 +220,11 @@ const HeaderClient = ({
<div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6"> <div className="grid grid-cols-1 md:grid-cols-3 gap-x-8 gap-y-6">
<Link <Link
href="/services/resource-augmentation" href="/services/resource-augmentation"
className={megaMenuItemClasses} className={`${megaMenuItemClasses} ${
isActive("/services/resource-augmentation")
? "text-primary"
: ""
}`} // Apply active class
> >
<FiUsers className={megaMenuIconClasses} /> <FiUsers className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}> <div className={megaMenuTextWrapperClasses}>
@ -248,7 +235,11 @@ const HeaderClient = ({
</Link> </Link>
<Link <Link
href="/services/project-management" href="/services/project-management"
className={megaMenuItemClasses} className={`${megaMenuItemClasses} ${
isActive("/services/project-management")
? "text-primary"
: ""
}`} // Apply active class
> >
<FiBriefcase className={megaMenuIconClasses} /> <FiBriefcase className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}> <div className={megaMenuTextWrapperClasses}>
@ -259,7 +250,11 @@ const HeaderClient = ({
</Link> </Link>
<Link <Link
href="/services/product-development" href="/services/product-development"
className={megaMenuItemClasses} className={`${megaMenuItemClasses} ${
isActive("/services/product-development")
? "text-primary"
: ""
}`} // Apply active class
> >
<FiCpu className={megaMenuIconClasses} /> <FiCpu className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}> <div className={megaMenuTextWrapperClasses}>
@ -269,39 +264,53 @@ const HeaderClient = ({
</div> </div>
</Link> </Link>
</div> </div>
<div className="mt-6 pt-4 border-t border-border flex justify-end">
<Link
href="/services"
className="flex items-center text-sm font-medium text-primary hover:underline"
>
Explore All Services
<FiArrowRight className="w-4 h-4 ml-1" />
</Link>
</div>
</div> </div>
</div> </div>
</div> </div>
{/* Products */} {/* Products */}
<div className="group"> <div
<button className={megaMenuTriggerClasses}> className={`group ${isActive("/obse") ? "active" : ""}`} // Add active class to group
onMouseEnter={handleProductsMouseEnter}
onMouseLeave={handleProductsMouseLeave}
>
<button
className={`${megaMenuTriggerClasses} ${
isActive("/obse") ? "after:w-full" : ""
}`}
>
{" "}
{/* Apply underline based on active state */}
Products Products
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 group-hover:rotate-180 transition-transform duration-200" /> <FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
</button> </button>
<div <div
className={` className={`
absolute left-0 top-full w-full shadow-lg z-40 absolute left-0 top-full w-full shadow-lg z-1000
bg-card border-x border-b border-border rounded-b-lg bg-card border-x border-b border-border rounded-b-lg
opacity-0 invisible translate-y-[-10px] opacity-0 invisible translate-y-[-10px]
group-hover:opacity-100 group-hover:visible group-hover:translate-y-0 ${
productsDropdownOpen
? "opacity-100 visible translate-y-0"
: ""
}
transition-all duration-300 ease-out transform transition-all duration-300 ease-out transform
`} `}
> >
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5"> <div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
<div className="max-w-md"> <div className="max-w-md">
<Link href="/obse" className={megaMenuItemClasses}> <Link
href="/obse"
className={`${megaMenuItemClasses} ${
isActive("/obse") ? "text-primary" : ""
}`}
>
{" "}
{/* Apply active class */}
<FiBox className={megaMenuIconClasses} /> <FiBox className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}> <div className={megaMenuTextWrapperClasses}>
<p className={megaMenuTitleClasses}>OBSE Platform</p> <p className={megaMenuTitleClasses}>
OBSE Platform
</p>
</div> </div>
</Link> </Link>
</div> </div>
@ -309,23 +318,54 @@ const HeaderClient = ({
</div> </div>
</div> </div>
{/* Join Our Team */} {/* Join Our Team */}
<div className="group"> <div
<button className={megaMenuTriggerClasses}> 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 Join Our Team
<FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 group-hover:rotate-180 transition-transform duration-200" /> <FiChevronDown className="w-4 h-4 ml-1.5 opacity-70 transition-transform duration-200" />
</button> </button>
<div <div
className={` className={`
absolute left-0 top-full w-full shadow-lg z-40 absolute left-0 top-full w-full shadow-lg z-1000
bg-card border-x border-b border-border rounded-b-lg bg-card border-x border-b border-border rounded-b-lg
opacity-0 invisible translate-y-[-10px] opacity-0 invisible translate-y-[-10px]
group-hover:opacity-100 group-hover:visible group-hover:translate-y-0 ${
joinUsDropdownOpen
? "opacity-100 visible translate-y-0"
: ""
}
transition-all duration-300 ease-out transform transition-all duration-300 ease-out transform
`} `}
> >
<div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5"> <div className="container mx-auto px-4 sm:px-6 lg:px-8 py-5">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 max-w-xl"> <div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 max-w-xl">
<Link href="/vacancies" className={megaMenuItemClasses}> <Link
href="/vacancies"
className={`${megaMenuItemClasses} ${
isActive("/vacancies") ? "text-primary" : ""
}`}
>
{" "}
{/* Apply active class */}
<FiFileText className={megaMenuIconClasses} /> <FiFileText className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}> <div className={megaMenuTextWrapperClasses}>
<p className={megaMenuTitleClasses}> <p className={megaMenuTitleClasses}>
@ -333,7 +373,14 @@ const HeaderClient = ({
</p> </p>
</div> </div>
</Link> </Link>
<Link href="/portal" className={megaMenuItemClasses}> <Link
href="/portal"
className={`${megaMenuItemClasses} ${
isActive("/portal") ? "text-primary" : ""
}`}
>
{" "}
{/* Apply active class */}
<FiUserCheck className={megaMenuIconClasses} /> <FiUserCheck className={megaMenuIconClasses} />
<div className={megaMenuTextWrapperClasses}> <div className={megaMenuTextWrapperClasses}>
<p className={megaMenuTitleClasses}> <p className={megaMenuTitleClasses}>
@ -349,12 +396,18 @@ const HeaderClient = ({
{/* ← Heres the Explore Our Offerings link, back in its original spot */} {/* ← Heres the Explore Our Offerings link, back in its original spot */}
<Link <Link
href="/services" href="/services" // Assuming this link goes to the main services page
className="flex items-center text-sm font-medium text-primary-foreground hover:opacity-80 transition-opacity group" className={`flex items-center text-sm font-medium hover:opacity-80 transition-opacity group ${
isActive("/services")
? "text-primary"
: "text-primary-foreground"
}`} // Apply active class
> >
Explore Our Offerings Explore Our Offerings
<FiArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" /> <FiArrowRight className="w-4 h-4 ml-1.5 transition-transform duration-200 group-hover:translate-x-1" />
</Link> </Link>
</div>{" "}
{/* Close the new flex container */}
</div> </div>
</div> </div>
</div> </div>
@ -424,29 +477,7 @@ const HeaderClient = ({
<FiClipboard className="w-4 h-4 mr-1.5" /> Request OBSE Demo <FiClipboard className="w-4 h-4 mr-1.5" /> Request OBSE Demo
</Link> </Link>
</div> </div>
<div className="pt-4 border-t border-border mt-4"> <div className="pt-4 border-t border-border mt-4"></div>
{session?.user ? (
<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>
) : (
<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" /> Sign In
</button>
)}
</div>
</nav> </nav>
</div> </div>
</header> </header>

View File

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