/* eslint-disable array-callback-return */ /* eslint-disable react/display-name */ /* eslint-disable react/jsx-no-bind */ import { type ForwardedRef, forwardRef, type PropsWithChildren, type ReactNode, useImperativeHandle, useRef, } from "react"; import { useDebounceCallback } from "usehooks-ts"; import type { FormHandles } from "@/components/form/form"; import Form from "@/components/form/form"; import { DateHelper } from "@/libs/helpers/date-time-helper"; import localStateCache from "@/libs/helpers/local-state-cache-helper"; import { cn } from "@/libs/utils"; import { useUserInformationsMutation } from "@/services/eva-display/user/user-information.service"; import { useNotifyStore } from "@/store/notify-store/use-notify-store"; import type { ICorePassengerInformation } from "../types/core-summary.types"; export const GROUP_KEY_PREFIX = "group_key"; // it cant include "-" character export interface CoreSummaryHandles extends FormHandles {} interface CoreSummaryProps extends PropsWithChildren { defaultValues?: any; formItemPrefixes?: string[]; wrapperClassName?: string; onSubmit: (values: { specialNote?: string; passengers: Partial[]; invoiceNote?: string; requestNote?: string; values?: PrefixesValues; paymentCard?: { creditCard: string; fullname: string; cardExpire: string; cardCvv: string; }; }) => void; } const CoreSummaryForm = ( props: CoreSummaryProps, ref: ForwardedRef, ) => { const formRef = useRef(null); const userInformationsMutation = useUserInformationsMutation(); const { setNotify } = useNotifyStore(); async function getPassengersFromForm(values: any) { const groups: any = {}; Object.entries(values) .filter(([x]) => x.startsWith(GROUP_KEY_PREFIX)) .forEach(([key, value]) => { const [groupKey, passengerKey, passengerType, passengerField] = key.split("-"); if (!groupKey || !passengerKey || !passengerType) { throw new Error("Invalid key"); } if (!groups[groupKey]) { groups[groupKey] = []; } if (passengerType === "employee") { groups[groupKey].push({ key: passengerKey, type: passengerType, value, }); } else if (passengerType === "guest" || passengerType === "child") { if (passengerField) { const passengerIndex: any = groups[groupKey].findIndex((x: any) => x.key === passengerKey) ?? {}; if (passengerIndex === -1) { const passenger: any = { key: passengerKey, type: passengerType, }; passenger[passengerField] = value; groups[groupKey].push(passenger); } else { const passenger = groups[groupKey][passengerIndex]; passenger[passengerField] = value; groups[groupKey][passengerIndex] = passenger; } } } }); const passengerList: any[] = []; Object.entries(groups) .filter(([key]) => key !== "group_key") .forEach(([key, value]: any[]) => { value.forEach((passenger: any) => { passengerList.push({ ...passenger, groupKey: key, }); }); }); const employeeIds = passengerList .filter((x) => !!x.value) .map((x) => +x.value); const employeeInformations = await userInformationsMutation.mutateAsync({ userIds: employeeIds, }); const usersHasntInformations = employeeIds.filter( (x) => !employeeInformations.find((y) => y.userId === x), ); const hasAllUsersInformations = usersHasntInformations.length === 0; if (!hasAllUsersInformations) { setNotify({ title: "Uyarı", message: "Kullanıcı bilgilerine ulaşılamadı", variant: "warning", }); throw new Error("Employee informations not found"); } let employeeIndex = 0; const corePassengerInformations: Partial[] = passengerList.map((formPassenger, formPassengerIndex) => { if (formPassenger.type === "employee") { const employeeInformation = employeeInformations[employeeIndex]; employeeIndex += 1; if (!employeeInformation) { throw new Error("Employee informations not found"); } return { employeeId: employeeInformation.userId, groupKey: formPassenger.groupKey, index: formPassengerIndex, key: formPassenger.key, passengerType: formPassenger.type, type: formPassenger.type, email: employeeInformation.email, phoneNumber: employeeInformation.phoneNumber, name: employeeInformation.userDetail.firstName, surname: employeeInformation.userDetail.lastName, identity: employeeInformation.passaportDetail?.citizenNo ?? "", identityCheck: false, birthDate: DateHelper.isoStringToFullYearString( employeeInformation.userDetail.birthDate, ".", ), gender: employeeInformation.userDetail.gender, milesCode: formPassenger.milesCode, address: undefined, city: undefined, country: undefined, employeeGUID: employeeInformation.userGuidId, passportNumber: employeeInformation.passaportDetail?.passportNo ?? "", specialServiceRequests: employeeInformation.specialServiceRequests, }; } return { birthDate: formPassenger.birthDate, email: formPassenger.email, gender: formPassenger.gender, name: formPassenger.name, surname: formPassenger.surname, identity: formPassenger.identity, identityCheck: formPassenger.identityCheck, groupKey: formPassenger.groupKey, index: formPassengerIndex, key: formPassenger.key, passengerType: formPassenger.type, phoneNumber: formPassenger.phone, type: formPassenger.type, employeeId: 0, milesCode: formPassenger.milesCode, address: formPassenger.address, city: formPassenger.city, country: formPassenger.country, employeeGUID: "", passportNumber: formPassenger.passport ?? "", specialServiceRequests: formPassenger.specialServiceRequests, }; }); return corePassengerInformations; } function getPrefixesObjectFromForm(values: any) { const result = new Map(); props.formItemPrefixes?.forEach((prefix) => { result.set(prefix, {}); }); Object.entries(values).forEach(([key, value]) => { const [prefix, fieldName] = key.split("-"); if (prefix && fieldName) { if (result.has(prefix)) { result.set(prefix, { ...result.get(prefix), [fieldName]: value, }); } } }); return Object.fromEntries(result); } async function handleSubmit(values: any) { const passengers = await getPassengersFromForm(values); const prefixesValues = getPrefixesObjectFromForm(values); const paymentCard = values.creditCard ? { creditCard: values.creditCard, fullname: values.fullname, cardExpire: values.cardExpire, cardCvv: values.cardCvv, } : undefined; props.onSubmit({ passengers, invoiceNote: values["invoice-note"], paymentCard, requestNote: values["request-note"], values: prefixesValues, specialNote: values.specialNote, }); } /** * @description values is any because Form return type is any */ const handleChange = useDebounceCallback((values: any) => { localStateCache.set("form", values); }, 500); useImperativeHandle(ref, () => ({ submit: () => { formRef.current?.submit(); }, onlyValidate: () => { formRef.current?.onlyValidate(); }, })); return (
{props.children}
); }; export { default as CoreSummaryContent } from "./core-summary-content"; export { default as CoreSummaryHeader } from "./core-summary-header"; export { default as CoreSummaryPassengerGroup } from "./core-summary-passenger-group"; export default forwardRef(CoreSummaryForm) as ( props: CoreSummaryProps & { ref?: ForwardedRef; }, ) => ReactNode;