add en/vi language
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useI18n } from "@/hooks/use-i18n";
|
||||
import { convertToDMS, kmhToKnot } from "@/utils/geom";
|
||||
import { MaterialIcons } from "@expo/vector-icons";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
@@ -13,7 +14,7 @@ const GPSInfoPanel = ({ gpsData }: GPSInfoPanelProps) => {
|
||||
const [panelHeight, setPanelHeight] = useState(0);
|
||||
const translateY = useRef(new Animated.Value(0)).current;
|
||||
const blockBottom = useRef(new Animated.Value(0)).current;
|
||||
|
||||
const { t } = useI18n();
|
||||
useEffect(() => {
|
||||
Animated.timing(translateY, {
|
||||
toValue: isExpanded ? 0 : 200, // Dịch chuyển xuống 200px khi thu gọn
|
||||
@@ -88,13 +89,13 @@ const GPSInfoPanel = ({ gpsData }: GPSInfoPanelProps) => {
|
||||
<View className="flex-row justify-between">
|
||||
<View className="flex-1">
|
||||
<Description
|
||||
title="Kinh độ"
|
||||
title={t("home.latitude")}
|
||||
description={convertToDMS(gpsData?.lat ?? 0, true)}
|
||||
/>
|
||||
</View>
|
||||
<View className="flex-1">
|
||||
<Description
|
||||
title="Vĩ độ"
|
||||
title={t("home.longitude")}
|
||||
description={convertToDMS(gpsData?.lon ?? 0, false)}
|
||||
/>
|
||||
</View>
|
||||
@@ -102,12 +103,15 @@ const GPSInfoPanel = ({ gpsData }: GPSInfoPanelProps) => {
|
||||
<View className="flex-row justify-between">
|
||||
<View className="flex-1">
|
||||
<Description
|
||||
title="Tốc độ"
|
||||
title={t("home.speed")}
|
||||
description={`${kmhToKnot(gpsData?.s ?? 0).toString()} knot`}
|
||||
/>
|
||||
</View>
|
||||
<View className="flex-1">
|
||||
<Description title="Hướng" description={`${gpsData?.h ?? 0}°`} />
|
||||
<Description
|
||||
title={t("home.heading")}
|
||||
description={`${gpsData?.h ?? 0}°`}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</Animated.View>
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
queryGetSos,
|
||||
querySendSosMessage,
|
||||
} from "@/controller/DeviceController";
|
||||
import { useI18n } from "@/hooks/use-i18n";
|
||||
import { showErrorToast } from "@/services/toast_service";
|
||||
import { sosMessage } from "@/utils/sosUtils";
|
||||
import { MaterialIcons } from "@expo/vector-icons";
|
||||
@@ -35,7 +36,7 @@ const SosButton = () => {
|
||||
const [customMessage, setCustomMessage] = useState("");
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const [errors, setErrors] = useState<{ [key: string]: string }>({});
|
||||
|
||||
const { t } = useI18n();
|
||||
const sosOptions = [
|
||||
...sosMessage.map((msg) => ({ ma: msg.ma, moTa: msg.moTa })),
|
||||
{ ma: 999, moTa: "Khác" },
|
||||
@@ -60,7 +61,7 @@ const SosButton = () => {
|
||||
// Không cần validate sosMessage vì luôn có default value (11)
|
||||
|
||||
if (selectedSosMessage === 999 && customMessage.trim() === "") {
|
||||
newErrors.customMessage = "Vui lòng nhập trạng thái";
|
||||
newErrors.customMessage = t("home.sos.statusRequired");
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
@@ -108,7 +109,7 @@ const SosButton = () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error when send sos: ", error);
|
||||
showErrorToast("Không thể gửi tín hiệu SOS");
|
||||
showErrorToast(t("home.sos.sendError"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,7 +123,7 @@ const SosButton = () => {
|
||||
>
|
||||
<MaterialIcons name="warning" size={15} color="white" />
|
||||
<ButtonText className="text-center">
|
||||
{sosData?.active ? "Đang trong trạng thái khẩn cấp" : "Khẩn cấp"}
|
||||
{sosData?.active ? t("home.sos.active") : t("home.sos.inactive")}
|
||||
</ButtonText>
|
||||
{/* <ButtonSpinner /> */}
|
||||
{/* <ButtonIcon /> */}
|
||||
@@ -142,14 +143,14 @@ const SosButton = () => {
|
||||
<Text
|
||||
style={{ fontSize: 18, fontWeight: "bold", textAlign: "center" }}
|
||||
>
|
||||
Thông báo khẩn cấp
|
||||
{t("home.sos.title")}
|
||||
</Text>
|
||||
</ModalHeader>
|
||||
<ModalBody className="mb-4">
|
||||
<ScrollView style={{ maxHeight: 400 }}>
|
||||
{/* Dropdown Nội dung SOS */}
|
||||
<View style={styles.formGroup}>
|
||||
<Text style={styles.label}>Nội dung:</Text>
|
||||
<Text style={styles.label}>{t("home.sos.content")}</Text>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.dropdownButton,
|
||||
@@ -165,8 +166,8 @@ const SosButton = () => {
|
||||
>
|
||||
{selectedSosMessage !== null
|
||||
? sosOptions.find((opt) => opt.ma === selectedSosMessage)
|
||||
?.moTa || "Chọn lý do"
|
||||
: "Chọn lý do"}
|
||||
?.moTa || t("home.sos.selectReason")
|
||||
: t("home.sos.selectReason")}
|
||||
</Text>
|
||||
<MaterialIcons
|
||||
name={showDropdown ? "expand-less" : "expand-more"}
|
||||
@@ -182,13 +183,13 @@ const SosButton = () => {
|
||||
{/* Input Custom Message nếu chọn "Khác" */}
|
||||
{selectedSosMessage === 999 && (
|
||||
<View style={styles.formGroup}>
|
||||
<Text style={styles.label}>Nhập trạng thái</Text>
|
||||
<Text style={styles.label}>{t("home.sos.statusInput")}</Text>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.input,
|
||||
errors.customMessage ? styles.errorInput : {},
|
||||
]}
|
||||
placeholder="Mô tả trạng thái khẩn cấp"
|
||||
placeholder={t("home.sos.enterStatus")}
|
||||
placeholderTextColor="#999"
|
||||
value={customMessage}
|
||||
onChangeText={(text) => {
|
||||
@@ -217,7 +218,7 @@ const SosButton = () => {
|
||||
// className="w-1/3"
|
||||
action="negative"
|
||||
>
|
||||
<ButtonText>Xác nhận</ButtonText>
|
||||
<ButtonText>{t("home.sos.confirm")}</ButtonText>
|
||||
</Button>
|
||||
<Button
|
||||
onPress={() => {
|
||||
@@ -229,7 +230,7 @@ const SosButton = () => {
|
||||
// className="w-1/3"
|
||||
action="secondary"
|
||||
>
|
||||
<ButtonText>Hủy</ButtonText>
|
||||
<ButtonText>{t("home.sos.cancel")}</ButtonText>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
||||
Reference in New Issue
Block a user