122 lines
4.7 KiB
TypeScript
122 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import Image from "next/legacy/image";
|
|
import Link from "next/link";
|
|
import { useMemo } from "react";
|
|
import { useServices } from "@/lib/hooks/useServices";
|
|
import { serviceUtils } from "@/lib/api/serviceService";
|
|
import one from "@/public/images/overview/one.png";
|
|
import two from "@/public/images/overview/two.png";
|
|
import three from "@/public/images/overview/three.png";
|
|
import four from "@/public/images/overview/four.png";
|
|
import five from "@/public/images/overview/five.png";
|
|
|
|
// Default images array for fallback
|
|
const defaultImages = [one, two, three, four, five];
|
|
|
|
const Overview = () => {
|
|
// Memoize the parameters to prevent infinite re-renders
|
|
const serviceParams = useMemo(() => ({
|
|
ordering: 'display_order',
|
|
page: 1
|
|
}), []);
|
|
|
|
// Fetch services from API, limit to 5 for overview section
|
|
const { services, loading, error } = useServices(serviceParams);
|
|
|
|
// Get first 5 services for the overview
|
|
const displayServices = services.slice(0, 5);
|
|
return (
|
|
<section
|
|
className="tp-overview pt-120 pb-120 sticky-wrapper"
|
|
id="scroll-to"
|
|
>
|
|
<div className="container">
|
|
<div className="row vertical-column-gap-lg">
|
|
<div className="col-12 col-lg-5">
|
|
<div className="tp-overview__content sticky-item">
|
|
<h2 className="fw-7 text-secondary title-anim mb-30 mt-8">
|
|
Enterprise Solutions That Scale
|
|
</h2>
|
|
<p className="mt-8 cur-lg">
|
|
Our enterprise software development teams deliver mission-critical solutions
|
|
for Fortune 500 companies. We design, build, and deploy scalable systems
|
|
that transform your business operations, enhance security, and drive digital
|
|
innovation across your organization.
|
|
</p>
|
|
<div className="mt-40">
|
|
<Link href="services" className="btn-line text-uppercase">
|
|
EXPLORE SOLUTIONS
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-12 col-lg-7 col-xxl-6 offset-xxl-1">
|
|
<div className="tp-overview__items sticky-item">
|
|
{loading ? (
|
|
// Loading state
|
|
<div className="text-center py-5">
|
|
<div className="spinner-border text-primary" role="status">
|
|
<span className="visually-hidden">Loading...</span>
|
|
</div>
|
|
<p className="mt-3 text-muted">Loading services...</p>
|
|
</div>
|
|
) : error ? (
|
|
// Error state
|
|
<div className="text-center py-5">
|
|
<p className="text-danger">Failed to load services. Please try again later.</p>
|
|
</div>
|
|
) : displayServices.length === 0 ? (
|
|
// No services state
|
|
<div className="text-center py-5">
|
|
<p className="text-muted">No services available at the moment.</p>
|
|
</div>
|
|
) : (
|
|
// Services list
|
|
displayServices.map((service, index) => {
|
|
// Always use hardcoded images, not API images
|
|
const serviceImage = defaultImages[index] || defaultImages[0];
|
|
|
|
return (
|
|
<div key={service.id} className="tp-overview-single appear-down">
|
|
<div className="thumb">
|
|
<Image
|
|
src={serviceImage}
|
|
width={80}
|
|
height={80}
|
|
alt={service.title}
|
|
/>
|
|
</div>
|
|
<div className="wrapper">
|
|
<div className="content">
|
|
<h4 className="mt-8 mb-12 fw-6 text-secondary">
|
|
<Link href={`/services/${service.slug}`}>
|
|
{service.title}
|
|
</Link>
|
|
</h4>
|
|
<p className="text-tertiary">
|
|
{service.short_description || service.description}
|
|
</p>
|
|
</div>
|
|
<div className="cta">
|
|
<Link href={`/services/${service.slug}`}>
|
|
<span className="material-symbols-outlined">
|
|
call_made
|
|
</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default Overview;
|