140 lines
4.6 KiB
TypeScript
140 lines
4.6 KiB
TypeScript
import { notFound } from 'next/navigation';
|
|
import Header from "@/components/shared/layout/header/Header";
|
|
import ServiceDetailsBanner from "@/components/shared/banners/ServiceDetailsBanner";
|
|
import ServiceDetails from "@/components/pages/services/ServiceDetails";
|
|
import ServiceFeatures from "@/components/pages/services/ServiceFeatures";
|
|
import ServiceDeliverables from "@/components/pages/services/ServiceDeliverables";
|
|
import ServiceProcess from "@/components/pages/services/ServiceProcess";
|
|
import Transform from "@/components/pages/services/Transform";
|
|
import Footer from "@/components/shared/layout/footer/Footer";
|
|
import ServicesScrollProgressButton from "@/components/pages/services/ServicesScrollProgressButton";
|
|
import ServicesInitAnimations from "@/components/pages/services/ServicesInitAnimations";
|
|
import { Service } from "@/lib/api/serviceService";
|
|
import { generateServiceMetadata } from "@/lib/seo/metadata";
|
|
import { ServiceSchema, BreadcrumbSchema } from "@/components/shared/seo/StructuredData";
|
|
import { API_CONFIG, getApiHeaders } from "@/lib/config/api";
|
|
|
|
interface ServicePageProps {
|
|
params: Promise<{
|
|
slug: string;
|
|
}>;
|
|
}
|
|
|
|
// Generate static params for all services at build time (optional - for better performance)
|
|
// This pre-generates known pages, but new pages can still be generated on-demand
|
|
export async function generateStaticParams() {
|
|
try {
|
|
// Use internal API URL for server-side requests
|
|
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://127.0.0.1:1086';
|
|
const response = await fetch(
|
|
`${apiUrl}/api/services/`,
|
|
{
|
|
method: 'GET',
|
|
headers: getApiHeaders(),
|
|
next: { revalidate: 60 }, // Revalidate every minute for faster image updates
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
console.error('Error fetching services for static params:', response.status);
|
|
return [];
|
|
}
|
|
|
|
const data = await response.json();
|
|
const services = data.results || data;
|
|
|
|
return services.map((service: Service) => ({
|
|
slug: service.slug,
|
|
}));
|
|
} catch (error) {
|
|
console.error('Error generating static params for services:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Generate enhanced metadata for each service page
|
|
export async function generateMetadata({ params }: ServicePageProps) {
|
|
const { slug } = await params;
|
|
|
|
try {
|
|
// Use internal API URL for server-side requests
|
|
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://127.0.0.1:1086';
|
|
const response = await fetch(
|
|
`${apiUrl}/api/services/${slug}/`,
|
|
{
|
|
method: 'GET',
|
|
headers: getApiHeaders(),
|
|
next: { revalidate: 60 }, // Revalidate every minute for faster image updates
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const service = await response.json();
|
|
|
|
return generateServiceMetadata(service);
|
|
} catch (error) {
|
|
return {
|
|
title: 'Service Not Found - GNX',
|
|
description: 'The requested service could not be found.',
|
|
};
|
|
}
|
|
}
|
|
|
|
const ServicePage = async ({ params }: ServicePageProps) => {
|
|
const { slug } = await params;
|
|
|
|
try {
|
|
// Use internal API URL for server-side requests
|
|
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://127.0.0.1:1086';
|
|
const response = await fetch(
|
|
`${apiUrl}/api/services/${slug}/`,
|
|
{
|
|
method: 'GET',
|
|
headers: getApiHeaders(),
|
|
next: { revalidate: 60 }, // Revalidate every minute for faster image updates
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const service: Service = await response.json();
|
|
|
|
// Breadcrumb data for structured data
|
|
const breadcrumbItems = [
|
|
{ name: 'Home', url: '/' },
|
|
{ name: 'Services', url: '/services' },
|
|
{ name: service.title, url: `/services/${service.slug}` },
|
|
];
|
|
|
|
return (
|
|
<div className="enterprise-app">
|
|
{/* SEO Structured Data */}
|
|
<ServiceSchema service={service} />
|
|
<BreadcrumbSchema items={breadcrumbItems} />
|
|
|
|
<Header />
|
|
<main className="enterprise-main">
|
|
<ServiceDetailsBanner service={service} />
|
|
<ServiceDetails service={service} />
|
|
<ServiceFeatures service={service} />
|
|
<ServiceDeliverables service={service} />
|
|
<Transform service={service} />
|
|
<ServiceProcess service={service} />
|
|
</main>
|
|
<Footer />
|
|
<ServicesScrollProgressButton />
|
|
<ServicesInitAnimations />
|
|
</div>
|
|
);
|
|
} catch (error) {
|
|
notFound();
|
|
}
|
|
};
|
|
|
|
export default ServicePage;
|