it/web/app/services/page.tsx
2025-10-25 21:14:15 +02:00

120 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Metadata } from "next";
import { getAllServices, SERVICE_CATEGORIES, type ServiceCategoryId } from "@/lib/services";
import ServiceCard from "@/components/ServiceCard";
import Link from "next/link";
export const revalidate = 86400;
export const metadata: Metadata = {
title: "Services — Van Hunen IT",
description:
"Explore Van Hunen IT's fixed-scope sprints and managed solutions — from VPS hardening and Docker orchestration to Kubernetes, Cloudflare, Core Web Vitals, and Minecraft operations.",
alternates: { canonical: "/services" },
};
export default function ServicesPage() {
const services = getAllServices();
const categories: ServiceCategoryId[] = Object.keys(SERVICE_CATEGORIES) as ServiceCategoryId[];
return (
<main className="relative isolate min-h-screen bg-gradient-to-b from-neutral-50 via-white to-neutral-100 dark:from-neutral-950 dark:via-neutral-900 dark:to-neutral-950">
{/* --- Hero Header --- */}
<section className="relative overflow-hidden border-b border-neutral-200 dark:border-neutral-800">
<div className="container mx-auto max-w-6xl px-4 py-20 text-center">
<h1 className="text-4xl font-bold tracking-tight sm:text-5xl bg-gradient-to-r from-blue-600 via-purple-600 to-blue-600 bg-clip-text text-transparent">
Professional IT Services
</h1>
<p className="mt-5 text-lg text-neutral-700 dark:text-neutral-300 max-w-2xl mx-auto">
Fixed-scope sprints and managed plans for{" "}
<strong>VPS</strong>, <strong>Docker</strong>, <strong>Kubernetes</strong>,{" "}
<strong>Cloudflare</strong>, <strong>Core Web Vitals</strong>, and{" "}
<strong>Minecraft</strong>. Clear outcomes, flat pricing, and proof you can keep.
</p>
<div className="mt-8 flex flex-wrap justify-center gap-3">
{categories.map((id) => (
<a
key={id}
href={`#${SERVICE_CATEGORIES[id].anchor}`}
className="rounded-full border border-neutral-300 dark:border-neutral-700 px-4 py-1.5 text-sm font-medium text-neutral-700 dark:text-neutral-300 hover:border-blue-500 hover:text-blue-600 dark:hover:text-blue-400 transition"
>
{SERVICE_CATEGORIES[id].label}
</a>
))}
</div>
</div>
</section>
{/* --- Service Categories --- */}
<div className="container mx-auto max-w-6xl px-4 py-16">
{categories.map((id, index) => {
const list = services.filter((s) => s.category === id);
if (!list.length) return null;
return (
<section
key={id}
id={SERVICE_CATEGORIES[id].anchor}
aria-labelledby={`${id}-heading`}
className={`relative py-16 scroll-mt-24 ${
index % 2 === 0
? "bg-white dark:bg-neutral-900/50"
: "bg-neutral-50 dark:bg-neutral-900/30"
} rounded-2xl mb-12 shadow-sm`}
>
<div className="absolute inset-0 -z-10 bg-gradient-to-br from-blue-50/10 via-transparent to-purple-50/10 dark:from-blue-950/10 dark:to-purple-950/10 rounded-2xl" />
<div className="px-4 sm:px-8">
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-8">
<h2
id={`${id}-heading`}
className="text-2xl sm:text-3xl font-bold tracking-tight bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
>
{SERVICE_CATEGORIES[id].label}
</h2>
<Link
href={`/services#${SERVICE_CATEGORIES[id].anchor}`}
className="mt-3 sm:mt-0 inline-flex items-center text-sm font-medium text-blue-600 hover:underline dark:text-blue-400"
>
Jump to top
</Link>
</div>
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{list.map((svc, i) => (
<div
key={svc.slug}
className="animate-[fadeInUp_0.6s_ease_forwards]"
style={{ animationDelay: `${i * 80}ms` }}
>
<ServiceCard svc={svc} />
</div>
))}
</div>
</div>
</section>
);
})}
</div>
{/* --- CTA footer --- */}
<section className="relative py-24 text-center bg-gradient-to-r from-blue-600 via-purple-600 to-blue-600 text-white">
<div className="container mx-auto max-w-4xl px-6">
<h2 className="text-3xl sm:text-4xl font-bold tracking-tight">
Ready to optimize your IT infrastructure?
</h2>
<p className="mt-4 text-lg text-blue-100">
Get in touch to discuss your goals well help you choose the right sprint or managed plan.
</p>
<Link
href="/contact"
className="mt-8 inline-flex items-center rounded-lg bg-white text-blue-700 font-semibold px-6 py-3 hover:bg-blue-50 transition"
>
Contact Us
</Link>
</div>
</section>
</main>
);
}