feat: add theme system with light/dark mode support

- Add ThemeStore (Zustand) for reactive theme switching
- Add Themes.tsx with THEMES object (defaultLight, defaultDark)
- Add Settings screen with theme switcher and logout button
- Add BaseButton component for reusable themed buttons
- Migrate all components from static currentTheme to useThemeStore()
- Add shadowColor to theme (iOS only, Android uses elevation)
- All text elements now use theme colors (textPrimary, textSecondary, etc.)
- Update tab navigation to include Settings tab
- Move logout from Header to Settings screen
This commit is contained in:
2026-01-24 16:57:33 +01:00
parent 1dbca79edd
commit 43d40b46d7
23 changed files with 450 additions and 236 deletions

View File

@@ -4,9 +4,10 @@ import { Link, router } from "expo-router";
import BaseBackground from "../components/BaseBackground";
import AuthButton from "../components/AuthButton";
import { AuthService } from "../services";
import currentTheme from "../Themes";
import { useThemeStore } from "../stores/ThemeStore";
const LoginScreen = () => {
const { theme } = useThemeStore();
const [identifier, setIdentifier] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState<string | null>(null);
@@ -36,44 +37,44 @@ const LoginScreen = () => {
<View className="flex-1 justify-center items-center p-8">
<Text
className="text-3xl font-bold mb-8"
style={{ color: currentTheme.textPrimary }}
style={{ color: theme.textPrimary }}
>
Anmelden
</Text>
{error && (
<Text className="mb-4 text-center" style={{ color: currentTheme.rejectButton }}>
<Text className="mb-4 text-center" style={{ color: theme.rejectButton }}>
{error}
</Text>
)}
<TextInput
placeholder="E-Mail oder Benutzername"
placeholderTextColor={currentTheme.textMuted}
placeholderTextColor={theme.textMuted}
value={identifier}
onChangeText={setIdentifier}
autoCapitalize="none"
className="w-full rounded-lg p-4 mb-4"
style={{
backgroundColor: currentTheme.secondaryBg,
color: currentTheme.textPrimary,
backgroundColor: theme.secondaryBg,
color: theme.textPrimary,
borderWidth: 1,
borderColor: currentTheme.borderPrimary,
borderColor: theme.borderPrimary,
}}
/>
<TextInput
placeholder="Passwort"
placeholderTextColor={currentTheme.textMuted}
placeholderTextColor={theme.textMuted}
value={password}
onChangeText={setPassword}
secureTextEntry
className="w-full rounded-lg p-4 mb-6"
style={{
backgroundColor: currentTheme.secondaryBg,
color: currentTheme.textPrimary,
backgroundColor: theme.secondaryBg,
color: theme.textPrimary,
borderWidth: 1,
borderColor: currentTheme.borderPrimary,
borderColor: theme.borderPrimary,
}}
/>
@@ -85,7 +86,7 @@ const LoginScreen = () => {
<Link href="/register" asChild>
<Pressable>
<Text style={{ color: currentTheme.chatBot }}>
<Text style={{ color: theme.chatBot }}>
Noch kein Konto? Registrieren
</Text>
</Pressable>