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}
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/page.tsx b/src/app/[locale]/page.tsx
similarity index 78%
rename from src/app/page.tsx
rename to src/app/[locale]/page.tsx
index 42403e1..d3ab4f4 100644
--- a/src/app/page.tsx
+++ b/src/app/[locale]/page.tsx
@@ -1,15 +1,17 @@
import { ImageConverter } from "@/components/image-converter";
+import { getI18n } from "@/lib/i18n/server";
-export default function Home() {
+export default async function Home() {
+ const t = await getI18n();
return (
- Image Web Exporter
+ {t('home.title')}
- Upload a picture, then export it in a different resolution and format.
+ {t('home.subtitle')}
diff --git a/src/app/privacy/page.tsx b/src/app/[locale]/privacy/page.tsx
similarity index 50%
rename from src/app/privacy/page.tsx
rename to src/app/[locale]/privacy/page.tsx
index 8469cdd..d41aa93 100644
--- a/src/app/privacy/page.tsx
+++ b/src/app/[locale]/privacy/page.tsx
@@ -2,45 +2,47 @@ 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 PrivacyPage() {
+export default async function PrivacyPage() {
+ const t = await getI18n();
return (
- Data Privacy Policy
+ {t('privacy.title')}
-
1. General Information
+
{t('privacy.general.title')}
- This is a placeholder for your data privacy policy. It outlines how personal data is collected, used, and protected when you use this website.
+ {t('privacy.general.text')}
-
2. Data Collection on This Website
+
{t('privacy.collection.title')}
- All image processing happens directly in your browser. The images you upload are not sent to any server and are not stored by us. We do not collect any personal data from the images.
+ {t('privacy.collection.text')}
-
3. Your Rights
+
{t('privacy.rights.title')}
- As no personal data is collected, rights regarding access, rectification, or erasure of personal data are not applicable in this context.
+ {t('privacy.rights.text')}
-
Disclaimer:
+
{t('privacy.disclaimer.title')}
- This is a sample privacy policy and not legally binding. It is crucial to adapt this text to your specific data processing activities and to consult with a legal professional to ensure full GDPR compliance.
+ {t('privacy.disclaimer.text')}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
deleted file mode 100644
index 0aaa019..0000000
--- a/src/app/layout.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-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";
-
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
-});
-
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
-
-export const metadata: Metadata = {
- title: "Image Web Exporter",
- description: "Upload a picture, then export it in a different resolution and format.",
-};
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
-
- {children}
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/src/components/changelog.tsx b/src/components/changelog.tsx
index 3de260e..1aa5dbc 100644
--- a/src/components/changelog.tsx
+++ b/src/components/changelog.tsx
@@ -3,17 +3,28 @@
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { cn } from "@/lib/utils";
-import { changelogData } from "@/lib/changelog-data";
+import { useI18n } from "@/lib/i18n/client";
+import { changelogData, type Change } from "@/lib/changelog-config";
export function Changelog() {
+ const t = useI18n();
+
+ const getBadgeText = (type: Change['type']) => {
+ switch (type) {
+ case 'New': return t('changelog.types.new');
+ case 'Improved': return t('changelog.types.improved');
+ case 'Fixed': return t('changelog.types.fixed');
+ }
+ };
+
return (
- Changelog
+ {t('changelog.title')}
- Tracking all the new features, improvements, and bug fixes.
+ {t('changelog.subtitle')}
@@ -21,7 +32,7 @@ export function Changelog() {
- Version {entry.version}
+ {t('changelog.version')} {entry.version}