Khởi tạo ban đầu

This commit is contained in:
Tran Anh Tuan
2025-11-28 16:59:57 +07:00
parent 2911be97b2
commit 4ba46a7df2
131 changed files with 28066 additions and 0 deletions

109
components/theme-toggle.tsx Normal file
View File

@@ -0,0 +1,109 @@
/**
* Theme Toggle Component for switching between light, dark, and system themes
*/
import React from "react";
import { View, TouchableOpacity, StyleSheet } from "react-native";
import { ThemedText } from "@/components/themed-text";
import { useThemeContext } from "@/hooks/use-theme-context";
import { useI18n } from "@/hooks/use-i18n";
import { Ionicons } from "@expo/vector-icons";
interface ThemeToggleProps {
style?: any;
}
export function ThemeToggle({ style }: ThemeToggleProps) {
const { themeMode, setThemeMode, colors } = useThemeContext();
const { t } = useI18n();
const themeOptions = [
{
mode: "light" as const,
label: t("common.theme_light"),
icon: "sunny-outline" as const,
},
{
mode: "dark" as const,
label: t("common.theme_dark"),
icon: "moon-outline" as const,
},
{
mode: "system" as const,
label: t("common.theme_system"),
icon: "phone-portrait-outline" as const,
},
];
return (
<View
style={[styles.container, style, { backgroundColor: colors.surface }]}
>
<ThemedText style={styles.title}>{t("common.theme")}</ThemedText>
<View style={styles.optionsContainer}>
{themeOptions.map((option) => (
<TouchableOpacity
key={option.mode}
style={[
styles.option,
{
backgroundColor:
themeMode === option.mode
? colors.primary
: colors.backgroundSecondary,
borderColor: colors.border,
},
]}
onPress={() => setThemeMode(option.mode)}
>
<Ionicons
name={option.icon}
size={20}
color={themeMode === option.mode ? "#fff" : colors.icon}
/>
<ThemedText
style={[
styles.optionText,
{ color: themeMode === option.mode ? "#fff" : colors.text },
]}
>
{option.label}
</ThemedText>
</TouchableOpacity>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 16,
borderRadius: 12,
marginVertical: 8,
},
title: {
fontSize: 16,
fontWeight: "600",
marginBottom: 12,
},
optionsContainer: {
flexDirection: "row",
gap: 8,
},
option: {
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
paddingVertical: 12,
paddingHorizontal: 8,
borderRadius: 8,
borderWidth: 1,
gap: 6,
},
optionText: {
fontSize: 14,
fontWeight: "500",
},
});