From 294c37564ca035dc9b658bdce1f6afb4ced3d916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frane=20Poli=C4=87?= <16856471+fPolic@users.noreply.github.com> Date: Wed, 24 Sep 2025 12:24:11 +0200 Subject: [PATCH] fix(dashboard): edit promotion campaign w/wo currrency (#13404) **What** - a promotion couldn't be added to a campaign without a currency budget (on promotion details screen) - fix fetching campaigns pagination issue - move select to Combobox - fix currency restriction and move warning description to the label hint --- .changeset/blue-hounds-unite.md | 5 + .../dashboard/src/hooks/api/campaigns.tsx | 1 + .../dashboard/src/i18n/translations/en.json | 2 +- .../add-campaign-promotion-form.tsx | 97 +++++++++---------- .../promotion-add-campaign.tsx | 25 +---- 5 files changed, 56 insertions(+), 74 deletions(-) create mode 100644 .changeset/blue-hounds-unite.md diff --git a/.changeset/blue-hounds-unite.md b/.changeset/blue-hounds-unite.md new file mode 100644 index 0000000000..842d2de948 --- /dev/null +++ b/.changeset/blue-hounds-unite.md @@ -0,0 +1,5 @@ +--- +"@medusajs/dashboard": patch +--- + +fix(dashboard): add campaign without currency to promotion diff --git a/packages/admin/dashboard/src/hooks/api/campaigns.tsx b/packages/admin/dashboard/src/hooks/api/campaigns.tsx index 1657ab2d8f..6d5f5824a2 100644 --- a/packages/admin/dashboard/src/hooks/api/campaigns.tsx +++ b/packages/admin/dashboard/src/hooks/api/campaigns.tsx @@ -130,6 +130,7 @@ export const useAddOrRemoveCampaignPromotions = ( onSuccess: (data, variables, context) => { queryClient.invalidateQueries({ queryKey: campaignsQueryKeys.details() }) queryClient.invalidateQueries({ queryKey: promotionsQueryKeys.lists() }) + queryClient.invalidateQueries({ queryKey: promotionsQueryKeys.details() }) options?.onSuccess?.(data, variables, context) }, ...options, diff --git a/packages/admin/dashboard/src/i18n/translations/en.json b/packages/admin/dashboard/src/i18n/translations/en.json index 7bcc278506..3be87b4f4a 100644 --- a/packages/admin/dashboard/src/i18n/translations/en.json +++ b/packages/admin/dashboard/src/i18n/translations/en.json @@ -2234,7 +2234,7 @@ "total_used": "Budget used", "budget_limit": "Budget limit", "campaign_id": { - "hint": "Only campaigns with the same currency code as the promotion are shown in this list." + "hint": "Disabled campaigns have budget in a different currency than the promotion." } }, "budget": { diff --git a/packages/admin/dashboard/src/routes/promotions/promotion-add-campaign/components/add-campaign-promotion-form/add-campaign-promotion-form.tsx b/packages/admin/dashboard/src/routes/promotions/promotion-add-campaign/components/add-campaign-promotion-form/add-campaign-promotion-form.tsx index 3b18547ef1..ee5aaf6d74 100644 --- a/packages/admin/dashboard/src/routes/promotions/promotion-add-campaign/components/add-campaign-promotion-form/add-campaign-promotion-form.tsx +++ b/packages/admin/dashboard/src/routes/promotions/promotion-add-campaign/components/add-campaign-promotion-form/add-campaign-promotion-form.tsx @@ -1,9 +1,9 @@ import { zodResolver } from "@hookform/resolvers/zod" import { AdminCampaign, AdminPromotion } from "@medusajs/types" -import { Button, RadioGroup, Select, Text, toast } from "@medusajs/ui" +import { Button, RadioGroup, toast } from "@medusajs/ui" import { useEffect } from "react" import { useForm, useWatch } from "react-hook-form" -import { Trans, useTranslation } from "react-i18next" +import { useTranslation } from "react-i18next" import * as zod from "zod" import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" @@ -11,11 +11,14 @@ import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useUpdatePromotion } from "../../../../../hooks/api/promotions" import { CreateCampaignFormFields } from "../../../../campaigns/common/components/create-campaign-form-fields" import { CampaignDetails } from "./campaign-details" +import { sdk } from "../../../../../lib/client" +import { useComboboxData } from "../../../../../hooks/use-combobox-data" +import { Combobox } from "../../../../../components/inputs/combobox" +import { useCampaign } from "../../../../../hooks/api/campaigns" import { useDocumentDirection } from "../../../../../hooks/use-document-direction" type EditPromotionFormProps = { promotion: AdminPromotion - campaigns: AdminCampaign[] } const EditPromotionSchema = zod.object({ @@ -25,14 +28,16 @@ const EditPromotionSchema = zod.object({ export const AddCampaignPromotionFields = ({ form, - campaigns, withNewCampaign = true, + promotionCurrencyCode, }: { form: any - campaigns: AdminCampaign[] withNewCampaign?: boolean + promotionCurrencyCode?: string }) => { const { t } = useTranslation() + const direction = useDocumentDirection() + const watchCampaignId = useWatch({ control: form.control, name: "campaign_id", @@ -43,8 +48,31 @@ export const AddCampaignPromotionFields = ({ name: "campaign_choice", }) - const selectedCampaign = campaigns.find((c) => c.id === watchCampaignId) - const direction = useDocumentDirection() + const campaignsCombobox = useComboboxData({ + queryFn: (params) => + sdk.admin.campaign.list({ + ...params, + }), + queryKey: ["campaigns"], + getOptions: (data) => + data.campaigns.map((campaign) => ({ + label: campaign.name.toUpperCase(), + value: campaign.id, + disabled: + campaign.budget?.currency_code && + campaign.budget?.currency_code?.toLowerCase() !== + promotionCurrencyCode?.toLowerCase(), // also cannot add promotion which doesn't have currency defined to a campaign with a currency amount budget + })), + }) + + const { campaign: selectedCampaign } = useCampaign( + watchCampaignId as string, + undefined, + { + enabled: !!watchCampaignId, + } + ) + return (