import { setRequestLocale } from 'next-intl/server'; import type { Metadata } from 'next'; import Link from 'next/link'; import { ArrowLeft, ArrowRight, CheckCircle, Brain, Mic, Workflow, Cloud, Code, Bot, Building, ShoppingCart, Factory } from 'lucide-react'; import { notFound } from 'next/navigation'; import { allServices, getServiceBySlug, getAllServiceSlugs } from '@/data/services'; import { BreadcrumbJsonLd, ServiceJsonLd, FAQJsonLd } from '@/components/seo'; import { type Locale, locales } from '@/i18n/config'; type Props = { params: Promise<{ locale: string; slug: string }>; }; const iconMap: Record> = { Brain, Mic, Workflow, Cloud, Code, Bot, Building, ShoppingCart, Factory, }; export async function generateStaticParams() { const slugs = getAllServiceSlugs(); return locales.flatMap((locale) => slugs.map((slug) => ({ locale, slug, })) ); } const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com'; export async function generateMetadata({ params }: Props): Promise { const { locale, slug } = await params; const service = getServiceBySlug(slug); if (!service) { return { title: 'Service Not Found' }; } const title = locale === 'de' ? `${service.name.de} - Köln & Deutschland | Damjan Savić` : locale === 'sr' ? `${service.name.sr} - Keln & Nemačka | Damjan Savić` : `${service.name.en} | Remote AI Developer for USA, UK & Europe`; const localePath = locale === 'de' ? `/leistungen/${slug}` : `/${locale}/leistungen/${slug}`; // Use seoKeywords if available, otherwise fall back to technologies const seoKw = service.seoKeywords?.[locale as Locale] || []; const allKeywords = [...service.technologies, ...seoKw]; if (locale === 'en') { allKeywords.push('Remote AI Developer', 'Hire AI Developer', 'AI Consultant USA', 'AI Developer UK'); } return { title, description: service.description[locale as Locale] || service.description.de, keywords: allKeywords.join(', '), alternates: { canonical: `${BASE_URL}${localePath}`, languages: { 'x-default': `${BASE_URL}/de/leistungen/${slug}`, de: `${BASE_URL}/de/leistungen/${slug}`, en: `${BASE_URL}/en/leistungen/${slug}`, sr: `${BASE_URL}/sr/leistungen/${slug}`, }, }, openGraph: { title, description: service.shortDescription[locale as Locale] || service.shortDescription.de, url: `${BASE_URL}${localePath}`, type: 'website', locale: locale === 'de' ? 'de_DE' : locale === 'sr' ? 'sr_RS' : 'en_US', alternateLocale: ['de_DE', 'en_US', 'sr_RS'].filter(l => l !== (locale === 'de' ? 'de_DE' : locale === 'sr' ? 'sr_RS' : 'en_US')), images: [ { url: `${BASE_URL}/images/og-image.avif`, width: 1200, height: 630, alt: `${service.name[locale as Locale]} - Damjan Savić`, }, ], }, }; } export default async function ServicePage({ params }: Props) { const { locale, slug } = await params; setRequestLocale(locale); const service = getServiceBySlug(slug); if (!service) { notFound(); } const IconComponent = iconMap[service.icon] || Brain; const breadcrumbItems = [ { name: locale === 'de' ? 'Start' : locale === 'sr' ? 'Početna' : 'Home', url: `/${locale}` }, { name: locale === 'de' ? 'Leistungen' : locale === 'sr' ? 'Usluge' : 'Services', url: `/${locale}/leistungen` }, { name: service.name[locale as Locale], url: `/${locale}/leistungen/${slug}` }, ]; // Get related services (excluding current) const relatedServices = allServices.filter((s) => s.slug !== slug).slice(0, 3); // FAQ items for this service const serviceFaqItems = locale === 'de' ? [ { question: `Was kostet ${service.name.de}?`, answer: `Die Kosten für ${service.name.de} variieren je nach Projektumfang und Komplexität. Ich erstelle gerne ein individuelles Angebot nach einem kostenlosen Erstgespräch.`, }, { question: `Welche Technologien nutzen Sie für ${service.name.de}?`, answer: `Für ${service.name.de} setze ich auf bewährte Technologien: ${service.technologies.join(', ')}. Die genaue Auswahl hängt von Ihren Anforderungen ab.`, }, { question: `Wie lange dauert ein typisches ${service.name.de}-Projekt?`, answer: `Die Dauer eines ${service.name.de}-Projekts hängt vom Umfang ab. Einfache Projekte können in 2-4 Wochen abgeschlossen werden, komplexere Lösungen in 6-12 Wochen.`, }, ] : locale === 'en' ? [ { question: `How much does ${service.name.en} cost?`, answer: `The cost of ${service.name.en} varies depending on project scope and complexity. I'm happy to provide a custom quote after a free initial consultation.`, }, { question: `What technologies do you use for ${service.name.en}?`, answer: `For ${service.name.en}, I use proven technologies: ${service.technologies.join(', ')}. The exact selection depends on your requirements.`, }, { question: `How long does a typical ${service.name.en} project take?`, answer: `The duration of a ${service.name.en} project depends on scope. Simple projects can be completed in 2-4 weeks, more complex solutions in 6-12 weeks.`, }, ] : [ { question: `Koliko košta ${service.name.sr}?`, answer: `Troškovi za ${service.name.sr} variraju u zavisnosti od obima i kompleksnosti projekta. Rado ću vam dati individualizovanu ponudu nakon besplatnog inicijalnog razgovora.`, }, { question: `Koje tehnologije koristite za ${service.name.sr}?`, answer: `Za ${service.name.sr} koristim proverene tehnologije: ${service.technologies.join(', ')}. Tačan izbor zavisi od vaših zahteva.`, }, { question: `Koliko traje tipičan ${service.name.sr} projekat?`, answer: `Trajanje ${service.name.sr} projekta zavisi od obima. Jednostavni projekti mogu se završiti za 2-4 nedelje, kompleksnija rešenja za 6-12 nedelja.`, }, ]; return (
{/* Hero Section */}
{/* Back Link */} {locale === 'de' ? 'Alle Leistungen' : locale === 'sr' ? 'Sve usluge' : 'All Services'}

{service.name[locale as Locale]}

{service.description[locale as Locale]}

{/* Technologies */}
{service.technologies.map((tech) => ( {tech} ))}
{/* Features Section */}

{locale === 'de' ? 'Was ich anbiete' : locale === 'sr' ? 'Šta nudim' : 'What I offer'}

{service.features[locale as Locale].map((feature, index) => (
{feature}
))}
{/* Use Cases Section */}

{locale === 'de' ? 'Anwendungsbeispiele' : locale === 'sr' ? 'Primeri primene' : 'Use Cases'}

{service.useCases[locale as Locale].map((useCase, index) => (
{index + 1}
{useCase}
))}
{/* Related Services */}

{locale === 'de' ? 'Weitere Leistungen' : locale === 'sr' ? 'Ostale usluge' : 'Other Services'}

{relatedServices.map((relatedService) => { const RelatedIcon = iconMap[relatedService.icon] || Brain; return (

{relatedService.name[locale as Locale]}

{relatedService.shortDescription[locale as Locale]}

); })}
{/* FAQ Section */}

{locale === 'de' ? `Häufige Fragen zu ${service.name.de}` : locale === 'sr' ? `Česta pitanja o ${service.name.sr}` : `FAQ about ${service.name.en}`}

{serviceFaqItems.map((item, index) => (

{item.question}

{item.answer}

))}
{/* CTA Section */}

{locale === 'de' ? `${service.name.de} für Ihr Unternehmen?` : locale === 'sr' ? `${service.name.sr} za vašu kompaniju?` : `${service.name.en} for your business?`}

{locale === 'de' ? 'Lassen Sie uns besprechen, wie ich Ihnen helfen kann.' : locale === 'sr' ? 'Razgovarajmo o tome kako vam mogu pomoći.' : "Let's discuss how I can help you."}

{locale === 'de' ? 'Projekt besprechen' : locale === 'sr' ? 'Razgovarajte o projektu' : 'Discuss project'}
); }