/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable no-restricted-globals */ /* eslint-disable no-unsafe-optional-chaining */ /* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable jsx-a11y/interactive-supports-focus */ /* eslint-disable import/no-named-as-default */ /* eslint-disable no-nested-ternary */ import dayjs from "dayjs"; import { isEmpty } from "lodash-es"; import { useRouter } from "next/navigation"; import { useCallback, useEffect, useRef } from "react"; import { useBoolean } from "usehooks-ts"; import Form from "@/components/form/form"; import Container from "@/components/shared/container"; import Card from "@/components/ui/card/card"; import { Dialog } from "@/components/ui/dialog/dialog"; import { EarlyBookingDiscount, HotelCurrencyTotalPrice, HotelDiscountPrice, HotelPrice, HotelRezervationSummary, HotelRezervationSummaryDateInfo, HotelRezervationSummaryRoomInfo, ReservationSummaryAdditionalService, RezervationSummaryDivider, RezervationSummaryProvider, RezervationSummaryTitle, RezervationSummaryTotalPrice, } from "@/components/widget/rezervation-summary/rezervation-summary"; import CoreSummaryActionButton from "@/features/core/summary/components/core-summary-action-button"; import { CoreSummaryAdditionalPrices } from "@/features/core/summary/components/core-summary-additional-prices"; import CoreSummaryContent from "@/features/core/summary/components/core-summary-content"; import CoreSummaryCouponCode from "@/features/core/summary/components/core-summary-coupon-code/core-summary-coupon-code"; import type { CoreSummaryHandles } from "@/features/core/summary/components/core-summary-form"; import CoreSummaryForm, { GROUP_KEY_PREFIX, } from "@/features/core/summary/components/core-summary-form"; import CoreSummaryHeader from "@/features/core/summary/components/core-summary-header"; import CoreSummaryInvoiceNoteFormItem from "@/features/core/summary/components/core-summary-invoice-note-form-item"; import CoreSummaryMainColumn from "@/features/core/summary/components/core-summary-main-column"; import CoreSummaryNoteFormItem from "@/features/core/summary/components/core-summary-note-form-input"; import CoreSummaryPassengerGroup from "@/features/core/summary/components/core-summary-passenger-group"; import CoreSummaryPolicyFormItem from "@/features/core/summary/components/core-summary-policy-form-item"; import CoreSummaryRequestNoteFormItem from "@/features/core/summary/components/core-summary-request-note-form-item"; import CoreSummarySideColumn from "@/features/core/summary/components/core-summary-side-column"; import CoreSummarySteps from "@/features/core/summary/components/core-summary-steps"; import { useCoreSummaryCtx } from "@/features/core/summary/context/core-summary-context"; import { getBillingRequestDataFromBillingForm, getBillingRequestDataFromPassengerInfo, } from "@/features/core/summary/libs/billing-helper"; import type { ICoreSummaryPassenger } from "@/features/core/summary/types/core-summary.types"; import type { IBillingInfoForm } from "@/features/customer/billing-info/billing-info-form"; import BillingInfoForm from "@/features/customer/billing-info/billing-info-form"; import type { HotelPaymentListHandles } from "@/features/modules/payment/payment-list"; import PaymentList from "@/features/modules/payment/payment-list"; import AllInstallmentsModalContent from "@/features/payment/credit-card-infos/components/all-installments-modal-content"; import { useApp } from "@/hooks/useApp"; import { useBreakpoints } from "@/hooks/useBreakpoints"; import { useLocale } from "@/hooks/useLocale"; import { getLoyaltyAddon } from "@/libs/helpers/addon-helper"; import localStateCache, { useLocalStateCache, } from "@/libs/helpers/local-state-cache-helper"; import { CorePassengerHelper } from "@/libs/helpers/passenger-helper"; import { PriceManager } from "@/libs/price-manager/price-manager"; import { storageManager } from "@/libs/storage-manager"; import { ILoaderKeys } from "@/models/loader.model"; import { useServerDataCtx } from "@/providers/server-data-provider/server-data-provider"; import type { IHotelAddToCartResponse } from "@/services/eva-display/hotel/hotel-add-to-cart/hotel-add-to-card-services.types"; import { useHotelBookingRequestMutation } from "@/services/eva-display/hotel/hotel-booking-request/hotel-booking-request.service"; import { useHotelValidateMutation } from "@/services/eva-display/hotel/hotel-validate/hotel-validate.service"; import { useLoaderStore } from "@/store/loader-store/use-loader-store"; import { useMasterpassStore } from "@/store/masterpass-store/use-masterpass-store"; import { useNotifyStore } from "@/store/notify-store/use-notify-store"; import { usePayment } from "../../payment/hooks/use-hotel-payment"; import { useHotelTravelPlanner } from "../../travel-planner/hooks/use-hotel-travel-planner"; import { useSummaryCtxState } from "../context/summary-context"; import { useHotelSummary } from "../hooks/use-hotel-summary"; import HotelSummaryCancelWarranty from "./hotel-summary-cancel-warranty"; import HotelSummaryEvents from "./hotel-summary-events"; interface HotelSummaryViewProps { hotelAddToCartData: IHotelAddToCartResponse; passengersGroups: Array; } const HotelSummaryView = (props: HotelSummaryViewProps) => { const { isB2E, isB2C, isOtel } = useApp(); const router = useRouter(); const { addonList } = useServerDataCtx(); const summaryState = useSummaryCtxState(); const { actions: setCoreSummaryActions, state: { discounts }, } = useCoreSummaryCtx(); const { setNotify } = useNotifyStore(); const { data: summaryData } = useHotelSummary(); const { data: tpData } = useHotelTravelPlanner(); const { paymentState, setBookingData, setPaymentState } = usePayment(); const { setMasterpassData } = useMasterpassStore(); const validateMutation = useHotelValidateMutation(); const coreSummaryFormRef = useRef(null); const hotelPaymentRef = useRef(null); const paymentFormRef = useRef(null); const diffrentBillingInfoBoolean = useBoolean(); const allInstallmentsBoolean = useBoolean(); const { t } = useLocale(); const { removeLoader } = useLoaderStore(); const { isDesktop } = useBreakpoints(); const { getLocalStateCacheValues } = useLocalStateCache( "hotelFormFields", props.passengersGroups, ); const bookingRequestMutation = useHotelBookingRequestMutation({ onSuccess(data) { if (!data) { setNotify({ title: "Bir Hata Oluştu!", message: "Bir hata oluştu", variant: "error", }); return; } if (data.success === false) { setNotify({ title: "Bir Hata Oluştu!", message: data.errors[0]?.message ?? "Bir hata oluştu", variant: "error", }); return; } router.push( `/booking-request-success?bookingId=${data.result.requestId}&withoutApprove=${data.result.withoutApprove}`, ); }, }); function getDefaultValues() { const defaultValues: any = getLocalStateCacheValues(); if (!isEmpty(defaultValues)) { return defaultValues; } props.hotelAddToCartData.roomItemList.forEach((_i, roomIndex) => { const passengers = props.passengersGroups[roomIndex]; if (passengers) { passengers.forEach((passenger: any) => { if (passenger.type === "employee") { defaultValues[ `${GROUP_KEY_PREFIX}_${roomIndex}-${passenger.key}-employee` ] = passenger.defaultValue; } }); } }); return defaultValues; } const defaultValues = getDefaultValues(); function handleSubmitButtonClick() { if (paymentState?.payload.paymentStatus === "payment") { paymentFormRef.current?.submit(); hotelPaymentRef.current?.onlyValidate(); } else { coreSummaryFormRef.current?.submit(); } } function getRoomPassengers(passengerKeys: string[]) { const passengers: any[] = []; props.passengersGroups.forEach((group) => { group.forEach((passenger) => { if (passengerKeys.includes(passenger.key)) { passengers.push(passenger); } }); }); return passengers; } useEffect(() => { removeLoader(ILoaderKeys.HotelDetailLoaderKey); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); function renderCouponCode() { if ( isB2C && paymentState?.payload?.transactionId && paymentState.payload?.paymentStatus === "payment" ) { return ( ); } return null; } const loyaltyAddon = getLoyaltyAddon(addonList); const milesCouponCode = discounts .find((x) => x.type === "CouponCode") ?.extras?.find((x) => x.type === "Loyalty")?.value; const milesValue = props.hotelAddToCartData?.loyaltyItem && props.hotelAddToCartData?.loyaltyItem.loyalities?.length > 0 ? props.hotelAddToCartData?.loyaltyItem.loyalities[0]?.value : null; const hasMiles = !!loyaltyAddon && Boolean(isB2C && milesValue && (+milesValue > 0 || milesCouponCode)); function calculateTotalPrice() { let totalPrice = 0; let tryTotalPrice = 0; if (summaryState.optionalAddOns) { summaryState.optionalAddOns.forEach( ({ addOn, selectedPassengerValues }) => { const passengerCount = selectedPassengerValues.reduce( (acc, curr) => acc + curr.length, 0, ); totalPrice += +addOn.totalExchangePrice.slice(3) * passengerCount; tryTotalPrice += +addOn.totalPrice.slice(3) * passengerCount; }, ); } totalPrice += summaryState.totalPrice; tryTotalPrice += summaryState.tryTotalPrice; return { totalPrice, tryTotalPrice }; } const onBackButtonEvent = useCallback( (e: PopStateEvent) => { const getCorePayment = storageManager.get("core-payment"); if (getCorePayment?.payload?.paymentStatus === "payment") { e.preventDefault(); storageManager.delete("core-payment"); setCoreSummaryActions.clearCreditCardCampaigns(); setPaymentState("idle"); } else { history.back(); } }, [paymentState?.payload?.paymentStatus], ); useEffect(() => { window.history.pushState(null, "", window.location.pathname); window.addEventListener("popstate", onBackButtonEvent); return () => { window.removeEventListener("popstate", onBackButtonEvent); }; }, [paymentState?.payload?.paymentStatus]); useEffect(() => { const cachedCancelWarranty = localStateCache.get("cancellationPolicy"); if (cachedCancelWarranty) { if ( summaryState.cancelWarranty && cachedCancelWarranty?.productKey && cachedCancelWarranty?.data?.searchId ) { localStateCache.set("cancellationPolicy", { data: summaryState.cancelWarranty, productKey: summaryData.payload.searchItemKey, }); } } }, []); useEffect(() => { window.scrollTo(0, 0); }, [paymentState?.payload?.paymentStatus]); return (
{(isB2C || isOtel) && ( { if (index !== 2) { if (summaryState.campaing) { hotelPaymentRef?.current?.clearSelectedCampaign?.(); } } }} /> )} {isB2C || isOtel ? paymentState?.payload?.paymentStatus === "payment" ? t("Payment Options") : t("Guest Information") : `${tpData.payload.destination?.value} ${tpData.payload.reason?.name} Seyahati`} {(isB2C && paymentState?.payload?.paymentStatus === "payment") || (isOtel && paymentState?.payload?.paymentStatus === "payment") ? ( {!isDesktop && renderCouponCode()}
hotelPaymentRef.current?.submit()} shouldAutoScroll > x.type === "CouponCode"), )} />
) : ( wrapperClassName="space-y-4" formItemPrefixes={["billingInfo"]} ref={coreSummaryFormRef} onSubmit={ isB2C || isOtel ? async (values) => { if ( paymentState?.payload?.paymentStatus === "payment" ) { return; } const passengersInformations = values.passengers.map( (psg) => CorePassengerHelper.corePassengerToPassengerInformation( psg, ), ); const passengerWithBillingInfo = passengersInformations.find( (x) => x.Address.Street !== "", ); const billingInfo = diffrentBillingInfoBoolean.value ? getBillingRequestDataFromBillingForm( values.values?.billingInfo!, passengerWithBillingInfo!, ) : getBillingRequestDataFromPassengerInfo( passengerWithBillingInfo!, ); try { const addOnsKeyList = (summaryState.optionalAddOns ?.map((item) => item.selectedPassengerValues) .flat() .flat() as string[]) || []; const cancelWarrantySearchId = summaryState.cancelWarranty?.searchId ?? ""; const resp = await validateMutation.mutateAsync({ HotelValidateBookingRequest: { AddOnsKeyList: addOnsKeyList, CartId: props.hotelAddToCartData.cartId, SearchId: summaryData.payload.searchId!, BookingPassengers: passengersInformations.map( (x) => ({ ...x, PhoneNumbers: ( x.PhoneNumbers as unknown as string[] ).filter( (phoneNumber) => phoneNumber !== "", ), }), ), KvkkApproval: true, CancelWarrantySearchId: cancelWarrantySearchId, BillingRequest: billingInfo, ReservationNotes: (values as any).specialNote ?? "", }, }); if ( !resp.data?.result?.serviceResponse?.success || !resp.data?.result?.serviceResponse?.result ?.transactionKey ) { setNotify({ title: "Bir Hata Oluştu!", message: resp.data.result.serviceResponse?.errors[0] ?.message ?? "Bir hata oluştu", variant: "error", }); return; } setBookingData({ cartId: props.hotelAddToCartData.cartId, searchId: summaryData.payload.searchId!, transactionId: resp.data.result.serviceResponse.result .transactionKey, preSaleAgreementText: resp.data.result.serviceResponse.result .preSaleAgreementText, saleAgreementText: resp.data.result.serviceResponse.result .saleAgreementText, }); if ( resp.data.result.serviceResponse.result .masterPassUserData ) { setMasterpassData({ moduleName: "Hotel", payload: { masterpassLoginState: false, masterpassOtherUser: false, cardList: [], masterpassUserData: resp.data.result.serviceResponse.result .masterPassUserData, customerEmail: values.passengers[0]!.email, masterPassengerName: values.passengers[0]!.name! + values.passengers[0]!.surname!, }, }); } } catch (error) { setNotify({ title: "Bir Hata Oluştu!", message: "Bir hata oluştu", variant: "error", }); } } : async (values) => { const passengersWithoutGenderInfo = CorePassengerHelper.getPassengersWithoutGenderInfo( values.passengers, ); if (passengersWithoutGenderInfo.length > 0) { setNotify({ variant: "error", title: "Bir Hata Oluştu!", message: `${"Seçilen kullanıcının cinsiyet bilgisini doldurunuz."} \n ${passengersWithoutGenderInfo.reduce((acc, curr) => `${acc} ${curr.name} ${curr.surname},`, "").slice(0, -1)}`, }); return; } const passengersInformations = values.passengers.map( (psg) => { const psgConverted = CorePassengerHelper.corePassengerToPassengerInformation( psg, ); return { ...psgConverted, Gender: psgConverted.Gender === 2 ? 0 : psgConverted.Gender, }; }, ); bookingRequestMutation.mutate({ CorpCreateHotelRequest: { SearchProductKey: summaryData.payload.searchItemKey!, SearchId: summaryData.payload.searchId!, CartId: props.hotelAddToCartData.cartId, DetailProductKey: summaryData.payload.roomGroupKey!, isPreBook: true, KvkkStatus: true, PassengerInformations: passengersInformations as any, LinkId: "", TravelReasonId: tpData.payload?.reason?.value ? +tpData.payload.reason.value : 0, BranchId: tpData.payload?.branchOffice?.value ? +tpData.payload.branchOffice.value : undefined, RequesterUserIds: values.passengers .filter((x) => x.type === "employee") .map((x) => x.employeeGUID ?? ""), RequestId: null, CancelWarrantySearchId: summaryState.cancelWarranty?.searchId, ProjectCode: values.invoiceNote, ReservationNote: values.requestNote, }, }); } } defaultValues={defaultValues} > {summaryData.payload.rooms.map((room, roomIndex) => ( item.roomIndex === room.room.roomIndex, )?.cancellationPolicy } groupKey={`${GROUP_KEY_PREFIX}_${roomIndex}`} showIdentityWarning groupProperties={[ { iconName: "User", title: `${room.room.passengerKeys.length} ${t( "person", )}`, }, { iconName: "Check", title: room.room.mealType.description, }, ]} passengers={getRoomPassengers(room.room.passengerKeys)} hasReservationNote={!isB2E} /> ))} {(isB2C || isOtel) && ( { diffrentBillingInfoBoolean.setValue(value); }} open={defaultValues?.billingInfoCompOpen} /> )} {!isB2E && props.hotelAddToCartData.cancelWarranty && ( )} {!isB2E && props.hotelAddToCartData?.optionalAddOns && (props.hotelAddToCartData.optionalAddOns?.length || 0) > 0 && ( )} {isB2E && ( <> )} {(isB2C || isOtel) && ( )} )} acc + +item.price, 0), })} button={ { handleSubmitButtonClick(); }} variant="primary" loading={ bookingRequestMutation.isLoading || validateMutation.isLoading } /> } > {props.hotelAddToCartData.roomItemList && props.hotelAddToCartData.roomItemList.map((roomItem) => ( <> {roomItem.roomPriceDiscountDescription && ( )} ))} {Boolean(summaryState?.cancelWarranty) && summaryState.cancelWarranty?.name && summaryState.cancelWarranty?.totalExchangePrice && ( <> )} {(summaryState.optionalAddOns?.length || 0) > 0 && ( <> {summaryState.optionalAddOns?.map( ({ addOn, selectedPassengerValues }) => { const passengerCount = selectedPassengerValues.reduce( (acc, curr) => acc + curr.length, 0, ); return ( ); }, )} )} {Boolean(summaryState.campaing) && summaryState.campaing?.name && summaryState.campaing?.discountAmount && ( )} {props.hotelAddToCartData.extendedDiscountInformationList && props.hotelAddToCartData.extendedDiscountInformationList.map( (discount) => ( ), )} acc + +item.price, 0), })} /> {props.hotelAddToCartData.totalPrice.slice(0, 3) !== props.hotelAddToCartData.totalExchangePrice.slice(0, 3) && ( )} {isDesktop && renderCouponCode()} {hasMiles && ( {t("You will earn {{point}} Miles", { point: milesCouponCode ?? milesValue, })} )} {(isB2C || isOtel) && (
{t("Up to 12 Monthly Installment Options")}
)} {props.hotelAddToCartData.totalPrice.slice(0, 3) !== props.hotelAddToCartData.totalExchangePrice.slice(0, 3) && ( <>
{props.hotelAddToCartData.currencyMessage}
)} { handleSubmitButtonClick(); }} variant="primary" loading={ bookingRequestMutation.isLoading || validateMutation.isLoading } />
{summaryData.payload.roomGroupKey && summaryData.payload.searchId && allInstallmentsBoolean.value && ( )}
); }; export default HotelSummaryView;