diff --git a/package.json b/package.json index e6537d8..7fe5477 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "input-otp": "^1.4.2", "lucide-react": "^0.511.0", "next": "15.3.8", + "next-international": "^1.3.1", "next-themes": "^0.4.6", "react": "^19.2.1", "react-day-picker": "^8.10.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1383c3..261330e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,6 +113,9 @@ importers: next: specifier: 15.3.8 version: 15.3.8(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + next-international: + specifier: ^1.3.1 + version: 1.3.1 next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -1495,6 +1498,9 @@ packages: react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + international-types@0.8.1: + resolution: {integrity: sha512-tajBCAHo4I0LIFlmQ9ZWfjMWVyRffzuvfbXCd6ssFt5u1Zw15DN0UBpVTItXdNa1ls+cpQt3Yw8+TxsfGF8JcA==} + internmap@2.0.3: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} @@ -1616,6 +1622,9 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + next-international@1.3.1: + resolution: {integrity: sha512-ydU9jQe+4MohMWltbZae/yuWeKhmp0QKQqJNNi8WCCMwrly03qfMAHw/tWbT2qgAlG++CxF5jMXmGQZgOHeVOw==} + next-themes@0.4.6: resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: @@ -1867,6 +1876,9 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + sharp@0.34.2: resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -3400,6 +3412,8 @@ snapshots: react: 19.2.1 react-dom: 19.2.1(react@19.2.1) + international-types@0.8.1: {} + internmap@2.0.3: {} is-arrayish@0.3.2: @@ -3498,6 +3512,12 @@ snapshots: neo-async@2.6.2: {} + next-international@1.3.1: + dependencies: + client-only: 0.0.1 + international-types: 0.8.1 + server-only: 0.0.1 + next-themes@0.4.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1): dependencies: react: 19.2.1 @@ -3736,6 +3756,8 @@ snapshots: dependencies: randombytes: 2.1.0 + server-only@0.0.1: {} + sharp@0.34.2: dependencies: color: 4.2.3 diff --git a/src/app/changelog/page.tsx b/src/app/[locale]/changelog/page.tsx similarity index 80% rename from src/app/changelog/page.tsx rename to src/app/[locale]/changelog/page.tsx index ba7c4dd..249dcd7 100644 --- a/src/app/changelog/page.tsx +++ b/src/app/[locale]/changelog/page.tsx @@ -2,15 +2,17 @@ import { Changelog } from "@/components/changelog"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { ArrowLeft } from "lucide-react"; +import { getI18n } from "@/lib/i18n/server"; -export default function ChangelogPage() { +export default async function ChangelogPage() { + const t = await getI18n(); return (
diff --git a/src/app/imprint/page.tsx b/src/app/[locale]/imprint/page.tsx similarity index 67% rename from src/app/imprint/page.tsx rename to src/app/[locale]/imprint/page.tsx index 4b252f5..380dc17 100644 --- a/src/app/imprint/page.tsx +++ b/src/app/[locale]/imprint/page.tsx @@ -2,28 +2,30 @@ import Link from "next/link"; import { Button } from "@/components/ui/button"; import { ArrowLeft } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { getI18n } from "@/lib/i18n/server"; -export default function ImprintPage() { +export default async function ImprintPage() { + const t = await getI18n(); return (
- Imprint + {t('imprint.title')}

- Information according to § 5 TMG (German Telemedia Act) + {t('imprint.info')}

-

Contact Information:

+

{t('imprint.contact.title')}

[Your Company Name]

[Street Name & Number]

[Postal Code & City]

@@ -31,13 +33,13 @@ export default function ImprintPage() {

Phone: [your-phone-number]

-

Represented by:

+

{t('imprint.represented_by.title')}

[Your Name/CEO's Name]

-

Disclaimer:

+

{t('imprint.disclaimer.title')}

- This is a sample imprint and not legally binding. Please replace the placeholder content with your own information and consult a legal professional to ensure compliance with all applicable laws. + {t('imprint.disclaimer.text')}

diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx new file mode 100644 index 0000000..3fb05ff --- /dev/null +++ b/src/app/[locale]/layout.tsx @@ -0,0 +1,55 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "../globals.css"; +import { ThemeProvider } from "@/components/theme-provider"; +import { Toaster } from "@/components/ui/sonner"; +import { Footer } from "@/components/footer"; +import { I18nProviderClient } from "@/lib/i18n/client"; +import { getI18n } from "@/lib/i18n/server"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export async function generateMetadata({ params: { locale } }: { params: { locale: string } }): Promise { + const t = await getI18n(); + return { + title: t('meta.title'), + description: t('meta.description'), + }; +} + +export default function RootLayout({ + children, + params: { locale } +}: Readonly<{ + children: React.ReactNode; + params: { locale: string }; +}>) { + return ( + + + + + {children} +