/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useState } from "react"; import { Modal } from "react-bootstrap"; import PlaceOrderModal from "../../../Modal/PlaceOrderModal"; import PaymentConfirmModal from "../../../Modal/PaymentConfirmModal"; import { createOrder, makePayment, placeOrderPreview, } from "../../../../Api/OrderApi"; import { useAppSelector } from "@/Redux/Hooks"; import HourGlassLoader from "../../../Loader/Loader"; import { useDispatch } from "react-redux"; import { resetOrderData, saveStepData, } from "@/Redux/Reducers/CreateOrderSlice"; import Swal from "sweetalert2"; import OrderSuccessModal from "../../../Modal/OrderSuccessModal"; import { useRouter, useSearchParams } from "next/navigation"; import { toast } from "react-toastify"; import { OrderFlowType } from "@/Constant/enums"; interface CreateOrderFooterProps { step: number; setStep: (step: number) => void; validation: () => void; backButton?: boolean; backButtonFn?: () => void; isEditMode?: boolean; defaultOrderDetails?: any; handleFuturePickupConfirm?: any; } interface CreateOrderState { step1: Record; step2: Record; step3: Record; } const CreateOrderFooter: React.FC = ({ step, setStep, validation, backButton = false, backButtonFn = () => {}, defaultOrderDetails = {}, isEditMode = false, handleFuturePickupConfirm = () => {}, }) => { const router = useRouter(); const [savedOrder, setSavedOrder] = useState([]); const dispatch = useDispatch(); const searchParams: any = useSearchParams(); const orderId: any = searchParams?.get("orderId") || ""; const createOrderData: any = useAppSelector((state) => state.createOrder); const handleSave = (stepKey: keyof CreateOrderState, data: any) => { const updatedStepData = { ...createOrderData[stepKey], // Merge existing step data ...data, // Add/update new fields }; dispatch(saveStepData({ step: stepKey, data: updatedStepData })); // ✅ Send merged }; const [isLoading, setIsLoading] = React.useState(false); const [paymentSuccess, setPaymentSuccess] = React.useState(false); const { step1, step2, step3 } = useAppSelector((state) => state.createOrder); const [openPlaceOrderModal, setOpenPlaceOrderModal] = React.useState(false); const [openOrderSuccessModal, setOpenOrderSuccessModal] = React.useState(false); const togglePlaceOrder = () => setOpenPlaceOrderModal(!openPlaceOrderModal); const toggleOrderSuccessModal = () => setOpenOrderSuccessModal(!openOrderSuccessModal); const [openPaymentConfirmModal, setOpenPaymentConfirmModal] = React.useState(false); const togglePaymentConfirm = () => setOpenPaymentConfirmModal(!openPaymentConfirmModal); const handleAddMore = async () => { window.location.href = "/create-order"; dispatch(resetOrderData()); setStep(1); }; const handlePlaceOrder = async () => { // Validate service type availability before showing Swal if (!step1?.serviceType) { await Swal.fire({ icon: "error", title: "Service Not Available", text: `The selected service type is not available at this time. Please select a different service or try again during the allowed hours.`, confirmButtonText: "OK", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }); return; } setIsLoading(true); const response = await placeOrderPreview(); setIsLoading(false); if (response?.status) { // 2️⃣ If no draft orders, ask to unmark future pickup if (!response?.data?.numberOfDraftOrders) { Swal.fire({ title: "Unmark Future Pickup?", text: "No active draft order available. Do you want to unmark the future pickup and continue to place the order?", icon: "warning", showCancelButton: true, confirmButtonText: "Yes, continue", cancelButtonText: "No, cancel", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }).then(async (result) => { if (result.isConfirmed) { await handleFuturePickupConfirm(); toast.success( "Future pickup unmarked. You can now place the order." ); try { if (!response?.data?.calculatedTotalShippingCharge) { const result = await Swal.fire({ icon: "warning", title: "Shipping Charge Not Available", text: "Shipping charge could not be calculated at the moment. Do you still want to continue without it? Please contact admin or customer service if you're unsure.", showCancelButton: true, confirmButtonText: "Yes, Continue", cancelButtonText: "No, Go Back", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }); if (result.dismiss === Swal.DismissReason.cancel) { return; } } togglePlaceOrder(); handleSave("step3", { ...step3, orderPreview: response?.data }); } catch (error) { console.error("Error during API call:", error); } finally { setIsLoading(false); } } else { return; } }); return; // stop here, wait for user confirm } } const result = await Swal.fire({ title: "Are you finished adding orders?", html: `
You can click on ADD MORE button to add more orders and place them together.
`, icon: "question", showCancelButton: true, confirmButtonText: "No, Place Order", cancelButtonText: "Okay, Add More", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }); if (result.isDismissed) { // User closed the dialog without choosing return; } if (result.isConfirmed) { // Proceed with placing the order try { setIsLoading(true); const response = await placeOrderPreview(); if (response?.status) { if (!response?.data?.numberOfDraftOrders) { handleFuturePickupConfirm(); return toast.warning("Draft order not available"); } else if (!response?.data?.calculatedTotalShippingCharge) { const result = await Swal.fire({ icon: "warning", title: "Shipping Charge Not Available", text: "Shipping charge could not be calculated at the moment. Do you still want to continue without it? Please contact admin or customer service if you're unsure.", showCancelButton: true, confirmButtonText: "Yes, Continue", cancelButtonText: "No, Go Back", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }); if (result.dismiss === Swal.DismissReason.cancel) { return; } } togglePlaceOrder(); handleSave("step3", { ...step3, orderPreview: response?.data }); } else { Swal.fire({ icon: "error", title: "Oops...", text: response.message || "Something went wrong. Please try again.", confirmButtonText: "OK", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }); } } catch (error) { console.error("Error during API call:", error); } finally { setIsLoading(false); } } else if (result.dismiss === Swal.DismissReason.cancel) { // User chose to add more handleAddMore(); } }; const handleNext = async (isBack: boolean = false) => { try { if (step === 2 && !step3?.step3?.preview?.calculatedTotalShippingCharge) { const result = await Swal.fire({ icon: "warning", title: "Shipping Charge Not Available", text: "Shipping charge could not be calculated at the moment. Do you still want to continue without it? Please contact admin or customer service if you're unsure.", showCancelButton: true, confirmButtonText: "Yes, Continue", cancelButtonText: "No, Go Back", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, reverseButtons: true, }); if (result.dismiss === Swal.DismissReason.cancel) { return; } } // if(!step1?.package_details && isEditMode && defaultOrderDetails) { // } const error: any = await validation(); if (error) { let dataToSend: any = {}; switch (step) { case 1: dataToSend = (step1?.package_details?.length === 0 || step1?.packageDetails?.length === 0 || !step1?.package_details) && isEditMode && defaultOrderDetails ? { ...step1, ...defaultOrderDetails, packageDetails: defaultOrderDetails?.order_package_list, } : { ...step1 }; break; case 2: dataToSend = { ...step2 }; break; case 3: dataToSend = { ...step3 }; break; default: throw new Error("Invalid step"); } const packageDisable: any = searchParams.get("packageDisable"); const dataWithStep: any = { ...dataToSend, step: step === 2 ? 3 : step, }; if (packageDisable === "true") dataWithStep.orderFlowType = { id: OrderFlowType.Return, name: "Return", }; let updatedDataWithStep = dataWithStep; if (step1?.codDetails?.codEnabled) { updatedDataWithStep = { ...dataWithStep, codDetails: { ...(dataWithStep.codDetails ?? {}), codEnabled: step1.codDetails.codEnabled, codAmount: step1.codDetails.codAmount, }, }; } setIsLoading(true); const response = await createOrder( updatedDataWithStep, 0, step3?.step3, orderId ); if (response?.status) { if (step === 1) { const { service_type_details, draft_order_package_list = [], totalWeight, isCod, codAmount, } = response?.data || {}; const step1Data = { ...step1, serviceType: { id: service_type_details?.id, name: service_type_details?.name, }, packageDetails: draft_order_package_list.map((pkg: any) => ({ package_id: pkg?.package_id || 1, weight: pkg?.weight || "", package_description: pkg?.packageDescription || "", customer_input_package_value: pkg?.customerInputPackageValue || "", })), packageCount: draft_order_package_list?.length ?? 1, totalWeight: totalWeight || "", ...(isCod && { codDetails: { codEnabled: isCod, codAmount: codAmount, }, }), }; if (packageDisable === "true") step1Data.orderFlowType = { id: OrderFlowType.Return, name: "Return", }; handleSave("step1", step1Data); handleSave("step3", { step1: response?.data }); } if (step === 2) { if (isBack) { const url = new URL(window.location.href); url.searchParams.set("mode", "edit"); url.searchParams.set("orderId", response?.data?.id); url.searchParams.set( "customerName", response?.data?.destinationCustomerName ); window.history.replaceState({}, "", url); const { deliveryInstructions, destinationAddress, destinationAlternateNumber, destinationMobileNumber, destinationCustomerName, destination_road_details, destination_building_details, destinationFlatOrOfficeNumber, destination_block_details, customerInputOrderId, } = response?.data || {}; const step2Data = { orderId: customerInputOrderId || "", draft_order_id: response?.data?.id || "", deliveryMobile: destinationMobileNumber || "", customerName: destinationCustomerName || "", altDeliveryMobile: destinationAlternateNumber || "", blockNo: { value: destination_block_details?.id, label: `${destination_block_details?.code} ${ destination_block_details?.name ? ` - ${destination_block_details?.name}` : "" }`, code: destination_block_details?.code, name: destination_block_details?.name, id: destination_block_details?.id, }, roadNo: { value: destination_road_details?.id, label: `${destination_road_details?.code} ${ destination_road_details?.name ? ` - ${destination_road_details?.name}` : "" }`, code: destination_road_details?.code, name: destination_road_details?.name, id: destination_road_details?.id, }, buildingNo: { value: destination_building_details?.id, label: `${destination_building_details?.code} ${ destination_building_details?.name ? ` - ${destination_building_details?.name}` : "" }`, code: destination_building_details?.code, name: destination_building_details?.name, id: destination_building_details?.id, }, flatNo: destinationFlatOrOfficeNumber || "", destinationAddress: destinationAddress || "", remarks: deliveryInstructions || "", }; handleSave("step2", { ...step2, ...step2Data }); setStep(1); } else router.replace("/create-order"); } if (!isBack) setStep(step + 1); // Swal.fire({ // icon: "success", // title: "Order Creation", // text: `Your ${ // step === 1 ? "package" : step === 2 ? "customer" : "" // } details has been saved successfully!`, // confirmButtonText: "OK", // }); } else { console.error("Failed to save details:", response.message); Swal.fire({ icon: "error", title: "Oops...", text: response.message || "Something went wrong. Please try again.", confirmButtonText: "OK", }); } } } catch (error) { console.error("Error during API call:", error); } finally { setIsLoading(false); } }; const handleMakePayment = async () => { try { if (!createOrderData?.step3?.makePayment?.date) Swal.fire({ icon: "warning", title: "Oops...", text: "Please select date", // text: response.message || "Something went wrong. Please try again.", confirmButtonText: "OK", }); else if (!createOrderData?.step3?.makePayment?.time) Swal.fire({ icon: "warning", title: "Oops...", text: "Please select time", // text: response.message || "Something went wrong. Please try again.", confirmButtonText: "OK", }); else { setIsLoading(true); const response = await makePayment({ pickup_date: createOrderData?.step3?.makePayment?.date || "", pickup_slot_type: createOrderData?.step3?.makePayment?.time || 1, }); if (response.status) { setSavedOrder(response?.data || []); togglePlaceOrder(); // togglePaymentConfirm(); toggleOrderSuccessModal(); setPaymentSuccess(true); } else { Swal.fire({ icon: "warning", title: "Payment Failed!", text: response?.message || "Something went wrong. Please try again.", confirmButtonText: "OK", customClass: { confirmButton: "delybell-primary px-4", cancelButton: "delybell-dark", }, }); // // Handle failure (e.g., show error toast or modal) // // togglePlaceOrder(); // togglePaymentConfirm(); // setPaymentSuccess(false); } } } catch (error) { // Handle unexpected error console.error("Payment error:", error); alert("An unexpected error occurred during payment."); } finally { setIsLoading(false); } }; return ( <> {isLoading && } {step === 3 ? (
) : ( )} {openPlaceOrderModal && ( )} {openPaymentConfirmModal && ( { togglePaymentConfirm(); toggleOrderSuccessModal(); }} paymentSuccess={paymentSuccess} /> )} {openOrderSuccessModal && ( )} ); }; export default CreateOrderFooter;