Skip to content

Commit

Permalink
feat: Add product routes and components to v2 in admin-next
Browse files Browse the repository at this point in the history
  • Loading branch information
sradevski committed Apr 6, 2024
1 parent d333db0 commit f99ea41
Show file tree
Hide file tree
Showing 81 changed files with 597 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,22 @@
},
"weight": {
"label": "Weight"
},
"options": {
"label": "Product options",
"hint": "Options are used to define the color, size, etc. of the product",
"optionTitle": "Option title",
"variations": "Variations (comma-separated)"
},
"variants": {
"label": "Product variants",
"hint": "Variants left unchecked won't be created, This ranking will affect how the variants are ranked in your frontend."
},
"mid_code": {
"label": "Mid code"
},
"hs_code": {
"label": "HS code"
}
},
"variant": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./list"
54 changes: 54 additions & 0 deletions packages/admin-next/dashboard/src/components/common/list/list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Checkbox, Text } from "@medusajs/ui"

export interface ListProps<T> {
options: { title: string; value: T }[]
value?: T[]
onChange?: (value: T[]) => void
compare?: (a: T, b: T) => boolean
disabled?: boolean
}

export const List = <T extends any>({
options,
onChange,
value,
compare,
disabled,
}: ListProps<T>) => {
if (options.length === 0) {
return <div>No options</div>
}

return (
<div className="flex-row justify-center border divide-y rounded-lg">
{options.map((option) => {
return (
<div className="flex p-4 gap-x-4">
{onChange && value !== undefined && (
<Checkbox
disabled={disabled}
checked={value.some(
(v) => compare?.(v, option.value) ?? v === option.value
)}
onCheckedChange={(checked) => {
if (checked) {
onChange([...value, option.value])
} else {
onChange(
value.filter(
(v) =>
!(compare?.(v, option.value) ?? v === option.value)
)
)
}
}}
/>
)}

<Text key={option.title}>{option.title}</Text>
</div>
)
})}
</div>
)
}
39 changes: 39 additions & 0 deletions packages/admin-next/dashboard/src/hooks/api/categories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { QueryKey, UseQueryOptions, useQuery } from "@tanstack/react-query"
import { client } from "../../lib/client"
import { queryKeysFactory } from "../../lib/query-key-factory"
import { CategoriesListRes, CategoryRes } from "../../types/api-responses"

const CATEGORIES_QUERY_KEY = "categories" as const
export const categoriesQueryKeys = queryKeysFactory(CATEGORIES_QUERY_KEY)

export const useCategory = (
id: string,
options?: Omit<
UseQueryOptions<CategoryRes, Error, CategoryRes, QueryKey>,
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryKey: categoriesQueryKeys.detail(id),
queryFn: async () => client.categories.retrieve(id),
...options,
})

return { ...data, ...rest }
}

export const useCategories = (
query?: Record<string, any>,
options?: Omit<
UseQueryOptions<CategoriesListRes, Error, CategoriesListRes, QueryKey>,
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryKey: categoriesQueryKeys.list(query),
queryFn: async () => client.categories.list(query),
...options,
})

return { ...data, ...rest }
}
60 changes: 58 additions & 2 deletions packages/admin-next/dashboard/src/hooks/api/products.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { QueryKey, UseQueryOptions, useQuery } from "@tanstack/react-query"
import {
QueryKey,
UseMutationOptions,
UseQueryOptions,
useMutation,
useQuery,
} from "@tanstack/react-query"
import { client } from "../../lib/client"
import { queryKeysFactory } from "../../lib/query-key-factory"
import { ProductListRes, ProductRes } from "../../types/api-responses"
import {
ProductDeleteRes,
ProductListRes,
ProductRes,
} from "../../types/api-responses"
import { queryClient } from "../../lib/medusa"

const PRODUCTS_QUERY_KEY = "products" as const
export const productsQueryKeys = queryKeysFactory(PRODUCTS_QUERY_KEY)
Expand Down Expand Up @@ -38,3 +49,48 @@ export const useProducts = (

return { ...data, ...rest }
}

export const useCreateProduct = (
options?: UseMutationOptions<ProductRes, Error, any>
) => {
return useMutation({
mutationFn: (payload: any) => client.products.create(payload),
onSuccess: (data: any, variables: any, context: any) => {
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
options?.onSuccess?.(data, variables, context)
},
...options,
})
}

export const useUpdateProduct = (
id: string,
options?: UseMutationOptions<ProductRes, Error, any>
) => {
return useMutation({
mutationFn: (payload: any) => client.products.update(id, payload),
onSuccess: (data: any, variables: any, context: any) => {
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
queryClient.invalidateQueries({ queryKey: productsQueryKeys.detail(id) })

options?.onSuccess?.(data, variables, context)
},
...options,
})
}

export const useDeleteProduct = (
id: string,
options?: UseMutationOptions<ProductDeleteRes, Error, void>
) => {
return useMutation({
mutationFn: () => client.products.delete(id),
onSuccess: (data: any, variables: any, context: any) => {
queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists() })
queryClient.invalidateQueries({ queryKey: productsQueryKeys.detail(id) })

options?.onSuccess?.(data, variables, context)
},
...options,
})
}
39 changes: 39 additions & 0 deletions packages/admin-next/dashboard/src/hooks/api/tags.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { QueryKey, UseQueryOptions, useQuery } from "@tanstack/react-query"
import { client } from "../../lib/client"
import { queryKeysFactory } from "../../lib/query-key-factory"
import { TagsListRes, TagRes } from "../../types/api-responses"

const TAGS_QUERY_KEY = "tags" as const
export const tagsQueryKeys = queryKeysFactory(TAGS_QUERY_KEY)

export const useTag = (
id: string,
options?: Omit<
UseQueryOptions<TagRes, Error, TagRes, QueryKey>,
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryKey: tagsQueryKeys.detail(id),
queryFn: async () => client.tags.retrieve(id),
...options,
})

return { ...data, ...rest }
}

export const useTags = (
query?: Record<string, any>,
options?: Omit<
UseQueryOptions<TagsListRes, Error, TagsListRes, QueryKey>,
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryKey: tagsQueryKeys.list(query),
queryFn: async () => client.tags.list(query),
...options,
})

return { ...data, ...rest }
}
21 changes: 21 additions & 0 deletions packages/admin-next/dashboard/src/lib/client/categories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
ProductCollectionListRes,
ProductCollectionRes,
} from "../../types/api-responses"
import { getRequest } from "./common"

async function listProductCategories(query?: Record<string, any>) {
return getRequest<ProductCollectionListRes>(`/admin/categories`, query)
}

async function retrieveProductCategory(
id: string,
query?: Record<string, any>
) {
return getRequest<ProductCollectionRes>(`/admin/categories/${id}`, query)
}

export const categories = {
list: listProductCategories,
retrieve: retrieveProductCategory,
}
4 changes: 4 additions & 0 deletions packages/admin-next/dashboard/src/lib/client/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { apiKeys } from "./api-keys"
import { auth } from "./auth"
import { categories } from "./categories"
import { collections } from "./collections"
import { currencies } from "./currencies"
import { customers } from "./customers"
Expand All @@ -11,18 +12,21 @@ import { regions } from "./regions"
import { salesChannels } from "./sales-channels"
import { stockLocations } from "./stock-locations"
import { stores } from "./stores"
import { tags } from "./tags"
import { users } from "./users"
import { workflowExecutions } from "./workflow-executions"

export const client = {
auth: auth,
apiKeys: apiKeys,
categories: categories,
customers: customers,
currencies: currencies,
collections: collections,
promotions: promotions,
stores: stores,
salesChannels: salesChannels,
tags: tags,
users: users,
regions: regions,
invites: invites,
Expand Down
23 changes: 21 additions & 2 deletions packages/admin-next/dashboard/src/lib/client/products.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
import { ProductListRes, ProductRes } from "../../types/api-responses"
import { getRequest } from "./common"
import {
ProductDeleteRes,
ProductListRes,
ProductRes,
} from "../../types/api-responses"
import { deleteRequest, getRequest, postRequest } from "./common"

async function retrieveProduct(id: string, query?: Record<string, any>) {
return getRequest<ProductRes>(`/admin/products/${id}`, query)
}

async function createProduct(payload: any) {
return postRequest<ProductRes>(`/admin/products`, payload)
}

async function listProducts(query?: Record<string, any>) {
return getRequest<ProductListRes>(`/admin/products`, query)
}

async function updateProduct(id: string, payload: any) {
return postRequest<ProductRes>(`/admin/products/${id}`, payload)
}

async function deleteProduct(id: string) {
return deleteRequest<ProductDeleteRes>(`/admin/products/${id}`)
}

export const products = {
retrieve: retrieveProduct,
list: listProducts,
create: createProduct,
update: updateProduct,
delete: deleteProduct,
}
18 changes: 18 additions & 0 deletions packages/admin-next/dashboard/src/lib/client/tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
ProductCollectionListRes,
ProductCollectionRes,
} from "../../types/api-responses"
import { getRequest } from "./common"

async function listProductTags(query?: Record<string, any>) {
return getRequest<ProductCollectionListRes>(`/admin/tags`, query)
}

async function retrieveProductTag(id: string, query?: Record<string, any>) {
return getRequest<ProductCollectionRes>(`/admin/tags/${id}`, query)
}

export const tags = {
list: listProductTags,
retrieve: retrieveProductTag,
}
Loading

0 comments on commit f99ea41

Please sign in to comment.