diff --git a/.changeset/gorgeous-bears-hear.md b/.changeset/gorgeous-bears-hear.md new file mode 100644 index 0000000000..9429ff0bca --- /dev/null +++ b/.changeset/gorgeous-bears-hear.md @@ -0,0 +1,5 @@ +--- +"medusa-react": patch +--- + +Add Collection batch (remove, add) endpoints to medusa-react diff --git a/packages/medusa-react/mocks/handlers/admin.ts b/packages/medusa-react/mocks/handlers/admin.ts index bd98e0dcf5..0f861bd7e5 100644 --- a/packages/medusa-react/mocks/handlers/admin.ts +++ b/packages/medusa-react/mocks/handlers/admin.ts @@ -108,6 +108,29 @@ export const adminHandlers = [ ) }), + rest.post("/admin/collections/:id/products/batch", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + collection: { + ...fixtures.get("product_collection"), + products: [fixtures.get("product")] + } + }) + ) + }), + + rest.delete("/admin/collections/:id/products/batch", (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + id: req.params.id, + object: "product-collection", + removed_products: [fixtures.get("product").id] + }) + ) + }), + rest.post("/admin/gift-cards/", (req, res, ctx) => { const body = req.body as Record return res( diff --git a/packages/medusa-react/src/hooks/admin/collections/mutations.ts b/packages/medusa-react/src/hooks/admin/collections/mutations.ts index 9871d695b4..df134276e0 100644 --- a/packages/medusa-react/src/hooks/admin/collections/mutations.ts +++ b/packages/medusa-react/src/hooks/admin/collections/mutations.ts @@ -1,8 +1,10 @@ import { AdminCollectionsDeleteRes, AdminCollectionsRes, + AdminDeleteProductsFromCollectionReq, AdminPostCollectionsCollectionReq, AdminPostCollectionsReq, + AdminPostProductsToCollectionReq, } from "@medusajs/medusa" import { Response } from "@medusajs/medusa-js" import { useMutation, UseMutationOptions, useQueryClient } from "react-query" @@ -62,3 +64,60 @@ export const useAdminDeleteCollection = ( ) ) } + + +/** + * Hook returns function for adding multiple products to a collection. + * + * @param id - id of the collection in which products are being added + * @param options + */ +export const useAdminAddProductsToCollection = ( + id: string, + options?: UseMutationOptions< + Response, + Error, + AdminPostProductsToCollectionReq + > +) => { + const { client } = useMedusa() + const queryClient = useQueryClient() + + return useMutation( + (payload: AdminPostProductsToCollectionReq) => + client.admin.collections.addProducts(id, payload), + buildOptions( + queryClient, + [adminCollectionKeys.lists(), adminCollectionKeys.detail(id)], + options + ) + ) +} + +/** + * Hook returns function for removal of multiple products from a collection. + * + * @param id - id of the collection from which products will be removed + * @param options + */ +export const useAdminRemoveProductsFromCollection = ( + id: string, + options?: UseMutationOptions< + Response, + Error, + AdminDeleteProductsFromCollectionReq + > +) => { + const { client } = useMedusa() + const queryClient = useQueryClient() + + return useMutation( + (payload: AdminDeleteProductsFromCollectionReq) => + client.admin.collections.removeProducts(id, payload), + buildOptions( + queryClient, + [adminCollectionKeys.lists(), adminCollectionKeys.detail(id)], + options + ) + ) +} diff --git a/packages/medusa-react/test/hooks/admin/collections/mutations.test.ts b/packages/medusa-react/test/hooks/admin/collections/mutations.test.ts index e18743dfb6..85a679d3f5 100644 --- a/packages/medusa-react/test/hooks/admin/collections/mutations.test.ts +++ b/packages/medusa-react/test/hooks/admin/collections/mutations.test.ts @@ -2,6 +2,8 @@ import { useAdminCreateCollection, useAdminUpdateCollection, useAdminDeleteCollection, + useAdminAddProductsToCollection, + useAdminRemoveProductsFromCollection, } from "../../../../src/" import { renderHook } from "@testing-library/react-hooks" import { fixtures } from "../../../../mocks/data" @@ -80,3 +82,57 @@ describe("useAdminDeleteCollection hook", () => { ) }) }) + +describe("useAdminAddProductsToCollection hook", () => { + test("add products to a collection", async () => { + const update = { + product_ids: [fixtures.get("product").id], + } + + const { result, waitFor } = renderHook( + () => useAdminAddProductsToCollection(fixtures.get("product_collection").id), + { + wrapper: createWrapper(), + } + ) + + result.current.mutate(update) + + await waitFor(() => result.current.isSuccess) + expect(result.current.data?.response.status).toEqual(200) + expect(result.current.data?.collection).toEqual( + expect.objectContaining({ + ...fixtures.get("product_collection"), + products: [fixtures.get("product")], + }) + ) + }) +}) + +describe("useAdminRemoveProductsFromCollection hook", () => { + test("remove products from a collection", async () => { + const remove = { + product_ids: [fixtures.get("product").id], + } + + const { result, waitFor } = renderHook( + () => useAdminRemoveProductsFromCollection(fixtures.get("product_collection").id), + { + wrapper: createWrapper(), + } + ) + + result.current.mutate(remove) + + await waitFor(() => result.current.isSuccess) + + expect(result.current.data?.response.status).toEqual(200) + expect(result.current.data).toEqual( + expect.objectContaining({ + id: fixtures.get("product_collection").id, + object: "product-collection", + removed_products: remove.product_ids + }) + ) + }) +})