Cập nhật theme cho cảnh báo, giám sát

This commit is contained in:
2025-12-29 17:05:05 +07:00
parent 871360af49
commit bf261e70e4
6 changed files with 234 additions and 115 deletions

View File

@@ -1,5 +1,6 @@
import { AlarmData } from "@/app/(tabs)";
import { ThemedText } from "@/components/themed-text";
import { useAppTheme } from "@/hooks/use-app-theme";
import { formatTimestamp } from "@/services/time_service";
import { Ionicons } from "@expo/vector-icons";
import { useCallback } from "react";
@@ -14,61 +15,66 @@ interface AlarmCardProps {
}
// ============ Config ============
const ALARM_CONFIG: Record<
AlarmType,
{
icon: keyof typeof Ionicons.glyphMap;
label: string;
bgColor: string;
borderColor: string;
iconBgColor: string;
iconColor: string;
labelColor: string;
}
> = {
const getAlarmConfig = (isDark: boolean) => ({
entered: {
icon: "warning",
icon: "warning" as keyof typeof Ionicons.glyphMap,
label: "Xâm nhập",
bgColor: "bg-red-50",
borderColor: "border-red-200",
iconBgColor: "bg-red-100",
iconColor: "#DC2626",
labelColor: "text-red-600",
bgColor: isDark ? "rgba(220, 38, 38, 0.15)" : "#FEF2F2",
borderColor: isDark ? "rgba(220, 38, 38, 0.3)" : "#FECACA",
iconBgColor: isDark ? "rgba(220, 38, 38, 0.25)" : "#FEE2E2",
iconColor: isDark ? "#F87171" : "#DC2626",
labelColor: isDark ? "#F87171" : "#DC2626",
},
approaching: {
icon: "alert-circle",
icon: "alert-circle" as keyof typeof Ionicons.glyphMap,
label: "Tiếp cận",
bgColor: "bg-amber-50",
borderColor: "border-amber-200",
iconBgColor: "bg-amber-100",
iconColor: "#D97706",
labelColor: "text-amber-600",
bgColor: isDark ? "rgba(217, 119, 6, 0.15)" : "#FFFBEB",
borderColor: isDark ? "rgba(217, 119, 6, 0.3)" : "#FDE68A",
iconBgColor: isDark ? "rgba(217, 119, 6, 0.25)" : "#FEF3C7",
iconColor: isDark ? "#FBBF24" : "#D97706",
labelColor: isDark ? "#FBBF24" : "#D97706",
},
fishing: {
icon: "fish",
icon: "fish" as keyof typeof Ionicons.glyphMap,
label: "Đánh bắt",
bgColor: "bg-orange-50",
borderColor: "border-orange-200",
iconBgColor: "bg-orange-100",
iconColor: "#EA580C",
labelColor: "text-orange-600",
bgColor: isDark ? "rgba(234, 88, 12, 0.15)" : "#FFF7ED",
borderColor: isDark ? "rgba(234, 88, 12, 0.3)" : "#FED7AA",
iconBgColor: isDark ? "rgba(234, 88, 12, 0.25)" : "#FFEDD5",
iconColor: isDark ? "#FB923C" : "#EA580C",
labelColor: isDark ? "#FB923C" : "#EA580C",
},
};
});
// ============ AlarmCard Component ============
const AlarmCard = ({ alarm, onPress }: AlarmCardProps) => {
const config = ALARM_CONFIG[alarm.type];
const { colors, utils } = useAppTheme();
const isDark = utils.isDark;
const alarmConfig = getAlarmConfig(isDark);
const config = alarmConfig[alarm.type];
return (
<TouchableOpacity
onPress={onPress}
activeOpacity={0.7}
className={`rounded-2xl p-4 ${config.bgColor} ${config.borderColor} border shadow-sm`}
style={{
borderRadius: 16,
padding: 16,
backgroundColor: config.bgColor,
borderWidth: 1,
borderColor: config.borderColor,
}}
>
<View className="flex-row items-start gap-3">
{/* Icon Container */}
<View
className={`w-12 h-12 rounded-xl items-center justify-center ${config.iconBgColor}`}
style={{
width: 48,
height: 48,
borderRadius: 12,
alignItems: "center",
justifyContent: "center",
backgroundColor: config.iconBgColor,
}}
>
<Ionicons name={config.icon} size={24} color={config.iconColor} />
</View>
@@ -77,12 +83,31 @@ const AlarmCard = ({ alarm, onPress }: AlarmCardProps) => {
<View className="flex-1">
{/* Header: Ship name + Badge */}
<View className="flex-row items-center justify-between mb-1">
<ThemedText className="text-base font-bold text-gray-800 flex-1 mr-2">
<ThemedText
style={{
fontSize: 16,
fontWeight: "700",
color: colors.text,
flex: 1,
marginRight: 8,
}}
>
{alarm.ship_name || alarm.thing_id}
</ThemedText>
<View className={`px-2 py-1 rounded-full ${config.iconBgColor}`}>
<View
style={{
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 9999,
backgroundColor: config.iconBgColor,
}}
>
<ThemedText
className={`text-xs font-semibold ${config.labelColor}`}
style={{
fontSize: 12,
fontWeight: "600",
color: config.labelColor,
}}
>
{config.label}
</ThemedText>
@@ -90,15 +115,27 @@ const AlarmCard = ({ alarm, onPress }: AlarmCardProps) => {
</View>
{/* Zone Info */}
<ThemedText className="text-xs text-gray-600 mb-2" numberOfLines={2}>
<ThemedText
style={{
fontSize: 12,
color: colors.textSecondary,
marginBottom: 8,
}}
numberOfLines={2}
>
{alarm.zone.message || alarm.zone.zone_name}
</ThemedText>
{/* Footer: Zone ID + Time */}
<View className="flex-row items-center justify-between">
<View className="flex-row items-center gap-1">
<Ionicons name="time-outline" size={20} color="#6B7280" />
<ThemedText className="text-xs text-gray-500">
<Ionicons name="time-outline" size={20} color={colors.icon} />
<ThemedText
style={{
fontSize: 12,
color: colors.textSecondary,
}}
>
{formatTimestamp(alarm.zone.gps_time)}
</ThemedText>
</View>