import { setRequestLocale } from 'next-intl/server'; import type { Metadata } from 'next'; import { getTranslations } from 'next-intl/server'; import { PortfolioGrid, CategoryFilter } from '@/components/portfolio'; import { BreadcrumbJsonLd, CollectionPageJsonLd } from '@/components/seo'; import { type Locale } from '@/i18n/config'; type Props = { params: Promise<{ locale: string }>; searchParams: Promise<{ category?: string }>; }; const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://damjan-savic.com'; export async function generateMetadata({ params }: Props): Promise { const { locale } = await params; const t = await getTranslations({ locale, namespace: 'portfolio.seo' }); const keywords: Record = { de: [ 'Portfolio Damjan Savić', 'KI Projekte', 'Automatisierung Projekte', 'Python Entwicklung', 'React Projekte', 'RFID IoT', 'n8n Automatisierung', 'Web Entwicklung Köln', ], en: [ 'AI Developer Portfolio', 'AI Projects', 'Automation Projects', 'Python Development', 'React Projects', 'n8n Automation', 'Remote Developer Portfolio', 'Hire AI Developer', 'AI Agent Projects', 'Voice AI Projects', 'SaaS Development Portfolio', ], sr: [ 'Portfolio Damjan Savić', 'AI Projekti', 'Automatizacija Projekti', 'Python Razvoj', 'React Projekti', 'RFID IoT', 'n8n Automatizacija', 'Web Razvoj Keln', ], }; const localePath = locale === 'de' ? '/portfolio' : `/${locale}/portfolio`; return { title: t('title'), description: t('description'), keywords: keywords[locale] || keywords.de, alternates: { canonical: `${BASE_URL}${localePath}`, languages: { 'x-default': `${BASE_URL}/portfolio`, de: `${BASE_URL}/portfolio`, en: `${BASE_URL}/en/portfolio`, sr: `${BASE_URL}/sr/portfolio`, }, }, openGraph: { title: t('title'), description: t('description'), url: `${BASE_URL}${localePath}`, siteName: 'Damjan Savić', 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: 'Damjan Savić - AI & Automation Specialist', }, ], }, twitter: { card: 'summary_large_image', title: t('title'), description: t('description'), images: [`${BASE_URL}/images/og-image.avif`], }, }; } // Project data for SSG const projects = [ { slug: 'ai-data-reader', title: 'AI Document Reader', description: 'KI-gestützte Dokumentenanalyse mit OLLAMA und Python', excerpt: 'KI-gestützte PDF-Datenextraktion mit Claude AI und JTL-Integration', category: 'AI Development', date: '2024-01', technologies: ['Python', 'OLLAMA', 'FastAPI', 'React', 'Claude AI', 'JTL-Wawi'], featured: true, }, { slug: 'smart-warehouse', title: 'Smart Warehouse RFID', description: 'RFID-basiertes Lagerverwaltungssystem mit IoT-Integration', excerpt: 'RFID-basierte Lagerverwaltung mit Zebra-Hardware und Echtzeit-Tracking', category: 'IoT', date: '2024-02', technologies: ['Python', 'RFID', 'IoT', 'PostgreSQL', 'Zebra Hardware'], featured: true, }, { slug: 'website-mit-ki', title: 'Portfolio mit KI', description: 'Moderne Portfolio-Website mit KI-Integration', excerpt: 'Next.js 15 Portfolio mit SSR, i18n und modernen Web-Technologien', category: 'Full-Stack', date: '2024-03', technologies: ['Next.js', 'TypeScript', 'Tailwind', 'Supabase', 'React'], featured: true, }, { slug: 'power-platform-governance', title: 'Power Platform Governance', description: 'Enterprise Governance-Lösung für Microsoft Power Platform', excerpt: 'Automatisierte Compliance-Prüfungen und Ressourcenverwaltung', category: 'Enterprise Software', date: '2023-11', technologies: ['Power Automate', 'SharePoint', 'Azure', 'TypeScript', 'Power Apps'], featured: false, }, { slug: 'automated-ad-creatives', title: 'Automated Ad Creatives', description: 'Automatisierte Erstellung von Werbeanzeigen', excerpt: 'KI-gestützte Generierung von Marketing-Creatives', category: 'AI Development', date: '2023-10', technologies: ['Python', 'OpenAI', 'Pillow', 'FastAPI'], featured: false, }, { slug: 'kamenpro', title: 'KamenPro', description: 'E-Commerce Platform für Steinprodukte', excerpt: 'Shopify-basierte E-Commerce-Lösung mit ERP-Integration', category: 'E-Commerce', date: '2023-08', technologies: ['Shopify', 'JavaScript', 'Liquid', 'ERP Integration'], featured: false, }, { slug: 'ai-music-production', title: 'AI Music Production', description: 'KI-gestützte Musikproduktion', excerpt: 'Automatisierte Musikgenerierung mit Machine Learning', category: 'AI Development', date: '2023-06', technologies: ['Python', 'TensorFlow', 'MIDI', 'Audio Processing'], featured: false, }, { slug: 'cursor-ide', title: 'Cursor IDE Integration', description: 'AI-gestützte Entwicklungsumgebung', excerpt: 'Integration von KI-Assistenten in den Entwicklungsworkflow', category: 'Developer Tools', date: '2023-05', technologies: ['TypeScript', 'VS Code API', 'Claude AI', 'GPT-4'], featured: false, }, ]; export default async function PortfolioPage({ params, searchParams }: Props) { const { locale } = await params; setRequestLocale(locale); const t = await getTranslations('portfolio'); // Get category filter from URL params const { category } = await searchParams; // Filter projects by category if specified const filteredProjects = category ? projects.filter((project) => project.category === category) : projects; const breadcrumbItems = [ { name: locale === 'de' ? 'Start' : locale === 'sr' ? 'Početna' : 'Home', url: `/${locale}` }, { name: 'Portfolio', url: `/${locale}/portfolio` }, ]; // Transform projects for JSON-LD schema const portfolioProjects = projects.map((project) => ({ name: project.title, description: project.description, url: `/${locale}/portfolio/${project.slug}`, dateCreated: project.date, technologies: project.technologies, })); return (

{t('sections.title')}

{t('sections.subtitle')}

); }