feat(admin): rework product admin UI for marketplace module#887
Open
vholik wants to merge 17 commits into
Open
feat(admin): rework product admin UI for marketplace module#887vholik wants to merge 17 commits into
vholik wants to merge 17 commits into
Conversation
- Rewrite product hooks to match new admin API routes (accept, reject, request-changes, activate, deactivate) - Rename attributes hooks from attributes.ts to product-attributes.tsx with proper SDK route (sdk.admin.productAttributes) - Add product-rejection-reasons hooks - Update product list table columns to match Figma design (add Category, remove Sales Channels and Seller columns) - Add CategoryCell table component with +N overflow badge - Update product table filters: add Category/Collection, remove sales_channel_id/seller_id, fix status options to marketplace statuses - Update ProductStatusCell to use marketplace ProductStatus enum (pending/accepted/changes_required/rejected) - Convert CategoryCombobox from multi-select to single-select - Simplify product create form: remove seller, sales channels, shipping profile; make category required; remove variants from Details tab - Update product organization edit form for single category - Update all consumer imports from old attribute hook names to new ones Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace individual create/update calls with a single upsert endpoint at POST /admin/product-attributes/:id/values that accepts a values array. Items with id are updated, items without are created. This eliminates N+1 API calls from the ranking and possible values pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d system Remove ProductOption/ProductOptionValue models and replace with direct Product ↔ ProductAttribute/ProductAttributeValue M2M relationships. - Add product_id FK on ProductAttribute for custom product-scoped attributes - Add variant_attributes, custom_attributes, attribute_values M2M on Product - Add attribute_values M2M on ProductVariant - Rewrite service normalizeAttributes_ to handle global refs and inline custom attrs - Update all API validators, query configs across admin/vendor/store - Add delete validation for attributes and attribute values in use - Rework admin product create UI: attributes tab with global/custom attrs, variant generation from attribute axes, Combobox multi-select for values - Remove old options field from form schema, rename to attribute_values Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…stom attribute linking - Add ProductAttributeSection to product detail page with Variations and Product Information groups, dotted divider between groups, and bordered rows - Fix custom attribute creation: defer product_id assignment until after product creation so hasMany FK is properly set - Restrict variant axis to multi_select only (remove single_select) - Derive informational attributes from both custom_attributes and attribute_values so existing global attributes appear in detail view - Re-fetch created attributes with values relation to ensure attribute value IDs are correctly linked to products Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ns, and add-existing flow - Add /admin/products/:id/attributes endpoints (GET, POST) and /admin/products/:id/attributes/:attribute_id (GET, POST, DELETE) - Add removeAttributeFromProduct service method and workflow to properly unlink attributes from variant_attributes M2M, attribute_values M2M, and delete product-scoped attributes - createProductAttributes now links variant_attributes M2M when is_variant_axis is true, and links attribute_values to the product - Add product attribute sub-resource hooks (list, create, update, delete) using fetchQuery - Add shared AttributeValueInput component for type-aware value inputs - Add product-create-attribute route page (RouteDrawer with create form) - Add product-add-existing-attributes route page (RouteFocusModal with two-step flow: DataTable selection → zod-validated value form) - Add delete action per attribute row in detail section with confirmation - Remove ProductOptionSection from product detail page - Fix Switch component in create attributes form (shrink-0, ref-only spread) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… service Add batch endpoint for product attributes (create/update/delete in one call), refactor product service for improved attribute handling, and update integration tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… include product_attributes in update check Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…and integration tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…apes
Update the composite unique index on product_attribute from (handle) to
(product_id, handle) so product-scoped attributes can reuse global handles.
Fix integration tests to use multi_select for variant axis attributes and
wrap value create payloads in { values: [...] } to match the upsert validator.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…factor admin UI Override listProductAttributes, listAndCountProductAttributes, and retrieveProductAttribute to resolve values only for single_select/multi_select types (empty for others). Migrate admin hooks to SDK route pattern, rename for clarity, add edit attribute route, and simplify product attribute section to use unified attributes array. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…te validation Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t create/update
Resolve map-form `attribute_values` ({ Color: "Red" }) to value IDs in the
product service for both create and update paths, and accept either form in
the variant DTOs. Refactor admin variant create/edit forms to use the shared
attribute-value-input and drop the unused `prices` field from the variant
create validator.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s enum - Introduce product brands: admin pages, hooks, route, settings nav, organization form/section integration, and i18n. - Rename product status enum to draft/proposed/published (default proposed), update workflow validators, status cell, store filter, i18n, and ship migrations. - Drop product seller section from variant detail and seller_id link filter from /admin/products. - Simplify variant detail to use default fields and render variant attribute_values grouped by attribute. - Allow status on product create/update validators; show JSON on attribute detail; switch product media upload to new SDK; block product_id filter on /admin/product-attributes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ace store column Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dmin UI Add POST /admin/products/batch with validator, workflow, and event names (draft/published/proposed). Wire up an admin bulk-edit page reachable from the product list table command, with row selection and a hook calling the new SDK route. Drop `is_restricted` from product brand create/edit forms and use the existing product status when emitting submit-seller status changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the marketplace-specific is_active column on Product along with its index, activate/deactivate workflows, admin routes, and admin hooks. Product visibility is now driven entirely by status. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…equired status Combine update/delete into a single batchProducts workflow and add a bulk delete action to the product list. Add the changes_required option to the edit form and color it blue on the detail page to match ProductStatusCell. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Si3r4dz
reviewed
Apr 29, 2026
| ) => { | ||
| return useMutation({ | ||
| mutationFn: (payload: HttpTypes.AdminUpdateProductVariant) => | ||
| mutationFn: (payload: any) => |
Collaborator
There was a problem hiding this comment.
Why type was removed and changed to any?
Comment on lines
+440
to
+452
| export const useBatchProductAttributes = ( | ||
| productId: string, | ||
| options?: UseMutationOptions< | ||
| HttpTypes.AdminExportProductResponse, | ||
| any, | ||
| ClientError, | ||
| HttpTypes.AdminExportProductRequest | ||
| { | ||
| create?: { | ||
| attribute_id: string; | ||
| attribute_value_ids?: string[]; | ||
| values?: string[]; | ||
| }[]; | ||
| delete?: string[]; | ||
| } |
Collaborator
There was a problem hiding this comment.
Don't we have type somewhere for this object passed as third param in options?
|
|
||
| export const useUpdateProductVariantsBatch = ( | ||
| productId: string, | ||
| options?: UseMutationOptions<any, ClientError, any>, |
Comment on lines
+501
to
+509
| options?: UseMutationOptions<any, ClientError, any>, | ||
| ) => { | ||
| return useMutation({ | ||
| mutationFn: (transactionId) => | ||
| sdk.admin.products.import.$transactionId.confirm.mutate({ | ||
| $transactionId: transactionId, | ||
| mutationFn: (payload: any) => | ||
| sdk.admin.products.$id.variants.inventoryItems.batch.mutate({ | ||
| $id: productId, | ||
| ...payload, | ||
| }), | ||
| onSuccess: (data, variables, context) => { | ||
| onSuccess: (data: any, variables: any, context: any) => { |
Comment on lines
+48
to
+51
| // const { variants = [], count } = useVariants({ | ||
| // ...searchParams, | ||
| // fields: "*inventory_items.inventory.location_levels,+inventory_quantity", | ||
| // }); |
Collaborator
There was a problem hiding this comment.
Do we need to leave it here? if so please add TODO.
Comment on lines
+139
to
+140
| // allow_backorder, | ||
| // manage_inventory, |
Comment on lines
+40
to
+53
| // mutateAsync(values, { | ||
| // onSuccess: () => { | ||
| // toast.success( | ||
| // t("products.options.create.successToast", { | ||
| // title: values.title, | ||
| // }) | ||
| // ) | ||
| // handleSuccess() | ||
| // }, | ||
| // onError: async (err) => { | ||
| // toast.error(err.message) | ||
| // }, | ||
| // }) | ||
| }); |
Comment on lines
+114
to
+116
| {/* <Button type="submit" size="small" isLoading={isPending}> | ||
| {t("actions.save")} | ||
| </Button> | ||
| </Button> */} |
|
|
||
| await mutateAsync() | ||
| } | ||
| // await mutateAsync(); |
Collaborator
There was a problem hiding this comment.
Same with comments in this file
Comment on lines
+37
to
+54
| // const { mutateAsync, isPending } = useUpdateProductOption( | ||
| // option.product_id!, | ||
| // option.id | ||
| // ) | ||
|
|
||
| const handleSubmit = form.handleSubmit(async (values) => { | ||
| mutateAsync( | ||
| { | ||
| id: option.id, | ||
| ...values, | ||
| }, | ||
| { | ||
| onSuccess: () => { | ||
| handleSuccess() | ||
| }, | ||
| } | ||
| ) | ||
| }) | ||
| // mutateAsync( | ||
| // { | ||
| // id: option.id, | ||
| // ...values, | ||
| // }, | ||
| // { | ||
| // onSuccess: () => { | ||
| // handleSuccess() | ||
| // }, | ||
| // } | ||
| // ) | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
🤖 Generated with Claude Code