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

@@ -1,6 +1,6 @@
import { View, Text, Pressable } from "react-native";
import { ProposedEventChange } from "@calchat/shared";
import currentTheme from "../Themes";
import { useThemeStore } from "../stores/ThemeStore";
import { EventCardBase } from "./EventCardBase";
type ProposedEventCardProps = {
@@ -19,42 +19,45 @@ const ConfirmRejectButtons = ({
respondedAction?: "confirm" | "reject";
onConfirm: () => void;
onReject: () => void;
}) => (
<View className="flex-row mt-3 gap-2">
<Pressable
onPress={onConfirm}
disabled={isDisabled}
className="flex-1 py-2 rounded-lg items-center"
style={{
backgroundColor: isDisabled
? currentTheme.disabledButton
: currentTheme.confirmButton,
borderWidth: respondedAction === "confirm" ? 2 : 0,
borderColor: currentTheme.confirmButton,
}}
>
<Text style={{ color: currentTheme.buttonText }} className="font-medium">
Annehmen
</Text>
</Pressable>
<Pressable
onPress={onReject}
disabled={isDisabled}
className="flex-1 py-2 rounded-lg items-center"
style={{
backgroundColor: isDisabled
? currentTheme.disabledButton
: currentTheme.rejectButton,
borderWidth: respondedAction === "reject" ? 2 : 0,
borderColor: currentTheme.rejectButton,
}}
>
<Text style={{ color: currentTheme.buttonText }} className="font-medium">
Ablehnen
</Text>
</Pressable>
</View>
);
}) => {
const { theme } = useThemeStore();
return (
<View className="flex-row mt-3 gap-2">
<Pressable
onPress={onConfirm}
disabled={isDisabled}
className="flex-1 py-2 rounded-lg items-center"
style={{
backgroundColor: isDisabled
? theme.disabledButton
: theme.confirmButton,
borderWidth: respondedAction === "confirm" ? 2 : 0,
borderColor: theme.confirmButton,
}}
>
<Text style={{ color: theme.buttonText }} className="font-medium">
Annehmen
</Text>
</Pressable>
<Pressable
onPress={onReject}
disabled={isDisabled}
className="flex-1 py-2 rounded-lg items-center"
style={{
backgroundColor: isDisabled
? theme.disabledButton
: theme.rejectButton,
borderWidth: respondedAction === "reject" ? 2 : 0,
borderColor: theme.rejectButton,
}}
>
<Text style={{ color: theme.buttonText }} className="font-medium">
Ablehnen
</Text>
</Pressable>
</View>
);
};
export const ProposedEventCard = ({
proposedChange,