allow adding discounts in cart

This commit is contained in:
2025-09-06 22:56:54 +03:00
parent d3202a2cb2
commit c83694222d
5 changed files with 119 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
"use client"
import { Badge, Heading, Text } from "@medusajs/ui"
import { Badge, Text } from "@medusajs/ui"
import { toast } from '@kit/ui/sonner';
import React, { useActionState } from "react";
import { applyPromotions, submitPromotionForm } from "@lib/data/cart"
@@ -31,11 +32,19 @@ export default function DiscountCode({ cart }: {
const removePromotionCode = async (code: string) => {
const validPromotions = promotions.filter(
(promotion) => promotion.code !== code
(promotion) => promotion.code !== code,
)
await applyPromotions(
validPromotions.filter((p) => p.code === undefined).map((p) => p.code!)
validPromotions.filter((p) => p.code === undefined).map((p) => p.code!),
{
onSuccess: () => {
toast.success(t('cart:discountCode.removeSuccess'));
},
onError: () => {
toast.error(t('cart:discountCode.removeError'));
},
}
)
}
@@ -45,7 +54,14 @@ export default function DiscountCode({ cart }: {
.map((p) => p.code!)
codes.push(code.toString())
await applyPromotions(codes)
await applyPromotions(codes, {
onSuccess: () => {
toast.success(t('cart:discountCode.addSuccess'));
},
onError: () => {
toast.error(t('cart:discountCode.addError'));
},
});
form.reset()
}
@@ -64,7 +80,7 @@ export default function DiscountCode({ cart }: {
<Form {...form}>
<form
onSubmit={form.handleSubmit((data) => addPromotionCode(data.code))}
className="w-full mb-2 flex gap-x-2"
className="w-full mb-2 flex gap-x-2 sm:flex-row flex-col gap-y-2"
>
<FormField
name={'code'}
@@ -87,16 +103,12 @@ export default function DiscountCode({ cart }: {
</form>
</Form>
<p className="text-sm text-muted-foreground">
<Trans i18nKey={'cart:discountCode.subtitle'} />
</p>
{promotions.length > 0 && (
<div className="w-full flex items-center">
<div className="flex flex-col w-full">
<Heading className="txt-medium mb-2">
Promotion(s) applied:
</Heading>
{promotions.length > 0 ? (
<div className="w-full flex items-center mt-4">
<div className="flex flex-col w-full gap-y-2">
<p>
<Trans i18nKey={'cart:discountCode.appliedCodes'} />
</p>
{promotions.map((promotion) => {
return (
@@ -110,6 +122,7 @@ export default function DiscountCode({ cart }: {
<Badge
color={promotion.is_automatic ? "green" : "grey"}
size="small"
className="px-4"
>
{promotion.code}
</Badge>{" "}
@@ -151,7 +164,7 @@ export default function DiscountCode({ cart }: {
>
<Trash size={14} />
<span className="sr-only">
Remove discount code from order
<Trans i18nKey={'cart:discountCode.remove'} />
</span>
</button>
)}
@@ -160,6 +173,10 @@ export default function DiscountCode({ cart }: {
})}
</div>
</div>
) : (
<p className="text-sm text-muted-foreground">
<Trans i18nKey={'cart:discountCode.subtitle'} />
</p>
)}
</div>
)

View File

@@ -18,7 +18,7 @@ import { useTranslation } from "react-i18next";
import { handleNavigateToPayment } from "@/lib/services/medusaCart.service";
import AnalysisLocation from "./analysis-location";
const IS_DISCOUNT_SHOWN = false as boolean;
const IS_DISCOUNT_SHOWN = true as boolean;
export default function Cart({
cart,
@@ -69,7 +69,7 @@ export default function Cart({
const hasCartItems = Array.isArray(cart.items) && cart.items.length > 0;
const isLocationsShown = synlabAnalyses.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">
@@ -77,28 +77,62 @@ export default function Cart({
<CartItems cart={cart} items={ttoServiceItems} productColumnLabelKey="cart:items.ttoServices.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 className="flex justify-end gap-x-4 px-6 pt-4">
<div className="mr-[36px]">
<p className="ml-0 font-bold text-sm text-muted-foreground">
<Trans i18nKey="cart:subtotal" />
</p>
</div>
<div className="mr-[116px]">
<p className="text-sm">
{formatCurrency({
value: cart.subtotal,
currencyCode: cart.currency_code,
locale: language,
})}
</p>
</div>
</div>
<div className="mr-[116px]">
<p className="text-sm">
{formatCurrency({
value: cart.total,
currencyCode: cart.currency_code,
locale: language,
})}
</p>
<div className="flex justify-end gap-x-4 px-6 py-2">
<div className="mr-[36px]">
<p className="ml-0 font-bold text-sm text-muted-foreground">
<Trans i18nKey="cart:promotionsTotal" />
</p>
</div>
<div className="mr-[116px]">
<p className="text-sm">
{formatCurrency({
value: cart.discount_total,
currencyCode: cart.currency_code,
locale: language,
})}
</p>
</div>
</div>
</div>
<div className="flex justify-end gap-x-4 px-6">
<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">
<div className="flex sm:flex-row flex-col gap-y-6 py-8 gap-x-4">
{IS_DISCOUNT_SHOWN && (
<Card
className="flex flex-col justify-between w-1/2"
className="flex flex-col justify-between w-full sm:w-1/2"
>
<CardHeader className="pb-4">
<h5>
@@ -113,7 +147,7 @@ export default function Cart({
{isLocationsShown && (
<Card
className="flex flex-col justify-between w-1/2"
className="flex flex-col justify-between w-full sm:w-1/2"
>
<CardHeader className="pb-4">
<h5>