From 2aad0329f3c0fa44917bcc3aa8d67aa48dbc669d Mon Sep 17 00:00:00 2001 From: Karli Date: Wed, 10 Sep 2025 06:32:55 +0300 Subject: [PATCH] update cart discount for prod build, add loading toast --- .../_components/cart/discount-code-actions.ts | 24 ++++++++ .../(user)/_components/cart/discount-code.tsx | 59 ++++++++----------- public/locales/en/cart.json | 18 ++++-- public/locales/et/cart.json | 6 +- public/locales/ru/cart.json | 5 +- 5 files changed, 70 insertions(+), 42 deletions(-) create mode 100644 app/home/(user)/_components/cart/discount-code-actions.ts diff --git a/app/home/(user)/_components/cart/discount-code-actions.ts b/app/home/(user)/_components/cart/discount-code-actions.ts new file mode 100644 index 0000000..869ec78 --- /dev/null +++ b/app/home/(user)/_components/cart/discount-code-actions.ts @@ -0,0 +1,24 @@ +"use server" + +import { applyPromotions } from "@lib/data/cart" + +export async function addPromotionCodeAction(code: string) { + try { + await applyPromotions([code]); + return { success: true, message: 'Discount code applied successfully' }; + } catch (error) { + console.error('Error applying promotion code:', error); + return { success: false, message: 'Failed to apply discount code' }; + } +} + +export async function removePromotionCodeAction(codeToRemove: string, appliedCodes: string[]) { + try { + const updatedCodes = appliedCodes.filter((appliedCode) => appliedCode !== codeToRemove); + await applyPromotions(updatedCodes); + return { success: true, message: 'Discount code removed successfully' }; + } catch (error) { + console.error('Error removing promotion code:', error); + return { success: false, message: 'Failed to remove discount code' }; + } +} diff --git a/app/home/(user)/_components/cart/discount-code.tsx b/app/home/(user)/_components/cart/discount-code.tsx index eea8ef4..9df9073 100644 --- a/app/home/(user)/_components/cart/discount-code.tsx +++ b/app/home/(user)/_components/cart/discount-code.tsx @@ -2,9 +2,8 @@ import { Badge, Text } from "@medusajs/ui" import { toast } from '@kit/ui/sonner'; -import React, { useActionState } from "react"; +import React 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" @@ -16,6 +15,7 @@ import { useTranslation } from "react-i18next"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { z } from "zod"; +import { addPromotionCodeAction, removePromotionCodeAction } from "./discount-code-actions"; const DiscountCodeSchema = z.object({ code: z.string().min(1), @@ -31,42 +31,35 @@ export default function DiscountCode({ cart }: { const { promotions = [] } = cart; const removePromotionCode = async (code: string) => { - const validPromotions = promotions.filter( - (promotion) => promotion.code !== code, - ) + const appliedCodes = promotions + .filter((p) => p.code !== undefined) + .map((p) => p.code!) - await applyPromotions( - validPromotions.filter((p) => p.code === undefined).map((p) => p.code!), - { - onSuccess: () => { - toast.success(t('cart:discountCode.removeSuccess')); - }, - onError: () => { - toast.error(t('cart:discountCode.removeError')); - }, - } - ) + 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) => { - const codes = promotions - .filter((p) => p.code === undefined) - .map((p) => p.code!) - codes.push(code.toString()) - - await applyPromotions(codes, { - onSuccess: () => { - toast.success(t('cart:discountCode.addSuccess')); - }, - onError: () => { - toast.error(t('cart:discountCode.addError')); - }, - }); - - form.reset() + 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')); + form.reset() + } else { + toast.error(t('cart:discountCode.addError')); + } } - const [message, formAction] = useActionState(submitPromotionForm, null) const form = useForm>({ defaultValues: { @@ -135,7 +128,7 @@ export default function DiscountCode({ cart }: { "percentage" ? `${promotion.application_method.value}%` : convertToLocale({ - amount: promotion.application_method.value, + amount: Number(promotion.application_method.value), currency_code: promotion.application_method .currency_code, diff --git a/public/locales/en/cart.json b/public/locales/en/cart.json index 0c9af9a..a78a8cb 100644 --- a/public/locales/en/cart.json +++ b/public/locales/en/cart.json @@ -25,13 +25,19 @@ "timeoutAction": "Continue" }, "discountCode": { - "title": "Gift card or promotion code", - "label": "Add Promotion Code(s)", + "title": "Gift card or promo code", + "label": "Add Promo Code(s)", "apply": "Apply", - "subtitle": "If you wish, you can add a promotion code", - "placeholder": "Enter promotion code", - "remove": "Remove promotion code", - "appliedCodes": "Promotion(s) applied:" + "subtitle": "If you wish, you can add a promo code", + "placeholder": "Enter promo code", + "remove": "Remove promo code", + "appliedCodes": "Promotions(s) applied:", + "removeError": "Failed to remove promo code", + "removeSuccess": "Promo code removed", + "removeLoading": "Removing promo code...", + "addError": "Failed to add promo code", + "addSuccess": "Promo code added", + "addLoading": "Setting promo code..." }, "items": { "synlabAnalyses": { diff --git a/public/locales/et/cart.json b/public/locales/et/cart.json index fe87f7b..e5e7376 100644 --- a/public/locales/et/cart.json +++ b/public/locales/et/cart.json @@ -4,8 +4,8 @@ "emptyCartMessage": "Sinu ostukorv on tühi", "emptyCartMessageDescription": "Lisa tooteid ostukorvi, et jätkata.", "subtotal": "Vahesumma", - "promotionsTotal": "Soodustuse summa", "total": "Summa", + "promotionsTotal": "Soodustuse summa", "table": { "item": "Toode", "quantity": "Kogus", @@ -34,8 +34,10 @@ "appliedCodes": "Rakendatud sooduskoodid:", "removeError": "Sooduskoodi eemaldamine ebaõnnestus", "removeSuccess": "Sooduskood eemaldatud", + "removeLoading": "Sooduskoodi eemaldamine", "addError": "Sooduskoodi rakendamine ebaõnnestus", - "addSuccess": "Sooduskood rakendatud" + "addSuccess": "Sooduskood rakendatud", + "addLoading": "Rakendan sooduskoodi..." }, "items": { "synlabAnalyses": { diff --git a/public/locales/ru/cart.json b/public/locales/ru/cart.json index 7f3c536..bac0c63 100644 --- a/public/locales/ru/cart.json +++ b/public/locales/ru/cart.json @@ -5,6 +5,7 @@ "emptyCartMessageDescription": "Добавьте товары в корзину, чтобы продолжить.", "subtotal": "Промежуточный итог", "total": "Сумма", + "promotionsTotal": "Скидка", "table": { "item": "Товар", "quantity": "Количество", @@ -33,8 +34,10 @@ "appliedCodes": "Примененные промокоды:", "removeError": "Не удалось удалить промокод", "removeSuccess": "Промокод удален", + "removeLoading": "Удаление промокода...", "addError": "Не удалось применить промокод", - "addSuccess": "Промокод применен" + "addSuccess": "Промокод применен", + "addLoading": "Применение промокода..." }, "items": { "synlabAnalyses": {