import React, { useEffect, useState, useCallback } from "react"; import { View, Text, StyleSheet, Platform, TouchableOpacity, ActivityIndicator, Alert, } 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 { queryTripCrew } from "@/controller/TripCrewController"; import CrewList from "@/components/diary/TripCrewModal/CrewList"; import AddEditCrewModal from "@/components/diary/TripCrewModal/AddEditCrewModal"; export default function TripCrewPage() { const { t } = useI18n(); const { colors } = useThemeContext(); const router = useRouter(); const { tripId, tripName } = useLocalSearchParams<{ tripId: string; tripName?: string }>(); // State const [loading, setLoading] = useState(false); const [crews, setCrews] = useState([]); const [error, setError] = useState(null); // Add/Edit modal state const [showAddEditModal, setShowAddEditModal] = useState(false); const [editingCrew, setEditingCrew] = useState(null); // Fetch crew data const fetchCrewData = useCallback(async () => { if (!tripId) return; setLoading(true); setError(null); try { const response = await queryTripCrew(tripId); const data = response.data as any; if (data?.trip_crews && Array.isArray(data.trip_crews)) { setCrews(data.trip_crews); } else if (Array.isArray(data)) { setCrews(data); } else { setCrews([]); } } catch (err) { console.error("Error fetching crew:", err); setError(t("diary.crew.fetchError")); setCrews([]); } finally { setLoading(false); } }, [tripId, t]); useEffect(() => { fetchCrewData(); }, [fetchCrewData]); // Add crew handler const handleAddCrew = () => { setEditingCrew(null); setShowAddEditModal(true); }; // Edit crew handler const handleEditCrew = (crew: Model.TripCrews) => { setEditingCrew(crew); setShowAddEditModal(true); }; // Delete crew handler const handleDeleteCrew = (crew: Model.TripCrews) => { Alert.alert( t("diary.crew.deleteConfirmTitle"), t("diary.crew.deleteConfirmMessage", { name: crew.Person?.name || "" }), [ { text: t("common.cancel"), style: "cancel" }, { text: t("common.delete"), style: "destructive", onPress: async () => { // TODO: Call delete API when available setCrews((prev) => prev.filter((c) => c.PersonalID !== crew.PersonalID)); Alert.alert(t("common.success"), t("diary.crew.deleteSuccess")); }, }, ] ); }; // Save crew handler const handleSaveCrew = async (formData: any) => { // TODO: Call API to add/edit crew when available await fetchCrewData(); }; const themedStyles = { container: { backgroundColor: colors.background }, header: { backgroundColor: colors.card, borderBottomColor: colors.separator }, title: { color: colors.text }, subtitle: { color: colors.textSecondary }, }; return ( {/* Header */} router.back()} style={styles.backButton}> {t("diary.crew.title")} {tripName && ( {tripName} )} {/* Content */} {loading ? ( {t("diary.crew.loading")} ) : error ? ( {error} {t("common.retry")} ) : ( )} {/* Footer - Crew count */} {t("diary.crew.totalMembers", { count: crews.length })} {/* Add/Edit Crew Modal */} { setShowAddEditModal(false); setEditingCrew(null); }} onSave={handleSaveCrew} mode={editingCrew ? "edit" : "add"} initialData={ editingCrew ? { personalId: editingCrew.PersonalID, name: editingCrew.Person?.name || "", phone: editingCrew.Person?.phone || "", email: editingCrew.Person?.email || "", address: editingCrew.Person?.address || "", role: editingCrew.role || "crew", note: editingCrew.note || "", } : undefined } /> ); } const styles = StyleSheet.create({ container: { flex: 1, }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16, paddingVertical: 12, borderBottomWidth: 1, }, backButton: { padding: 4, }, addButton: { padding: 4, }, headerTitles: { flex: 1, alignItems: "center", }, title: { fontSize: 18, fontWeight: "700", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, subtitle: { fontSize: 13, marginTop: 2, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, content: { flex: 1, padding: 16, }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", gap: 12, }, loadingText: { fontSize: 14, fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, 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" }), }, retryButton: { marginTop: 8, paddingHorizontal: 24, paddingVertical: 10, borderRadius: 8, }, retryButtonText: { color: "#FFFFFF", fontSize: 14, fontWeight: "600", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, footer: { borderTopWidth: 1, paddingHorizontal: 20, paddingTop: 16, paddingBottom: 30, }, countContainer: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8, }, countText: { fontSize: 14, fontWeight: "600", fontFamily: Platform.select({ ios: "System", android: "Roboto", default: "System" }), }, });