114 lines
4.1 KiB
TypeScript
114 lines
4.1 KiB
TypeScript
import Image from "next/image";
|
|
import type { CmsServiceContent } from "@/types/cms-landing";
|
|
|
|
const DEFAULT_HEADING = "Innovative solutions for your business growth.";
|
|
const DEFAULT_BODY =
|
|
"Professional services tailored to your organization. Update this text from the CMS admin under Content Website → Our Services.";
|
|
|
|
function bannerUrl(s: CmsServiceContent) {
|
|
return s.images?.[0]?.image_url?.trim() || "/image/s1.png";
|
|
}
|
|
|
|
export default function ServiceSection({
|
|
services,
|
|
}: {
|
|
services?: CmsServiceContent[] | null;
|
|
}) {
|
|
const list = services?.filter((s) => s.id) ?? [];
|
|
|
|
if (list.length === 0) {
|
|
const imgSrc = "/image/s1.png";
|
|
return (
|
|
<section className="bg-white py-20">
|
|
<div className="container mx-auto px-6">
|
|
<div className="mb-16 text-center">
|
|
<p className="text-sm uppercase tracking-widest text-gray-400">Our Services</p>
|
|
<h2 className="mt-2 text-3xl font-bold text-gray-900 md:text-4xl whitespace-pre-line">
|
|
{DEFAULT_HEADING}
|
|
</h2>
|
|
</div>
|
|
<div className="grid items-center gap-12 md:grid-cols-2">
|
|
<div className="overflow-hidden rounded-2xl shadow-lg">
|
|
<Image
|
|
src={imgSrc}
|
|
alt="Service"
|
|
width={600}
|
|
height={400}
|
|
className="h-auto w-full object-cover"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<p className="leading-relaxed text-gray-600 whitespace-pre-line">{DEFAULT_BODY}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<section className="bg-white py-20">
|
|
<div className="container mx-auto px-6">
|
|
<div className="mb-16 text-center">
|
|
<p className="text-sm uppercase tracking-widest text-gray-400">Our Services</p>
|
|
<h2 className="mt-2 text-3xl font-bold text-gray-900 md:text-4xl whitespace-pre-line">
|
|
{list.length > 1 ? "What we deliver" : list[0]?.primary_title?.trim() || DEFAULT_HEADING}
|
|
</h2>
|
|
{list.length > 1 && list[0]?.secondary_title?.trim() ? (
|
|
<p className="mx-auto mt-4 max-w-2xl text-gray-600">
|
|
{list[0].secondary_title.trim()}
|
|
</p>
|
|
) : list.length === 1 && list[0]?.secondary_title?.trim() ? (
|
|
<p className="mx-auto mt-4 max-w-2xl text-gray-600">
|
|
{list[0].secondary_title.trim()}
|
|
</p>
|
|
) : null}
|
|
</div>
|
|
|
|
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
|
|
{list.map((s) => {
|
|
const imgSrc = bannerUrl(s);
|
|
const external = /^https?:\/\//i.test(imgSrc);
|
|
const body = s.description?.trim() || DEFAULT_BODY;
|
|
return (
|
|
<div
|
|
key={s.id}
|
|
className="flex flex-col overflow-hidden rounded-2xl border border-gray-100 bg-white shadow-md"
|
|
>
|
|
<div className="relative aspect-video w-full overflow-hidden bg-gray-100">
|
|
{external ? (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img
|
|
src={imgSrc}
|
|
alt=""
|
|
width={600}
|
|
height={400}
|
|
className="h-full w-full object-cover"
|
|
/>
|
|
) : (
|
|
<Image
|
|
src={imgSrc}
|
|
alt=""
|
|
width={600}
|
|
height={400}
|
|
className="h-full w-full object-cover"
|
|
/>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-1 flex-col p-5">
|
|
<h3 className="text-lg font-bold text-gray-900 whitespace-pre-line">
|
|
{s.primary_title?.trim() || "Service"}
|
|
</h3>
|
|
<p className="mt-2 line-clamp-4 text-sm leading-relaxed text-gray-600 whitespace-pre-line">
|
|
{body}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|