From 1d540af7830417301d7dd8340f8c81582a4d8fca Mon Sep 17 00:00:00 2001 From: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com> Date: Thu, 17 Oct 2024 11:38:12 +0200 Subject: [PATCH] feat(dashboard): Submit forms on Cmd + Enter (#9623) **What** - Changes all forms to only submit on Cmd/Ctrl + Enter instead of just Enter. - Cleans up the position of submit/cancel buttons in many FocusModals that still had them in the header. - Fixes responsiveness of multiple forms - Removes the SplitView component, and replaces its usages with StackedDrawer/Modal to align the UX across the project. Resolves CC-103, CC-535 --- .../forms/metadata-form/metadata-form.tsx | 5 +- .../components/inputs/combobox/combobox.tsx | 2 +- .../src/components/layout/split-view/index.ts | 1 - .../layout/split-view/split-view.tsx | 103 ---- .../generic-forward-ref.tsx | 0 .../generic-forward-ref/index.ts | 0 .../utilities/keybound-form/index.ts | 1 + .../utilities/keybound-form/keybound-form.tsx | 35 ++ .../utilities/visually-hidden/index.ts | 1 + .../visually-hidden/visually-hidden.tsx | 5 + .../dashboard/src/i18n/translations/en.json | 6 + .../api-key-create-form.tsx | 54 ++- .../api-key-management-edit.tsx | 10 +- .../edit-api-key-form/edit-api-key-form.tsx | 5 +- .../api-key-sales-channels-form.tsx | 44 +- .../add-campaign-promotions-form.tsx | 25 +- .../campaign-budget-edit.tsx | 4 +- .../edit-campaign-budget-form.tsx | 5 +- .../campaign-configuration-form.tsx | 5 +- .../create-campaign-form.tsx | 34 +- .../campaigns/campaign-edit/campaign-edit.tsx | 8 +- .../edit-campaign-form/edit-campaign-form.tsx | 5 +- .../create-campaign-form-fields.tsx | 15 +- .../src/routes/campaigns/common/constants.ts | 14 + .../create-category-form.tsx | 5 +- .../edit-category-form/edit-category-form.tsx | 5 +- .../edit-category-products-form.tsx | 5 +- .../add-products-to-collection-form.tsx | 5 +- .../create-collection-form.tsx | 13 +- .../edit-collection-form.tsx | 10 +- .../add-customers-form/add-customers-form.tsx | 5 +- .../create-customer-group-form.tsx | 50 +- .../edit-customer-group-form.tsx | 5 +- .../create-customer-form.tsx | 45 +- .../edit-customer-form/edit-customer-form.tsx | 5 +- ...transfer-customer-order-ownership-form.tsx | 7 +- .../add-customer-groups-form.tsx | 19 +- .../inventory-create-form.tsx | 5 +- .../components/adjust-inventory-form.tsx | 5 +- .../components/edit-item-attributes-form.tsx | 5 +- .../components/edit-item-form.tsx | 5 +- .../components/manage-locations-form.tsx | 5 +- .../dashboard/src/routes/invite/invite.tsx | 16 +- .../geo-zone-form/geo-zone-form.tsx | 68 +-- .../src/routes/locations/common/constants.ts | 2 + .../create-location-form.tsx | 30 +- .../edit-location-form/edit-location-form.tsx | 5 +- .../create-service-zone-form.tsx | 109 +++-- .../edit-service-zone-form.tsx | 10 +- .../edit-service-zone-areas-form.tsx | 54 +-- .../create-shipping-options-form.tsx | 43 +- .../edit-shipping-option-form.tsx | 5 +- .../edit-shipping-options-pricing-form.tsx | 5 +- .../dashboard/src/routes/login/login.tsx | 5 +- .../order-allocate-items-form.tsx | 52 ++- .../claim-create-form/claim-create-form.tsx | 20 +- .../order-edit-create-form.tsx | 11 +- .../exchange-create-form.tsx | 9 +- .../order-create-fulfillment-form.tsx | 31 +- .../create-refund-form/create-refund-form.tsx | 12 +- .../return-create-form/return-create-form.tsx | 20 +- .../order-create-shipment-form.tsx | 5 +- .../order-note-form.tsx | 5 +- .../order-receive-return-form.tsx | 7 +- .../price-list-configuration-form.tsx | 5 +- .../price-list-create-form.tsx | 16 +- .../edit-price-list-form.tsx | 5 +- .../price-list-prices-add-form.tsx | 5 +- .../price-list-prices-edit-form.tsx | 38 +- .../product-tag-create-form.tsx | 5 +- .../product-tag-edit-form.tsx | 5 +- .../create-product-type-form.tsx | 8 +- .../edit-product-type-form.tsx | 5 +- .../product-edit-variant-form.tsx | 17 +- .../manage-variant-inventory-items-form.tsx | 5 +- .../product-attributes-form.tsx | 5 +- .../create-product-option-form.tsx | 5 +- .../create-product-variant-form.tsx | 26 +- .../product-create-form.tsx | 21 +- .../product-create-organize-context/index.ts | 2 - .../product-create-details-context.tsx | 9 - .../use-product-create-details-context.tsx | 14 - ...roduct-create-details-organize-section.tsx | 16 +- .../index.ts | 0 .../product-create-sales-channel-drawer.tsx | 55 ++- .../product-create-organize-form/constants.ts | 1 + .../product-create-organize-form.tsx | 40 +- .../edit-product-option-form.tsx | 10 +- .../edit-product-form/edit-product-form.tsx | 5 +- .../edit-product-media-form.tsx | 27 +- .../product-organization-form.tsx | 5 +- .../products/product-prices/pricing-edit.tsx | 5 +- .../edit-sales-channels-form.tsx | 32 +- .../edit-profile-form/edit-profile-form.tsx | 5 +- .../edit-rules-form/edit-rules-form.tsx | 8 +- .../add-campaign-promotion-form.tsx | 5 +- .../create-promotion-form.tsx | 11 +- .../edit-promotion-details-form.tsx | 5 +- .../add-countries-form/add-countries-form.tsx | 5 +- .../create-region-form/create-region-form.tsx | 439 +++++++++--------- .../edit-region-form/edit-region-form.tsx | 5 +- .../reservation-create-from.tsx | 5 +- .../components/edit-reservation-form.tsx | 7 +- .../routes/reset-password/reset-password.tsx | 15 +- .../return-reason-create-form.tsx | 5 +- .../return-reason-edit-form.tsx | 5 +- .../add-products-to-sales-channel-form.tsx | 25 +- .../create-sales-channel-form.tsx | 30 +- .../edit-sales-channel-form.tsx | 5 +- .../create-shipping-profile-form.tsx | 30 +- .../add-currencies-form.tsx | 27 +- .../edit-store-form/edit-store-form.tsx | 5 +- .../tax-region-create-form.tsx | 5 +- .../tax-region-province-create-form.tsx | 5 +- .../tax-region-tax-override-create.tsx | 5 +- .../tax-region-tax-override-edit-form.tsx | 5 +- .../tax-region-tax-rate-create-form.tsx | 5 +- .../tax-region-tax-rate-edit-form.tsx | 5 +- .../edit-user-form/edit-user-form.tsx | 10 +- .../invite-user-form/invite-user-form.tsx | 5 +- 120 files changed, 1138 insertions(+), 1056 deletions(-) delete mode 100644 packages/admin/dashboard/src/components/layout/split-view/index.ts delete mode 100644 packages/admin/dashboard/src/components/layout/split-view/split-view.tsx rename packages/admin/dashboard/src/components/{common => utilities}/generic-forward-ref/generic-forward-ref.tsx (100%) rename packages/admin/dashboard/src/components/{common => utilities}/generic-forward-ref/index.ts (100%) create mode 100644 packages/admin/dashboard/src/components/utilities/keybound-form/index.ts create mode 100644 packages/admin/dashboard/src/components/utilities/keybound-form/keybound-form.tsx create mode 100644 packages/admin/dashboard/src/components/utilities/visually-hidden/index.ts create mode 100644 packages/admin/dashboard/src/components/utilities/visually-hidden/visually-hidden.tsx create mode 100644 packages/admin/dashboard/src/routes/campaigns/common/constants.ts delete mode 100644 packages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-context/index.ts delete mode 100644 packages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-context/product-create-details-context.tsx delete mode 100644 packages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-context/use-product-create-details-context.tsx rename packages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/{product-create-sales-channel-drawer => product-create-sales-channel-stacked-modal}/index.ts (100%) rename packages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/{product-create-sales-channel-drawer => product-create-sales-channel-stacked-modal}/product-create-sales-channel-drawer.tsx (78%) create mode 100644 packages/admin/dashboard/src/routes/products/product-create/components/product-create-organize-form/constants.ts diff --git a/packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx b/packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx index f19ff2d33a..c59374f055 100644 --- a/packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx +++ b/packages/admin/dashboard/src/components/forms/metadata-form/metadata-form.tsx @@ -24,6 +24,7 @@ import { Form } from "../../common/form" import { InlineTip } from "../../common/inline-tip" import { Skeleton } from "../../common/skeleton" import { RouteDrawer, useRouteModal } from "../../modals" +import { KeyboundForm } from "../../utilities/keybound-form" type MetaDataSubmitHook = ( params: { metadata?: Record | null }, @@ -125,7 +126,7 @@ const InnerForm = ({ return ( -
@@ -277,7 +278,7 @@ const InnerForm = ({ - +
) } diff --git a/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx b/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx index 38414c3287..e1670cea96 100644 --- a/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx +++ b/packages/admin/dashboard/src/components/inputs/combobox/combobox.tsx @@ -32,7 +32,7 @@ import { } from "react" import { useTranslation } from "react-i18next" -import { genericForwardRef } from "../../common/generic-forward-ref" +import { genericForwardRef } from "../../utilities/generic-forward-ref" type ComboboxOption = { value: string diff --git a/packages/admin/dashboard/src/components/layout/split-view/index.ts b/packages/admin/dashboard/src/components/layout/split-view/index.ts deleted file mode 100644 index b717c0fded..0000000000 --- a/packages/admin/dashboard/src/components/layout/split-view/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./split-view" diff --git a/packages/admin/dashboard/src/components/layout/split-view/split-view.tsx b/packages/admin/dashboard/src/components/layout/split-view/split-view.tsx deleted file mode 100644 index decade8003..0000000000 --- a/packages/admin/dashboard/src/components/layout/split-view/split-view.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { Button, clx } from "@medusajs/ui" -import * as Dialog from "@radix-ui/react-dialog" -import { - ComponentPropsWithoutRef, - PropsWithChildren, - createContext, - useContext, - useRef, -} from "react" - -type SplitViewContextValue = { - open: boolean - onOpenChange: (open: boolean) => void -} - -const SplitViewContext = createContext(null) - -const useSplitViewContext = () => { - const context = useContext(SplitViewContext) - - if (!context) { - throw new Error("useSplitViewContext must be used within a SplitView") - } - - return context -} - -type SplitViewProps = PropsWithChildren<{ - open?: boolean - onOpenChange?: (open: boolean) => void -}> - -const Root = ({ open, onOpenChange, children }: SplitViewProps) => { - const containerRef = useRef(null) - - return ( - -
- {children} -
-
- ) -} - -const Content = ({ - children, - className, - ...props -}: ComponentPropsWithoutRef<"div">) => { - return ( -
- {children} -
- ) -} - -const Drawer = ({ children }: PropsWithChildren) => { - return ( -
- - - {children} - -
- ) -} - -const Close = ({ - variant = "secondary", - size = "small", - children, - ...props -}: ComponentPropsWithoutRef) => { - return ( - - - - ) -} - -/** - * SplitView is a layout component that allows you to create a split view layout within a FocusModal. - */ -export const SplitView = Object.assign(Root, { - Content, - Drawer, - Close, -}) diff --git a/packages/admin/dashboard/src/components/common/generic-forward-ref/generic-forward-ref.tsx b/packages/admin/dashboard/src/components/utilities/generic-forward-ref/generic-forward-ref.tsx similarity index 100% rename from packages/admin/dashboard/src/components/common/generic-forward-ref/generic-forward-ref.tsx rename to packages/admin/dashboard/src/components/utilities/generic-forward-ref/generic-forward-ref.tsx diff --git a/packages/admin/dashboard/src/components/common/generic-forward-ref/index.ts b/packages/admin/dashboard/src/components/utilities/generic-forward-ref/index.ts similarity index 100% rename from packages/admin/dashboard/src/components/common/generic-forward-ref/index.ts rename to packages/admin/dashboard/src/components/utilities/generic-forward-ref/index.ts diff --git a/packages/admin/dashboard/src/components/utilities/keybound-form/index.ts b/packages/admin/dashboard/src/components/utilities/keybound-form/index.ts new file mode 100644 index 0000000000..b310b055fb --- /dev/null +++ b/packages/admin/dashboard/src/components/utilities/keybound-form/index.ts @@ -0,0 +1 @@ +export * from "./keybound-form" diff --git a/packages/admin/dashboard/src/components/utilities/keybound-form/keybound-form.tsx b/packages/admin/dashboard/src/components/utilities/keybound-form/keybound-form.tsx new file mode 100644 index 0000000000..6315b80c35 --- /dev/null +++ b/packages/admin/dashboard/src/components/utilities/keybound-form/keybound-form.tsx @@ -0,0 +1,35 @@ +import React from "react" + +/** + * A form that can only be submitted when using the meta or control key. + */ +export const KeyboundForm = React.forwardRef< + HTMLFormElement, + React.FormHTMLAttributes +>(({ onSubmit, onKeyDown, ...rest }, ref) => { + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault() + onSubmit?.(event) + } + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key === "Enter") { + event.preventDefault() + + if (event.metaKey || event.ctrlKey) { + handleSubmit(event) + } + } + } + + return ( +
+ ) +}) + +KeyboundForm.displayName = "KeyboundForm" diff --git a/packages/admin/dashboard/src/components/utilities/visually-hidden/index.ts b/packages/admin/dashboard/src/components/utilities/visually-hidden/index.ts new file mode 100644 index 0000000000..2a2698d67f --- /dev/null +++ b/packages/admin/dashboard/src/components/utilities/visually-hidden/index.ts @@ -0,0 +1 @@ +export * from "./visually-hidden" diff --git a/packages/admin/dashboard/src/components/utilities/visually-hidden/visually-hidden.tsx b/packages/admin/dashboard/src/components/utilities/visually-hidden/visually-hidden.tsx new file mode 100644 index 0000000000..d55b1c464a --- /dev/null +++ b/packages/admin/dashboard/src/components/utilities/visually-hidden/visually-hidden.tsx @@ -0,0 +1,5 @@ +import { PropsWithChildren } from "react" + +export const VisuallyHidden = ({ children }: PropsWithChildren) => { + return {children} +} diff --git a/packages/admin/dashboard/src/i18n/translations/en.json b/packages/admin/dashboard/src/i18n/translations/en.json index ec3c6b9b83..6b4a0a3e13 100644 --- a/packages/admin/dashboard/src/i18n/translations/en.json +++ b/packages/admin/dashboard/src/i18n/translations/en.json @@ -1877,6 +1877,7 @@ }, "edit": { "header": "Edit Campaign", + "description": "Edit the details of the campaign.", "successToast": "Campaign '{{name}}' was successfully updated." }, "configuration": { @@ -1888,6 +1889,8 @@ } }, "create": { + "title": "Create Campaign", + "description": "Create a promotional campaign.", "hint": "Create a promotional campaign.", "header": "Create Campaign", "successToast": "Campaign '{{name}}' was successfully created." @@ -2301,9 +2304,12 @@ }, "edit": { "header": "Edit API Key", + "description": "Edit the API key's title.", "successToast": "API key {{title}} was successfully updated." }, "salesChannels": { + "title": "Add Sales Channels", + "description": "Add the sales channels that the API key should be limited to.", "successToast_one": "{{count}} sales channel was successfully added to the API key.", "successToast_other": "{{count}} sales channels were successfully added to the API key.", "alreadyAddedTooltip": "The sales channel has already been added to the API key.", diff --git a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-create/components/api-key-create-form/api-key-create-form.tsx b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-create/components/api-key-create-form/api-key-create-form.tsx index 7de281ece1..defd3a6949 100644 --- a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-create/components/api-key-create-form/api-key-create-form.tsx +++ b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-create/components/api-key-create-form/api-key-create-form.tsx @@ -12,6 +12,7 @@ import { RouteFocusModal, useRouteModal, } from "../../../../../components/modals" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useCreateApiKey } from "../../../../../hooks/api/api-keys" import { ApiKeyType } from "../../../common/constants" @@ -97,36 +98,29 @@ export const ApiKeyCreateForm = ({ keyType }: ApiKeyCreateFormProps) => { return ( - - -
- - - - -
-
+
- - {keyType === ApiKeyType.PUBLISHABLE - ? t("apiKeyManagement.create.createPublishableHeader") - : t("apiKeyManagement.create.createSecretHeader")} - - - {keyType === ApiKeyType.PUBLISHABLE - ? t("apiKeyManagement.create.createPublishableHint") - : t("apiKeyManagement.create.createSecretHint")} - + + + {keyType === ApiKeyType.PUBLISHABLE + ? t("apiKeyManagement.create.createPublishableHeader") + : t("apiKeyManagement.create.createSecretHeader")} + + + + + {keyType === ApiKeyType.PUBLISHABLE + ? t("apiKeyManagement.create.createPublishableHint") + : t("apiKeyManagement.create.createSecretHint")} + +
{
- + +
+ + + + +
+
+ diff --git a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx index 43ebb25378..f549ee29d7 100644 --- a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx +++ b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/api-key-management-edit.tsx @@ -2,6 +2,7 @@ import { Heading } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { useParams } from "react-router-dom" import { RouteDrawer } from "../../../components/modals" +import { VisuallyHidden } from "../../../components/utilities/visually-hidden" import { useApiKey } from "../../../hooks/api/api-keys" import { EditApiKeyForm } from "./components/edit-api-key-form" @@ -18,7 +19,14 @@ export const ApiKeyManagementEdit = () => { return ( - {t("apiKeyManagement.edit.header")} + + {t("apiKeyManagement.edit.header")} + + + + {t("apiKeyManagement.edit.description")} + + {!isLoading && !!api_key && } diff --git a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx index 977604cd6a..607f4cfdd7 100644 --- a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx +++ b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-edit/components/edit-api-key-form/edit-api-key-form.tsx @@ -7,6 +7,7 @@ import * as zod from "zod" import { ApiKeyDTO } from "@medusajs/types" import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useUpdateApiKey } from "../../../../../hooks/api/api-keys" type EditApiKeyFormProps = { @@ -48,7 +49,7 @@ export const EditApiKeyForm = ({ apiKey }: EditApiKeyFormProps) => { return ( -
+
{
- +
) } diff --git a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-sales-channels/components/api-key-sales-channels-form/api-key-sales-channels-form.tsx b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-sales-channels/components/api-key-sales-channels-form/api-key-sales-channels-form.tsx index 61fd4486ce..21455f62c8 100644 --- a/packages/admin/dashboard/src/routes/api-key-management/api-key-management-sales-channels/components/api-key-sales-channels-form/api-key-sales-channels-form.tsx +++ b/packages/admin/dashboard/src/routes/api-key-management/api-key-management-sales-channels/components/api-key-sales-channels-form/api-key-sales-channels-form.tsx @@ -16,9 +16,12 @@ import { useRouteModal, } from "../../../../../components/modals" import { DataTable } from "../../../../../components/table/data-table" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" +import { VisuallyHidden } from "../../../../../components/utilities/visually-hidden" import { useBatchAddSalesChannelsToApiKey } from "../../../../../hooks/api/api-keys" import { useSalesChannels } from "../../../../../hooks/api/sales-channels" import { useSalesChannelTableColumns } from "../../../../../hooks/table/columns/use-sales-channel-table-columns" +import { useSalesChannelTableFilters } from "../../../../../hooks/table/filters" import { useSalesChannelTableQuery } from "../../../../../hooks/table/query/use-sales-channel-table-query" import { useDataTable } from "../../../../../hooks/use-data-table" @@ -58,6 +61,7 @@ export const ApiKeySalesChannelsForm = ({ }) const columns = useColumns() + const filters = useSalesChannelTableFilters() const { sales_channels, count, isLoading } = useSalesChannels( { ...searchParams }, @@ -114,33 +118,33 @@ export const ApiKeySalesChannelsForm = ({ return ( -
+ + + + {t("apiKeyManagement.salesChannels.title")} + + + + + {t("apiKeyManagement.salesChannels.description")} + +
{form.formState.errors.sales_channel_ids && ( {form.formState.errors.sales_channel_ids.message} )} - - - -
- + - + +
+ + + + +
+
+
) } diff --git a/packages/admin/dashboard/src/routes/campaigns/add-campaign-promotions/components/add-campaign-promotions-form.tsx b/packages/admin/dashboard/src/routes/campaigns/add-campaign-promotions/components/add-campaign-promotions-form.tsx index d968f45bfb..ab9f89f1b3 100644 --- a/packages/admin/dashboard/src/routes/campaigns/add-campaign-promotions/components/add-campaign-promotions-form.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/add-campaign-promotions/components/add-campaign-promotions-form.tsx @@ -13,6 +13,7 @@ import { useTranslation } from "react-i18next" import * as zod from "zod" import { RouteFocusModal, useRouteModal } from "../../../../components/modals" import { DataTable } from "../../../../components/table/data-table" +import { KeyboundForm } from "../../../../components/utilities/keybound-form" import { useAddOrRemoveCampaignPromotions } from "../../../../hooks/api/campaigns" import { usePromotions } from "../../../../hooks/api/promotions" import { usePromotionTableColumns } from "../../../../hooks/table/columns/use-promotion-table-columns" @@ -109,7 +110,7 @@ export const AddCampaignPromotionsForm = ({ return ( -
@@ -120,14 +121,6 @@ export const AddCampaignPromotionsForm = ({ {form.formState.errors.promotion_ids.message} )} - - - -
@@ -148,7 +141,19 @@ export const AddCampaignPromotionsForm = ({ }} /> - + +
+ + + + +
+
+
) } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/campaign-budget-edit.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/campaign-budget-edit.tsx index 2de7752828..ba1b4e7013 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/campaign-budget-edit.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/campaign-budget-edit.tsx @@ -18,7 +18,9 @@ export const CampaignBudgetEdit = () => { return ( - {t("campaigns.budget.edit.header")} + + {t("campaigns.budget.edit.header")} + {!isLoading && campaign && } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/components/edit-campaign-budget-form/edit-campaign-budget-form.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/components/edit-campaign-budget-form/edit-campaign-budget-form.tsx index 871ae05f14..c920bd5ea2 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/components/edit-campaign-budget-form/edit-campaign-budget-form.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-budget-edit/components/edit-campaign-budget-form/edit-campaign-budget-form.tsx @@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next" import * as zod from "zod" import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useUpdateCampaign } from "../../../../../hooks/api/campaigns" import { getCurrencySymbol } from "../../../../../lib/data/currencies" @@ -58,7 +59,7 @@ export const EditCampaignBudgetForm = ({ return ( -
+
- +
) } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-configuration/components/campaign-configuration-form/campaign-configuration-form.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-configuration/components/campaign-configuration-form/campaign-configuration-form.tsx index 5159523b9d..eee0d6cbc4 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-configuration/components/campaign-configuration-form/campaign-configuration-form.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-configuration/components/campaign-configuration-form/campaign-configuration-form.tsx @@ -7,6 +7,7 @@ import { z } from "zod" import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useUpdateCampaign } from "../../../../../hooks/api/campaigns" type CampaignConfigurationFormProps = { @@ -59,7 +60,7 @@ export const CampaignConfigurationForm = ({ return ( -
+
- +
) } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-create/components/create-campaign-form/create-campaign-form.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-create/components/create-campaign-form/create-campaign-form.tsx index d6fb17e932..057149dd11 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-create/components/create-campaign-form/create-campaign-form.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-create/components/create-campaign-form/create-campaign-form.tsx @@ -4,20 +4,22 @@ import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import * as zod from "zod" -import { CampaignBudgetTypeValues } from "@medusajs/types" import { RouteFocusModal, useRouteModal, } from "../../../../../components/modals" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" +import { VisuallyHidden } from "../../../../../components/utilities/visually-hidden" import { useCreateCampaign } from "../../../../../hooks/api/campaigns" import { CreateCampaignFormFields } from "../../../common/components/create-campaign-form-fields" +import { DEFAULT_CAMPAIGN_VALUES } from "../../../common/constants" export const CreateCampaignSchema = zod.object({ name: zod.string().min(1), description: zod.string().optional(), campaign_identifier: zod.string().min(1), - starts_at: zod.date().optional(), - ends_at: zod.date().optional(), + starts_at: zod.date().nullable(), + ends_at: zod.date().nullable(), budget: zod.object({ limit: zod.number().min(0).nullish(), type: zod.enum(["spend", "usage"]), @@ -25,24 +27,13 @@ export const CreateCampaignSchema = zod.object({ }), }) -export const defaultCampaignValues = { - name: "", - description: "", - campaign_identifier: "", - budget: { - type: "usage" as CampaignBudgetTypeValues, - currency_code: null, - limit: null, - }, -} - export const CreateCampaignForm = () => { const { t } = useTranslation() const { handleSuccess } = useRouteModal() const { mutateAsync, isPending } = useCreateCampaign() const form = useForm>({ - defaultValues: defaultCampaignValues, + defaultValues: DEFAULT_CAMPAIGN_VALUES, resolver: zodResolver(CreateCampaignSchema), }) @@ -78,11 +69,18 @@ export const CreateCampaignForm = () => { return ( -
- + + + {t("campaigns.create.title")} + + + {t("campaigns.create.description")} + + @@ -103,7 +101,7 @@ export const CreateCampaignForm = () => { - +
) } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-edit/campaign-edit.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-edit/campaign-edit.tsx index 80ee8355de..8659deb69a 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-edit/campaign-edit.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-edit/campaign-edit.tsx @@ -2,6 +2,7 @@ import { Heading } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { useParams } from "react-router-dom" import { RouteDrawer } from "../../../components/modals" +import { VisuallyHidden } from "../../../components/utilities/visually-hidden" import { useCampaign } from "../../../hooks/api/campaigns" import { EditCampaignForm } from "./components/edit-campaign-form" @@ -18,7 +19,12 @@ export const CampaignEdit = () => { return ( - {t("campaigns.edit.header")} + + {t("campaigns.edit.header")} + + + {t("campaigns.edit.description")} + {!isLoading && campaign && } diff --git a/packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx b/packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx index 2f4af75eab..0a734aa086 100644 --- a/packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/campaign-edit/components/edit-campaign-form/edit-campaign-form.tsx @@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next" import * as zod from "zod" import { Form } from "../../../../../components/common/form" import { RouteDrawer, useRouteModal } from "../../../../../components/modals" +import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useUpdateCampaign } from "../../../../../hooks/api/campaigns" type EditCampaignFormProps = { @@ -65,7 +66,7 @@ export const EditCampaignForm = ({ campaign }: EditCampaignFormProps) => { return ( -
+
{
- +
) } diff --git a/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx b/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx index f630974da3..e525d1534c 100644 --- a/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx +++ b/packages/admin/dashboard/src/routes/campaigns/common/components/create-campaign-form-fields/create-campaign-form-fields.tsx @@ -14,7 +14,10 @@ import { useTranslation } from "react-i18next" import { Form } from "../../../../../components/common/form" import { useStore } from "../../../../../hooks/api/store" -import { currencies, getCurrencySymbol } from "../../../../../lib/data/currencies" +import { + currencies, + getCurrencySymbol, +} from "../../../../../lib/data/currencies" export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => { const { t } = useTranslation() @@ -118,7 +121,7 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => { render={({ field }) => { return ( - {t("fields.description")} + {t("fields.description")}