Files
sgw-owner-app/components/map/ShipInfo.tsx

170 lines
5.3 KiB
TypeScript

import { STATUS_DANGEROUS, STATUS_NORMAL, STATUS_WARNING } from "@/constants";
import { useAppTheme } from "@/hooks/use-app-theme";
import { useI18n } from "@/hooks/use-i18n";
import { formatRelativeTime } from "@/services/time_service";
import { convertToDMS, kmhToKnot } from "@/utils/geom";
import { Ionicons } from "@expo/vector-icons";
import { ScrollView, Text, View } from "react-native";
import { ThemedText } from "../themed-text";
interface ShipInfoProps {
thingMetadata?: Model.ThingMetadata;
}
const ShipInfo = ({ thingMetadata }: ShipInfoProps) => {
const { t } = useI18n();
const { colors, utils } = useAppTheme();
const isDark = utils.isDark;
// Định nghĩa màu sắc theo trạng thái - hỗ trợ cả light và dark theme
const statusConfig = {
normal: {
dotColor: colors.success,
badgeColor: isDark ? "rgba(52, 199, 89, 0.2)" : "#dcfce7",
badgeTextColor: isDark ? "#30D158" : "#15803d",
badgeText: "Bình thường",
},
warning: {
dotColor: colors.warning,
badgeColor: isDark ? "rgba(255, 102, 0, 0.2)" : "#fef3c7",
badgeTextColor: isDark ? "#ff9500" : "#b45309",
badgeText: "Cảnh báo",
},
danger: {
dotColor: colors.error,
badgeColor: isDark ? "rgba(255, 69, 58, 0.2)" : "#fee2e2",
badgeTextColor: isDark ? "#FF453A" : "#b91c1c",
badgeText: "Nguy hiểm",
},
};
const getThingStatus = () => {
switch (thingMetadata?.state_level) {
case STATUS_NORMAL:
return "normal";
case STATUS_WARNING:
return "warning";
case STATUS_DANGEROUS:
return "danger";
default:
return "normal";
}
};
const gpsData: Model.GPSResponse = JSON.parse(thingMetadata?.gps || "{}");
const currentStatus = statusConfig[getThingStatus()];
// Format tọa độ
const formatCoordinate = (lat: number, lon: number) => {
const latDir = lat >= 0 ? "N" : "S";
const lonDir = lon >= 0 ? "E" : "W";
return `${Math.abs(lat).toFixed(4)}°${latDir}, ${Math.abs(lon).toFixed(
4
)}°${lonDir}`;
};
return (
<View className="px-4 py-3">
{/* Header: Tên tàu và trạng thái */}
<View className="flex-row items-center justify-between mb-3">
<View className="flex-row items-center gap-2">
{/* Status dot */}
<View
style={{
height: 12,
width: 12,
borderRadius: 6,
backgroundColor: currentStatus.dotColor,
}}
/>
{/* Tên tàu */}
<Text
style={{
fontSize: 18,
fontWeight: "600",
color: colors.text,
}}
>
{thingMetadata?.ship_name}
</Text>
</View>
{/* Badge trạng thái */}
<View
style={{
paddingHorizontal: 12,
paddingVertical: 4,
borderRadius: 9999,
backgroundColor: currentStatus.badgeColor,
}}
>
<Text
style={{
fontSize: 14,
fontWeight: "500",
color: currentStatus.badgeTextColor,
}}
>
{currentStatus.badgeText}
</Text>
</View>
</View>
{/* Tốc độ và hướng */}
<View className="flex-row items-center justify-between gap-2 mb-3">
<View className="flex-row items-center gap-2 w-2/3">
<Ionicons name="speedometer-outline" size={16} color={colors.icon} />
<Text style={{ fontSize: 14, color: colors.textSecondary }}>
{kmhToKnot(gpsData.s || 0)} {t("home.speed_units")}
</Text>
</View>
<View className="flex-row items-start gap-2 w-1/3 ">
<Ionicons name="compass-outline" size={16} color={colors.icon} />
<Text style={{ fontSize: 14, color: colors.textSecondary }}>
{gpsData.h}°
</Text>
</View>
</View>
{/* Tọa độ */}
<View className="flex-row items-center justify-between gap-2 mb-2">
<View className="flex-row items-center gap-2 w-2/3">
<Ionicons name="location-outline" size={16} color={colors.icon} />
<Text style={{ fontSize: 14, color: colors.textSecondary }}>
{convertToDMS(gpsData.lat || 0, true)},
{convertToDMS(gpsData.lon || 0, false)}
</Text>
</View>
<View className=" flex-row items-start gap-2 w-1/3 ">
<Ionicons name="time-outline" size={16} color={colors.icon} />
<Text style={{ fontSize: 14, color: colors.textSecondary }}>
{formatRelativeTime(gpsData.t)}
</Text>
</View>
</View>
{/* Trạng thái */}
{thingMetadata?.state !== "" && (
<View className="flex-row items-center gap-2">
<ThemedText style={{ color: colors.textSecondary, fontSize: 15 }}>
Trạng thái:
</ThemedText>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
style={{ flex: 1 }}
>
<ThemedText style={{ color: colors.text, fontSize: 15 }}>
{thingMetadata?.state || "-"}
</ThemedText>
</ScrollView>
</View>
)}
</View>
);
};
export default ShipInfo;