162 lines
5.3 KiB
TypeScript
162 lines
5.3 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 type { AccountWithParams } from '@kit/accounts/types/accounts';
|
|
import type { 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,
|
|
{
|
|
variant,
|
|
variantId: variant.id,
|
|
nrOfAnalyses: getAnalysisElementMedusaProductIds([{ ...product, variant }]).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);
|