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,41 @@
// src/i18n/locales/en/pages/contact/contactform.ts
export const contactform = {
// Form Header
title: 'Contact Me',
description: 'Have questions or want to collaborate? Send me a message.',
// Form Fields
name: {
label: 'Name',
placeholder: 'Your full name'
},
email: {
label: 'Email',
placeholder: 'your.email@example.com'
},
message: {
label: 'Message',
placeholder: 'Your message to me...'
},
// Button
submit: 'Send Message',
// Status Messages
successMessage: 'Thank you for your message! I will get back to you as soon as possible.',
errorMessage: 'Sorry, there was an error sending your message. Please try again later.',
// Error Messages
errors: {
nameRequired: 'Please enter your name',
emailRequired: 'Please enter your email address',
emailInvalid: 'Please enter a valid email address',
messageRequired: 'Please enter a message'
},
// Aria Labels
aria: {
form: 'Contact form',
submitting: 'Sending form',
successAlert: 'Success message',
errorAlert: 'Error message'
}
} as const;
// Type for type safety
export type ContactFormTranslations = typeof contactform;
@@ -0,0 +1,27 @@
// src/i18n/locales/en/pages/contact/contactinfo.ts
export const contactinfo = {
// Header
title: 'Contact Information',
description: 'You can reach me through the following channels',
// Contact Method Labels
addressLabel: 'Office Location',
phoneLabel: 'Phone',
emailLabel: 'Email',
// Contact Information
address: 'Rotdornallee, Köln',
phone: '+49 175 695 0979',
email: 'info@damjan-savic.com',
// Additional Information
availabilityNote: 'Business hours: Monday to Friday, 9:00 AM - 5:00 PM',
// Aria Labels
aria: {
contactCard: 'Contact information card',
addressLink: 'Open location in Google Maps',
phoneLink: 'Call',
emailLink: 'Send email',
externalLink: 'Opens in new tab'
}
} as const;
// Type for type safety
export type ContactInfoTranslations = typeof contactinfo;
@@ -0,0 +1,71 @@
// src/i18n/locales/en/pages/contact/index.ts
export const contact = {
breadcrumb: "CONTACT",
hero: {
title: "Let's Work Together",
subtitle: "Have a project in mind? Let's discuss how we can help you achieve your goals."
},
contactInfo: {
title: "Contact Information",
description: "You can reach me through the following channels",
address: {
label: "Office Location",
value: "Rotdornallee, Köln"
},
phone: {
label: "Phone",
value: "+49 175 695 0979"
},
email: {
label: "Email",
value: "info@damjan-savic.com"
},
availabilityNote: "Business hours: Monday to Friday, 9:00 AM - 5:00 PM",
aria: {
contactCard: "Contact information card",
addressLink: "Open location in Google Maps",
phoneLink: "Call",
emailLink: "Send email",
externalLink: "Opens in new tab"
}
},
contactForm: {
title: "Contact Me",
description: "Have questions or want to collaborate? Send me a message.",
name: {
label: "Name",
placeholder: "Your full name"
},
email: {
label: "Email",
placeholder: "your.email@example.com"
},
message: {
label: "Message",
placeholder: "Your message to me..."
},
submit: "Send Message",
successMessage: "Thank you for your message! I will get back to you as soon as possible.",
errorMessage: "Sorry, there was an error sending your message. Please try again later.",
errors: {
nameRequired: "Please enter your name",
emailRequired: "Please enter your email address",
emailInvalid: "Please enter a valid email address",
messageRequired: "Please enter a message"
},
aria: {
form: "Contact form",
submitting: "Sending form",
successAlert: "Success message",
errorAlert: "Error message"
}
}
} as const;
export type ContactTranslations = typeof contact;
export default {
pages: {
contact: contact
}
};