import React, { useEffect, useState, useMemo } from "react"; import { View, Text, StyleSheet, Platform, TouchableOpacity, ScrollView, ActivityIndicator, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import { useLocalSearchParams, useRouter } from "expo-router"; import { Ionicons } from "@expo/vector-icons"; import { useI18n } from "@/hooks/use-i18n"; import { useThemeContext } from "@/hooks/use-theme-context"; import { TRIP_STATUS_CONFIG } from "@/components/diary/types"; import { convertFishingGears, convertTripCosts, } from "@/utils/tripDataConverters"; // Reuse existing components import CrewList from "@/components/diary/TripCrewModal/CrewList"; import FishingGearList from "@/components/diary/TripFormModal/FishingGearList"; import MaterialCostList from "@/components/diary/TripFormModal/MaterialCostList"; // Section components import { SectionCard, AlertsSection, FishingLogsSection, BasicInfoSection, } from "@/components/diary/TripDetailSections"; export default function TripDetailPage() { const { t } = useI18n(); const { colors } = useThemeContext(); const router = useRouter(); const { tripId, tripData: tripDataParam } = useLocalSearchParams<{ tripId: string; tripData?: string; }>(); const [loading, setLoading] = useState(true); const [trip, setTrip] = useState(null); const [alerts] = useState([]); // TODO: Fetch from API // Parse trip data from params or fetch from API useEffect(() => { if (tripDataParam) { try { const parsedTrip = JSON.parse(tripDataParam) as Model.Trip; setTrip(parsedTrip); } catch (e) { console.error("Error parsing trip data:", e); } } // TODO: Fetch trip detail from API using tripId if not passed via params setLoading(false); }, [tripDataParam, tripId]); // Convert trip data to component format using memoization const fishingGears = useMemo( () => convertFishingGears(trip?.fishing_gears, "view"), [trip?.fishing_gears] ); const tripCosts = useMemo( () => convertTripCosts(trip?.trip_cost, "view"), [trip?.trip_cost] ); const statusConfig = useMemo(() => { const status = trip?.trip_status ?? 0; return TRIP_STATUS_CONFIG[status as keyof typeof TRIP_STATUS_CONFIG] || TRIP_STATUS_CONFIG[0]; }, [trip?.trip_status]); // Empty section component const EmptySection = ({ icon, message }: { icon: string; message: string }) => ( {message} ); // Render loading state if (loading) { return ( {t("common.loading")} ); } // Render error state if (!trip) { return (
router.back()} colors={colors} /> {t("diary.tripDetail.notFound")} ); } return ( {/* Header with status badge */} router.back()} style={styles.backButton}> {trip.name || t("diary.tripDetail.title")} {statusConfig.label} {/* Content */} {/* Basic Info */} {/* Alerts */} {/* Trip Costs */} {tripCosts.length > 0 ? ( {}} disabled hideTitle /> ) : ( )} {/* Fishing Gears */} {fishingGears.length > 0 ? ( {}} disabled hideTitle /> ) : ( )} {/* Crew List */} {trip.crews && trip.crews.length > 0 ? ( ) : ( )} {/* Fishing Logs */} ); } // Header component for reuse function Header({ title, onBack, colors, }: { title: string; onBack: () => void; colors: any; }) { return ( {title} ); } const styles = StyleSheet.create({ container: { flex: 1, }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", gap: 12, }, loadingText: { fontSize: 14, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16, paddingVertical: 12, borderBottomWidth: 1, }, backButton: { padding: 4, }, headerTitles: { flex: 1, alignItems: "center", gap: 6, }, title: { fontSize: 18, fontWeight: "700", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, statusBadge: { flexDirection: "row", alignItems: "center", gap: 4, paddingHorizontal: 10, paddingVertical: 4, borderRadius: 12, }, statusText: { fontSize: 11, fontWeight: "600", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, placeholder: { width: 32, }, content: { flex: 1, }, contentContainer: { padding: 16, paddingBottom: 40, }, errorContainer: { flex: 1, justifyContent: "center", alignItems: "center", gap: 12, paddingHorizontal: 20, }, errorText: { fontSize: 14, textAlign: "center", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, sectionInnerContent: { marginTop: 5, }, emptySection: { alignItems: "center", justifyContent: "center", paddingVertical: 24, gap: 8, }, emptyText: { fontSize: 14, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, });