Files
sgw-owner-app/components/diary/TripDetailSections/AlertsSection.tsx

157 lines
4.2 KiB
TypeScript

import React from "react";
import { View, Text, StyleSheet, Platform } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { useThemeContext } from "@/hooks/use-theme-context";
import { useI18n } from "@/hooks/use-i18n";
import SectionCard from "./SectionCard";
interface AlertsSectionProps {
alerts?: Model.Alarm[];
}
export default function AlertsSection({ alerts = [] }: AlertsSectionProps) {
const { t } = useI18n();
const { colors } = useThemeContext();
const getAlertLevelColor = (level?: number) => {
switch (level) {
case 0:
return { bg: "#FEF3C7", text: "#92400E" }; // Warning - Yellow
case 1:
return { bg: "#FEE2E2", text: "#991B1B" }; // Error - Red
case 2:
return { bg: "#DBEAFE", text: "#1E40AF" }; // Info - Blue
default:
return { bg: "#F3F4F6", text: "#4B5563" }; // Default - Gray
}
};
const formatTime = (timestamp?: number) => {
if (!timestamp) return "--";
const date = new Date(timestamp * 1000);
return date.toLocaleString("vi-VN");
};
return (
<SectionCard
title={t("diary.tripDetail.alerts")}
icon="warning-outline"
count={alerts.length}
collapsible
defaultExpanded={alerts.length > 0}
>
{alerts.length === 0 ? (
<View style={styles.emptyContainer}>
<Ionicons name="checkmark-circle-outline" size={40} color={colors.success || "#22C55E"} />
<Text style={[styles.emptyText, { color: colors.textSecondary }]}>
{t("diary.tripDetail.noAlerts")}
</Text>
</View>
) : (
<View style={styles.list}>
{alerts.map((alert, index) => {
const levelColor = getAlertLevelColor(alert.level);
return (
<View
key={alert.id || index}
style={[styles.alertItem, { backgroundColor: levelColor.bg }]}
>
<View style={styles.alertHeader}>
<View style={styles.alertInfo}>
<Ionicons
name={alert.level === 1 ? "alert-circle" : "warning"}
size={18}
color={levelColor.text}
/>
<Text style={[styles.alertName, { color: levelColor.text }]}>
{alert.name || t("diary.tripDetail.unknownAlert")}
</Text>
</View>
{alert.confirmed && (
<View style={[styles.confirmedBadge, { backgroundColor: colors.success || "#22C55E" }]}>
<Text style={styles.confirmedText}>{t("diary.tripDetail.confirmed")}</Text>
</View>
)}
</View>
<Text style={[styles.alertTime, { color: levelColor.text }]}>
{formatTime(alert.time)}
</Text>
</View>
);
})}
</View>
)}
</SectionCard>
);
}
const styles = StyleSheet.create({
emptyContainer: {
alignItems: "center",
justifyContent: "center",
paddingVertical: 24,
gap: 8,
},
emptyText: {
fontSize: 14,
fontFamily: Platform.select({
ios: "System",
android: "Roboto",
default: "System",
}),
},
list: {
gap: 10,
},
alertItem: {
padding: 12,
borderRadius: 8,
},
alertHeader: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginBottom: 4,
},
alertInfo: {
flexDirection: "row",
alignItems: "center",
gap: 8,
flex: 1,
},
alertName: {
fontSize: 14,
fontWeight: "600",
flex: 1,
fontFamily: Platform.select({
ios: "System",
android: "Roboto",
default: "System",
}),
},
alertTime: {
fontSize: 12,
marginLeft: 26,
fontFamily: Platform.select({
ios: "System",
android: "Roboto",
default: "System",
}),
},
confirmedBadge: {
paddingHorizontal: 8,
paddingVertical: 2,
borderRadius: 4,
},
confirmedText: {
color: "#FFFFFF",
fontSize: 11,
fontWeight: "600",
fontFamily: Platform.select({
ios: "System",
android: "Roboto",
default: "System",
}),
},
});