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

170 lines
5.7 KiB
TypeScript

'use client';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import { convertToLocale } from '@lib/util/money';
import { StoreCart, StorePromotion } from '@medusajs/types';
import { Badge, Text } from '@medusajs/ui';
import Trash from '@modules/common/icons/trash';
import { useTranslation } from 'react-i18next';
import { Button } from '@kit/ui/button';
import { FormControl, FormField, FormItem } from '@kit/ui/form';
import { Input } from '@kit/ui/input';
import { toast } from '@kit/ui/sonner';
import { Trans } from '@kit/ui/trans';
import { addPromotionCodeAction, removePromotionCodeAction } from './discount-code-actions';
export default function DiscountCode({
cart,
}: {
cart: StoreCart & {
promotions: StorePromotion[];
};
}) {
const { t } = useTranslation('cart');
const { setValue, watch } = useFormContext();
const currentValue = watch('code');
const { promotions = [] } = cart;
const removePromotionCode = async (code: string) => {
const appliedCodes = promotions
.filter((p) => p.code !== undefined)
.map((p) => p.code!);
const loading = toast.loading(t('cart:discountCode.removeLoading'));
const result = await removePromotionCodeAction(code, appliedCodes);
toast.dismiss(loading);
if (result.success) {
toast.success(t('cart:discountCode.removeSuccess'));
} else {
toast.error(t('cart:discountCode.removeError'));
}
};
const addPromotionCode = async (code: string) => {
if (!code || code.length === 0) {
return;
}
const loading = toast.loading(t('cart:discountCode.addLoading'));
const result = await addPromotionCodeAction(code);
toast.dismiss(loading);
if (result.success) {
toast.success(t('cart:discountCode.addSuccess'));
setValue('code', '');
} else {
toast.error(t('cart:discountCode.addError'));
}
};
return (
<div className="txt-medium flex h-full w-full flex-col gap-y-4 bg-white">
<p className="text-muted-foreground text-sm">
<Trans i18nKey={'cart:discountCode.subtitle'} />
</p>
<div className="mb-2 flex w-full flex-1 flex-col gap-x-2 gap-y-2 sm:flex-row">
<FormField
name={'code'}
render={({ field }) => (
<FormItem className="flex-1">
<FormControl>
<Input
required
type="text"
{...field}
placeholder={t('cart:discountCode.placeholder')}
/>
</FormControl>
</FormItem>
)}
/>
<Button type="button" variant="secondary" className="h-min" onClick={() => addPromotionCode(currentValue)}>
<Trans i18nKey={'cart:discountCode.apply'} />
</Button>
</div>
{promotions.length > 0 && (
<div className="mt-4 flex w-full items-center">
<div className="flex w-full flex-col gap-y-2">
<p>
<Trans i18nKey={'cart:discountCode.appliedCodes'} />
</p>
{promotions.map((promotion) => {
return (
<div
key={promotion.id}
className="mb-2 flex w-full max-w-full items-center justify-between"
data-testid="discount-row"
>
<Text className="flex w-4/5 items-baseline gap-x-1 pr-1 text-sm">
<span className="truncate" data-testid="discount-code">
<Badge
color={promotion.is_automatic ? 'green' : 'grey'}
size="small"
className="px-4 text-sm"
>
{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: Number(
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">
<Trans i18nKey={'cart:discountCode.remove'} />
</span>
</button>
)}
</div>
);
})}
</div>
</div>
)}
</div>
);
}