Files
sgw-owner-app/components/ButtonCreateNewHaulOrTrip.tsx
2025-11-28 16:59:57 +07:00

214 lines
5.5 KiB
TypeScript

import { queryGpsData } from "@/controller/DeviceController";
import {
queryStartNewHaul,
queryUpdateTripState,
} from "@/controller/TripController";
import { useI18n } from "@/hooks/use-i18n";
import {
showErrorToast,
showSuccessToast,
showWarningToast,
} from "@/services/toast_service";
import { useTrip } from "@/state/use-trip";
import { AntDesign } from "@expo/vector-icons";
import React, { useEffect, useState } from "react";
import { Alert, StyleSheet, View } from "react-native";
import IconButton from "./IconButton";
import CreateOrUpdateHaulModal from "./tripInfo/modal/CreateOrUpdateHaulModal";
interface StartButtonProps {
gpsData?: Model.GPSResponse;
onPress?: () => void;
}
interface a {
fishingLogs?: Model.FishingLogInfo[] | null;
onCallback?: (fishingLogs: Model.FishingLogInfo[]) => void;
isEditing?: boolean;
}
const ButtonCreateNewHaulOrTrip: React.FC<StartButtonProps> = ({
gpsData,
onPress,
}) => {
const [isStarted, setIsStarted] = useState(false);
const [isFinishHaulModalOpen, setIsFinishHaulModalOpen] = useState(false);
const { t } = useI18n();
const { trip, getTrip } = useTrip();
useEffect(() => {
getTrip();
}, []);
const checkHaulFinished = () => {
return trip?.fishing_logs?.some((h) => h.status === 0);
};
const handlePress = () => {
if (isStarted) {
Alert.alert(t("trip.endHaulTitle"), t("trip.endHaulConfirm"), [
{
text: t("trip.cancelButton"),
style: "cancel",
},
{
text: t("trip.endButton"),
onPress: () => {
setIsStarted(false);
Alert.alert(t("trip.successTitle"), t("trip.endHaulSuccess"));
},
},
]);
} else {
Alert.alert(t("trip.startHaulTitle"), t("trip.startHaulConfirm"), [
{
text: t("trip.cancelButton"),
style: "cancel",
},
{
text: t("trip.startButton"),
onPress: () => {
setIsStarted(true);
Alert.alert(t("trip.successTitle"), t("trip.startHaulSuccess"));
},
},
]);
}
if (onPress) {
onPress();
}
};
const handleStartTrip = async (state: number, note?: string) => {
if (trip?.trip_status !== 2) {
showWarningToast(t("trip.alreadyStarted"));
return;
}
try {
const resp = await queryUpdateTripState({
status: state,
note: note || "",
});
if (resp.status === 200) {
showSuccessToast(t("trip.startTripSuccess"));
await getTrip();
}
} catch (error) {
console.error("Error stating trip :", error);
showErrorToast("");
}
};
const createNewHaul = async () => {
if (trip?.fishing_logs?.some((f) => f.status === 0)) {
showWarningToast(t("trip.finishCurrentHaul"));
return;
}
if (!gpsData) {
const response = await queryGpsData();
gpsData = response.data;
}
try {
const body: Model.NewFishingLogRequest = {
trip_id: trip?.id || "",
start_at: new Date(),
start_lat: gpsData.lat,
start_lon: gpsData.lon,
weather_description: t("trip.weatherDescription"),
};
const resp = await queryStartNewHaul(body);
if (resp.status === 200) {
showSuccessToast(t("trip.startHaulSuccess"));
await getTrip();
} else {
showErrorToast(t("trip.createHaulFailed"));
}
} catch (error) {
console.log(error);
// showErrorToast(t("trip.createHaulFailed"));
}
};
// Không render gì nếu trip đã hoàn thành hoặc bị hủy
if (trip?.trip_status === 4 || trip?.trip_status === 5) {
return null;
}
return (
<View>
{trip?.trip_status === 2 ? (
<IconButton
icon={<AntDesign name="plus" />}
type="primary"
style={{ backgroundColor: "green", borderRadius: 10 }}
onPress={async () => handleStartTrip(3)}
>
{t("trip.startTrip")}
</IconButton>
) : checkHaulFinished() ? (
<IconButton
icon={<AntDesign name="plus" color={"white"} />}
type="primary"
style={{ borderRadius: 10 }}
onPress={() => setIsFinishHaulModalOpen(true)}
>
{t("trip.endHaul")}
</IconButton>
) : (
<IconButton
icon={<AntDesign name="plus" color={"white"} />}
type="primary"
style={{ borderRadius: 10 }}
onPress={async () => {
createNewHaul();
}}
>
{t("trip.startHaul")}
</IconButton>
)}
<CreateOrUpdateHaulModal
fishingLog={trip?.fishing_logs?.find((f) => f.status === 0)!}
fishingLogIndex={trip?.fishing_logs?.length!}
isVisible={isFinishHaulModalOpen}
onClose={function (): void {
setIsFinishHaulModalOpen(false);
}}
/>
</View>
);
};
const styles = StyleSheet.create({
button: {
backgroundColor: "#4ecdc4", // màu ngọc lam
borderRadius: 8,
paddingVertical: 10,
paddingHorizontal: 16,
alignSelf: "flex-start",
shadowColor: "#000",
shadowOpacity: 0.15,
shadowRadius: 3,
shadowOffset: { width: 0, height: 2 },
elevation: 3, // hiệu ứng nổi trên Android
},
buttonActive: {
backgroundColor: "#e74c3c", // màu đỏ khi đang hoạt động
},
content: {
flexDirection: "row",
alignItems: "center",
},
icon: {
marginRight: 6,
},
text: {
color: "#fff",
fontSize: 16,
fontWeight: "600",
},
});
export default ButtonCreateNewHaulOrTrip;