139 lines
4.3 KiB
TypeScript
139 lines
4.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Loader2 } from "lucide-react";
|
|
import { StoreCart, StoreCartLineItem } from "@medusajs/types"
|
|
import CartItems from "./cart-items"
|
|
import { Trans } from '@kit/ui/trans';
|
|
import { Button } from '@kit/ui/button';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardHeader,
|
|
} from '@kit/ui/card';
|
|
import DiscountCode from "./discount-code";
|
|
import { initiatePaymentSession } from "@lib/data/cart";
|
|
import { formatCurrency } from "@/packages/shared/src/utils";
|
|
import { useTranslation } from "react-i18next";
|
|
import { handleNavigateToPayment } from "@/lib/services/medusaCart.service";
|
|
import AnalysisLocation from "./analysis-location";
|
|
|
|
const IS_DISCOUNT_SHOWN = false as boolean;
|
|
|
|
export default function Cart({
|
|
cart,
|
|
analysisPackages,
|
|
otherItems,
|
|
}: {
|
|
cart: StoreCart | null
|
|
analysisPackages: StoreCartLineItem[];
|
|
otherItems: StoreCartLineItem[];
|
|
}) {
|
|
const { i18n: { language } } = useTranslation();
|
|
|
|
const [isInitiatingSession, setIsInitiatingSession] = useState(false);
|
|
|
|
const items = cart?.items ?? [];
|
|
|
|
if (!cart || items.length === 0) {
|
|
return (
|
|
<div className="content-container py-5 lg:px-4">
|
|
<div>
|
|
<div className="flex flex-col justify-center items-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>
|
|
);
|
|
}
|
|
|
|
async function initiatePayment() {
|
|
setIsInitiatingSession(true);
|
|
const response = await initiatePaymentSession(cart!, {
|
|
provider_id: 'pp_montonio_montonio',
|
|
});
|
|
if (response.payment_collection) {
|
|
const { payment_sessions } = response.payment_collection;
|
|
const paymentSessionId = payment_sessions![0]!.id;
|
|
const url = await handleNavigateToPayment({ language, paymentSessionId });
|
|
window.location.href = url;
|
|
} else {
|
|
setIsInitiatingSession(false);
|
|
}
|
|
}
|
|
|
|
const hasCartItems = Array.isArray(cart.items) && cart.items.length > 0;
|
|
const isLocationsShown = analysisPackages.length > 0;
|
|
|
|
return (
|
|
<div className="grid grid-cols-1 small:grid-cols-[1fr_360px] gap-x-40 lg:px-4">
|
|
<div className="flex flex-col bg-white gap-y-6">
|
|
<CartItems cart={cart} items={analysisPackages} productColumnLabelKey="cart:items.analysisPackages.productColumnLabel" />
|
|
<CartItems cart={cart} items={otherItems} productColumnLabelKey="cart:items.services.productColumnLabel" />
|
|
</div>
|
|
{hasCartItems && (
|
|
<div className="flex justify-end gap-x-4 px-6 py-4">
|
|
<div className="mr-[36px]">
|
|
<p className="ml-0 font-bold text-sm">
|
|
<Trans i18nKey="cart:total" />
|
|
</p>
|
|
</div>
|
|
<div className="mr-[116px]">
|
|
<p className="text-sm">
|
|
{formatCurrency({
|
|
value: cart.total,
|
|
currencyCode: cart.currency_code,
|
|
locale: language,
|
|
})}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div className="flex gap-y-6 py-8">
|
|
{IS_DISCOUNT_SHOWN && (
|
|
<Card
|
|
className="flex flex-col justify-between w-1/2"
|
|
>
|
|
<CardHeader className="pb-4">
|
|
<h5>
|
|
<Trans i18nKey="cart:discountCode.title" />
|
|
</h5>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<DiscountCode cart={{ ...cart }} />
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{isLocationsShown && (
|
|
<Card
|
|
className="flex flex-col justify-between w-1/2"
|
|
>
|
|
<CardHeader className="pb-4">
|
|
<h5>
|
|
<Trans i18nKey="cart:locations.title" />
|
|
</h5>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<AnalysisLocation cart={{ ...cart }} analysisPackages={analysisPackages} />
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
</div>
|
|
|
|
<div>
|
|
<Button className="h-10" onClick={initiatePayment} disabled={isInitiatingSession}>
|
|
{isInitiatingSession && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
|
|
<Trans i18nKey="cart:checkout.goToCheckout" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|