import React, { useState } from "react"; import { View, Text, Modal, TouchableOpacity, StyleSheet, Platform, ScrollView, } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { useI18n } from "@/hooks/use-i18n"; import { useThemeContext } from "@/hooks/use-theme-context"; import FishingGearList from "@/components/diary/addTripModal/FishingGearList"; import MaterialCostList from "@/components/diary/addTripModal/MaterialCostList"; import TripNameInput from "@/components/diary/addTripModal/TripNameInput"; import TripDurationPicker from "@/components/diary/addTripModal/TripDurationPicker"; import PortSelector from "@/components/diary/addTripModal/PortSelector"; import BasicInfoInput from "@/components/diary/addTripModal/BasicInfoInput"; import ShipSelector from "./ShipSelector"; import AutoFillSection from "./AutoFillSection"; // Internal component interfaces export interface FishingGear { id: string; name: string; number: string; // Changed from quantity to number (string) } export interface TripCost { id: string; type: string; amount: number; unit: string; cost_per_unit: number; total_cost: number; } // API body interface export interface TripAPIBody { thing_id?: string; // Ship ID name: string; departure_time: string; // ISO string departure_port_id: number; arrival_time: string; // ISO string arrival_port_id: number; fishing_ground_codes: number[]; // Array of numbers fishing_gears: Array<{ name: string; number: string; }>; trip_cost: Array<{ type: string; amount: number; unit: string; cost_per_unit: number; total_cost: number; }>; } interface AddTripModalProps { visible: boolean; onClose: () => void; } export default function AddTripModal({ visible, onClose }: AddTripModalProps) { const { t } = useI18n(); const { colors } = useThemeContext(); // Form state const [selectedShipId, setSelectedShipId] = useState(""); const [tripName, setTripName] = useState(""); const [fishingGears, setFishingGears] = useState([]); const [tripCosts, setTripCosts] = useState([]); const [startDate, setStartDate] = useState(null); const [endDate, setEndDate] = useState(null); const [departurePortId, setDeparturePortId] = useState(1); const [arrivalPortId, setArrivalPortId] = useState(1); const [fishingGroundCodes, setFishingGroundCodes] = useState(""); // Input as string, convert to array const handleCancel = () => { // Reset form setSelectedShipId(""); setTripName(""); setFishingGears([]); setTripCosts([]); setStartDate(null); setEndDate(null); setDeparturePortId(1); setArrivalPortId(1); setFishingGroundCodes(""); onClose(); }; // Handle auto-fill from last trip data const handleAutoFill = (tripData: Model.Trip, selectedThingId: string) => { // Fill ship ID (use the thingId from the selected ship for ShipSelector) setSelectedShipId(selectedThingId); // Fill trip name if (tripData.name) { setTripName(tripData.name); } // Fill fishing gears if (tripData.fishing_gears && Array.isArray(tripData.fishing_gears)) { const gears: FishingGear[] = tripData.fishing_gears.map((gear, index) => ({ id: `auto-${Date.now()}-${index}`, name: gear.name || "", number: gear.number?.toString() || "", })); setFishingGears(gears); } // Fill trip costs if (tripData.trip_cost && Array.isArray(tripData.trip_cost)) { const costs: TripCost[] = tripData.trip_cost.map((cost, index) => ({ id: `auto-${Date.now()}-${index}`, type: cost.type || "", amount: cost.amount || 0, unit: cost.unit || "", cost_per_unit: cost.cost_per_unit || 0, total_cost: cost.total_cost || 0, })); setTripCosts(costs); } // Fill departure and arrival ports if (tripData.departure_port_id) { setDeparturePortId(tripData.departure_port_id); } if (tripData.arrival_port_id) { setArrivalPortId(tripData.arrival_port_id); } // Fill fishing ground codes if (tripData.fishing_ground_codes && Array.isArray(tripData.fishing_ground_codes)) { setFishingGroundCodes(tripData.fishing_ground_codes.join(", ")); } }; const handleSubmit = () => { // Parse fishing ground codes from comma-separated string to array of numbers const fishingGroundCodesArray = fishingGroundCodes .split(",") .map((code) => parseInt(code.trim())) .filter((code) => !isNaN(code)); // Format API body const apiBody: TripAPIBody = { thing_id: selectedShipId || undefined, name: tripName, departure_time: startDate ? startDate.toISOString() : "", departure_port_id: departurePortId, arrival_time: endDate ? endDate.toISOString() : "", arrival_port_id: arrivalPortId, fishing_ground_codes: fishingGroundCodesArray, fishing_gears: fishingGears.map((gear) => ({ name: gear.name, number: gear.number, })), trip_cost: tripCosts.map((cost) => ({ type: cost.type, amount: cost.amount, unit: cost.unit, cost_per_unit: cost.cost_per_unit, total_cost: cost.total_cost, })), }; // Simulate API call - log the formatted data console.log("=== Submitting Trip Data (API Format) ==="); console.log(JSON.stringify(apiBody, null, 2)); console.log("=== End Trip Data ==="); // Reset form and close modal handleCancel(); }; const themedStyles = { modalContainer: { backgroundColor: colors.card, }, header: { borderBottomColor: colors.separator, }, title: { color: colors.text, }, footer: { borderTopColor: colors.separator, }, cancelButton: { backgroundColor: colors.backgroundSecondary, }, cancelButtonText: { color: colors.textSecondary, }, submitButton: { backgroundColor: colors.primary, }, }; return ( {/* Header */} {t("diary.addTrip")} {/* Content */} {/* Auto Fill Section */} {/* Ship Selector */} {/* Trip Name */} {/* Fishing Gear List */} {/* Trip Cost List */} {/* Trip Duration */} {/* Port Selector */} {/* Fishing Ground Codes */} {/* Footer */} {t("common.cancel")} {t("diary.createTrip")} ); } const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: "rgba(0, 0, 0, 0.5)", justifyContent: "flex-end", }, modalContainer: { borderTopLeftRadius: 24, borderTopRightRadius: 24, maxHeight: "90%", shadowColor: "#000", shadowOffset: { width: 0, height: -4, }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 8, }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 20, paddingVertical: 16, borderBottomWidth: 1, }, closeButton: { padding: 4, }, title: { fontSize: 18, fontWeight: "700", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, placeholder: { width: 32, }, content: { padding: 20, }, footer: { flexDirection: "row", gap: 12, padding: 20, borderTopWidth: 1, }, cancelButton: { flex: 1, paddingVertical: 14, borderRadius: 12, alignItems: "center", }, cancelButtonText: { fontSize: 16, fontWeight: "600", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, submitButton: { flex: 1, paddingVertical: 14, borderRadius: 12, alignItems: "center", }, submitButtonText: { fontSize: 16, fontWeight: "600", color: "#FFFFFF", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System", }), }, });