diff --git a/packages/admin-next/dashboard/public/locales/en-US/translation.json b/packages/admin-next/dashboard/public/locales/en-US/translation.json index d5eeb6458b..423ab856a6 100644 --- a/packages/admin-next/dashboard/public/locales/en-US/translation.json +++ b/packages/admin-next/dashboard/public/locales/en-US/translation.json @@ -154,7 +154,6 @@ "editAttributes": "Edit Attributes", "organization": "Organize", "editOrganization": "Edit Organization", - "options": "Options", "editOptions": "Edit Options", "media": { "label": "Media", @@ -250,6 +249,15 @@ "allowBackordersLabel": "Allow backorders", "allowBackordersHint": "When enabled the variant can be sold even if the inventory level is below zero." } + }, + "options": { + "header": "Options", + "edit": { + "header": "Edit Option" + }, + "create": { + "header": "Create Option" + } } }, "collections": { diff --git a/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx b/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx index 0d582d200d..065a33a5bf 100644 --- a/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx +++ b/packages/admin-next/dashboard/src/providers/router-provider/v1.tsx @@ -231,8 +231,14 @@ export const v1Routes: RouteObject[] = [ import("../../routes/products/product-attributes"), }, { - path: "options", - lazy: () => import("../../routes/products/product-options"), + path: "options/create", + lazy: () => + import("../../routes/products/product-create-option"), + }, + { + path: "options/:option_id/edit", + lazy: () => + import("../../routes/products/product-edit-option"), }, { path: "media", diff --git a/packages/admin-next/dashboard/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx b/packages/admin-next/dashboard/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx new file mode 100644 index 0000000000..f99dbdb541 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx @@ -0,0 +1,83 @@ +import { zodResolver } from "@hookform/resolvers/zod" +import { Product } from "@medusajs/medusa" +import { Button, Input } from "@medusajs/ui" +import { useAdminCreateProductOption } from "medusa-react" +import { useForm } from "react-hook-form" +import { useTranslation } from "react-i18next" +import { z } from "zod" +import { Form } from "../../../../../components/common/form" +import { + RouteDrawer, + useRouteModal, +} from "../../../../../components/route-modal" + +type EditProductOptionsFormProps = { + product: Product +} + +const CreateProductOptionSchema = z.object({ + title: z.string().min(1), +}) + +export const CreateProductOptionForm = ({ + product, +}: EditProductOptionsFormProps) => { + const { t } = useTranslation() + const { handleSuccess } = useRouteModal() + + const form = useForm>({ + defaultValues: { + title: "", + }, + resolver: zodResolver(CreateProductOptionSchema), + }) + + const { mutateAsync, isLoading } = useAdminCreateProductOption(product.id) + + const handleSubmit = form.handleSubmit(async (values) => { + mutateAsync(values, { + onSuccess: () => { + handleSuccess() + }, + }) + }) + + return ( + +
+ + { + return ( + + {t("fields.title")} + + + + + + ) + }} + /> + + +
+ + + + +
+
+
+
+ ) +} diff --git a/packages/admin-next/dashboard/src/routes/products/product-create-option/components/create-product-option-form/index.ts b/packages/admin-next/dashboard/src/routes/products/product-create-option/components/create-product-option-form/index.ts new file mode 100644 index 0000000000..72faecda04 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-create-option/components/create-product-option-form/index.ts @@ -0,0 +1 @@ +export * from "./create-product-option-form" diff --git a/packages/admin-next/dashboard/src/routes/products/product-create-option/index.ts b/packages/admin-next/dashboard/src/routes/products/product-create-option/index.ts new file mode 100644 index 0000000000..b75822a2d9 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-create-option/index.ts @@ -0,0 +1 @@ +export { ProductCreateOption as Component } from "./product-create-option" diff --git a/packages/admin-next/dashboard/src/routes/products/product-options/product-options.tsx b/packages/admin-next/dashboard/src/routes/products/product-create-option/product-create-option.tsx similarity index 65% rename from packages/admin-next/dashboard/src/routes/products/product-options/product-options.tsx rename to packages/admin-next/dashboard/src/routes/products/product-create-option/product-create-option.tsx index 60f8469e74..02c4f84973 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-options/product-options.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-create-option/product-create-option.tsx @@ -3,9 +3,9 @@ import { useAdminProduct } from "medusa-react" import { useTranslation } from "react-i18next" import { useParams } from "react-router-dom" import { RouteDrawer } from "../../../components/route-modal" -import { EditProductOptionsForm } from "./components/edit-product-options-form" +import { CreateProductOptionForm } from "./components/create-product-option-form" -export const ProductOptions = () => { +export const ProductCreateOption = () => { const { id } = useParams() const { t } = useTranslation() @@ -18,9 +18,9 @@ export const ProductOptions = () => { return ( - {t("products.editOptions")} + {t("products.options.create.header")} - {!isLoading && product && } + {!isLoading && product && } ) } diff --git a/packages/admin-next/dashboard/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx b/packages/admin-next/dashboard/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx index 24d7ac133e..f2ff2783cb 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx @@ -1,4 +1,4 @@ -import { PencilSquare } from "@medusajs/icons" +import { PencilSquare, Plus } from "@medusajs/icons" import { Product, ProductOption } from "@medusajs/medusa" import { Badge, Container, Heading, Text } from "@medusajs/ui" import { useTranslation } from "react-i18next" @@ -16,15 +16,15 @@ export const ProductOptionSection = ({ return (
- {t("products.options")} + {t("products.options.header")} , + label: t("actions.create"), + to: "options/create", + icon: , }, ], }, @@ -35,7 +35,7 @@ export const ProductOptionSection = ({ return (
{option.title} @@ -53,6 +53,19 @@ export const ProductOptionSection = ({ ) })}
+ , + }, + ], + }, + ]} + />
) })} diff --git a/packages/admin-next/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx b/packages/admin-next/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx new file mode 100644 index 0000000000..9c5e91b3b8 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx @@ -0,0 +1,91 @@ +import { zodResolver } from "@hookform/resolvers/zod" +import { ProductOption } from "@medusajs/medusa" +import { Button, Input } from "@medusajs/ui" +import { useAdminUpdateProductOption } from "medusa-react" +import { useForm } from "react-hook-form" +import { useTranslation } from "react-i18next" +import { z } from "zod" +import { Form } from "../../../../../components/common/form" +import { + RouteDrawer, + useRouteModal, +} from "../../../../../components/route-modal" + +type EditProductOptionFormProps = { + option: ProductOption +} + +const CreateProductOptionSchema = z.object({ + title: z.string().min(1), +}) + +export const CreateProductOptionForm = ({ + option, +}: EditProductOptionFormProps) => { + const { t } = useTranslation() + const { handleSuccess } = useRouteModal() + + const form = useForm>({ + defaultValues: { + title: option.title, + }, + resolver: zodResolver(CreateProductOptionSchema), + }) + + const { mutateAsync, isLoading } = useAdminUpdateProductOption( + option.product_id + ) + + const handleSubmit = form.handleSubmit(async (values) => { + mutateAsync( + { + option_id: option.id, + ...values, + }, + { + onSuccess: () => { + handleSuccess() + }, + } + ) + }) + + return ( + +
+ + { + return ( + + {t("fields.title")} + + + + + + ) + }} + /> + + +
+ + + + +
+
+
+
+ ) +} diff --git a/packages/admin-next/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/index.ts b/packages/admin-next/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/index.ts new file mode 100644 index 0000000000..280d44cc3c --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-edit-option/components/edit-product-option-form/index.ts @@ -0,0 +1 @@ +export * from "./edit-product-option-form" diff --git a/packages/admin-next/dashboard/src/routes/products/product-edit-option/index.ts b/packages/admin-next/dashboard/src/routes/products/product-edit-option/index.ts new file mode 100644 index 0000000000..0d70a2c552 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-edit-option/index.ts @@ -0,0 +1 @@ +export { ProductEditOption as Component } from "./product-edit-option" diff --git a/packages/admin-next/dashboard/src/routes/products/product-edit-option/product-edit-option.tsx b/packages/admin-next/dashboard/src/routes/products/product-edit-option/product-edit-option.tsx new file mode 100644 index 0000000000..ee30be18c6 --- /dev/null +++ b/packages/admin-next/dashboard/src/routes/products/product-edit-option/product-edit-option.tsx @@ -0,0 +1,34 @@ +import { Heading } from "@medusajs/ui" +import { useAdminProduct } from "medusa-react" +import { useTranslation } from "react-i18next" +import { json, useParams } from "react-router-dom" +import { RouteDrawer } from "../../../components/route-modal" +import { CreateProductOptionForm } from "./components/edit-product-option-form" + +export const ProductEditOption = () => { + const { id, option_id } = useParams() + const { t } = useTranslation() + + const { product, isLoading, isError, error } = useAdminProduct(id!) + + const option = product?.options.find((o) => o.id === option_id) + + const ready = !isLoading && option + + if (!isLoading && !option) { + throw json({ message: `An option with ID ${option_id} was not found` }, 404) + } + + if (isError) { + throw error + } + + return ( + + + {t("products.options.edit.header")} + + {ready && } + + ) +} diff --git a/packages/admin-next/dashboard/src/routes/products/product-options/components/edit-product-options-form/edit-product-options-form.tsx b/packages/admin-next/dashboard/src/routes/products/product-options/components/edit-product-options-form/edit-product-options-form.tsx deleted file mode 100644 index d71f91b15c..0000000000 --- a/packages/admin-next/dashboard/src/routes/products/product-options/components/edit-product-options-form/edit-product-options-form.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { zodResolver } from "@hookform/resolvers/zod" -import { Product } from "@medusajs/medusa" -import { Button } from "@medusajs/ui" -import { useForm } from "react-hook-form" -import { useTranslation } from "react-i18next" -import * as zod from "zod" -import { RouteDrawer } from "../../../../../components/route-modal" - -type EditProductOptionsFormProps = { - product: Product -} - -const EditProductOptionsSchema = zod.object({}) - -export const EditProductOptionsForm = (props: EditProductOptionsFormProps) => { - const { t } = useTranslation() - - const form = useForm>({ - resolver: zodResolver(EditProductOptionsSchema), - }) - - return ( - -
- - -
- - - - -
-
-
-
- ) -} diff --git a/packages/admin-next/dashboard/src/routes/products/product-options/components/edit-product-options-form/index.ts b/packages/admin-next/dashboard/src/routes/products/product-options/components/edit-product-options-form/index.ts deleted file mode 100644 index e4cab80bac..0000000000 --- a/packages/admin-next/dashboard/src/routes/products/product-options/components/edit-product-options-form/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./edit-product-options-form" diff --git a/packages/admin-next/dashboard/src/routes/products/product-options/index.ts b/packages/admin-next/dashboard/src/routes/products/product-options/index.ts deleted file mode 100644 index 9bd1f33231..0000000000 --- a/packages/admin-next/dashboard/src/routes/products/product-options/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ProductOptions as Component } from "./product-options"