Files
medreport_mrb2b/app/home/(user)/_components/order-analyses-cards.tsx
2025-10-21 09:36:29 +03:00

121 lines
3.6 KiB
TypeScript

'use client';
import { useState } from 'react';
import { formatCurrency } from '@/packages/shared/src/utils';
import { StoreProduct } from '@medusajs/types';
import { HeartPulse, Loader2, ShoppingCart } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { InfoTooltip } from '@kit/shared/components/ui/info-tooltip';
import { Button } from '@kit/ui/button';
import { Card, CardDescription, CardFooter, CardHeader } from '@kit/ui/card';
import { toast } from '@kit/ui/sonner';
import { Trans } from '@kit/ui/trans';
import { handleAddToCart } from '~/lib/services/medusaCart.service';
export type OrderAnalysisCard = Pick<
StoreProduct,
'title' | 'description' | 'subtitle'
> & {
variant: { id: string };
price: number | null;
};
export default function OrderAnalysesCards({
analyses,
countryCode,
}: {
analyses: OrderAnalysisCard[];
countryCode: string;
}) {
const {
i18n: { language },
} = useTranslation();
const [variantAddingToCart, setVariantAddingToCart] = useState<string | null>(
null,
);
const handleSelect = async (variantId: string) => {
if (variantAddingToCart) {
return null;
}
setVariantAddingToCart(variantId);
try {
await handleAddToCart({
selectedVariant: { id: variantId },
countryCode,
});
toast.success(<Trans i18nKey={'order-analysis:analysisAddedToCart'} />);
setVariantAddingToCart(null);
} catch (e) {
toast.error(<Trans i18nKey={'order-analysis:analysisAddToCartError'} />);
setVariantAddingToCart(null);
console.error(e);
}
};
return analyses.map(({ title, variant, description, subtitle, price }) => {
const formattedPrice =
typeof price === 'number'
? formatCurrency({
currencyCode: 'eur',
locale: language,
value: price,
})
: null;
return (
<Card
key={title}
variant="gradient-success"
className="flex flex-col justify-between"
>
<CardHeader className="flex-row">
<div className="bg-primary/10 mb-6 flex size-8 items-center-safe justify-center-safe rounded-full text-white">
<HeartPulse className="size-4 fill-green-500" />
</div>
<div className="bg-warning ml-auto flex size-8 items-center-safe justify-center-safe rounded-full text-white">
<Button
size="icon"
variant="outline"
className="px-2 text-black"
onClick={() => handleSelect(variant.id)}
>
{variantAddingToCart === variant.id ? (
<Loader2 className="size-4 animate-spin stroke-2" />
) : (
<ShoppingCart className="size-4 stroke-2" />
)}
</Button>
</div>
</CardHeader>
<CardFooter className="flex gap-2">
<div className="flex flex-1 flex-col items-start gap-2">
<h5>
{title}
{description && (
<>
<InfoTooltip
content={
<div className="flex flex-col gap-2">
<span>{formattedPrice}</span>
<span>{description}</span>
</div>
}
/>
</>
)}
</h5>
{subtitle && <CardDescription>{subtitle}</CardDescription>}
</div>
<div className="flex flex-col items-end gap-2 self-end text-sm">
<span>{formattedPrice}</span>
</div>
</CardFooter>
</Card>
);
});
}