Cập nhật tab Nhật ký ( CRUD chuyến đi, CRUD thuyền viên trong chuyến đi )

This commit is contained in:
2025-12-29 15:56:47 +07:00
parent 190e44b09e
commit 871360af49
24 changed files with 1451 additions and 407 deletions

View File

@@ -9,13 +9,13 @@ import {
import { Ionicons } from "@expo/vector-icons";
import { useTripStatusConfig } from "./types";
import { useThings } from "@/state/use-thing";
import { useShip } from "@/state/use-ship";
import dayjs from "dayjs";
import { useI18n } from "@/hooks/use-i18n";
import { useThemeContext } from "@/hooks/use-theme-context";
interface TripCardProps {
trip: Model.Trip;
onPress?: () => void;
onView?: () => void;
onEdit?: () => void;
onTeam?: () => void;
@@ -25,7 +25,6 @@ interface TripCardProps {
export default function TripCard({
trip,
onPress,
onView,
onEdit,
onTeam,
@@ -35,6 +34,7 @@ export default function TripCard({
const { t } = useI18n();
const { colors } = useThemeContext();
const { things } = useThings();
const { ships } = useShip();
const TRIP_STATUS_CONFIG = useTripStatusConfig();
// Tìm thing có id trùng với vms_id của trip
@@ -42,6 +42,9 @@ export default function TripCard({
(thing) => thing.id === trip.vms_id
);
// Tìm ship để lấy reg_number
const shipOfTrip = ships?.find((s) => s.id === trip.ship_id);
// Lấy config status từ trip_status (number)
const statusKey = trip.trip_status as keyof typeof TRIP_STATUS_CONFIG;
const statusConfig = TRIP_STATUS_CONFIG[statusKey] || {
@@ -54,7 +57,7 @@ export default function TripCard({
// Determine which actions to show based on status
const showEdit = trip.trip_status === 0 || trip.trip_status === 1;
const showSend = trip.trip_status === 0;
const showDelete = trip.trip_status === 1;
const showDelete = trip.trip_status === 1 || trip.trip_status === 2;
const themedStyles = {
card: {
@@ -90,7 +93,9 @@ export default function TripCard({
color={statusConfig.textColor}
/>
<View style={styles.titleContainer}>
<Text style={[styles.title, themedStyles.title]}>{trip.name}</Text>
<Text style={[styles.title, themedStyles.title]}>
{trip.name}
</Text>
</View>
</View>
<View
@@ -117,14 +122,27 @@ export default function TripCard({
{/* Info Grid */}
<View style={styles.infoGrid}>
<View style={styles.infoRow}>
<Text style={[styles.label, themedStyles.label]}>{t("diary.tripCard.shipName")}</Text>
<Text style={[styles.label, themedStyles.label]}>
{t("diary.tripCard.shipName")}
</Text>
<Text style={[styles.value, themedStyles.value]}>
{thingOfTrip?.metadata?.ship_name /* hoặc trip.ship_id */}
</Text>
</View>
<View style={styles.infoRow}>
<Text style={[styles.label, themedStyles.label]}>{t("diary.tripCard.departure")}</Text>
<Text style={[styles.label, themedStyles.label]}>
{t("diary.tripCard.shipCode")}
</Text>
<Text style={[styles.value, themedStyles.value]}>
{shipOfTrip?.reg_number || "-"}
</Text>
</View>
<View style={styles.infoRow}>
<Text style={[styles.label, themedStyles.label]}>
{t("diary.tripCard.departure")}
</Text>
<Text style={[styles.value, themedStyles.value]}>
{trip.departure_time
? dayjs(trip.departure_time).format("DD/MM/YYYY HH:mm")
@@ -133,7 +151,9 @@ export default function TripCard({
</View>
<View style={styles.infoRow}>
<Text style={[styles.label, themedStyles.label]}>{t("diary.tripCard.return")}</Text>
<Text style={[styles.label, themedStyles.label]}>
{t("diary.tripCard.return")}
</Text>
{/* FIXME: trip.returnDate không có trong dữ liệu API, cần mapping từ trip.arrival_time */}
<Text style={[styles.value, themedStyles.value]}>
{trip.arrival_time
@@ -153,7 +173,9 @@ export default function TripCard({
activeOpacity={0.7}
>
<Ionicons name="eye-outline" size={20} color={colors.textSecondary} />
<Text style={[styles.actionText, themedStyles.actionText]}>{t("diary.tripCard.view")}</Text>
<Text style={[styles.actionText, themedStyles.actionText]}>
{t("diary.tripCard.view")}
</Text>
</TouchableOpacity>
{showEdit && (
@@ -162,8 +184,14 @@ export default function TripCard({
onPress={onEdit}
activeOpacity={0.7}
>
<Ionicons name="create-outline" size={20} color={colors.textSecondary} />
<Text style={[styles.actionText, themedStyles.actionText]}>{t("diary.tripCard.edit")}</Text>
<Ionicons
name="create-outline"
size={20}
color={colors.textSecondary}
/>
<Text style={[styles.actionText, themedStyles.actionText]}>
{t("diary.tripCard.edit")}
</Text>
</TouchableOpacity>
)}
@@ -172,8 +200,14 @@ export default function TripCard({
onPress={onTeam}
activeOpacity={0.7}
>
<Ionicons name="people-outline" size={20} color={colors.textSecondary} />
<Text style={[styles.actionText, themedStyles.actionText]}>{t("diary.tripCard.team")}</Text>
<Ionicons
name="people-outline"
size={20}
color={colors.textSecondary}
/>
<Text style={[styles.actionText, themedStyles.actionText]}>
{t("diary.tripCard.team")}
</Text>
</TouchableOpacity>
{showSend && (
@@ -182,8 +216,14 @@ export default function TripCard({
onPress={onSend}
activeOpacity={0.7}
>
<Ionicons name="send-outline" size={20} color={colors.textSecondary} />
<Text style={[styles.actionText, themedStyles.actionText]}>{t("diary.tripCard.send")}</Text>
<Ionicons
name="send-outline"
size={20}
color={colors.textSecondary}
/>
<Text style={[styles.actionText, themedStyles.actionText]}>
{t("diary.tripCard.send")}
</Text>
</TouchableOpacity>
)}
@@ -194,7 +234,9 @@ export default function TripCard({
activeOpacity={0.7}
>
<Ionicons name="trash-outline" size={20} color={colors.error} />
<Text style={[styles.actionText, styles.deleteText]}>{t("diary.tripCard.delete")}</Text>
<Text style={[styles.actionText, styles.deleteText]}>
{t("diary.tripCard.delete")}
</Text>
</TouchableOpacity>
)}
</View>