Migrate from Vite to Next.js 15 with SSR

- Replace Vite + React Router with Next.js 15 App Router
- Implement i18n with next-intl (URL-based: /de, /en, /sr)
- Add SSR/SSG for all pages (48 static pages generated)
- Setup Supabase SSR client for auth
- Migrate all pages: Home, About, Portfolio, Blog, Contact, Login, Dashboard, Imprint, Privacy, Terms
- Add Docker support with standalone output
- Replace i18next with next-intl JSON translations
- Use next/image for optimized images

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-17 01:00:33 +01:00
co-authored by Claude Opus 4.5
parent a66f51b9a2
commit b1ec7b4d61
281 changed files with 8024 additions and 8901 deletions
@@ -0,0 +1,33 @@
export const hero = {
// Navigation/Header
aboutMe: 'FULLSTACK ENTWICKLER KÖLN - DAMJAN SAVIĆ',
// Main Section
title: 'Python Entwickler Köln & React Developer - Damjan Savić',
description: 'Als Fullstack Entwickler Köln ist Damjan Savić Ihr Freelance Developer für Python Automatisierung und React Entwicklung. Mit Expertise in OLLAMA KI Integration, ERP System Integration Köln und E-Commerce Entwicklung bietet Software Entwickler Köln Damjan Savić Custom Software Entwicklung für B2B Enterprise Kunden. Von API Entwicklung Python FastAPI bis zu Microservices - Ihr Backend Entwickler Köln.',
// Expertise Areas
expertise: {
processAutomation: {
title: 'Python Automatisierung Köln',
description: 'Prozessautomatisierung Python für B2B Unternehmen'
},
systemIntegration: {
title: 'ERP System Integration Köln',
description: 'Enterprise Software Integration & API Entwicklung'
},
customDevelopment: {
title: 'Custom Software Entwicklung Köln',
description: 'Freelance Developer für individuelle Lösungen'
}
},
// Languages
languages: {
english: 'Englisch',
serbian: 'Serbisch',
german: 'Deutsch',
french: 'Französisch',
spanish: 'Spanisch',
russian: 'Russisch'
}
} as const;
// Type für Typsicherheit
export type HeroTranslations = typeof hero;
@@ -0,0 +1,28 @@
import { hero } from './hero';
import { journey } from './journey';
import { schema } from './schema';
import { skillbar } from './skillbar';
import { skillgroup } from './skillgroup';
import { skills } from './skills';
import { workflow } from './workflow';
export const about = {
seo: {
title: 'Über Mich - Damjan Savić | Fullstack Entwickler & KI-Spezialist',
description: 'Erfahren Sie mehr über Damjan Savić - AI & Automation Specialist mit Fokus auf Voice AI, autonome Agenten und Prozessautomatisierung aus Köln.'
},
hero,
journey,
schema,
skillbar,
skillgroup,
skills,
workflow
} as const;
// Typen exportieren
export type { HeroTranslations } from './hero';
export type { JourneyTranslations } from './journey';
export type { SchemaTranslations } from './schema';
export type { SkillBarTranslations } from './skillbar';
export type { SkillGroupTranslations } from './skillgroup';
export type { SkillsTranslations } from './skills';
export type { WorkflowTranslations } from './workflow';
@@ -0,0 +1,95 @@
export const journey = {
// Header
title: 'Beruflicher Werdegang',
subtitle: 'Von digitalen Medien zu Unternehmenslösungen',
// Education Section
education: {
title: 'Ausbildung',
degrees: {
masters: {
degree: 'M.A. Softwareentwicklung',
university: 'Middlesex University, London',
period: '2020 - 2022'
},
bachelors: {
degree: 'B.A. Cross-Media Produktion',
university: 'Middlesex University, London',
period: '2018 - 2020'
}
}
},
// Languages Section
languages: {
title: 'Sprachen',
items: {
english: {
name: 'Englisch',
level: 'C2'
},
serbian: {
name: 'Serbisch',
level: 'C2'
},
german: {
name: 'Deutsch',
level: 'C2'
},
french: {
name: 'Französisch',
level: 'B2'
},
spanish: {
name: 'Spanisch',
level: 'B2'
},
russian: {
name: 'Russisch',
level: 'A1'
}
}
},
// Work History
work: {
positions: [
{
period: '08/2023 - Heute',
company: 'Ritter Digital GmbH',
title: 'Digital Solutions Consultant',
location: 'Oberhausen',
highlights: [
'ERP-Beratung und -Implementierung (JTL WaWi)',
'Prozessautomatisierung & Full-Stack-Entwicklung',
'RFID-Technologie & Automatisierung',
'Lead-Generierung & -Management',
'KI-gestütztes Content-Management'
]
},
{
period: '02/2023 - 08/2023',
company: 'Joyce & Girls Co AG',
title: 'ERP Integration Specialist',
location: 'Köln',
highlights: [
'Komplexe Systemintegration (Apparel Magic, TradeByte)',
'Server-Administration und Automatisierung',
'Datenbank- und API-Entwicklung',
'Digitales Marketing und Kampagnenanalyse'
]
},
{
period: '08/2022 - 01/2023',
company: 'Magnarius',
title: 'RPA Developer & E-Commerce Manager',
location: 'Bergisch Gladbach',
highlights: [
'Shopware 6 Entwicklung und JTL-Integration',
'Google Ads Automatisierung',
'CMS-Management und -Optimierung',
'SEO-Strategieumsetzung'
]
}
]
}
} as const;
// Type für Typsicherheit
export type JourneyTranslations = typeof journey;
@@ -0,0 +1,31 @@
export const schema = {
page: {
name: 'Über Damjan Savić',
description: 'Erfahren Sie mehr über Damjan Savić, einen zertifizierten JTL-Experten mit umfassender Erfahrung in E-Commerce und Warenwirtschaftslösungen.'
},
person: {
jobTitle: 'JTL Integrations-Experte',
description: 'Mit umfangreicher Erfahrung in der Integration und Optimierung von E-Commerce-Systemen unterstütze ich Unternehmen bei der digitalen Transformation ihrer Geschäftsprozesse.',
languages: {
english: 'Englisch',
serbian: 'Serbisch',
german: 'Deutsch',
french: 'Französisch',
spanish: 'Spanisch',
russian: 'Russisch'
},
skills: {
python: 'Python',
googleAds: 'Google Ads',
metaAds: 'Meta Ads',
shopware: 'Shopware',
shopify: 'Shopify',
wooCommerce: 'WooCommerce',
jtlWawi: 'JTL WAWI',
serverAdmin: 'Server-Administration',
airflow: 'AirFlow'
}
}
} as const;
// Type für Typsicherheit
export type SchemaTranslations = typeof schema;
@@ -0,0 +1,13 @@
export const skillbar = {
// Accessibility labels
ariaLabel: {
skillLevel: 'Fähigkeitsniveau',
progressBar: 'Fortschrittsbalken'
},
// Screen reader text
screenReader: {
progress: '{{level}} Prozent Fortschritt für {{skill}}'
}
} as const;
// Type für Typsicherheit
export type SkillBarTranslations = typeof skillbar;
@@ -0,0 +1,63 @@
export const skillgroup = {
// Kategorien
categories: {
development: 'Entwicklung',
ecommerce: 'E-Commerce',
marketing: 'Marketing',
automation: 'Automatisierung',
languages: 'Programmiersprachen',
databases: 'Datenbanken'
},
// Skills nach Kategorien
skills: {
development: {
frontend: 'Frontend-Entwicklung',
backend: 'Backend-Entwicklung',
fullstack: 'Full-Stack-Entwicklung',
api: 'API-Entwicklung',
testing: 'Software-Testing'
},
ecommerce: {
jtl: 'JTL WaWi',
shopware: 'Shopware',
shopify: 'Shopify',
woocommerce: 'WooCommerce',
magento: 'Magento'
},
marketing: {
seo: 'Suchmaschinenoptimierung',
sea: 'Suchmaschinenwerbung',
analytics: 'Web-Analyse',
googleAds: 'Google Ads',
metaAds: 'Meta Ads'
},
automation: {
rpa: 'Robotergestützte Prozessautomatisierung',
workflow: 'Workflow-Automatisierung',
cicd: 'CI/CD',
testing: 'Test-Automatisierung',
deployment: 'Deployment-Automatisierung'
},
languages: {
python: 'Python',
javascript: 'JavaScript',
typescript: 'TypeScript',
php: 'PHP',
sql: 'SQL'
},
databases: {
mysql: 'MySQL',
postgresql: 'PostgreSQL',
mongodb: 'MongoDB',
redis: 'Redis',
elasticsearch: 'Elasticsearch'
}
},
// Accessibility
ariaLabels: {
skillGroup: 'Fähigkeitsgruppe',
skillList: 'Liste der Fähigkeiten in dieser Kategorie'
}
} as const;
// Type für Typsicherheit
export type SkillGroupTranslations = typeof skillgroup;
@@ -0,0 +1,46 @@
// de/pages/about/skills.ts
export const skills = {
title: 'Fähigkeiten',
skillGroups: [
{
category: 'Entwicklung',
items: [
{ name: 'Python', level: 90 },
{ name: 'Google Ads', level: 85 },
{ name: 'Meta Ads', level: 85 }
]
},
{
category: 'E-Commerce',
items: [
{ name: 'Shopware', level: 85 },
{ name: 'Shopify', level: 85 },
{ name: 'WooCommerce', level: 85 }
]
},
{
category: 'Systemadministration',
items: [
{ name: 'JTL WAWI', level: 85 },
{ name: 'Server', level: 75 },
{ name: 'AirFlow', level: 60 }
]
}
],
ui: {
percentage: 'Prozent',
levelLabel: 'Niveau',
skillLevel: '{{level}}% Beherrschung in {{skill}}'
},
aria: {
skillGroup: 'Fähigkeitsgruppe für {{category}}',
skillBar: 'Fortschrittsbalken für {{skill}}',
skillIcon: 'Symbol für {{category}}',
selectSkill: 'Fähigkeit auswählen'
},
screenReader: {
skillProgress: '{{skill}} mit einem Niveau von {{level}} Prozent'
}
} as const;
export type SkillsTranslations = typeof skills;
@@ -0,0 +1,44 @@
export const workflow = {
// Seitentitel
title: 'MEIN WORKFLOW',
description: 'Systematischer Ansatz zur Softwareentwicklung durch definierte Schritte',
// Workflow-Schritte
steps: [
{
number: '01',
title: 'ANFORDERUNGSANALYSE'
},
{
number: '02',
title: 'ABFRAGE VON DEADLINES UND EINSCHRÄNKUNGEN'
},
{
number: '03',
title: 'EINRICHTUNG DER ENTWICKLUNGSUMGEBUNG'
},
{
number: '04',
title: 'PROGRAMMIERUNG'
},
{
number: '05',
title: 'TESTEN DER ERGEBNISSE'
},
{
number: '06',
title: 'SUPPORT UND SKALIERUNG DES CODES'
}
],
// Aria Labels für Barrierefreiheit
aria: {
workflowSection: 'Workflow-Prozess',
stepNumber: 'Schritt {{number}}',
stepDescription: 'Workflow-Schritt: {{title}}'
},
// Screen Reader Texte
screenReader: {
stepProgress: 'Schritt {{number}} von {{total}}: {{title}}'
}
} as const;
// Type für Typsicherheit
export type WorkflowTranslations = typeof workflow;