214 lines
5.5 KiB
TypeScript
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;
|