/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useEffect, useState, useCallback, useMemo, useRef, } from "react"; import CreateOrderFooter from "./CreateOrderFooter"; import PackageForm from "./Step1/PackageForm"; import CodOrder from "./Step1/CodOrder"; import { OrderFlowType, orderFlowTypeMap, serviceIconMap, UserTypes, } from "@/Constant/enums"; import { step1Schema } from "./ValidationSchema"; import { useAppSelector } from "@/Redux/Hooks"; import { getMasterList } from "../../../../Api/MastersApi"; import HourGlassLoader from "../../../Loader/Loader"; // import { saveStepData } from "@/Redux/Actions/createOrderActions"; import { getOrders } from "../../../../Api/OrderApi"; import ServiceTypeSelector from "./Step1/ServiceTypeSelector"; import OrderFlowTypeSelector from "./Step1/OrderFlowTypeSelector"; import { useSearchParams } from "next/navigation"; // import { saveStepData } from "@/Redux/Reducers/CreateOrderSlice"; type Step1Props = { onSave: (data: any) => void; step: number; setStep: React.Dispatch>; defaultOrderDetails: any; isEditMode?: boolean; confirmSaveStep?: (step: number, data: any) => void; }; interface PackageDetail { package_id: number; weight: string; package_description: string; customer_input_package_value: number; external_package_id?: string; } interface CodDetails { codEnabled: boolean; codAmount: string; } interface ServiceType { id: number; name: string; } const Step1: React.FC = ({ onSave, step, setStep, defaultOrderDetails, isEditMode, // confirmSaveStep }) => { const [isLoading, setIsLoading] = useState(false); const storedUser = localStorage.getItem("ALL_DATA"); const allData: any = storedUser ? JSON.parse(storedUser)?.data : null; const searchParams: any = useSearchParams(); const packageDisable: any = searchParams.get("packageDisable"); const createOrderData: any = useAppSelector( (state) => state.createOrder )?.step1; const [errors, setErrors] = useState>({}); const [packageCount, setPackageCount] = useState( typeof createOrderData?.packageCount === "number" && createOrderData?.packageCount > 0 ? createOrderData.packageCount : defaultOrderDetails?.packageCount || 1 ); const initialPackageDetails = createOrderData?.packageDetails && createOrderData.packageDetails.length > 0 ? createOrderData.packageDetails : defaultOrderDetails?.order_package_list && defaultOrderDetails.order_package_list.length > 0 ? defaultOrderDetails.order_package_list : [ { package_id: 1, weight: 1, package_description: allData?.packageDescription || "", customer_input_package_value: 0, external_package_id: "", }, ]; const [packageDetails, setPackageDetails] = useState( initialPackageDetails.map((pkg: any) => ({ ...pkg, weight: pkg?.weight || defaultOrderDetails?.order_package_list?.[0]?.weight || 1, customer_input_package_value: pkg?.customer_input_package_value || defaultOrderDetails?.order_package_list?.[0] ?.customerInputPackageValue || 0, package_description: allData?.packageDescription || pkg.package_description || "", external_package_id: pkg.external_package_id || "", })) ); const [codDetails, setCodDetails] = useState( createOrderData?.codDetails ?? defaultOrderDetails?.codDetails ?? { codEnabled: false, codAmount: "" } ); useEffect(() => { setCodDetails( createOrderData?.codDetails ?? defaultOrderDetails?.codDetails ?? { codEnabled: false, codAmount: "" } ); // eslint-disable-next-line react-hooks/exhaustive-deps },[defaultOrderDetails?.codDetails]) const [packageDescription] = useState( createOrderData?.packageDescription || allData?.packageDescription || "" ); const [packageValue] = useState(createOrderData?.packageValue ?? ""); const [serviceType, setServiceType] = useState( createOrderData?.serviceType || null ); const [serviceTypes, setServiceTypes] = useState([]); const [orderFlowTypes, setOrderFlowTypes] = useState( allData?.order_flow_type || [] ); const getDefaultOrderFlowType = (list: any[]): ServiceType => { const selected = list.find((t) => t.name === "Forward") ?? list.find((t) => t.name === "Return") ?? { id: OrderFlowType.Forward, name: "Forward", }; // fallback onSave({ orderFlowType: selected }); // ✅ call before returning return selected; }; const [orderFlowType, setOrderFlowType] = useState( createOrderData?.orderFlowType || getDefaultOrderFlowType(allData?.order_flow_types || []) ); // const [orderFlowType, setOrderFlowType] = useState( // createOrderData?.orderFlowType || { id: OrderFlowType.Forward, name: 'Forward' } // ); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [isServiceTypeDisabled, setIsServiceTypeDisabled] = useState(false); const [allowedServiceTypeId, setAllowedServiceTypeId] = useState< number | null >(null); const [allowedOrderTypeId, setAllowedOrderTypeId] = useState( null ); // Add ref to track previous package details const prevPackageDetailsRef = useRef([]); useEffect(() => { setOrderFlowTypes(allData?.order_flow_types || []); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { const fetchMasterLists = async () => { try { setIsLoading(true); const [services] = await Promise.all([getMasterList("service_type")]); setServiceTypes(services.data || []); } catch (err) { console.error("Error loading masterlists", err); } finally { setIsLoading(false); } }; fetchMasterLists(); }, []); const handleServiceTypeChange = (serviceName: string | null) => { if (serviceName === null) { setServiceType(null); onSave({ serviceType: null }); } else { const selected = serviceTypes.find((s) => s.name === serviceName); if (selected) { setServiceType(selected); onSave({ serviceType: selected }); setErrors({ ...errors, serviceType: "" }); } } }; const handleOrderFlowTypeChange = (serviceName: string | null) => { if (serviceName === null) { setOrderFlowType(null); onSave({ orderFlowType: null }); } else { const selected = orderFlowTypes.find((s) => s.name === serviceName); if (selected) { setOrderFlowType(selected); onSave({ orderFlowType: selected }); setErrors((prev) => ({ ...prev, orderFlowType: "" })); } } }; useEffect(() => { // setServiceType(createOrderData?.serviceType || null); // if ( // !createOrderData?.serviceType && // defaultOrderDetails?.service_type_details // ) { // setServiceType( // !createOrderData?.serviceType && // defaultOrderDetails?.service_type_details // ? { // id: defaultOrderDetails?.service_type_details?.id, // name: defaultOrderDetails?.service_type_details?.name, // } // : null // ); // handleServiceTypeChange(defaultOrderDetails?.service_type_details?.name); // } console.log("Step1 useEffect: Updating packageDetails", { createOrderDataPackageDetails: createOrderData?.packageDetails, defaultOrderDetailsPackageList: defaultOrderDetails?.order_package_list, merged: createOrderData?.packageDetails ?? defaultOrderDetails?.order_package_list ?? [], }); setPackageDetails( ( createOrderData?.packageDetails ?? defaultOrderDetails?.order_package_list ?? [] ).map((pkg: any) => ({ ...pkg, weight: pkg?.weight || defaultOrderDetails?.order_package_list?.[0]?.weight || 0, customer_input_package_value: pkg?.customer_input_package_value || defaultOrderDetails?.order_package_list?.[0] ?.customerInputPackageValue || 0, package_description: pkg.package_description || "", external_package_id: pkg.external_package_id || "", })) ); }, [ allData?.packageDescription, createOrderData?.packageDetails, createOrderData.serviceType, defaultOrderDetails?.order_package_list, defaultOrderDetails.service_type_details, ]); const handlePackagesChange = (value: number) => { setPackageCount(value); onSave({ packageCount: value }); if (value > 0) setErrors({ ...errors, packageCount: "" }); else setErrors({ ...errors, packageCount: "Please select valid value" }); }; // Memoize the total weight calculation const calculateTotalWeight = useCallback((packages: PackageDetail[]) => { return packages.reduce((sum, pkg) => { const weight = parseFloat(pkg.weight); return sum + (isNaN(weight) ? 0 : weight); }, 0); }, []); // Memoize the package details change handler const handlePackageDetailsChange = useCallback( (updatedPackages: PackageDetail[]) => { try { console.log("handlePackageDetailsChange called", updatedPackages); // Check if the packages have actually changed const packagesChanged = JSON.stringify(updatedPackages) !== JSON.stringify(prevPackageDetailsRef.current); console.error( packagesChanged, "|||||||||||||||||||||||||||packagesChanged|||||||||||||||||||||||||||||" ); // if (packagesChanged) { // Update the ref with new values prevPackageDetailsRef.current = updatedPackages; // Update local state setPackageDetails(updatedPackages); // Calculate total weight const totalWeight = calculateTotalWeight(updatedPackages); // Update parent state once with all changes onSave({ packageDetails: updatedPackages, order_package_list: updatedPackages, package_details: updatedPackages, totalWeight: totalWeight, }); setErrors({ ...errors, packageDetails: "" }); // } } catch (error: any) { console.error(error); } }, [calculateTotalWeight, errors, onSave] ); // Initialize the ref with initial package details useEffect(() => { prevPackageDetailsRef.current = packageDetails; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Calculate total weight using memoized function const totalWeight = useMemo( () => calculateTotalWeight(packageDetails), [packageDetails, calculateTotalWeight] ); // const dispatch = useAppDispatch(); useEffect(() => { if (defaultOrderDetails?.packageCount > 1 && isEditMode) { setPackageCount(defaultOrderDetails?.packageCount ?? 1); // const updatedStepData = { // ...createOrderData[1], // Merge existing step data // ...defaultOrderDetails, // Add/update new fields // }; // handlePackageDetailsChange(updatedStepData?.order_package_list) // if (typeof confirmSaveStep === "function") { // confirmSaveStep(1, updatedStepData); // } } }, [defaultOrderDetails, isEditMode]); // confirmSaveStep, createOrderData, const handleCodDetailsChange = (updatedCod: any) => { console.log("handleCodDetailsChange", updatedCod); setCodDetails(updatedCod); onSave({ codDetails: updatedCod }); }; const validateStep1 = async () => { try { await step1Schema.validate( { serviceType, packageCount, packageDetails, packageDescription, packageValue, codDetails, }, { abortEarly: false } ); setErrors({}); return true; } catch (err: any) { const newErrors: Record = {}; err.inner.forEach((e: any) => { if (e.path?.startsWith("packageDetails[")) { const match = e.path.match(/packageDetails\[(\d+)\]\.(\w+)/); if (match) { const index = parseInt(match[1], 10); const field = match[2]; if (!newErrors.packageDetails) newErrors.packageDetails = {}; if (!newErrors.packageDetails[index]) newErrors.packageDetails[index] = {}; newErrors.packageDetails[index][field] = e.message; } } else { newErrors[e.path] = e.message; } }); setErrors(newErrors); return false; } }; console.error(errors, "ERRORS"); useEffect(() => { const fetchOrders = async () => { setIsLoading(true); try { const orderList: any[] = await getOrders("draft", { limit: 1 }); if ( orderList && orderList.length > 0 && orderList[0].service_type_details ) { setServiceType(orderList[0].service_type_details); setOrderFlowType(orderList[0].orderFlowType); onSave({ serviceType: orderList[0].service_type_details }); setIsServiceTypeDisabled(true); if (orderList?.length !== 1) { setAllowedServiceTypeId(orderList[0].service_type_details.id); setAllowedOrderTypeId( orderList[0]?.orderFlowType?.id ?? createOrderData?.orderFlowType?.id ); } else if (packageDisable === "true") { setAllowedOrderTypeId(OrderFlowType.Return); } } else { setIsServiceTypeDisabled(false); setAllowedServiceTypeId(null); setAllowedOrderTypeId(null); } } catch (error) { console.error("Failed to fetch orders:", error); setIsServiceTypeDisabled(false); setAllowedServiceTypeId(null); setAllowedOrderTypeId(null); } finally { setIsLoading(false); } }; fetchOrders(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( <> {isLoading && }
Service Type
{orderFlowTypes?.length > 0 && orderFlowTypes.some((t) => t.name === "Forward") && orderFlowTypes.some((t) => t.name === "Return") && (
Order Type
t.name === "Forward" || t.name === "Return" )} // selectedServiceType={orderFlowType ?? { id: OrderFlowType.Forward, name: 'Forward' }} selectedServiceType={ orderFlowType ?? (orderFlowTypes.find((t) => t.name === "Forward") ?? orderFlowTypes.find((t) => t.name === "Return") ?? packageDisable === "true" ? { id: OrderFlowType.Return, name: "Return" } : { id: OrderFlowType.Forward, name: "Forward" }) // final fallback } onChange={handleOrderFlowTypeChange} errors={{ serviceType: errors.orderFlowType }} serviceIconMap={orderFlowTypeMap} allowedServiceTypeId={allowedOrderTypeId} type="create-order" />
)} ({ ...pkg, customer_input_package_value: String( pkg.customer_input_package_value ), }))} onPackageDetailsChange={(updatedPackages) => { const formattedPackages = updatedPackages.map((pkg) => ({ ...pkg, customer_input_package_value: Number( pkg.customer_input_package_value ), })); handlePackageDetailsChange(formattedPackages); }} errors={errors} isEditMode={isEditMode ? true : false} /> {packageCount > 1 ? (
{/* */}
) : ( <> )} {(allData?.userType?.id === UserTypes.CorporateCodCustomer || allData?.userType?.id === UserTypes.InternationalCustomer) && ( )}
{ const isValid = await validateStep1(); if (isValid) setStep(nextStep); }} validation={validateStep1} backButton={false} defaultOrderDetails={defaultOrderDetails} isEditMode={isEditMode} /> ); }; export default Step1;