handleChange('')}
- className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300"
>
diff --git a/frontend/src/components/StatusBadge.tsx b/frontend/src/components/StatusBadge.tsx
index 77a90e4..36517ed 100644
--- a/frontend/src/components/StatusBadge.tsx
+++ b/frontend/src/components/StatusBadge.tsx
@@ -6,19 +6,19 @@ const statusConfig: Record<
> = {
DRAFT: {
label: 'Entwurf',
- className: 'bg-gray-100 text-gray-700 ring-gray-300',
+ className: 'bg-gray-100 text-gray-700 ring-gray-300 dark:bg-gray-700 dark:text-gray-300 dark:ring-gray-600',
},
REVIEW: {
label: 'In Prüfung',
- className: 'bg-yellow-50 text-yellow-700 ring-yellow-300',
+ className: 'bg-yellow-50 text-yellow-700 ring-yellow-300 dark:bg-yellow-900/30 dark:text-yellow-400 dark:ring-yellow-700',
},
PUBLISHED: {
label: 'Veröffentlicht',
- className: 'bg-green-50 text-green-700 ring-green-300',
+ className: 'bg-green-50 text-green-700 ring-green-300 dark:bg-green-900/30 dark:text-green-400 dark:ring-green-700',
},
ARCHIVED: {
label: 'Archiviert',
- className: 'bg-red-50 text-red-700 ring-red-300',
+ className: 'bg-red-50 text-red-700 ring-red-300 dark:bg-red-900/30 dark:text-red-400 dark:ring-red-700',
},
};
diff --git a/frontend/src/hooks/useDarkMode.ts b/frontend/src/hooks/useDarkMode.ts
new file mode 100644
index 0000000..9a4966d
--- /dev/null
+++ b/frontend/src/hooks/useDarkMode.ts
@@ -0,0 +1,38 @@
+import { useEffect, useState } from 'react';
+
+function getInitialTheme(): boolean {
+ const stored = localStorage.getItem('theme');
+ if (stored === 'dark') return true;
+ if (stored === 'light') return false;
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
+}
+
+export function useDarkMode() {
+ const [isDark, setIsDark] = useState(getInitialTheme);
+
+ useEffect(() => {
+ const root = document.documentElement;
+ if (isDark) {
+ root.classList.add('dark');
+ } else {
+ root.classList.remove('dark');
+ }
+ localStorage.setItem('theme', isDark ? 'dark' : 'light');
+ }, [isDark]);
+
+ // Listen for system preference changes when no explicit choice stored
+ useEffect(() => {
+ const mq = window.matchMedia('(prefers-color-scheme: dark)');
+ const handler = (e: MediaQueryListEvent) => {
+ if (!localStorage.getItem('theme')) {
+ setIsDark(e.matches);
+ }
+ };
+ mq.addEventListener('change', handler);
+ return () => mq.removeEventListener('change', handler);
+ }, []);
+
+ const toggle = () => setIsDark((prev) => !prev);
+
+ return { isDark, toggle };
+}
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 9f0e20a..9d52fe2 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -7,24 +7,24 @@
@apply scroll-smooth;
}
body {
- @apply min-h-screen bg-gray-50 text-gray-900;
+ @apply min-h-screen bg-gray-50 text-gray-900 dark:bg-gray-900 dark:text-gray-100;
}
}
@layer components {
.btn-primary {
- @apply inline-flex items-center justify-center rounded-lg bg-primary-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50;
+ @apply inline-flex items-center justify-center rounded-lg bg-primary-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:focus:ring-offset-gray-900;
}
.btn-secondary {
- @apply inline-flex items-center justify-center rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50;
+ @apply inline-flex items-center justify-center rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus:ring-offset-gray-900;
}
.btn-danger {
- @apply inline-flex items-center justify-center rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50;
+ @apply inline-flex items-center justify-center rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:focus:ring-offset-gray-900;
}
.input-field {
- @apply block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-gray-400 focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500;
+ @apply block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-gray-400 focus:border-primary-500 focus:outline-none focus:ring-1 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder:text-gray-400;
}
.card {
- @apply rounded-xl border border-gray-200 bg-white shadow-sm;
+ @apply rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-gray-800;
}
}
diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx
index 99a49ef..fc0eace 100644
--- a/frontend/src/pages/Dashboard.tsx
+++ b/frontend/src/pages/Dashboard.tsx
@@ -77,25 +77,25 @@ export default function Dashboard() {
label: 'Gesamt',
value: stats.total,
icon: FileText,
- color: 'bg-primary-50 text-primary-600',
+ color: 'bg-primary-50 text-primary-600 dark:bg-primary-900/30 dark:text-primary-400',
},
{
label: 'Veröffentlicht',
value: stats.published,
icon: FileCheck,
- color: 'bg-green-50 text-green-600',
+ color: 'bg-green-50 text-green-600 dark:bg-green-900/30 dark:text-green-400',
},
{
label: 'In Prüfung',
value: stats.review,
icon: Clock,
- color: 'bg-yellow-50 text-yellow-600',
+ color: 'bg-yellow-50 text-yellow-600 dark:bg-yellow-900/30 dark:text-yellow-400',
},
{
label: 'Entwurf',
value: stats.draft,
icon: Archive,
- color: 'bg-gray-100 text-gray-600',
+ color: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400',
},
];
@@ -104,10 +104,10 @@ export default function Dashboard() {
{/* Header */}
-
+
Willkommen, {user?.firstName}!
-
+
Hier ist eine Übersicht Ihrer Workflows.
@@ -139,10 +139,10 @@ export default function Dashboard() {