Files
medreport_mrb2b/app/home/(user)/_components/cart/discount-code.tsx

167 lines
5.4 KiB
TypeScript

"use client"
import { Badge, Heading, Text } from "@medusajs/ui"
import React, { useActionState } from "react";
import { applyPromotions, submitPromotionForm } from "@lib/data/cart"
import { convertToLocale } from "@lib/util/money"
import { StoreCart, StorePromotion } from "@medusajs/types"
import Trash from "@modules/common/icons/trash"
import { Button } from '@kit/ui/button';
import { Form, FormControl, FormField, FormItem } from "@kit/ui/form";
import { Trans } from '@kit/ui/trans';
import { Input } from "@kit/ui/input";
import { useTranslation } from "react-i18next";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
const DiscountCodeSchema = z.object({
code: z.string().min(1),
})
export default function DiscountCode({ cart }: {
cart: StoreCart & {
promotions: StorePromotion[]
}
}) {
const { t } = useTranslation('cart');
const { promotions = [] } = cart;
const removePromotionCode = async (code: string) => {
const validPromotions = promotions.filter(
(promotion) => promotion.code !== code
)
await applyPromotions(
validPromotions.filter((p) => p.code === undefined).map((p) => p.code!)
)
}
const addPromotionCode = async (code: string) => {
const codes = promotions
.filter((p) => p.code === undefined)
.map((p) => p.code!)
codes.push(code.toString())
await applyPromotions(codes)
form.reset()
}
const [message, formAction] = useActionState(submitPromotionForm, null)
const form = useForm<z.infer<typeof DiscountCodeSchema>>({
defaultValues: {
code: '',
},
resolver: zodResolver(DiscountCodeSchema),
});
return (
<div className="w-full bg-white flex flex-col txt-medium">
<Form {...form}>
<form
onSubmit={form.handleSubmit((data) => addPromotionCode(data.code))}
className="w-full mb-2 flex gap-x-2"
>
<FormField
name={'code'}
render={({ field }) => (
<FormItem className="flex-1">
<FormControl>
<Input required type="text" {...field} placeholder={t('cart:discountCode.placeholder')} />
</FormControl>
</FormItem>
)}
/>
<Button
type="submit"
variant="secondary"
className="h-full"
>
<Trans i18nKey={'cart:discountCode.apply'} />
</Button>
</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.map((promotion) => {
return (
<div
key={promotion.id}
className="flex items-center justify-between w-full max-w-full mb-2"
data-testid="discount-row"
>
<Text className="flex gap-x-1 items-baseline txt-small-plus w-4/5 pr-1">
<span className="truncate" data-testid="discount-code">
<Badge
color={promotion.is_automatic ? "green" : "grey"}
size="small"
>
{promotion.code}
</Badge>{" "}
(
{promotion.application_method?.value !== undefined &&
promotion.application_method.currency_code !==
undefined && (
<>
{promotion.application_method.type ===
"percentage"
? `${promotion.application_method.value}%`
: convertToLocale({
amount: promotion.application_method.value,
currency_code:
promotion.application_method
.currency_code,
})}
</>
)}
)
{/* {promotion.is_automatic && (
<Tooltip content="This promotion is automatically applied">
<InformationCircleSolid className="inline text-zinc-400" />
</Tooltip>
)} */}
</span>
</Text>
{!promotion.is_automatic && (
<button
className="flex items-center"
onClick={() => {
if (!promotion.code) {
return
}
removePromotionCode(promotion.code)
}}
data-testid="remove-discount-button"
>
<Trash size={14} />
<span className="sr-only">
Remove discount code from order
</span>
</button>
)}
</div>
)
})}
</div>
</div>
)}
</div>
)
}