Merge branch 'develop' into MED-97

This commit is contained in:
2025-09-26 17:01:24 +03:00
86 changed files with 11249 additions and 3151 deletions

View File

@@ -34,8 +34,15 @@ export default function MontonioCallbackClient({
setHasProcessed(true);
try {
const { orderId } = await processMontonioCallback(orderToken);
router.push(`/home/order/${orderId}/confirmed`);
const result = await processMontonioCallback(orderToken);
if (result.success) {
return router.push(`/home/order/${result.orderId}/confirmed`);
}
if (result.failedServiceBookings?.length) {
router.push(
`/home/cart/montonio-callback/error?reasonFailed=${result.failedServiceBookings.map(({ reason }) => reason).join(',')}`,
);
}
} catch (error) {
console.error('Failed to place order', error);
router.push('/home/cart/montonio-callback/error');

View File

@@ -1,8 +1,11 @@
import { use } from 'react';
import Link from 'next/link';
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
import { PageBody, PageHeader } from '@/packages/ui/src/makerkit/page';
import { toArray } from '@kit/shared/utils';
import { Button } from '@kit/ui/button';
import { Alert, AlertDescription } from '@kit/ui/shadcn/alert';
import { AlertTitle } from '@kit/ui/shadcn/alert';
@@ -16,7 +19,15 @@ export async function generateMetadata() {
};
}
export default async function MontonioCheckoutCallbackErrorPage() {
export default async function MontonioCheckoutCallbackErrorPage({
searchParams,
}: {
searchParams: Promise<{ reasonFailed: string }>;
}) {
const params = await searchParams;
const failedBookingData: string[] = toArray(params.reasonFailed?.split(','));
return (
<div className={'flex h-full flex-1 flex-col'}>
<PageHeader title={<Trans i18nKey="cart:montonioCallback.title" />} />
@@ -28,9 +39,15 @@ export default async function MontonioCheckoutCallbackErrorPage() {
</AlertTitle>
<AlertDescription>
<p>
{failedBookingData.length ? (
failedBookingData.map((failureReason, index) => (
<p key={index}>
<Trans i18nKey={`checkout.error.${failureReason}`} />
</p>
))
) : (
<Trans i18nKey={'checkout.error.description'} />
</p>
)}
</AlertDescription>
</Alert>

View File

@@ -6,11 +6,14 @@ import { listProductTypes } from '@lib/data/products';
import { Trans } from '@kit/ui/trans';
import { withI18n } from '~/lib/i18n/with-i18n';
import { getCartReservations } from '~/lib/services/reservation.service';
import { findProductTypeIdByHandle } from '~/lib/utils';
import Cart from '../../_components/cart';
import CartTimer from '../../_components/cart/cart-timer';
import { loadCurrentUserAccount } from '../../_lib/server/load-user-account';
import { AccountBalanceService } from '@kit/accounts/services/account-balance.service';
import { EnrichedCartItem } from '../../_components/cart/types';
export async function generateMetadata() {
const { t } = await createI18nServerInstance();
@@ -37,29 +40,32 @@ async function CartPage() {
const balanceSummary = await new AccountBalanceService().getBalanceSummary(account.id);
const analysisPackagesType = productTypes.find(
({ metadata }) => metadata?.handle === 'analysis-packages',
const synlabAnalysisTypeId = findProductTypeIdByHandle(
productTypes,
'synlab-analysis',
);
const synlabAnalysisType = productTypes.find(
({ metadata }) => metadata?.handle === 'synlab-analysis',
const analysisPackagesTypeId = findProductTypeIdByHandle(
productTypes,
'analysis-packages',
);
const synlabAnalyses =
analysisPackagesType && synlabAnalysisType && cart?.items
analysisPackagesTypeId && synlabAnalysisTypeId && cart?.items
? cart.items.filter((item) => {
const productTypeId = item.product?.type_id;
if (!productTypeId) {
return false;
}
return [analysisPackagesType.id, synlabAnalysisType.id].includes(
return [analysisPackagesTypeId, synlabAnalysisTypeId].includes(
productTypeId,
);
})
: [];
const ttoServiceItems =
cart?.items?.filter(
(item) => !synlabAnalyses.some((analysis) => analysis.id === item.id),
) ?? [];
let ttoServiceItems: EnrichedCartItem[] = [];
if (cart?.items?.length) {
ttoServiceItems = await getCartReservations(cart);
}
const otherItemsSorted = ttoServiceItems.sort((a, b) =>
(a.updated_at ?? '') > (b.updated_at ?? '') ? -1 : 1,
);