diff --git a/packages/admin-next/dashboard/src/hooks/use-combobox-data.tsx b/packages/admin-next/dashboard/src/hooks/use-combobox-data.tsx index 213a68cf5c..10cb4e0fec 100644 --- a/packages/admin-next/dashboard/src/hooks/use-combobox-data.tsx +++ b/packages/admin-next/dashboard/src/hooks/use-combobox-data.tsx @@ -38,12 +38,12 @@ export const useComboboxData = < }) => { const { searchValue, onSearchValueChange, query } = useDebouncedSearch() - const queryIntialDataBy = defaultValueKey || "id" + const queryInitialDataBy = defaultValueKey || "id" const { data: initialData } = useQuery({ queryKey: queryKey, queryFn: async () => { return queryFn({ - [queryIntialDataBy]: defaultValue, + [queryInitialDataBy]: defaultValue, limit: Array.isArray(defaultValue) ? defaultValue.length : 1, } as TParams) }, diff --git a/packages/admin-next/dashboard/src/i18n/translations/en.json b/packages/admin-next/dashboard/src/i18n/translations/en.json index b63f1bcbc7..bf7034aa18 100644 --- a/packages/admin-next/dashboard/src/i18n/translations/en.json +++ b/packages/admin-next/dashboard/src/i18n/translations/en.json @@ -178,7 +178,9 @@ }, "inventory": { "heading": "Inventory kits", - "label": "Inventory kit" + "label": "Inventory kit", + "itemPlaceholder": "Select inventory item", + "quantityPlaceholder": "How many of these are needed for the kit?" }, "variants": { "header": "Variants", @@ -1659,6 +1661,7 @@ "discountable": "Discountable", "handle": "Handle", "subtitle": "Subtitle", + "item": "Item", "limit": "Limit", "tags": "Tags", "type": "Type", diff --git a/packages/admin-next/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx b/packages/admin-next/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx index f25a528f97..a8bc59714d 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-create-variant/components/create-product-variant-form/create-product-variant-form.tsx @@ -60,7 +60,9 @@ export const CreateProductVariantForm = ({ resolver: zodResolver(CreateProductVariantSchema), }) - const { mutateAsync, isLoading } = useCreateProductVariant(product.id) + const { mutateAsync, isPending: isLoading } = useCreateProductVariant( + product.id + ) const handleSubmit = form.handleSubmit(async (data) => { const parseNumber = (value?: string | number) => { 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 97e0caba78..be1dd43939 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 @@ -141,7 +141,7 @@ export const ProductCreateVariantsSection = ({ should_create: hasUserSelectedVariants ? false : true, variant_rank: newVariants.length, // NOTE - prepare inventory array here for now so we prevent rendering issue if we append the items later - inventory: [{ title: "", quantity: 0 }], + inventory: [{ inventory_item_id: "", required_quantity: "" }], }) }) @@ -276,7 +276,7 @@ export const ProductCreateVariantsSection = ({ options: { "Default option": "Default option value", }, - inventory: [{ title: "", quantity: 0 }], + inventory: [{ inventory_item_id: "", required_quantity: "" }], is_default: true, }, ]) diff --git a/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-inventory-kit-form/components/product-create-inventory-kit-section/product-create-inventory-kit-section.tsx b/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-inventory-kit-form/components/product-create-inventory-kit-section/product-create-inventory-kit-section.tsx index f752bea5eb..acb8e98905 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-inventory-kit-form/components/product-create-inventory-kit-section/product-create-inventory-kit-section.tsx +++ b/packages/admin-next/dashboard/src/routes/products/product-create/components/product-create-inventory-kit-form/components/product-create-inventory-kit-section/product-create-inventory-kit-section.tsx @@ -6,6 +6,9 @@ import { useTranslation } from "react-i18next" import { ProductCreateSchemaType } from "../../../../types" import { Form } from "../../../../../../../components/common/form" +import { Combobox } from "../../../../../../../components/inputs/combobox" +import { useComboboxData } from "../../../../../../../hooks/use-combobox-data" +import { sdk } from "../../../../../../../lib/client" type VariantSectionProps = { form: UseFormReturn @@ -21,6 +24,16 @@ function VariantSection({ form, variant, index }: VariantSectionProps) { name: `variants.${index}.inventory`, }) + const items = useComboboxData({ + queryKey: ["inventory_items"], + queryFn: (params) => sdk.admin.inventoryItem.list(params), + getOptions: (data) => + data.inventory_items.map((item) => ({ + label: item.title, + value: item.id, + })), + }) + return (
@@ -34,8 +47,8 @@ function VariantSection({ form, variant, index }: VariantSectionProps) { type="button" onClick={() => { inventory.append({ - title: "", - quantity: 0, + inventory_item_id: "", + required_quantity: "", }) }} > @@ -53,30 +66,49 @@ function VariantSection({ form, variant, index }: VariantSectionProps) { size="xsmall" weight="plus" className="text-ui-fg-subtle" - htmlFor={`variants.${index}.inventory.${inventoryIndex}.title`} + htmlFor={`variants.${index}.inventory.${inventoryIndex}.inventory_item_id`} > - {t("fields.name")} + {t("fields.item")}
- { + return ( + + + + + + ) + }} /> +
{ return ( @@ -84,9 +116,6 @@ function VariantSection({ form, variant, index }: VariantSectionProps) { { @@ -95,10 +124,13 @@ function VariantSection({ form, variant, index }: VariantSectionProps) { if (value === "") { onChange(null) } else { - onChange(parseFloat(value)) + onChange(Number(value)) } }} {...field} + placeholder={t( + "products.create.inventory.quantityPlaceholder" + )} /> diff --git a/packages/admin-next/dashboard/src/routes/products/product-create/constants.ts b/packages/admin-next/dashboard/src/routes/products/product-create/constants.ts index 0d54af2df6..a77e63b669 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-create/constants.ts +++ b/packages/admin-next/dashboard/src/routes/products/product-create/constants.ts @@ -71,7 +71,12 @@ export const ProductCreateSchema = z variant_rank: z.number(), prices: z.record(z.string(), z.string().optional()).optional(), inventory: z - .array(z.object({ title: z.string(), quantity: z.number() })) + .array( + z.object({ + inventory_item_id: z.string(), + required_quantity: optionalInt, + }) + ) .optional(), }) ) @@ -112,7 +117,7 @@ export const PRODUCT_CREATE_FORM_DEFAULTS: Partial< options: { "Default option": "Default option value", }, - inventory: [{ title: "", quantity: 0 }], + inventory: [{ inventory_item_id: "", required_quantity: "" }], is_default: true, }, ]), diff --git a/packages/admin-next/dashboard/src/routes/products/product-create/utils.ts b/packages/admin-next/dashboard/src/routes/products/product-create/utils.ts index a6e845343e..6eb320e877 100644 --- a/packages/admin-next/dashboard/src/routes/products/product-create/utils.ts +++ b/packages/admin-next/dashboard/src/routes/products/product-create/utils.ts @@ -54,7 +54,20 @@ export const normalizeVariants = ( sku: variant.sku || undefined, manage_inventory: variant.manage_inventory || undefined, allow_backorder: variant.allow_backorder || undefined, - // TODO: inventory - should be added to the workflow + inventory_items: variant + .inventory!.map((i) => { + const quantity = castNumber(i.required_quantity) + + if (!i.inventory_item_id || !quantity) { + return false + } + + return { + ...i, + required_quantity: quantity, + } + }) + .filter(Boolean), prices: Object.entries(variant.prices || {}) .map(([key, value]: any) => { if (key.startsWith("reg_")) {