Files
medreport_mrb2b/app/home/(user)/_components/cart/index.tsx
2025-10-08 13:50:04 +03:00

158 lines
4.2 KiB
TypeScript

'use client';
import { useCallback, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
StoreCart,
StoreCartLineItem,
StoreCartPromotion,
} from '@medusajs/types';
import { useTranslation } from 'react-i18next';
import { AccountBalanceSummary } from '@kit/accounts/services/account-balance.service';
import { Trans } from '@kit/ui/trans';
import { initiatePayment } from '../../_lib/server/cart-actions';
import CartForm, { CartFormOnSubmit } from './cart-form';
import CartFormContent from './cart-form-content';
import { EnrichedCartItem } from './types';
export default function Cart({
accountId,
cart,
synlabAnalyses,
ttoServiceItems,
balanceSummary,
}: {
accountId: string;
cart:
| (StoreCart & {
promotions: StoreCartPromotion[];
})
| null;
synlabAnalyses: StoreCartLineItem[];
ttoServiceItems: EnrichedCartItem[];
balanceSummary: AccountBalanceSummary | null;
}) {
const {
i18n: { language },
} = useTranslation();
const [isInitiatingSession, setIsInitiatingSession] = useState(false);
const router = useRouter();
const [unavailableLineItemIds, setUnavailableLineItemIds] =
useState<string[]>();
const getBalanceSummarySelection = useCallback(
({
useCompanyBenefits,
}: {
useCompanyBenefits: boolean;
}): {
benefitsAmount: number;
benefitsAmountTotal: number;
montonioAmount: number;
} => {
if (!cart) {
return {
benefitsAmount: 0,
benefitsAmountTotal: 0,
montonioAmount: 0,
};
}
const benefitsAmountTotal = balanceSummary?.totalBalance ?? 0;
const cartTotal = cart.total;
if (!useCompanyBenefits) {
return {
benefitsAmount: 0,
benefitsAmountTotal,
montonioAmount: cartTotal,
};
}
const benefitsAmount =
benefitsAmountTotal > cartTotal ? cartTotal : benefitsAmountTotal;
const montonioAmount =
benefitsAmount > 0 ? cartTotal - benefitsAmount : cartTotal;
return {
benefitsAmount,
benefitsAmountTotal,
montonioAmount,
};
},
[balanceSummary, cart],
);
const items = cart?.items ?? [];
const hasCartItems = cart && Array.isArray(items) && items.length > 0;
if (!hasCartItems) {
return (
<div className="content-container py-5 lg:px-4">
<div>
<div
className="flex flex-col items-center justify-center"
data-testid="empty-cart-message"
>
<h4 className="text-center">
<Trans i18nKey="cart:emptyCartMessage" />
</h4>
<p className="text-center">
<Trans i18nKey="cart:emptyCartMessageDescription" />
</p>
</div>
</div>
</div>
);
}
const initiateSession: CartFormOnSubmit = async ({ useCompanyBenefits }) => {
setIsInitiatingSession(true);
try {
const { benefitsAmount } = getBalanceSummarySelection({
useCompanyBenefits,
});
const { url, isFullyPaidByBenefits, orderId, unavailableLineItemIds } =
await initiatePayment({
accountId,
benefitsAmount,
cart: cart!,
language,
});
if (unavailableLineItemIds) {
setUnavailableLineItemIds(unavailableLineItemIds);
}
if (url) {
window.location.href = url;
} else if (isFullyPaidByBenefits) {
if (typeof orderId !== 'number') {
throw new Error('Order ID is missing');
}
router.push(`/home/order/${orderId}/confirmed`);
}
} catch (error) {
console.error('Failed to initiate payment', error);
setIsInitiatingSession(false);
}
};
return (
<div className="small:grid-cols-[1fr_360px] grid grid-cols-1 gap-x-40 lg:px-4">
<CartForm cart={cart} onSubmit={initiateSession}>
<CartFormContent
cart={cart}
synlabAnalyses={synlabAnalyses}
ttoServiceItems={ttoServiceItems}
unavailableLineItemIds={unavailableLineItemIds}
isInitiatingSession={isInitiatingSession}
getBalanceSummarySelection={getBalanceSummarySelection}
/>
</CartForm>
</div>
);
}