import React, { useEffect, useMemo } 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"; import { useShip } from "@/state/use-ship"; import { usePort } from "@/state/use-ports"; import { useGroup } from "@/state/use-group"; import { filterPortsByProvinceCode } from "@/utils/tripDataConverters"; 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(); // Get data from zustand stores const { ships, getShip } = useShip(); const { ports, getPorts } = usePort(); const { groups, getUserGroups } = useGroup(); // Fetch data if not available useEffect(() => { if (!ships) { getShip(); } }, [ships, getShip]); useEffect(() => { if (!ports) { getPorts(); } }, [ports, getPorts]); useEffect(() => { if (!groups) { getUserGroups(); } }, [groups, getUserGroups]); // Filter ports by province codes from groups const filteredPorts = useMemo(() => { return filterPortsByProvinceCode(ports, groups); }, [ports, groups]); // Get ship name by ship_id const shipName = useMemo(() => { if (!trip?.ship_id || !ships) return "--"; const ship = ships.find((s) => s.id === trip.ship_id); return ship?.name || "--"; }, [trip?.ship_id, ships]); // Get ship code (reg_number) by ship_id const shipCode = useMemo(() => { if (!trip?.ship_id || !ships) return "--"; const ship = ships.find((s) => s.id === trip.ship_id); return ship?.reg_number || "--"; }, [trip?.ship_id, ships]); // Get port name by ID const getPortName = (portId: number): string => { const port = filteredPorts.find((p) => p.id === portId); return port?.name || "--"; }; 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.shipName"), value: shipName, }, { icon: "barcode" as const, label: t("diary.tripDetail.shipCode"), value: shipCode, }, { 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: getPortName(trip.departure_port_id), }, { icon: "flag" as const, label: t("diary.tripDetail.arrivalPort"), value: getPortName(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 ( {t("diary.tripDetail.basicInfo")} {infoItems.map((item, index) => ( {item.label} {item.value} ))} ); } 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", }), }, });