Files
medreport_mrb2b/app/home/(user)/_lib/server/load-analysis-packages.ts
2025-09-09 09:57:01 +03:00

161 lines
5.2 KiB
TypeScript

import { cache } from 'react';
import { listProductTypes, listProducts } from "@lib/data/products";
import { listRegions } from '@lib/data/regions';
import { getAnalysisElementMedusaProductIds } from '@/utils/medusa-product';
import type { StoreProduct } from '@medusajs/types';
import { loadCurrentUserAccount } from './load-user-account';
import { AccountWithParams } from '@/packages/features/accounts/src/server/api';
import { AnalysisPackageWithVariant } from '@kit/shared/components/select-analysis-package';
import PersonalCode from '~/lib/utils';
async function countryCodesLoader() {
const countryCodes = await listRegions().then((regions) =>
regions?.map((r) => r.countries?.map((c) => c.iso_2)).flat(),
);
return countryCodes ?? [];
}
export const loadCountryCodes = cache(countryCodesLoader);
async function productTypesLoader() {
const { productTypes } = await listProductTypes();
return productTypes ?? [];
}
export const loadProductTypes = cache(productTypesLoader);
function userSpecificVariantLoader({
account,
}: {
account: AccountWithParams;
}) {
const { personal_code: personalCode } = account;
if (!personalCode) {
throw new Error('Personal code not found');
}
const { ageRange, gender: { value: gender } } = PersonalCode.parsePersonalCode(personalCode);
return ({
product,
}: {
product: StoreProduct;
}) => {
const variants = product.variants;
if (!variants) {
return null;
}
const variant = variants.find((v) => v.options?.every((o) => [ageRange, gender].includes(o.value)));
if (!variant) {
return null;
}
return variant;
}
}
async function analysisPackageElementsLoader({
analysisPackagesWithVariant,
countryCode,
}: {
analysisPackagesWithVariant: AnalysisPackageWithVariant[];
countryCode: string;
}) {
const analysisElementMedusaProductIds = getAnalysisElementMedusaProductIds(analysisPackagesWithVariant);
if (analysisElementMedusaProductIds.length === 0) {
return [];
}
const { response: { products } } = await listProducts({
countryCode,
queryParams: {
id: analysisElementMedusaProductIds,
limit: 100,
order: "title",
},
});
const standardPackage = analysisPackagesWithVariant.find(({ isStandard }) => isStandard);
const standardPlusPackage = analysisPackagesWithVariant.find(({ isStandardPlus }) => isStandardPlus);
const premiumPackage = analysisPackagesWithVariant.find(({ isPremium }) => isPremium);
if (!standardPackage || !standardPlusPackage || !premiumPackage) {
return [];
}
const standardPackageAnalyses = getAnalysisElementMedusaProductIds([standardPackage]);
const standardPlusPackageAnalyses = getAnalysisElementMedusaProductIds([standardPlusPackage]);
const premiumPackageAnalyses = getAnalysisElementMedusaProductIds([premiumPackage]);
return products.map(({ id, title, description }) => ({
id,
title,
description,
isIncludedInStandard: standardPackageAnalyses.includes(id),
isIncludedInStandardPlus: standardPlusPackageAnalyses.includes(id),
isIncludedInPremium: premiumPackageAnalyses.includes(id),
}));
}
async function analysisPackagesWithVariantLoader({
account,
countryCode,
}: {
account: AccountWithParams;
countryCode: string;
}) {
const productTypes = await loadProductTypes();
const productType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages');
if (!productType) {
return null;
}
const analysisPackagesResponse = await listProducts({
countryCode,
queryParams: { limit: 100, "type_id[0]": productType.id },
});
const getVariant = userSpecificVariantLoader({ account });
const analysisPackagesWithVariant = analysisPackagesResponse.response.products
.reduce((acc, product) => {
const variant = getVariant({ product });
if (!variant) {
return acc;
}
return [
...acc,
{
variantId: variant.id,
nrOfAnalyses: getAnalysisElementMedusaProductIds([product]).length,
price: variant.calculated_price?.calculated_amount ?? 0,
title: product.title,
subtitle: product.subtitle,
description: product.description,
metadata: product.metadata,
isStandard: product.metadata?.analysisPackageTier === 'standard',
isStandardPlus: product.metadata?.analysisPackageTier === 'standard-plus',
isPremium: product.metadata?.analysisPackageTier === 'premium',
},
];
}, [] as AnalysisPackageWithVariant[]);
return analysisPackagesWithVariant;
}
async function analysisPackagesLoader() {
const account = await loadCurrentUserAccount();
if (!account) {
throw new Error('Account not found');
}
const countryCodes = await loadCountryCodes();
const countryCode = countryCodes[0]!;
const analysisPackagesWithVariant = await analysisPackagesWithVariantLoader({ account, countryCode });
if (!analysisPackagesWithVariant) {
return { analysisPackageElements: [], analysisPackages: [], countryCode };
}
const analysisPackageElements = await analysisPackageElementsLoader({ analysisPackagesWithVariant, countryCode });
return { analysisPackageElements, analysisPackages: analysisPackagesWithVariant, countryCode };
}
export const loadAnalysisPackages = cache(analysisPackagesLoader);