142 lines
4.0 KiB
TypeScript
142 lines
4.0 KiB
TypeScript
'use client';
|
|
|
|
import { useCallback, useState } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { StoreCart, StoreCartLineItem } from '@medusajs/types';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { Trans } from '@kit/ui/trans';
|
|
import { AccountBalanceSummary } from '@kit/accounts/services/account-balance.service';
|
|
|
|
import { initiatePayment } from '../../_lib/server/cart-actions';
|
|
import { EnrichedCartItem } from './types';
|
|
import CartForm, { CartFormOnSubmit } from './cart-form';
|
|
import CartFormContent from './cart-form-content';
|
|
|
|
export default function Cart({
|
|
accountId,
|
|
cart,
|
|
synlabAnalyses,
|
|
ttoServiceItems,
|
|
balanceSummary,
|
|
}: {
|
|
accountId: string;
|
|
cart: StoreCart | 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>
|
|
);
|
|
}
|