add en/vi language

This commit is contained in:
Tran Anh Tuan
2025-11-15 16:58:07 +07:00
parent 1a534eccb0
commit e725819c01
31 changed files with 1843 additions and 232 deletions

View File

@@ -4,14 +4,16 @@ import { HapticTab } from "@/components/haptic-tab";
import { IconSymbol } from "@/components/ui/icon-symbol";
import { Colors } from "@/constants/theme";
import { useColorScheme } from "@/hooks/use-color-scheme";
import { useI18n } from "@/hooks/use-i18n";
import { startEvents, stopEvents } from "@/services/device_events";
import { useEffect, useRef } from "react";
export default function TabLayout() {
const colorScheme = useColorScheme();
const segments = useSegments();
const segments = useSegments() as string[];
const prev = useRef<string | null>(null);
const currentSegment = segments[1] ?? segments[segments.length - 1] ?? null; // tuỳ cấu trúc của bạn
const currentSegment = segments[1] ?? segments[segments.length - 1] ?? null;
const { t, locale } = useI18n();
useEffect(() => {
if (prev.current !== currentSegment) {
// console.log("Tab changed ->", { from: prev.current, to: currentSegment });
@@ -39,7 +41,7 @@ export default function TabLayout() {
<Tabs.Screen
name="index"
options={{
title: "Giám sát",
title: t("navigation.home"),
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="map.fill" color={color} />
),
@@ -49,7 +51,7 @@ export default function TabLayout() {
<Tabs.Screen
name="tripInfo"
options={{
title: "Chuyến Đi",
title: t("navigation.trip"),
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="ferry.fill" color={color} />
),
@@ -58,7 +60,7 @@ export default function TabLayout() {
<Tabs.Screen
name="diary"
options={{
title: "Nhật Ký",
title: t("navigation.diary"),
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="book.closed.fill" color={color} />
),
@@ -67,7 +69,7 @@ export default function TabLayout() {
<Tabs.Screen
name="sensor"
options={{
title: "Cảm biến",
title: t("navigation.sensor"),
tabBarIcon: ({ color }) => (
<IconSymbol
size={28}
@@ -80,7 +82,7 @@ export default function TabLayout() {
<Tabs.Screen
name="setting"
options={{
title: "Cài đặt",
title: t("navigation.setting"),
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="gear" color={color} />
),

View File

@@ -91,7 +91,7 @@ export default function HomeScreen() {
if (TrackPointsData && TrackPointsData.length > 0) {
setTrackPointsData(TrackPointsData);
} else {
setTrackPointsData(null);
setTrackPointsData([]);
}
};

View File

@@ -1,13 +1,15 @@
import { useRouter } from "expo-router";
import { StyleSheet } from "react-native";
import { useEffect, useState } from "react";
import { StyleSheet, View } from "react-native";
import EnIcon from "@/assets/icons/en_icon.png";
import VnIcon from "@/assets/icons/vi_icon.png";
import RotateSwitch from "@/components/rotate-switch";
import { ThemedText } from "@/components/themed-text";
import { ThemedView } from "@/components/themed-view";
import { api } from "@/config";
import { DOMAIN, TOKEN } from "@/constants";
import { useI18n } from "@/hooks/use-i18n";
import { removeStorageItem } from "@/utils/storage";
import { useState } from "react";
type Todo = {
userId: number;
id: number;
@@ -18,23 +20,40 @@ type Todo = {
export default function SettingScreen() {
const router = useRouter();
const [data, setData] = useState<Todo | null>(null);
const { t, locale, setLocale } = useI18n();
const [isEnabled, setIsEnabled] = useState(locale === "vi");
// Sync isEnabled state khi locale thay đổi
useEffect(() => {
setIsEnabled(locale === "vi");
}, [locale]);
// useEffect(() => {
// getData();
// }, []);
const getData = async () => {
try {
const response = await api.get("/todos/1");
setData(response.data);
} catch (error) {
console.error("Error fetching data:", error);
}
const toggleSwitch = async () => {
const newLocale = isEnabled ? "en" : "vi";
await setLocale(newLocale);
};
return (
<ThemedView style={styles.container}>
<ThemedText type="title">Settings</ThemedText>
<ThemedText type="title">{t("navigation.setting")}</ThemedText>
<View style={styles.settingItem}>
<ThemedText type="default">{t("common.language")}</ThemedText>
{/* <Switch
trackColor={{ false: "#767577", true: "#81b0ff" }}
thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
ios_backgroundColor="#3e3e3e"
onValueChange={toggleSwitch}
value={isEnabled}
/> */}
<RotateSwitch
initialValue={isEnabled}
onChange={toggleSwitch}
size="sm"
offImage={EnIcon}
onImage={VnIcon}
/>
</View>
<ThemedView
style={styles.button}
onTouchEnd={async () => {
@@ -43,8 +62,9 @@ export default function SettingScreen() {
router.navigate("/auth/login");
}}
>
<ThemedText type="defaultSemiBold">Đăng xuất</ThemedText>
<ThemedText type="defaultSemiBold">{t("auth.logout")}</ThemedText>
</ThemedView>
{data && (
<ThemedView style={{ marginTop: 20 }}>
<ThemedText type="default">{data.title}</ThemedText>
@@ -62,11 +82,23 @@ const styles = StyleSheet.create({
alignItems: "center",
justifyContent: "center",
padding: 20,
gap: 16,
},
settingItem: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
paddingHorizontal: 16,
paddingVertical: 12,
borderRadius: 8,
backgroundColor: "rgba(0, 122, 255, 0.1)",
},
button: {
marginTop: 20,
padding: 10,
paddingVertical: 12,
paddingHorizontal: 20,
backgroundColor: "#007AFF",
borderRadius: 5,
borderRadius: 8,
},
});