136 lines
3.7 KiB
TypeScript
136 lines
3.7 KiB
TypeScript
import React from "react";
|
|
import { View, Text, StyleSheet, Platform } from "react-native";
|
|
import { Ionicons } from "@expo/vector-icons";
|
|
import { useI18n } from "@/hooks/use-i18n";
|
|
import { useThemeContext } from "@/hooks/use-theme-context";
|
|
|
|
interface BasicInfoSectionProps {
|
|
trip: Model.Trip;
|
|
}
|
|
|
|
/**
|
|
* Displays basic trip information like ship, dates, ports
|
|
*/
|
|
export default function BasicInfoSection({ trip }: BasicInfoSectionProps) {
|
|
const { t } = useI18n();
|
|
const { colors } = useThemeContext();
|
|
|
|
const formatDateTime = (dateStr?: string) => {
|
|
if (!dateStr) return "--";
|
|
const date = new Date(dateStr);
|
|
return date.toLocaleString("vi-VN", {
|
|
day: "2-digit",
|
|
month: "2-digit",
|
|
year: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
});
|
|
};
|
|
|
|
const infoItems = [
|
|
{
|
|
icon: "boat" as const,
|
|
label: t("diary.tripDetail.shipId"),
|
|
value: trip.vms_id || "--",
|
|
},
|
|
{
|
|
icon: "play-circle" as const,
|
|
label: t("diary.tripDetail.departureTime"),
|
|
value: formatDateTime(trip.departure_time),
|
|
},
|
|
{
|
|
icon: "stop-circle" as const,
|
|
label: t("diary.tripDetail.arrivalTime"),
|
|
value: formatDateTime(trip.arrival_time),
|
|
},
|
|
{
|
|
icon: "location" as const,
|
|
label: t("diary.tripDetail.departurePort"),
|
|
value: trip.departure_port_id ? `Cảng #${trip.departure_port_id}` : "--",
|
|
},
|
|
{
|
|
icon: "flag" as const,
|
|
label: t("diary.tripDetail.arrivalPort"),
|
|
value: trip.arrival_port_id ? `Cảng #${trip.arrival_port_id}` : "--",
|
|
},
|
|
{
|
|
icon: "map" as const,
|
|
label: t("diary.tripDetail.fishingGrounds"),
|
|
value: trip.fishing_ground_codes?.length > 0
|
|
? trip.fishing_ground_codes.join(", ")
|
|
: "--",
|
|
},
|
|
];
|
|
|
|
return (
|
|
<View style={[styles.container, { backgroundColor: colors.card, borderColor: colors.separator }]}>
|
|
<View style={styles.header}>
|
|
<Ionicons name="information-circle-outline" size={20} color={colors.primary} />
|
|
<Text style={[styles.title, { color: colors.text }]}>
|
|
{t("diary.tripDetail.basicInfo")}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.content}>
|
|
{infoItems.map((item, index) => (
|
|
<View key={index} style={styles.infoItem}>
|
|
<View style={styles.infoLabel}>
|
|
<Ionicons name={item.icon} size={16} color={colors.textSecondary} />
|
|
<Text style={[styles.infoLabelText, { color: colors.textSecondary }]}>
|
|
{item.label}
|
|
</Text>
|
|
</View>
|
|
<Text style={[styles.infoValue, { color: colors.text }]}>
|
|
{item.value}
|
|
</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
borderRadius: 12,
|
|
borderWidth: 1,
|
|
marginBottom: 16,
|
|
overflow: "hidden",
|
|
},
|
|
header: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
gap: 10,
|
|
paddingHorizontal: 16,
|
|
paddingVertical: 14,
|
|
},
|
|
title: {
|
|
fontSize: 16,
|
|
fontWeight: "600",
|
|
fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }),
|
|
},
|
|
content: {
|
|
paddingHorizontal: 16,
|
|
paddingBottom: 16,
|
|
gap: 12,
|
|
},
|
|
infoItem: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
},
|
|
infoLabel: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
gap: 8,
|
|
},
|
|
infoLabelText: {
|
|
fontSize: 13,
|
|
fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }),
|
|
},
|
|
infoValue: {
|
|
fontSize: 13,
|
|
fontWeight: "500",
|
|
fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }),
|
|
},
|
|
});
|