diff --git a/packages/admin-next/dashboard/src/components/common/switch-box/index.ts b/packages/admin-next/dashboard/src/components/common/switch-box/index.ts new file mode 100644 index 0000000000..c245e8b7ad --- /dev/null +++ b/packages/admin-next/dashboard/src/components/common/switch-box/index.ts @@ -0,0 +1 @@ +export * from "./switch-box" diff --git a/packages/admin-next/dashboard/src/components/common/switch-box/switch-box.tsx b/packages/admin-next/dashboard/src/components/common/switch-box/switch-box.tsx new file mode 100644 index 0000000000..856753c599 --- /dev/null +++ b/packages/admin-next/dashboard/src/components/common/switch-box/switch-box.tsx @@ -0,0 +1,70 @@ +import { Switch } from "@medusajs/ui" +import { ReactNode } from "react" +import { ControllerProps, FieldPath, FieldValues } from "react-hook-form" + +import { Form } from "../../common/form" + +interface HeadlessControllerProps< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> extends Omit, "render"> {} + +interface SwitchBoxProps< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> extends HeadlessControllerProps{ + label: string + description: string + optional?: boolean + tooltip?: ReactNode + /** + * Callback for performing additional actions when the checked state changes. + * This does not intercept the form control, it is only used for injecting side-effects. + */ + onCheckedChange?: (checked: boolean) => void +} + +/** + * Wrapper for the Switch component to be used with `react-hook-form`. + * + * Use this component whenever a design calls for wrapping the Switch component + * in a container with a label and description. + */ +export const SwitchBox = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +>({ + label, + description, + optional = false, + tooltip, + onCheckedChange, + ...props +}: SwitchBoxProps) => { + return ( + { + return ( + +
+ + { + onCheckedChange?.(e) + onChange(e) + }} /> + +
+ + {label} + + {description} +
+
+ +
+ ) + }} + /> + ) +} \ No newline at end of file diff --git a/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx b/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx index b7c026fcb6..97e0caba78 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx @@ -23,6 +23,7 @@ import { useTranslation } from "react-i18next" import { Form } from "../../../../../../../components/common/form" import { SortableList } from "../../../../../../../components/common/sortable-list" +import { SwitchBox } from "../../../../../../../components/common/switch-box" import { ChipInput } from "../../../../../../../components/inputs/chip-input" import { ProductCreateSchemaType } from "../../../../types" import { decorateVariantsWithDefaultValues } from "../../../../utils" @@ -285,46 +286,23 @@ export const ProductCreateVariantsSection = ({ return (
{t("products.create.variants.header")} - { - return ( - -
- - { - if (checked) { - form.setValue("options", [ - { - title: "", - values: [], - }, - ]) - form.setValue("variants", []) - } else { - createDefaultOptionAndVariant() - } - - onChange(!!checked) - }} - {...field} - className="mt-1" - /> - -
- - {t("products.create.variants.subHeadingTitle")} - - - {t("products.create.variants.subHeadingDescription")} - -
-
-
- ) + label={t("products.create.variants.subHeadingTitle")} + description={t("products.create.variants.subHeadingDescription")} + onCheckedChange={(checked) => { + if (checked) { + form.setValue("options", [ + { + title: "", + values: [], + }, + ]) + form.setValue("variants", []) + } else { + createDefaultOptionAndVariant() + } }} /> {watchedAreVariantsEnabled && ( diff --git a/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsx b/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsx index ff6c5f02af..96efdcae6f 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-organize-form/components/product-create-organize-section/product-create-details-organize-section.tsx @@ -1,9 +1,10 @@ -import { Button, Heading, Switch } from "@medusajs/ui" +import { Button, Heading } from "@medusajs/ui" import { UseFormReturn, useFieldArray } from "react-hook-form" import { Trans, useTranslation } from "react-i18next" import { ChipGroup } from "../../../../../../../components/common/chip-group" import { Form } from "../../../../../../../components/common/form" +import { SwitchBox } from "../../../../../../../components/common/switch-box" import { Combobox } from "../../../../../../../components/inputs/combobox" import { useComboboxData } from "../../../../../../../hooks/use-combobox-data" import { client, sdk } from "../../../../../../../lib/client" @@ -64,36 +65,13 @@ export const ProductCreateOrganizationSection = ({ return (
{t("products.organization.header")} -
- { - return ( - -
- - - -
- - {t("products.fields.discountable.label")} - - - {t("products.fields.discountable.hint")} - -
-
-
- ) - }} - /> -
+
{
- {/*TODO: WHERE DO WE SET PRODUCT ATTRIBUTES? -> the plan is to moved that to Inventory UI */} - {/**/} - {/**/} + {/* TODO: WHERE DO WE SET PRODUCT ATTRIBUTES? -> the plan is to moved that to Inventory UI */} + {/* */} + {/* */}
diff --git a/packages/admin-next/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx b/packages/admin-next/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx index 51ff8cebd5..b80fc8ce91 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-edit/components/edit-product-form/edit-product-form.tsx @@ -1,12 +1,13 @@ import { zodResolver } from "@hookform/resolvers/zod" import { Product } from "@medusajs/medusa" import { ProductStatus } from "@medusajs/types" -import { Button, Input, Select, Switch, Text, Textarea } from "@medusajs/ui" +import { Button, Input, Select, Text, Textarea } from "@medusajs/ui" import { useForm } 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 { SwitchBox } from "../../../../../components/common/switch-box" import { RouteDrawer, useRouteModal, @@ -74,8 +75,8 @@ export const EditProductForm = ({ product }: EditProductFormProps) => { onSubmit={handleSubmit} className="flex flex-1 flex-col overflow-hidden" > - -
+ +
{ ) }} /> - - ]} - /> - -
-
{