import { Book, Brain, Calendar, Cpu, Code2, Database, Rocket, Unplug, Wrench } from "lucide-react" import type { LucideIcon } from "lucide-react" import { drupal } from "@/lib/drupal" import type { DrupalServiceNode } from "@/lib/types" import { ScrollRevealCard } from "@/components/scroll-reveal-card" const drupalBaseUrl = process.env.NEXT_PUBLIC_DRUPAL_BASE_URL ?? "" const ICON_MAP: Record = { coordination: Calendar, data_processing: Cpu, deployment: Rocket, development: Code2, documentation: Book, interface_api: Unplug, interface_and_api: Unplug, maintainance: Wrench, maintenance: Wrench, modelling: Database, ai: Brain, } function toIconKey(type: string): string { return type.toLowerCase().replace(/\s+/g, "_").replace(/-/g, "_") } function getIcon(serviceType: string | undefined): LucideIcon { if (!serviceType) return Database const key = toIconKey(serviceType) return ICON_MAP[key] ?? Database } function stripHtml(html: string | undefined): string { if (!html) return "" return html.replace(/<[^>]*>/g, "").trim() } async function getServices(): Promise< { label: string; body: string; icon: LucideIcon }[] > { if (!drupalBaseUrl) return [] try { let raw: { data?: DrupalServiceNode[] } | null = null try { raw = await drupal.getResourceCollection<{ data: DrupalServiceNode[] }>("node--service", { params: { "filter[status]": "1", sort: "created", }, deserialize: false, next: { revalidate: 60 }, }) } catch (firstError) { const msg = (firstError as Error).message ?? "" if (msg.includes("Unauthorized")) { await new Promise((r) => setTimeout(r, 1000)) raw = await drupal.getResourceCollection<{ data: DrupalServiceNode[] }>("node--service", { params: { "filter[status]": "1", sort: "created", }, deserialize: false, next: { revalidate: 60 }, }) } else { throw firstError } } const nodes = raw?.data ?? [] if (!nodes.length) return [] return nodes.map((node) => { const bodyObj = node.body const bodyText = typeof bodyObj === "string" ? stripHtml(bodyObj) : stripHtml(bodyObj?.value ?? bodyObj?.processed) return { body: bodyText, icon: getIcon(node.field__service__type), label: node.title ?? "", } }) } catch (error) { if ((error as Error).name !== "AbortError") { console.warn( "[HomeServices] CMS unreachable:", (error as Error).message ) } return [] } } export async function HomeServices() { const services = await getServices() return (

Services

Data engineering, development, deployment, and ongoing support for your projects.

{services.map(({ label, body, icon: Icon }) => (
{label} {body && ( {body} )}
))}
) }