diff --git a/package-lock.json b/package-lock.json index 8f6c1559..861f955b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "zod": "3.25.76" }, "devDependencies": { + "@ianvs/prettier-plugin-sort-imports": "^4.7.0", "@medusajs/admin-shared": "2.10.3", "@medusajs/admin-vite-plugin": "2.10.3", "@medusajs/types": "2.10.3", @@ -260,14 +261,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -277,13 +278,13 @@ } }, "node_modules/@babel/generator/node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -293,14 +294,14 @@ } }, "node_modules/@babel/generator/node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -494,9 +495,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -1480,6 +1481,90 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@ianvs/prettier-plugin-sort-imports": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.7.0.tgz", + "integrity": "sha512-soa2bPUJAFruLL4z/CnMfSEKGznm5ebz29fIa9PxYtu8HHyLKNE1NXAs6dylfw1jn/ilEIfO2oLLN6uAafb7DA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/generator": "^7.26.2", + "@babel/parser": "^7.26.2", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "semver": "^7.5.2" + }, + "peerDependencies": { + "@prettier/plugin-oxc": "^0.0.4", + "@vue/compiler-sfc": "2.7.x || 3.x", + "content-tag": "^4.0.0", + "prettier": "2 || 3 || ^4.0.0-0", + "prettier-plugin-ember-template-tag": "^2.1.0" + }, + "peerDependenciesMeta": { + "@prettier/plugin-oxc": { + "optional": true + }, + "@vue/compiler-sfc": { + "optional": true + }, + "content-tag": { + "optional": true + }, + "prettier-plugin-ember-template-tag": { + "optional": true + } + } + }, + "node_modules/@ianvs/prettier-plugin-sort-imports/node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ianvs/prettier-plugin-sort-imports/node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ianvs/prettier-plugin-sort-imports/node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@internationalized/date": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.0.tgz", diff --git a/src/components/common/customer-info/customer-info.tsx b/src/components/common/customer-info/customer-info.tsx index 2c0c82ea..c86f88f1 100644 --- a/src/components/common/customer-info/customer-info.tsx +++ b/src/components/common/customer-info/customer-info.tsx @@ -1,10 +1,10 @@ import { Avatar, Copy, Text } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { Link } from "react-router-dom" -import { HttpTypes } from "@medusajs/types" -import { getFormattedAddress, isSameAddress } from "../../../lib/addresses" +import { getFormattedAddress, isSameAddress } from "@lib/addresses" +import type { ExtendedAdminOrder } from "@custom-types/order" -const ID = ({ data }: { data: HttpTypes.AdminOrder }) => { +const ID = ({ data }: { data: ExtendedAdminOrder }) => { const { t } = useTranslation() const id = data.customer_id @@ -36,7 +36,7 @@ const ID = ({ data }: { data: HttpTypes.AdminOrder }) => { ) } -const Company = ({ data }: { data: HttpTypes.AdminOrder }) => { +const Company = ({ data }: { data: ExtendedAdminOrder }) => { const { t } = useTranslation() const company = data.shipping_address?.company || data.billing_address?.company @@ -57,7 +57,7 @@ const Company = ({ data }: { data: HttpTypes.AdminOrder }) => { ) } -const Contact = ({ data }: { data: HttpTypes.AdminOrder }) => { +const Contact = ({ data }: { data: ExtendedAdminOrder }) => { const { t } = useTranslation() const phone = data.shipping_address?.phone || data.billing_address?.phone @@ -107,8 +107,8 @@ const AddressPrint = ({ type, }: { address: - | HttpTypes.AdminOrder["shipping_address"] - | HttpTypes.AdminOrder["billing_address"] + | ExtendedAdminOrder["shipping_address"] + | ExtendedAdminOrder["billing_address"] type: "shipping" | "billing" }) => { const { t } = useTranslation() @@ -148,7 +148,7 @@ const AddressPrint = ({ ) } -const Addresses = ({ data }: { data: HttpTypes.AdminOrder }) => { +const Addresses = ({ data }: { data: ExtendedAdminOrder }) => { const { t } = useTranslation() return ( @@ -185,7 +185,7 @@ export const CustomerInfo = Object.assign( } ) -const getOrderCustomer = (obj: HttpTypes.AdminOrder) => { +const getOrderCustomer = (obj: ExtendedAdminOrder) => { const { first_name: sFirstName, last_name: sLastName } = obj.shipping_address || {} const { first_name: bFirstName, last_name: bLastName } = diff --git a/src/components/data-grid/components/data-grid-root.tsx b/src/components/data-grid/components/data-grid-root.tsx index 64ff426e..dc52b86f 100644 --- a/src/components/data-grid/components/data-grid-root.tsx +++ b/src/components/data-grid/components/data-grid-root.tsx @@ -444,6 +444,7 @@ export const DataGridRoot = < const specialFocusHandler = (e: KeyboardEvent) => { if (isSpecialFocusKey(e)) { handleSpecialFocusKeys(e) + return } } @@ -715,6 +716,7 @@ const DataGridHeader = ({ onHeaderInteractionChange(value) setColumnsOpen(value) } + return (
@@ -861,10 +863,10 @@ const DataGridCell = ({ type DataGridRowProps = { row: Row rowIndex: number - virtualRow: VirtualItem + virtualRow: VirtualItem virtualPaddingLeft?: number virtualPaddingRight?: number - virtualColumns: VirtualItem[] + virtualColumns: VirtualItem[] flatColumns: Column[] anchor: DataGridCoordinates | null onDragToFillStart: (e: React.MouseEvent) => void diff --git a/src/components/search/use-search-results.tsx b/src/components/search/use-search-results.tsx index 41149d9b..bc1d77e7 100644 --- a/src/components/search/use-search-results.tsx +++ b/src/components/search/use-search-results.tsx @@ -29,6 +29,7 @@ import { useReturnReasons } from "../../hooks/api/return-reasons" import { Shortcut, ShortcutType } from "../../providers/keybind-provider" import { useGlobalShortcuts } from "../../providers/keybind-provider/hooks" import { DynamicSearchResult, SearchArea } from "./types" +import { ExtendedAdminProduct, ExtendedAdminProductVariant } from "@custom-types/product" type UseSearchProps = { q?: string @@ -426,6 +427,7 @@ const useDynamicSearchResults = ( if (isAreaEnabled(currentArea, area) || currentArea === "all") { return transformDynamicSearchResults(area, limit, t, response) } + return null }) .filter(Boolean) // Remove null values @@ -488,6 +490,7 @@ function isAreaEnabled(area: SearchArea, currentArea: SearchArea) { if (area === currentArea) { return true } + return false } @@ -518,7 +521,7 @@ const transformMap: TransformMap = { }, product: { dataKey: "products", - transform: (product: HttpTypes.AdminProduct) => ({ + transform: (product: ExtendedAdminProduct) => ({ id: product.id, title: product.title, to: `/products/${product.id}`, @@ -528,7 +531,7 @@ const transformMap: TransformMap = { }, productVariant: { dataKey: "variants", - transform: (variant: HttpTypes.AdminProductVariant) => ({ + transform: (variant: ExtendedAdminProductVariant) => ({ id: variant.id, title: variant.title!, subtitle: variant.sku ?? undefined, @@ -561,6 +564,7 @@ const transformMap: TransformMap = { const name = [customer.first_name, customer.last_name] .filter(Boolean) .join(" ") + return { id: customer.id, title: name || customer.email, diff --git a/src/components/table/table-cells/product/variant-cell/variant-cell.tsx b/src/components/table/table-cells/product/variant-cell/variant-cell.tsx index bdaa33d0..294fba63 100644 --- a/src/components/table/table-cells/product/variant-cell/variant-cell.tsx +++ b/src/components/table/table-cells/product/variant-cell/variant-cell.tsx @@ -1,10 +1,10 @@ import { useTranslation } from "react-i18next" import { PlaceholderCell } from "../../common/placeholder-cell" -import { HttpTypes } from "@medusajs/types" +import type { ExtendedAdminProductVariant } from "@custom-types/product" type VariantCellProps = { - variants?: HttpTypes.AdminProductVariant[] | null + variants?: ExtendedAdminProductVariant[] | null "data-testid"?: string } diff --git a/src/dashboard-app/routes/get-route.map.tsx b/src/dashboard-app/routes/get-route.map.tsx index f0f02cff..745d0c07 100644 --- a/src/dashboard-app/routes/get-route.map.tsx +++ b/src/dashboard-app/routes/get-route.map.tsx @@ -12,6 +12,9 @@ import { ErrorBoundary } from "@components/utilities/error-boundary"; import { TaxRegionDetailBreadcrumb } from "@routes/tax-regions/tax-region-detail/breadcrumb"; import { taxRegionLoader } from "@routes/tax-regions/tax-region-detail/loader"; +import type { ExtendedAdminProductResponse, ExtendedAdminProductVariantResponse } from "@custom-types/product"; +import type { ExtendedAdminInventoryItemResponse } from "@custom-types/inventory"; + export function getRouteMap({ settingsRoutes, coreRoutes, @@ -73,7 +76,7 @@ export function getRouteMap({ loader, handle: { breadcrumb: ( - match: UIMatch, + match: UIMatch, ) => , }, }; @@ -175,8 +178,7 @@ export function getRouteMap({ loader, handle: { breadcrumb: ( - // eslint-disable-next-line max-len - match: UIMatch, + match: UIMatch, ) => , }, }; @@ -974,7 +976,7 @@ export function getRouteMap({ loader, handle: { breadcrumb: ( - match: UIMatch, + match: UIMatch, ) => , }, }; diff --git a/src/hooks/api/claims.tsx b/src/hooks/api/claims.tsx index 4fb5bbeb..d0d0784c 100644 --- a/src/hooks/api/claims.tsx +++ b/src/hooks/api/claims.tsx @@ -1,18 +1,19 @@ -import { FetchError } from "@medusajs/js-sdk" -import { HttpTypes } from "@medusajs/types" +import type { FetchError } from "@medusajs/js-sdk" +import type { HttpTypes } from "@medusajs/types" import { - QueryKey, + type QueryKey, useMutation, - UseMutationOptions, + type UseMutationOptions, useQuery, - UseQueryOptions, + type UseQueryOptions, } from "@tanstack/react-query" -import { sdk } from "../../lib/client" -import { queryClient } from "../../lib/query-client" -import { queryKeysFactory } from "../../lib/query-key-factory" +import { sdk } from "@lib/client" +import { queryClient } from "@lib/query-client" +import { queryKeysFactory } from "@lib/query-key-factory" import { ordersQueryKeys } from "./orders" import { returnsQueryKeys } from "./returns" +import type { ExtendedAdminClaimListResponse, AdminAddClaimOutboundItemsPayload } from "@custom-types/claims" const CLAIMS_QUERY_KEY = "claims" as const export const claimsQueryKeys = queryKeysFactory(CLAIMS_QUERY_KEY) @@ -43,16 +44,16 @@ export const useClaims = ( query?: HttpTypes.AdminClaimListParams, options?: Omit< UseQueryOptions< - HttpTypes.AdminClaimListParams, + ExtendedAdminClaimListResponse, FetchError, - HttpTypes.AdminClaimListResponse, + ExtendedAdminClaimListResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: async () => sdk.admin.claim.list(query), + queryFn: async () => sdk.admin.claim.list(query) as Promise, queryKey: claimsQueryKeys.list(query), ...options, }) @@ -71,7 +72,7 @@ export const useCreateClaim = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminCreateClaim) => sdk.admin.claim.create(payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: HttpTypes.AdminCreateClaim, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -93,11 +94,11 @@ export const useCreateClaim = ( export const useCancelClaim = ( id: string, orderId: string, - options?: UseMutationOptions + options?: UseMutationOptions ) => { return useMutation({ mutationFn: () => sdk.admin.claim.cancel(id), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: void, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -131,7 +132,7 @@ export const useAddClaimItems = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminAddClaimItems) => sdk.admin.claim.addItems(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: HttpTypes.AdminAddClaimItems, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -162,7 +163,7 @@ export const useUpdateClaimItems = ( }: HttpTypes.AdminUpdateClaimItem & { actionId: string }) => { return sdk.admin.claim.updateItem(id, actionId, payload) }, - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: HttpTypes.AdminUpdateClaimItem & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -189,7 +190,7 @@ export const useRemoveClaimItem = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.return.removeReturnItem(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminReturnResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -214,8 +215,8 @@ export const useAddClaimInboundItems = ( > ) => { return useMutation({ - mutationFn: (payload) => sdk.admin.claim.addInboundItems(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + mutationFn: (payload: HttpTypes.AdminAddClaimInboundItems) => sdk.admin.claim.addInboundItems(id, payload), + onSuccess: (data: HttpTypes.AdminClaimReturnPreviewResponse, variables: HttpTypes.AdminAddClaimInboundItems, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -234,7 +235,7 @@ export const useUpdateClaimInboundItem = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminClaimResponse, + HttpTypes.AdminClaimReturnPreviewResponse, FetchError, HttpTypes.AdminUpdateClaimInboundItem & { actionId: string } > @@ -246,7 +247,7 @@ export const useUpdateClaimInboundItem = ( }: HttpTypes.AdminUpdateClaimInboundItem & { actionId: string }) => { return sdk.admin.claim.updateInboundItem(id, actionId, payload) }, - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimReturnPreviewResponse, variables: HttpTypes.AdminUpdateClaimInboundItem & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -264,12 +265,12 @@ export const useUpdateClaimInboundItem = ( export const useRemoveClaimInboundItem = ( id: string, orderId: string, - options?: UseMutationOptions + options?: UseMutationOptions ) => { return useMutation({ mutationFn: (actionId: string) => sdk.admin.claim.removeInboundItem(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimReturnPreviewResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -292,7 +293,7 @@ export const useAddClaimInboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminClaimResponse, + HttpTypes.AdminClaimReturnPreviewResponse, FetchError, HttpTypes.AdminClaimAddInboundShipping > @@ -300,7 +301,7 @@ export const useAddClaimInboundShipping = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminClaimAddInboundShipping) => sdk.admin.claim.addInboundShipping(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimReturnPreviewResponse, variables: HttpTypes.AdminClaimAddInboundShipping, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -319,9 +320,9 @@ export const useUpdateClaimInboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminClaimResponse, + HttpTypes.AdminClaimPreviewResponse, FetchError, - HttpTypes.AdminClaimUpdateInboundShipping + HttpTypes.AdminClaimUpdateInboundShipping & { actionId: string } > ) => { return useMutation({ @@ -330,7 +331,7 @@ export const useUpdateClaimInboundShipping = ( ...payload }: HttpTypes.AdminClaimUpdateInboundShipping & { actionId: string }) => sdk.admin.claim.updateInboundShipping(id, actionId, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimPreviewResponse, variables: HttpTypes.AdminClaimUpdateInboundShipping & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -348,12 +349,12 @@ export const useUpdateClaimInboundShipping = ( export const useDeleteClaimInboundShipping = ( id: string, orderId: string, - options?: UseMutationOptions + options?: UseMutationOptions ) => { return useMutation({ mutationFn: (actionId: string) => sdk.admin.claim.deleteInboundShipping(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimReturnPreviewResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -374,13 +375,13 @@ export const useAddClaimOutboundItems = ( options?: UseMutationOptions< HttpTypes.AdminClaimResponse, FetchError, - HttpTypes.AdminAddClaimOutboundItems + AdminAddClaimOutboundItemsPayload > ) => { return useMutation({ - mutationFn: (payload: HttpTypes.AdminAddClaimOutboundItems) => - sdk.admin.claim.addOutboundItems(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + mutationFn: (payload: AdminAddClaimOutboundItemsPayload) => + sdk.admin.claim.addOutboundItems(id, payload as unknown as HttpTypes.AdminAddClaimOutboundItems), + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: AdminAddClaimOutboundItemsPayload, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -411,7 +412,7 @@ export const useUpdateClaimOutboundItems = ( }: HttpTypes.AdminUpdateClaimOutboundItem & { actionId: string }) => { return sdk.admin.claim.updateOutboundItem(id, actionId, payload) }, - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: HttpTypes.AdminUpdateClaimOutboundItem & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -434,7 +435,7 @@ export const useRemoveClaimOutboundItem = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.claim.removeOutboundItem(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -461,7 +462,7 @@ export const useAddClaimOutboundShipping = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminClaimAddOutboundShipping) => sdk.admin.claim.addOutboundShipping(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: HttpTypes.AdminClaimAddOutboundShipping, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -480,9 +481,9 @@ export const useUpdateClaimOutboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminClaimResponse, + HttpTypes.AdminClaimPreviewResponse, FetchError, - HttpTypes.AdminClaimUpdateOutboundShipping + HttpTypes.AdminClaimUpdateOutboundShipping & { actionId: string } > ) => { return useMutation({ @@ -491,7 +492,7 @@ export const useUpdateClaimOutboundShipping = ( ...payload }: HttpTypes.AdminClaimUpdateOutboundShipping & { actionId: string }) => sdk.admin.claim.updateOutboundShipping(id, actionId, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimPreviewResponse, variables: HttpTypes.AdminClaimUpdateOutboundShipping & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -514,7 +515,7 @@ export const useDeleteClaimOutboundShipping = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.claim.deleteOutboundShipping(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -541,7 +542,7 @@ export const useClaimConfirmRequest = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminRequestClaim) => sdk.admin.claim.request(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimResponse, variables: HttpTypes.AdminRequestClaim, context: unknown) => { queryClient.invalidateQueries({ queryKey: returnsQueryKeys.all, }) @@ -567,11 +568,11 @@ export const useClaimConfirmRequest = ( export const useCancelClaimRequest = ( id: string, orderId: string, - options?: UseMutationOptions + options?: UseMutationOptions ) => { return useMutation({ mutationFn: () => sdk.admin.claim.cancelRequest(id), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminClaimDeleteResponse, variables: void, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) diff --git a/src/hooks/api/exchanges.tsx b/src/hooks/api/exchanges.tsx index f28600f5..ed7a54fe 100644 --- a/src/hooks/api/exchanges.tsx +++ b/src/hooks/api/exchanges.tsx @@ -1,17 +1,22 @@ -import { FetchError } from "@medusajs/js-sdk" -import { HttpTypes } from "@medusajs/types" +import type { FetchError } from "@medusajs/js-sdk" +import type { HttpTypes } from "@medusajs/types" import { - QueryKey, + type QueryKey, useMutation, - UseMutationOptions, + type UseMutationOptions, useQuery, - UseQueryOptions, + type UseQueryOptions, } from "@tanstack/react-query" -import { sdk } from "../../lib/client" -import { queryClient } from "../../lib/query-client" -import { queryKeysFactory } from "../../lib/query-key-factory" +import { sdk } from "@lib/client" +import { queryClient } from "@lib/query-client" +import { queryKeysFactory } from "@lib/query-key-factory" import { ordersQueryKeys } from "./orders" import { returnsQueryKeys } from "./returns" +import type { + ExtendedAdminExchangeListResponse, + ExtendedAdminExchangeResponse, + AdminAddExchangeOutboundItemsPayload +} from "@custom-types/exchanges/common" const EXCHANGES_QUERY_KEY = "exchanges" as const export const exchangesQueryKeys = queryKeysFactory(EXCHANGES_QUERY_KEY) @@ -21,16 +26,16 @@ export const useExchange = ( query?: HttpTypes.AdminExchangeListParams, options?: Omit< UseQueryOptions< - HttpTypes.AdminExchangeResponse, + ExtendedAdminExchangeResponse, FetchError, - HttpTypes.AdminExchangeResponse, + ExtendedAdminExchangeResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: async () => sdk.admin.exchange.retrieve(id, query), + queryFn: async () => sdk.admin.exchange.retrieve(id, query) as unknown as Promise, queryKey: exchangesQueryKeys.detail(id, query), ...options, }) @@ -42,16 +47,16 @@ export const useExchanges = ( query?: HttpTypes.AdminExchangeListParams, options?: Omit< UseQueryOptions< - HttpTypes.AdminExchangeListParams, + ExtendedAdminExchangeListResponse, FetchError, - HttpTypes.AdminExchangeListResponse, + ExtendedAdminExchangeListResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: async () => sdk.admin.exchange.list(query), + queryFn: async () => sdk.admin.exchange.list(query) as unknown as Promise, queryKey: exchangesQueryKeys.list(query), ...options, }) @@ -62,7 +67,7 @@ export const useExchanges = ( export const useCreateExchange = ( orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + ExtendedAdminExchangeResponse, FetchError, HttpTypes.AdminCreateExchange > @@ -70,7 +75,7 @@ export const useCreateExchange = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminCreateExchange) => sdk.admin.exchange.create(payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: ExtendedAdminExchangeResponse, variables: HttpTypes.AdminCreateExchange, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -92,11 +97,11 @@ export const useCreateExchange = ( export const useCancelExchange = ( id: string, orderId: string, - options?: UseMutationOptions + options?: UseMutationOptions ) => { return useMutation({ mutationFn: () => sdk.admin.exchange.cancel(id), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: ExtendedAdminExchangeResponse, variables: void, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -122,7 +127,7 @@ export const useAddExchangeInboundItems = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeReturnResponse, FetchError, HttpTypes.AdminAddExchangeInboundItems > @@ -130,7 +135,7 @@ export const useAddExchangeInboundItems = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminAddExchangeInboundItems) => sdk.admin.exchange.addInboundItems(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeReturnResponse, variables: HttpTypes.AdminAddExchangeInboundItems, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -144,7 +149,7 @@ export const useUpdateExchangeInboundItem = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeReturnResponse, FetchError, HttpTypes.AdminUpdateExchangeInboundItem & { actionId: string } > @@ -156,7 +161,7 @@ export const useUpdateExchangeInboundItem = ( }: HttpTypes.AdminUpdateExchangeInboundItem & { actionId: string }) => { return sdk.admin.exchange.updateInboundItem(id, actionId, payload) }, - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeReturnResponse, variables: HttpTypes.AdminUpdateExchangeInboundItem & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -170,7 +175,7 @@ export const useRemoveExchangeInboundItem = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeReturnResponse, FetchError, string > @@ -178,7 +183,7 @@ export const useRemoveExchangeInboundItem = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.exchange.removeInboundItem(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeReturnResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -201,7 +206,7 @@ export const useAddExchangeInboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeReturnResponse, FetchError, HttpTypes.AdminExchangeAddInboundShipping > @@ -209,7 +214,7 @@ export const useAddExchangeInboundShipping = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminExchangeAddInboundShipping) => sdk.admin.exchange.addInboundShipping(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeReturnResponse, variables: HttpTypes.AdminExchangeAddInboundShipping, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -223,9 +228,9 @@ export const useUpdateExchangeInboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeReturnResponse, FetchError, - HttpTypes.AdminExchangeUpdateInboundShipping + HttpTypes.AdminExchangeUpdateInboundShipping & { actionId: string } > ) => { return useMutation({ @@ -234,7 +239,7 @@ export const useUpdateExchangeInboundShipping = ( ...payload }: HttpTypes.AdminExchangeUpdateInboundShipping & { actionId: string }) => sdk.admin.exchange.updateInboundShipping(id, actionId, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeReturnResponse, variables: HttpTypes.AdminExchangeUpdateInboundShipping & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -248,7 +253,7 @@ export const useDeleteExchangeInboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeReturnResponse, FetchError, string > @@ -256,7 +261,7 @@ export const useDeleteExchangeInboundShipping = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.exchange.deleteInboundShipping(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeReturnResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -271,15 +276,15 @@ export const useAddExchangeOutboundItems = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangePreviewResponse, FetchError, - HttpTypes.AdminAddExchangeOutboundItems + AdminAddExchangeOutboundItemsPayload > ) => { return useMutation({ - mutationFn: (payload: HttpTypes.AdminAddExchangeOutboundItems) => - sdk.admin.exchange.addOutboundItems(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + mutationFn: (payload: AdminAddExchangeOutboundItemsPayload) => + sdk.admin.exchange.addOutboundItems(id, payload as unknown as HttpTypes.AdminAddExchangeOutboundItems), + onSuccess: (data: HttpTypes.AdminExchangePreviewResponse, variables: AdminAddExchangeOutboundItemsPayload, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -293,7 +298,7 @@ export const useUpdateExchangeOutboundItems = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangePreviewResponse, FetchError, HttpTypes.AdminUpdateExchangeOutboundItem & { actionId: string } > @@ -305,7 +310,7 @@ export const useUpdateExchangeOutboundItems = ( }: HttpTypes.AdminUpdateExchangeOutboundItem & { actionId: string }) => { return sdk.admin.exchange.updateOutboundItem(id, actionId, payload) }, - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangePreviewResponse, variables: HttpTypes.AdminUpdateExchangeOutboundItem & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -319,7 +324,7 @@ export const useRemoveExchangeOutboundItem = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangePreviewResponse, FetchError, string > @@ -327,7 +332,7 @@ export const useRemoveExchangeOutboundItem = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.exchange.removeOutboundItem(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangePreviewResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) @@ -346,7 +351,7 @@ export const useAddExchangeOutboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangePreviewResponse, FetchError, HttpTypes.AdminExchangeAddOutboundShipping > @@ -354,7 +359,7 @@ export const useAddExchangeOutboundShipping = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminExchangeAddOutboundShipping) => sdk.admin.exchange.addOutboundShipping(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangePreviewResponse, variables: HttpTypes.AdminExchangeAddOutboundShipping, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -368,9 +373,9 @@ export const useUpdateExchangeOutboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangePreviewResponse, FetchError, - HttpTypes.AdminExchangeUpdateOutboundShipping + HttpTypes.AdminExchangeUpdateOutboundShipping & { actionId: string } > ) => { return useMutation({ @@ -379,7 +384,7 @@ export const useUpdateExchangeOutboundShipping = ( ...payload }: HttpTypes.AdminExchangeUpdateOutboundShipping & { actionId: string }) => sdk.admin.exchange.updateOutboundShipping(id, actionId, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangePreviewResponse, variables: HttpTypes.AdminExchangeUpdateOutboundShipping & { actionId: string }, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -393,7 +398,7 @@ export const useDeleteExchangeOutboundShipping = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangePreviewResponse, FetchError, string > @@ -401,7 +406,7 @@ export const useDeleteExchangeOutboundShipping = ( return useMutation({ mutationFn: (actionId: string) => sdk.admin.exchange.deleteOutboundShipping(id, actionId), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangePreviewResponse, variables: string, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.preview(orderId), }) @@ -415,7 +420,7 @@ export const useExchangeConfirmRequest = ( id: string, orderId: string, options?: UseMutationOptions< - HttpTypes.AdminExchangeResponse, + HttpTypes.AdminExchangeRequestResponse, FetchError, HttpTypes.AdminRequestExchange > @@ -423,7 +428,7 @@ export const useExchangeConfirmRequest = ( return useMutation({ mutationFn: (payload: HttpTypes.AdminRequestExchange) => sdk.admin.exchange.request(id, payload), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeRequestResponse, variables: HttpTypes.AdminRequestExchange, context: unknown) => { queryClient.invalidateQueries({ queryKey: returnsQueryKeys.all, }) @@ -449,11 +454,11 @@ export const useExchangeConfirmRequest = ( export const useCancelExchangeRequest = ( id: string, orderId: string, - options?: UseMutationOptions + options?: UseMutationOptions ) => { return useMutation({ mutationFn: () => sdk.admin.exchange.cancelRequest(id), - onSuccess: (data: any, variables: any, context: any) => { + onSuccess: (data: HttpTypes.AdminExchangeDeleteResponse, variables: void, context: unknown) => { queryClient.invalidateQueries({ queryKey: ordersQueryKeys.details(), }) diff --git a/src/hooks/api/orders.tsx b/src/hooks/api/orders.tsx index aaa06849..b0527e05 100644 --- a/src/hooks/api/orders.tsx +++ b/src/hooks/api/orders.tsx @@ -12,6 +12,7 @@ import { queryClient } from "../../lib/query-client" import { queryKeysFactory, TQueryKey } from "../../lib/query-key-factory" import { inventoryItemsQueryKeys } from "./inventory" import { reservationItemsQueryKeys } from "./reservations" +import type { ExtendedAdminOrderResponse, ExtendedAdminOrderChangesResponse } from "@custom-types/order" const ORDERS_QUERY_KEY = "orders" as const const _orderKeys = queryKeysFactory(ORDERS_QUERY_KEY) as TQueryKey<"orders"> & { @@ -41,14 +42,14 @@ export const ordersQueryKeys = _orderKeys export const useOrder = ( id: string, - query?: Record, + query?: Record, options?: Omit< - UseQueryOptions, + UseQueryOptions, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: async () => sdk.admin.order.retrieve(id, query), + queryFn: async () => sdk.admin.order.retrieve(id, query) as Promise, queryKey: ordersQueryKeys.detail(id, query), ...options, }) @@ -157,16 +158,16 @@ export const useOrderChanges = ( query?: HttpTypes.AdminOrderChangesFilters, options?: Omit< UseQueryOptions< - HttpTypes.AdminOrderChangesResponse, + ExtendedAdminOrderChangesResponse, FetchError, - HttpTypes.AdminOrderChangesResponse, + ExtendedAdminOrderChangesResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: async () => sdk.admin.order.listChanges(id, query), + queryFn: async () => sdk.admin.order.listChanges(id, query) as Promise, queryKey: ordersQueryKeys.changes(id), ...options, }) diff --git a/src/hooks/api/products.tsx b/src/hooks/api/products.tsx index 2b9c136a..f4daf408 100644 --- a/src/hooks/api/products.tsx +++ b/src/hooks/api/products.tsx @@ -13,9 +13,12 @@ import { queryKeysFactory } from "../../lib/query-key-factory"; import { inventoryItemsQueryKeys } from "./inventory.tsx"; import { AttributeDTO } from "../../types/index.ts"; import { - AdminProductResponse, - AdminProductUpdate, + ExtendedAdminProductResponse, + ExtendedAdminProductUpdate, ExtendedAdminProductListParams, + ExtendedAdminProductListResponse, + ExtendedAdminProductVariantResponse, + ExtendedAdminProductVariantListResponse, } from "../../types/product/common.ts"; const PRODUCTS_QUERY_KEY = "products" as const; @@ -96,17 +99,16 @@ export const useProductVariant = ( query?: HttpTypes.AdminProductVariantParams, options?: Omit< UseQueryOptions< - HttpTypes.AdminProductVariantResponse, - FetchError, - HttpTypes.AdminProductVariantResponse, - QueryKey + ExtendedAdminProductVariantResponse, + FetchError, + ExtendedAdminProductVariantResponse, + QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: () => - sdk.admin.product.retrieveVariant(productId, variantId, query), + queryFn: async () => sdk.admin.product.retrieveVariant(productId, variantId, query) as Promise, queryKey: variantsQueryKeys.detail(variantId, query), ...options, }); @@ -117,18 +119,20 @@ export const useProductVariant = ( export const useProductVariants = ( productId: string, query?: HttpTypes.AdminProductVariantParams, + options?: Omit< UseQueryOptions< - HttpTypes.AdminProductVariantListResponse, + ExtendedAdminProductVariantListResponse, FetchError, - HttpTypes.AdminProductVariantListResponse, + ExtendedAdminProductVariantListResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: () => sdk.admin.product.listVariants(productId, query), + queryFn: async () => + sdk.admin.product.listVariants(productId, query) as Promise, queryKey: variantsQueryKeys.list({ productId, ...query }), ...options, }); @@ -275,19 +279,19 @@ export const useDeleteVariantLazy = ( export const useProduct = ( id: string, - query?: Record, + query?: Record, options?: Omit< UseQueryOptions< - AdminProductResponse, + ExtendedAdminProductResponse, FetchError, - AdminProductResponse, + ExtendedAdminProductResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: () => sdk.admin.product.retrieve(id, query), + queryFn: async () => sdk.admin.product.retrieve(id, query) as Promise, queryKey: productsQueryKeys.detail(id, query), ...options, }); @@ -299,16 +303,20 @@ export const useProducts = ( query?: ExtendedAdminProductListParams, options?: Omit< UseQueryOptions< - HttpTypes.AdminProductListResponse, + ExtendedAdminProductListResponse, FetchError, - HttpTypes.AdminProductListResponse, + ExtendedAdminProductListResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: () => sdk.admin.product.list(query), + queryFn: async () => { + const response = await sdk.admin.product.list(query) + + return response as unknown as ExtendedAdminProductListResponse + }, queryKey: productsQueryKeys.list(query), ...options, }); @@ -340,13 +348,17 @@ export const useCreateProduct = ( export const useUpdateProduct = ( id: string, options?: UseMutationOptions< - AdminProductResponse, + ExtendedAdminProductResponse, FetchError, - AdminProductUpdate + ExtendedAdminProductUpdate > ) => { return useMutation({ - mutationFn: (payload) => sdk.admin.product.update(id, payload), + mutationFn: async (payload) => { + const response = await sdk.admin.product.update(id, payload) + + return response as unknown as ExtendedAdminProductResponse + }, onSuccess: async (data, variables, context) => { await queryClient.invalidateQueries({ queryKey: productsQueryKeys.lists(), diff --git a/src/hooks/api/returns.tsx b/src/hooks/api/returns.tsx index e91fd911..7f66d66a 100644 --- a/src/hooks/api/returns.tsx +++ b/src/hooks/api/returns.tsx @@ -12,6 +12,7 @@ import { sdk } from "../../lib/client" import { queryClient } from "../../lib/query-client" import { queryKeysFactory } from "../../lib/query-key-factory" import { ordersQueryKeys } from "./orders" +import type { ExtendedAdminReturnsResponse } from "@custom-types/returns" const RETURNS_QUERY_KEY = "returns" as const export const returnsQueryKeys = queryKeysFactory(RETURNS_QUERY_KEY) @@ -37,16 +38,16 @@ export const useReturns = ( query?: HttpTypes.AdminReturnFilters, options?: Omit< UseQueryOptions< - HttpTypes.AdminReturnFilters, + ExtendedAdminReturnsResponse, FetchError, - HttpTypes.AdminReturnsResponse, + ExtendedAdminReturnsResponse, QueryKey >, "queryFn" | "queryKey" > ) => { const { data, ...rest } = useQuery({ - queryFn: async () => sdk.admin.return.list(query), + queryFn: async () => sdk.admin.return.list(query) as Promise, queryKey: returnsQueryKeys.list(query), ...options, }) diff --git a/src/hooks/api/sellers.tsx b/src/hooks/api/sellers.tsx index a195ae40..3ec87494 100644 --- a/src/hooks/api/sellers.tsx +++ b/src/hooks/api/sellers.tsx @@ -8,9 +8,9 @@ import { import { sdk } from "../../lib/client"; import { queryKeysFactory } from "../../lib/query-key-factory"; -import { VendorSeller } from "../../types"; -import { AdminCustomerGroup, AdminOrder, AdminProduct } from "@medusajs/types"; -import { OrderSet } from "../../types/order/common"; +import { ExtendedAdminProductListResponse, ExtendedAdminProduct, VendorSeller } from "../../types"; +import type { AdminCustomerGroup, AdminOrder } from "@medusajs/types"; +import type { OrderSet } from "@custom-types/seller-orders"; export const sellerQueryKeys = queryKeysFactory("seller"); @@ -25,8 +25,8 @@ const sortOrders = (orders: any[], order: string) => { const isDesc = order.startsWith("-"); return [...orders].sort((a, b) => { - let aValue: string | number | null | undefined = a[field]; - let bValue: string | number | null | undefined = b[field]; + const aValue: string | number | null | undefined = a[field]; + const bValue: string | number | null | undefined = b[field]; // Handle null/undefined values if (!aValue && aValue !== "") return isDesc ? -1 : 1; @@ -36,6 +36,7 @@ const sortOrders = (orders: any[], order: string) => { if (field === "created_at" || field === "updated_at") { const aDate = new Date(String(aValue)).getTime(); const bDate = new Date(String(bValue)).getTime(); + return isDesc ? bDate - aDate : aDate - bDate; } @@ -43,6 +44,7 @@ const sortOrders = (orders: any[], order: string) => { if (field === "display_id") { const aNum = Number(aValue); const bNum = Number(bValue); + return isDesc ? bNum - aNum : aNum - bNum; } @@ -52,6 +54,7 @@ const sortOrders = (orders: any[], order: string) => { if (aString < bString) return isDesc ? 1 : -1; if (aString > bString) return isDesc ? -1 : 1; + return 0; }); }; @@ -63,8 +66,8 @@ const sortProducts = (products: any[], order: string) => { const isDesc = order.startsWith("-"); return [...products].sort((a, b) => { - let aValue: string | number | null | undefined = a[field]; - let bValue: string | number | null | undefined = b[field]; + const aValue: string | number | null | undefined = a[field]; + const bValue: string | number | null | undefined = b[field]; // Handle null/undefined values if (!aValue && aValue !== "") return isDesc ? -1 : 1; @@ -74,6 +77,7 @@ const sortProducts = (products: any[], order: string) => { if (field === "created_at" || field === "updated_at") { const aDate = new Date(String(aValue)).getTime(); const bDate = new Date(String(bValue)).getTime(); + return isDesc ? bDate - aDate : aDate - bDate; } @@ -83,6 +87,7 @@ const sortProducts = (products: any[], order: string) => { if (aString < bString) return isDesc ? 1 : -1; if (aString > bString) return isDesc ? -1 : 1; + return 0; }); }; @@ -94,8 +99,8 @@ const sortCustomerGroups = (customerGroups: any[], order: string) => { const isDesc = order.startsWith("-"); return [...customerGroups].sort((a, b) => { - let aValue: string | number | null | undefined = a[field]; - let bValue: string | number | null | undefined = b[field]; + const aValue: string | number | null | undefined = a[field]; + const bValue: string | number | null | undefined = b[field]; // Handle null/undefined values if (!aValue && aValue !== "") return isDesc ? -1 : 1; @@ -105,6 +110,7 @@ const sortCustomerGroups = (customerGroups: any[], order: string) => { if (field === "created_at" || field === "updated_at") { const aDate = new Date(String(aValue)).getTime(); const bDate = new Date(String(bValue)).getTime(); + return isDesc ? bDate - aDate : aDate - bDate; } @@ -114,6 +120,7 @@ const sortCustomerGroups = (customerGroups: any[], order: string) => { if (aString < bString) return isDesc ? 1 : -1; if (aString > bString) return isDesc ? -1 : 1; + return 0; }); }; @@ -222,6 +229,7 @@ export const useSellerOrders = ( const filterDate = new Date(dateFilter.$gte); processedOrders = processedOrders.filter((order) => { const orderCreatedAt = new Date(order.created_at || ""); + return orderCreatedAt >= filterDate; }); } @@ -229,6 +237,7 @@ export const useSellerOrders = ( const filterDate = new Date(dateFilter.$lte); processedOrders = processedOrders.filter((order) => { const orderCreatedAt = new Date(order.created_at || ""); + return orderCreatedAt <= filterDate; }); } @@ -236,12 +245,13 @@ export const useSellerOrders = ( // Filter by updated_at date ranges if (filters?.updated_at) { - const dateFilter = filters.updated_at as any; + const dateFilter = filters.updated_at; if (dateFilter.$gte) { const filterDate = new Date(dateFilter.$gte); processedOrders = processedOrders.filter((order) => { const orderUpdatedAt = new Date(order.updated_at || ""); + return orderUpdatedAt >= filterDate; }); } @@ -249,6 +259,7 @@ export const useSellerOrders = ( const filterDate = new Date(dateFilter.$lte); processedOrders = processedOrders.filter((order) => { const orderUpdatedAt = new Date(order.updated_at || ""); + return orderUpdatedAt <= filterDate; }); } @@ -303,23 +314,23 @@ export const useSellerProducts = ( filters?: any ) => { const { data, isLoading, refetch } = useQuery< - { products: AdminProduct[] }, + ExtendedAdminProductListResponse, Error, - { products: AdminProduct[] } + ExtendedAdminProductListResponse >({ queryKey: ["seller-products", id, query], queryFn: () => sdk.client.fetch(`/admin/sellers/${id}/products`, { method: "GET", query, - }), + }) as Promise, }); if (!data?.products) { return { data, isLoading, refetch }; } - let processedProducts = [...data.products]; + let processedProducts: ExtendedAdminProduct[] = [...data.products]; // Apply search filter if present if (filters?.q) { @@ -332,7 +343,7 @@ export const useSellerProducts = ( // Filter by tag_id if (filters?.tag_id && Array.isArray(filters.tag_id)) { processedProducts = processedProducts.filter((product) => - product.tags?.some((tag: any) => filters.tag_id.includes(tag.id)) + product.tags?.some((tag) => filters.tag_id.includes(tag.id)) ); } @@ -346,7 +357,7 @@ export const useSellerProducts = ( // Filter by sales_channel_id if (filters?.sales_channel_id && Array.isArray(filters.sales_channel_id)) { processedProducts = processedProducts.filter((product) => - product.sales_channels?.some((channel: any) => + product.sales_channels?.some((channel) => filters.sales_channel_id.includes(channel.id) ) ); @@ -361,11 +372,12 @@ export const useSellerProducts = ( // Filter by created_at date ranges if (filters?.created_at) { - const dateFilter = filters.created_at as any; + const dateFilter = filters.created_at; if (dateFilter.$gte) { const filterDate = new Date(dateFilter.$gte); processedProducts = processedProducts.filter((product) => { const productCreatedAt = new Date(product.created_at || ""); + return productCreatedAt >= filterDate; }); } @@ -373,6 +385,7 @@ export const useSellerProducts = ( const filterDate = new Date(dateFilter.$lte); processedProducts = processedProducts.filter((product) => { const productCreatedAt = new Date(product.created_at || ""); + return productCreatedAt <= filterDate; }); } @@ -380,11 +393,12 @@ export const useSellerProducts = ( // Filter by updated_at date ranges if (filters?.updated_at) { - const dateFilter = filters.updated_at as any; + const dateFilter = filters.updated_at; if (dateFilter.$gte) { const filterDate = new Date(dateFilter.$gte); processedProducts = processedProducts.filter((product) => { const productUpdatedAt = new Date(product.updated_at || ""); + return productUpdatedAt >= filterDate; }); } @@ -392,6 +406,7 @@ export const useSellerProducts = ( const filterDate = new Date(dateFilter.$lte); processedProducts = processedProducts.filter((product) => { const productUpdatedAt = new Date(product.updated_at || ""); + return productUpdatedAt <= filterDate; }); } @@ -474,6 +489,7 @@ export const useSellerCustomerGroups = ( const filterDate = new Date(dateFilter.$gte); processedCustomerGroups = processedCustomerGroups.filter((group) => { const groupCreatedAt = new Date(group.created_at || ""); + return groupCreatedAt >= filterDate; }); } @@ -481,6 +497,7 @@ export const useSellerCustomerGroups = ( const filterDate = new Date(dateFilter.$lte); processedCustomerGroups = processedCustomerGroups.filter((group) => { const groupCreatedAt = new Date(group.created_at || ""); + return groupCreatedAt <= filterDate; }); } @@ -493,6 +510,7 @@ export const useSellerCustomerGroups = ( const filterDate = new Date(dateFilter.$gte); processedCustomerGroups = processedCustomerGroups.filter((group) => { const groupUpdatedAt = new Date(group.updated_at || ""); + return groupUpdatedAt >= filterDate; }); } @@ -500,6 +518,7 @@ export const useSellerCustomerGroups = ( const filterDate = new Date(dateFilter.$lte); processedCustomerGroups = processedCustomerGroups.filter((group) => { const groupUpdatedAt = new Date(group.updated_at || ""); + return groupUpdatedAt <= filterDate; }); } diff --git a/src/hooks/table/columns/use-product-table-columns.tsx b/src/hooks/table/columns/use-product-table-columns.tsx index d0c69f7a..066d0e64 100644 --- a/src/hooks/table/columns/use-product-table-columns.tsx +++ b/src/hooks/table/columns/use-product-table-columns.tsx @@ -21,9 +21,9 @@ import { VariantCell, VariantHeader, } from "../../../components/table/table-cells/product/variant-cell" -import { HttpTypes } from "@medusajs/types" +import type { ExtendedAdminProduct } from "@custom-types/product" -const columnHelper = createColumnHelper() +const columnHelper = createColumnHelper() export const useProductTableColumns = () => { return useMemo( diff --git a/src/hooks/table/columns/use-refund-reason-table-columns.tsx b/src/hooks/table/columns/use-refund-reason-table-columns.tsx index 9595d474..805420a2 100644 --- a/src/hooks/table/columns/use-refund-reason-table-columns.tsx +++ b/src/hooks/table/columns/use-refund-reason-table-columns.tsx @@ -5,7 +5,7 @@ import { createDataTableColumnHelper } from "@medusajs/ui"; import { useTranslation } from "react-i18next"; import { DescriptionCell } from "../../../components/table/table-cells/sales-channel/description-cell"; -import { AdminRefundReason } from "../../../types/refund-reasons/common"; +import type { AdminRefundReason } from "@custom-types/refund-reasons"; const columnHelper = createDataTableColumnHelper(); diff --git a/src/hooks/table/query/use-product-table-query.tsx b/src/hooks/table/query/use-product-table-query.tsx index c213e89e..29a276ff 100644 --- a/src/hooks/table/query/use-product-table-query.tsx +++ b/src/hooks/table/query/use-product-table-query.tsx @@ -7,10 +7,6 @@ type UseProductTableQueryProps = { pageSize?: number } -type ExtendedAdminProductListParams = HttpTypes.AdminProductListParams & { - tag_id?: string[] -} - const DEFAULT_FIELDS = "id,title,handle,status,*collection,*sales_channels,variants.id,thumbnail" diff --git a/src/hooks/table/query/use-refund-reason-table-query.tsx b/src/hooks/table/query/use-refund-reason-table-query.tsx index 578a88b8..0ca35848 100644 --- a/src/hooks/table/query/use-refund-reason-table-query.tsx +++ b/src/hooks/table/query/use-refund-reason-table-query.tsx @@ -1,5 +1,5 @@ -import { HttpTypes } from "@medusajs/types" import { useQueryParams } from "../../use-query-params" +import type { AdminRefundReasonListParams } from "@custom-types/refund-reasons" type UseRefundReasonTableQueryProps = { prefix?: string @@ -16,7 +16,7 @@ export const useRefundReasonTableQuery = ({ ) const { offset, q, order, created_at, updated_at } = queryObject - const searchParams: HttpTypes.AdminRefundReasonListParams = { + const searchParams: AdminRefundReasonListParams = { limit: pageSize, offset: offset ? Number(offset) : 0, order, diff --git a/src/i18n/translations/$schema.json b/src/i18n/translations/$schema.json index 25f4daa2..1ab49b48 100644 --- a/src/i18n/translations/$schema.json +++ b/src/i18n/translations/$schema.json @@ -4216,6 +4216,9 @@ }, "selectPaymentToRefund": { "type": "string" + }, + "refundAmountWarning": { + "type": "string" } }, "required": [ @@ -4239,7 +4242,8 @@ "createRefundWrongQuantity", "refundAmount", "paymentLink", - "selectPaymentToRefund" + "selectPaymentToRefund", + "refundAmountWarning" ], "additionalProperties": false }, @@ -5025,6 +5029,9 @@ }, "toastCreated": { "type": "string" + }, + "toastFulfillmentNotFound": { + "type": "string" } }, "required": [ @@ -5033,7 +5040,8 @@ "addTracking", "sendNotification", "sendNotificationHint", - "toastCreated" + "toastCreated", + "toastFulfillmentNotFound" ], "additionalProperties": false }, @@ -5554,9 +5562,24 @@ }, "confirmed": { "type": "string" + }, + "declined": { + "type": "string" + }, + "canceled": { + "type": "string" + }, + "pending": { + "type": "string" } }, - "required": ["requested", "confirmed"], + "required": [ + "requested", + "confirmed", + "declined", + "canceled", + "pending" + ], "additionalProperties": false }, "transfer": { @@ -11889,9 +11912,22 @@ "properties": { "domain": { "type": "string" + }, + "create": { + "type": "object", + "properties": { + "fillNameWarning": { + "type": "string" + }, + "possibleValuesRequired": { + "type": "string" + } + }, + "required": ["fillNameWarning", "possibleValuesRequired"], + "additionalProperties": false } }, - "required": ["domain"], + "required": ["domain", "create"], "additionalProperties": false }, "requests": { diff --git a/src/i18n/translations/en.json b/src/i18n/translations/en.json index 805e4044..f88b721d 100644 --- a/src/i18n/translations/en.json +++ b/src/i18n/translations/en.json @@ -1125,7 +1125,8 @@ "createRefundWrongQuantity": "Quantity should be a number between 1 and {{number}}", "refundAmount": "Refund {{ amount }}", "paymentLink": "Copy payment link for {{ amount }}", - "selectPaymentToRefund": "Select payment to refund" + "selectPaymentToRefund": "Select payment to refund", + "refundAmountWarning": "Refund amount must be greater than 0" }, "edits": { "title": "Edit order", @@ -1335,7 +1336,8 @@ "addTracking": "Add tracking number", "sendNotification": "Send notification", "sendNotificationHint": "Notify the customer about this shipment.", - "toastCreated": "Shipment created successfully." + "toastCreated": "Shipment created successfully.", + "toastFulfillmentNotFound": "Fulfillment not found." }, "fulfillment": { "cancelWarning": "You are about to cancel a fulfillment. This action cannot be undone.", @@ -1472,7 +1474,10 @@ }, "edit": { "requested": "Order edit #{{editId}} requested", - "confirmed": "Order edit #{{editId}} confirmed" + "confirmed": "Order edit #{{editId}} confirmed", + "declined": "Order edit #{{editId}} declined", + "canceled": "Order edit #{{editId}} canceled", + "pending": "Order edit #{{editId}} pending" }, "transfer": { "requested": "Order transfer #{{transferId}} requested", diff --git a/src/lib/order-helpers.ts b/src/lib/order-helpers.ts index 5fee3f17..ddacfb62 100644 --- a/src/lib/order-helpers.ts +++ b/src/lib/order-helpers.ts @@ -1,4 +1,4 @@ -import { TFunction } from "i18next" +import type { TFunction } from "i18next" export const getCanceledOrderStatus = ( t: TFunction<"translation">, diff --git a/src/lib/order-item.ts b/src/lib/order-item.ts index 2d09973e..47df7fee 100644 --- a/src/lib/order-item.ts +++ b/src/lib/order-item.ts @@ -1,5 +1,5 @@ -import { OrderLineItemDTO } from "@medusajs/types" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" -export const getFulfillableQuantity = (item: OrderLineItemDTO) => { +export const getFulfillableQuantity = (item: ExtendedAdminOrderLineItem) => { return item.quantity - item.detail.fulfilled_quantity } diff --git a/src/routes/categories/category-detail/components/category-product-section/category-product-section.tsx b/src/routes/categories/category-detail/components/category-product-section/category-product-section.tsx index db990a77..e8d933b5 100644 --- a/src/routes/categories/category-detail/components/category-product-section/category-product-section.tsx +++ b/src/routes/categories/category-detail/components/category-product-section/category-product-section.tsx @@ -21,6 +21,7 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters" import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query" import { useDataTable } from "../../../../../hooks/use-data-table" +import { ExtendedAdminProduct } from "@custom-types/product" type CategoryProductSectionProps = { category: HttpTypes.AdminProductCategory @@ -162,7 +163,7 @@ export const CategoryProductSection = ({ ) } -const columnHelper = createColumnHelper() +const columnHelper = createColumnHelper() const useColumns = () => { const base = useProductTableColumns() diff --git a/src/routes/categories/category-products/components/edit-category-products-form/edit-category-products-form.tsx b/src/routes/categories/category-products/components/edit-category-products-form/edit-category-products-form.tsx index 163358a9..91a49d85 100644 --- a/src/routes/categories/category-products/components/edit-category-products-form/edit-category-products-form.tsx +++ b/src/routes/categories/category-products/components/edit-category-products-form/edit-category-products-form.tsx @@ -2,7 +2,6 @@ import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { z } from "zod" -import { HttpTypes } from "@medusajs/types" import { Button, Checkbox, Hint, Tooltip, toast } from "@medusajs/ui" import { OnChangeFn, @@ -23,10 +22,11 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters" import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query" import { useDataTable } from "../../../../../hooks/use-data-table" +import { ExtendedAdminProduct } from "@custom-types/product" type EditCategoryProductsFormProps = { categoryId: string - products?: Pick[] + products?: Pick[] } const EditCategoryProductsSchema = z.object({ @@ -46,6 +46,7 @@ export const EditCategoryProductsForm = ({ const [selection, setSelection] = useState( products.reduce((acc, p) => { acc[p.id!] = true + return acc }, {} as RowSelectionState) ) @@ -185,7 +186,7 @@ export const EditCategoryProductsForm = ({ ) } -const columnHelper = createColumnHelper() +const columnHelper = createColumnHelper() const useColumns = () => { const { t } = useTranslation() diff --git a/src/routes/collections/collection-add-products/components/add-products-to-collection-form/add-products-to-collection-form.tsx b/src/routes/collections/collection-add-products/components/add-products-to-collection-form/add-products-to-collection-form.tsx index 50c21c54..f25ce725 100644 --- a/src/routes/collections/collection-add-products/components/add-products-to-collection-form/add-products-to-collection-form.tsx +++ b/src/routes/collections/collection-add-products/components/add-products-to-collection-form/add-products-to-collection-form.tsx @@ -1,5 +1,5 @@ import { zodResolver } from "@hookform/resolvers/zod" -import { HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { Button, Checkbox, Hint, Tooltip, toast } from "@medusajs/ui" import { keepPreviousData } from "@tanstack/react-query" import { @@ -23,6 +23,7 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters.tsx" import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query.tsx" import { useDataTable } from "../../../../../hooks/use-data-table.tsx" +import { ExtendedAdminProduct } from "@custom-types/index.ts" type AddProductsToCollectionFormProps = { collection: HttpTypes.AdminCollection @@ -194,7 +195,7 @@ export const AddProductsToCollectionForm = ({ ) } -const columnHelper = createColumnHelper() +const columnHelper = createColumnHelper() const useColumns = () => { const { t } = useTranslation() diff --git a/src/routes/collections/collection-detail/components/collection-product-section/collection-product-section.tsx b/src/routes/collections/collection-detail/components/collection-product-section/collection-product-section.tsx index 0cc72319..353f6566 100644 --- a/src/routes/collections/collection-detail/components/collection-product-section/collection-product-section.tsx +++ b/src/routes/collections/collection-detail/components/collection-product-section/collection-product-section.tsx @@ -13,6 +13,7 @@ import { useProductTableColumns } from "../../../../../hooks/table/columns/use-p import { useProductTableFilters } from "../../../../../hooks/table/filters/use-product-table-filters" import { useProductTableQuery } from "../../../../../hooks/table/query/use-product-table-query" import { useDataTable } from "../../../../../hooks/use-data-table" +import { ExtendedAdminProduct } from "@custom-types/product" type CollectionProductSectionProps = { collection: HttpTypes.AdminCollection @@ -215,7 +216,7 @@ const ProductActions = ({ ) } -const columnHelper = createColumnHelper() +const columnHelper = createColumnHelper() const useColumns = () => { const columns = useProductTableColumns() diff --git a/src/routes/inventory/inventory-detail/breadcrumb.tsx b/src/routes/inventory/inventory-detail/breadcrumb.tsx index 9e9f7a30..7788cf3a 100644 --- a/src/routes/inventory/inventory-detail/breadcrumb.tsx +++ b/src/routes/inventory/inventory-detail/breadcrumb.tsx @@ -1,11 +1,11 @@ -import { HttpTypes } from "@medusajs/types" import { UIMatch } from "react-router-dom" import { useInventoryItem } from "../../../hooks/api" import { INVENTORY_DETAIL_FIELDS } from "./constants" +import type { ExtendedAdminInventoryItemResponse } from "@custom-types/inventory" type InventoryDetailBreadcrumbProps = - UIMatch + UIMatch export const InventoryDetailBreadcrumb = ( props: InventoryDetailBreadcrumbProps diff --git a/src/routes/inventory/inventory-detail/components/location-levels-table/location-list-table.tsx b/src/routes/inventory/inventory-detail/components/location-levels-table/location-list-table.tsx index 30b2e509..33c0b81a 100644 --- a/src/routes/inventory/inventory-detail/components/location-levels-table/location-list-table.tsx +++ b/src/routes/inventory/inventory-detail/components/location-levels-table/location-list-table.tsx @@ -1,13 +1,12 @@ +import { useInventoryItemLevels } from "@hooks/api" +import { useLocationListTableColumns } from "./use-location-list-table-columns" +import { useLocationLevelTableQuery } from "./use-location-list-table-query" import type { ExtendedInventoryItemLevel } from "@custom-types/inventory"; import { _DataTable } from "@components/table/data-table"; -import { useInventoryItemLevels } from "@hooks/api"; import { useDataTable } from "@hooks/use-data-table"; -import { useLocationListTableColumns } from "./use-location-list-table-columns"; -import { useLocationLevelTableQuery } from "./use-location-list-table-query"; - const PAGE_SIZE = 20; const PREFIX = "invlvl"; diff --git a/src/routes/inventory/inventory-detail/components/location-levels-table/use-location-list-table-columns.tsx b/src/routes/inventory/inventory-detail/components/location-levels-table/use-location-list-table-columns.tsx index 6323decc..4f5ac8ad 100644 --- a/src/routes/inventory/inventory-detail/components/location-levels-table/use-location-list-table-columns.tsx +++ b/src/routes/inventory/inventory-detail/components/location-levels-table/use-location-list-table-columns.tsx @@ -68,6 +68,7 @@ export const useLocationListTableColumns = () => { return useMemo( () => [ columnHelper.display({ + id: "location", header: t("fields.location"), cell: ({ row }) => { @@ -139,6 +140,7 @@ export const useLocationListTableColumns = () => { columnHelper.action({ actions: (ctx) => { const level = ctx.row.original; + return [ [ { diff --git a/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-form.tsx b/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-form.tsx index 19bcf093..6a0d9116 100644 --- a/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-form.tsx +++ b/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-form.tsx @@ -3,7 +3,6 @@ import { useEffect, useMemo, useState } from "react" import { useTranslation } from "react-i18next" import * as zod from "zod" -import { AdminOrder, InventoryItemDTO, OrderLineItemDTO } from "@medusajs/types" import { Alert, Button, Heading, Input, Select, toast } from "@medusajs/ui" import { useForm, useWatch } from "react-hook-form" @@ -19,11 +18,22 @@ import { useStockLocations } from "../../../../../hooks/api/stock-locations" import { queryClient } from "../../../../../lib/query-client" import { AllocateItemsSchema } from "./constants" import { OrderAllocateItemsItem } from "./order-allocate-items-item" -import { checkInventoryKit } from "./utils" +import { + checkInventoryKit, + getFirstInventoryId, + getInventory, + getInventoryItems, + getQuantityKey, + getRequiredQuantity, +} from "./utils" import { useDocumentDirection } from "../../../../../hooks/use-document-direction" +import { getErrorMessage } from "@utils/error-helper" +import type { ExtendedAdminOrder, ExtendedAdminOrderLineItem } from "@custom-types/order" +import type { ExtendedAdminProductVariantInventoryItem } from "@custom-types/product" + type OrderAllocateItemsFormProps = { - order: AdminOrder + order: ExtendedAdminOrder } export function OrderAllocateItemsForm({ order }: OrderAllocateItemsFormProps) { @@ -41,7 +51,7 @@ export function OrderAllocateItemsForm({ order }: OrderAllocateItemsFormProps) { order.items.filter( (item) => item.variant?.manage_inventory && - item.variant?.inventory.length && + item.variant?.inventory?.length && item.quantity - item.detail.fulfilled_quantity > 0 ), [order.items] @@ -116,71 +126,72 @@ export function OrderAllocateItemsForm({ order }: OrderAllocateItemsFormProps) { description: t("orders.allocateItems.toast.error", { items: failedItems, }), - dismissLabel: t("actions.close"), }) } } catch (e) { toast.error(t("general.error"), { - description: e.message, - dismissLabel: t("actions.close"), + description: getErrorMessage(e), }) } }) const onQuantityChange = ( - inventoryItem: InventoryItemDTO, - lineItem: OrderLineItemDTO, + inventoryItem: ExtendedAdminProductVariantInventoryItem | undefined, + lineItem: ExtendedAdminOrderLineItem, hasInventoryKit: boolean, value: number | null, isRoot?: boolean - ) => { + ): void => { let shouldDisableSubmit = false - const key = - isRoot && hasInventoryKit - ? `quantity.${lineItem.id}-` - : `quantity.${lineItem.id}-${inventoryItem.id}` + const inventoryId = inventoryItem?.id + const key = getQuantityKey(lineItem.id, inventoryId, !!(isRoot && hasInventoryKit)) + const formKey = `quantity.${key}` as `quantity.${string}` - form.setValue(key, value) + form.setValue(formKey, value ?? "") - if (value) { - const location = inventoryItem.location_levels.find( - (l) => l.location_id === selectedLocationId + if (value && inventoryItem && selectedLocationId) { + const location = inventoryItem.location_levels?.find( + (l: { location_id: string }) => l.location_id === selectedLocationId ) - if (location) { - if (location.available_quantity < value) { - shouldDisableSubmit = true - } + if (location && location.available_quantity < value) { + shouldDisableSubmit = true } } if (hasInventoryKit && !isRoot) { - // changed subitem in the kit -> we need to set parent to "-" - form.resetField(`quantity.${lineItem.id}-`, { defaultValue: "" }) + const parentKey = `quantity.${lineItem.id}-` as `quantity.${string}` + form.resetField(parentKey, { defaultValue: "" }) } if (hasInventoryKit && isRoot) { - // changed root -> we need to set items to parent quantity x required_quantity - const item = itemsToAllocate.find((i) => i.id === lineItem.id) - item.variant?.inventory_items.forEach((ii, ind) => { - const num = value || 0 - const inventory = item.variant?.inventory[ind] + if (!item?.variant) { + return + } + + const inventoryItems = getInventoryItems(item.variant) + const inventory = getInventory(item.variant) + const num = value || 0 + + inventoryItems.forEach((_ii, ind) => { + const inv = inventory[ind] + if (!inv) { + return + } + + const requiredQty = getRequiredQuantity(item.variant, ind) + const childKey = `quantity.${lineItem.id}-${inv.id}` as `quantity.${string}` - form.setValue( - `quantity.${lineItem.id}-${inventory.id}`, - num * ii.required_quantity - ) + form.setValue(childKey, num * requiredQty) - if (value) { - const location = inventory?.location_levels.find( - (l) => l.location_id === selectedLocationId + if (value && selectedLocationId) { + const location = inv.location_levels?.find( + (l: { location_id: string }) => l.location_id === selectedLocationId ) - if (location) { - if (location.available_quantity < value) { - shouldDisableSubmit = true - } + if (location && location.available_quantity < value) { + shouldDisableSubmit = true } } }) @@ -326,20 +337,25 @@ export function OrderAllocateItemsForm({ order }: OrderAllocateItemsFormProps) { ) } -function defaultAllocations(items: OrderLineItemDTO) { - const ret = {} +function defaultAllocations( + items: ExtendedAdminOrderLineItem[] +): Record { + const ret: Record = {} items.forEach((item) => { const hasInventoryKit = checkInventoryKit(item) + const firstInventoryId = getFirstInventoryId(item) + + if (!firstInventoryId && !hasInventoryKit) { + return + } - ret[ - hasInventoryKit - ? `${item.id}-` - : `${item.id}-${item.variant?.inventory[0].id}` - ] = "" + const key = getQuantityKey(item.id, firstInventoryId, hasInventoryKit) + ret[key] = "" if (hasInventoryKit) { - item.variant?.inventory.forEach((i) => { + const inventory = getInventory(item.variant) + inventory.forEach((i) => { ret[`${item.id}-${i.id}`] = "" }) } diff --git a/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-item.tsx b/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-item.tsx index d4d4791d..13a7d1be 100644 --- a/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-item.tsx +++ b/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/order-allocate-items-item.tsx @@ -1,32 +1,41 @@ import { useMemo, useState } from "react" import { useTranslation } from "react-i18next" -import { InventoryItemDTO, OrderLineItemDTO } from "@medusajs/types" import { Component, ExclamationCircleSolid, TriangleDownMini, } from "@medusajs/icons" -import { UseFormReturn, useWatch } from "react-hook-form" +import { type UseFormReturn, useWatch } from "react-hook-form" import { Input, Text, clx } from "@medusajs/ui" -import * as zod from "zod" +import type * as zod from "zod" -import { Thumbnail } from "../../../../../components/common/thumbnail" -import { getFulfillableQuantity } from "../../../../../lib/order-item" -import { Form } from "../../../../../components/common/form" -import { AllocateItemsSchema } from "./constants" -import { checkInventoryKit } from "./utils" +import { Thumbnail } from "@components/common/thumbnail" +import { getFulfillableQuantity } from "@lib/order-item" +import { Form } from "@components/common/form" +import type { AllocateItemsSchema } from "./constants" +import { + checkInventoryKit, + getFirstInventoryId, + getFirstInventoryItem, + getInventory, + getQuantityKey, + getQuantityValue, + getRequiredQuantity, +} from "./utils" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" +import type { ExtendedAdminProductVariantInventoryItem } from "@custom-types/product" type OrderEditItemProps = { - item: OrderLineItemDTO + item: ExtendedAdminOrderLineItem locationId?: string form: UseFormReturn> onQuantityChange: ( - inventoryItem: InventoryItemDTO, - lineItem: OrderLineItemDTO, + inventoryItem: ExtendedAdminProductVariantInventoryItem | undefined, + lineItem: ExtendedAdminOrderLineItem, hasInventoryKit: boolean, value: number | null, isRoot?: boolean - ) => {} + ) => void } export function OrderAllocateItemsItem({ @@ -38,7 +47,9 @@ export function OrderAllocateItemsItem({ const { t } = useTranslation() const variant = item.variant - const inventory = item.variant?.inventory || [] + const inventory = getInventory(variant) + const firstInventoryItem = getFirstInventoryItem(item) + const firstInventoryId = getFirstInventoryId(item) const [isOpen, setIsOpen] = useState(false) @@ -68,12 +79,13 @@ export function OrderAllocateItemsItem({ } }, [variant, locationId]) + const quantityKey = getQuantityKey(item.id, firstInventoryId, hasInventoryKit) + const quantityValue = getQuantityValue(quantityField, quantityKey) const hasQuantityError = !hasInventoryKit && - availableQuantity && - quantityField[`${item.id}-${item.variant?.inventory[0].id}`] && - quantityField[`${item.id}-${item.variant?.inventory[0].id}`] > - availableQuantity + availableQuantity !== undefined && + quantityValue !== null && + quantityValue > availableQuantity const minValue = 0 const maxValue = Math.min( @@ -128,19 +140,12 @@ export function OrderAllocateItemsItem({ {t("labels.available")} - {availableQuantity || "-"} - {availableQuantity && + {availableQuantity ?? "-"} + {availableQuantity !== undefined && !hasInventoryKit && - quantityField[ - `${item.id}-${item.variant?.inventory[0].id}` - ] && ( + quantityValue !== null && ( - - - { - quantityField[ - `${item.id}-${item.variant?.inventory[0].id}` - ] - } + -{quantityValue} )} @@ -168,14 +173,10 @@ export function OrderAllocateItemsItem({
{ @@ -194,7 +195,7 @@ export function OrderAllocateItemsItem({ : Number(e.target.value) onQuantityChange( - item.variant?.inventory[0], + firstInventoryItem ?? undefined, item, hasInventoryKit, val, @@ -233,14 +234,17 @@ export function OrderAllocateItemsItem({ )} {isOpen && - variant.inventory.map((i, ind) => { - const location = i.location_levels.find( + inventory.map((i, ind) => { + const location = i?.location_levels?.find( (l) => l.location_id === locationId ) + const itemQuantityKey = `${item.id}-${i.id}` + const itemQuantityValue = getQuantityValue(quantityField, itemQuantityKey) const hasQuantityError = - !!quantityField[`${item.id}-${i.id}`] && - quantityField[`${item.id}-${i.id}`] > location.available_quantity + itemQuantityValue !== null && + location !== undefined && + itemQuantityValue > location.available_quantity return (
@@ -250,11 +254,11 @@ export function OrderAllocateItemsItem({ )}
{i.title} - - {t("orders.allocateItems.requires", { - num: variant.inventory_items[ind].required_quantity, - })} - + + {t("orders.allocateItems.requires", { + num: getRequiredQuantity(variant, ind), + })} +
@@ -267,11 +271,11 @@ export function OrderAllocateItemsItem({ {t("labels.available")} - {location?.available_quantity || "-"} - {location?.available_quantity && - quantityField[`${item.id}-${i.id}`] && ( + {location?.available_quantity ?? "-"} + {location?.available_quantity !== undefined && + itemQuantityValue !== null && ( - -{quantityField[`${item.id}-${i.id}`]} + -{itemQuantityValue} )} @@ -332,8 +336,7 @@ export function OrderAllocateItemsItem({ }} /> /{" "} - {item.quantity * - variant.inventory_items[ind].required_quantity}{" "} + {item.quantity * getRequiredQuantity(variant, ind)}{" "} {t("fields.qty")}
diff --git a/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/utils.ts b/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/utils.ts index 8423e151..c0d1f6f6 100644 --- a/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/utils.ts +++ b/src/routes/orders/order-allocate-items/components/order-create-fulfillment-form/utils.ts @@ -1,18 +1,8 @@ -import { - AdminProductVariant, - AdminProductVariantInventoryItemLink, - OrderLineItemDTO, -} from "@medusajs/types" - -/** - * Check if the line item has inventory kit. - */ +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" +import type { ExtendedAdminProductVariantInventoryItemLink } from "@custom-types/product" + export function checkInventoryKit( - item: OrderLineItemDTO & { - variant?: AdminProductVariant & { - inventory_items: AdminProductVariantInventoryItemLink[] - } - } + item: ExtendedAdminOrderLineItem ) { const variant = item.variant @@ -21,8 +11,66 @@ export function checkInventoryKit( } return ( - (!!variant.inventory_items.length && variant.inventory_items.length > 1) || - (variant.inventory_items.length === 1 && + (!!variant.inventory_items?.length && variant.inventory_items?.length > 1) || + (variant.inventory_items?.length === 1 && variant.inventory_items[0].required_quantity! > 1) ) } + +export function getFirstInventoryId( + item: ExtendedAdminOrderLineItem +): string | undefined { + return item.variant?.inventory?.[0]?.id +} + +export function getFirstInventoryItem( + item: ExtendedAdminOrderLineItem +) { + return item.variant?.inventory?.[0] +} + +export function getRequiredQuantity( + variant: ExtendedAdminOrderLineItem["variant"], + index: number +): number { + return variant?.inventory_items?.[index]?.required_quantity ?? 0 +} + +export function getInventoryItems( + variant: ExtendedAdminOrderLineItem["variant"] +): ExtendedAdminProductVariantInventoryItemLink[] { + return variant?.inventory_items ?? [] +} + +export function getInventory( + variant: ExtendedAdminOrderLineItem["variant"] +) { + return variant?.inventory ?? [] +} + +export function getQuantityKey( + itemId: string, + inventoryId: string | undefined, + hasInventoryKit: boolean +): string { + if (hasInventoryKit) { + return `${itemId}-` + } + if (!inventoryId) { + return `${itemId}-` + } + + return `${itemId}-${inventoryId}` +} + +export function getQuantityValue( + quantityField: Record, + key: string +): number | null { + const value = quantityField[key] + if (value === undefined || value === null || value === "") { + return null + } + + return typeof value === "string" ? Number(value) : value +} diff --git a/src/routes/orders/order-create-claim/claim-create.tsx b/src/routes/orders/order-create-claim/claim-create.tsx index 16a66942..eaf7c1cc 100644 --- a/src/routes/orders/order-create-claim/claim-create.tsx +++ b/src/routes/orders/order-create-claim/claim-create.tsx @@ -9,6 +9,7 @@ import { useOrder, useOrderPreview } from "../../../hooks/api/orders" import { useReturn } from "../../../hooks/api/returns" import { DEFAULT_FIELDS } from "../order-detail/constants" import { ClaimCreateForm } from "./components/claim-create-form" +import { getErrorMessage } from "@utils/error-helper" let IS_REQUEST_RUNNING = false @@ -22,13 +23,13 @@ export const ClaimCreate = () => { }) const { order: preview } = useOrderPreview(id!) - const [activeClaimId, setActiveClaimId] = useState() - const { mutateAsync: createClaim } = useCreateClaim(order.id) + const [activeClaimId, setActiveClaimId] = useState() + const { mutateAsync: createClaim } = useCreateClaim(order?.id ?? "") - const { claim } = useClaim(activeClaimId!, undefined, { + const { claim } = useClaim(activeClaimId ?? "", undefined, { enabled: !!activeClaimId, }) - const { return: orderReturn } = useReturn(claim?.return_id!, undefined, { + const { return: orderReturn } = useReturn(claim?.return_id ?? "", undefined, { enabled: !!claim?.return_id, }) @@ -59,7 +60,7 @@ export const ClaimCreate = () => { setActiveClaimId(createdClaim.id) } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) navigate(`/orders/${preview.id}`, { replace: true }) } finally { IS_REQUEST_RUNNING = false diff --git a/src/routes/orders/order-create-claim/components/add-claim-items-table/add-claim-items-table.tsx b/src/routes/orders/order-create-claim/components/add-claim-items-table/add-claim-items-table.tsx index b9c2bf26..85ae0b60 100644 --- a/src/routes/orders/order-create-claim/components/add-claim-items-table/add-claim-items-table.tsx +++ b/src/routes/orders/order-create-claim/components/add-claim-items-table/add-claim-items-table.tsx @@ -1,19 +1,19 @@ -import { +import type { AdminOrderLineItem, DateComparisonOperator, NumericalComparisonOperator, } from "@medusajs/types" -import { OnChangeFn, RowSelectionState } from "@tanstack/react-table" +import type { OnChangeFn, RowSelectionState } from "@tanstack/react-table" import { useMemo, useState } from "react" import { useTranslation } from "react-i18next" -import { _DataTable } from "../../../../../components/table/data-table" -import { useDataTable } from "../../../../../hooks/use-data-table" -import { getStylizedAmount } from "../../../../../lib/money-amount-helpers" -import { getReturnableQuantity } from "../../../../../lib/rma" +import { _DataTable } from "@components/table/data-table" +import { useDataTable } from "@hooks/use-data-table" +import { getReturnableQuantity } from "@lib/rma" import { useClaimItemTableColumns } from "./use-claim-item-table-columns" import { useClaimItemTableFilters } from "./use-claim-item-table-filters" import { useClaimItemTableQuery } from "./use-claim-item-table-query" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" const PAGE_SIZE = 50 const PREFIX = "rit" @@ -21,7 +21,7 @@ const PREFIX = "rit" type AddReturnItemsTableProps = { onSelectionChange: (ids: string[]) => void selectedItems: string[] - items: AdminOrderLineItem[] + items: ExtendedAdminOrderLineItem[] currencyCode: string } @@ -36,6 +36,7 @@ export const AddClaimItemsTable = ({ const [rowSelection, setRowSelection] = useState( selectedItems.reduce((acc, id) => { acc[id] = true + return acc }, {} as RowSelectionState) ) @@ -65,7 +66,7 @@ export const AddClaimItemsTable = ({ returnable_quantity, } = searchParams - let results: AdminOrderLineItem[] = items + let results = items if (q) { results = results.filter((i) => { @@ -96,8 +97,7 @@ export const AddClaimItemsTable = ({ results = filterByNumber( results, returnable_quantity, - "returnable_quantity", - currencyCode + "returnable_quantity" ) } @@ -105,8 +105,7 @@ export const AddClaimItemsTable = ({ results = filterByNumber( results, refundable_amount, - "refundable_amount", - currencyCode + "refundable_amount" ) } @@ -164,7 +163,7 @@ export const AddClaimItemsTable = ({ } const sortItems = ( - items: AdminOrderLineItem[], + items: ExtendedAdminOrderLineItem[], field: string, direction: "asc" | "desc" ) => { @@ -195,12 +194,13 @@ const sortItems = ( if (aValue > bValue) { return direction === "asc" ? 1 : -1 } + return 0 }) } const filterByDate = ( - items: AdminOrderLineItem[], + items: ExtendedAdminOrderLineItem[], date: DateComparisonOperator, field: "created_at" | "updated_at" ) => { @@ -239,10 +239,9 @@ const defaultOperators = { } const filterByNumber = ( - items: AdminOrderLineItem[], + items: ExtendedAdminOrderLineItem[], value: NumericalComparisonOperator | number, - field: "returnable_quantity" | "refundable_amount", - currency_code: string + field: "returnable_quantity" | "refundable_amount" ) => { const { eq, gt, lt, gte, lte } = typeof value === "object" @@ -251,7 +250,7 @@ const filterByNumber = ( return items.filter((i) => { const returnableQuantity = i.quantity - (i.returned_quantity || 0) - const refundableAmount = getStylizedAmount(i.refundable || 0, currency_code) + const refundableAmount = i.refundable || 0 const itemValue = field === "returnable_quantity" ? returnableQuantity : refundableAmount diff --git a/src/routes/orders/order-create-claim/components/claim-create-form/claim-create-form.tsx b/src/routes/orders/order-create-claim/components/claim-create-form/claim-create-form.tsx index 6f603c75..e76f071c 100644 --- a/src/routes/orders/order-create-claim/components/claim-create-form/claim-create-form.tsx +++ b/src/routes/orders/order-create-claim/components/claim-create-form/claim-create-form.tsx @@ -1,11 +1,11 @@ import { zodResolver } from "@hookform/resolvers/zod" import { PencilSquare } from "@medusajs/icons" -import { +import type { AdminClaim, - AdminOrder, AdminOrderPreview, InventoryLevelDTO, } from "@medusajs/types" +import type { ExtendedAdminProductVariantListResponse } from "@custom-types/product" import { Alert, Button, @@ -56,9 +56,10 @@ import { currencies } from "../../../../../lib/data/currencies" import { ReturnShippingPlaceholder } from "../../../common/placeholders" import { ClaimOutboundSection } from "./claim-outbound-section" import { ItemPlaceholder } from "./item-placeholder" +import { ExtendedAdminOrder } from "@custom-types/order/common.ts" type ReturnCreateFormProps = { - order: AdminOrder + order: ExtendedAdminOrder claim: AdminClaim preview: AdminOrderPreview orderReturn?: AdminReturn @@ -206,13 +207,14 @@ export const ClaimCreateForm = ({ const inboundAction = i.actions?.find( (a) => a.action === "RETURN_ITEM" ) + const reasonId = inboundAction?.details?.reason_id return { item_id: i.id, variant_id: i.variant_id, quantity: i.detail.return_requested_quantity, note: inboundAction?.internal_note, - reason_id: inboundAction?.details?.reason_id as string | undefined, + reason_id: typeof reasonId === "string" ? reasonId : undefined, } }), outbound_items: outboundPreviewItems.map((i) => ({ @@ -317,12 +319,13 @@ export const ClaimCreateForm = ({ const returnItemAction = i.actions?.find( (a) => a.action === "RETURN_ITEM" ) + const reasonId = returnItemAction?.details?.reason_id update(ind, { ...inboundItems[ind], quantity: i.detail.return_requested_quantity, note: returnItemAction?.internal_note, - reason_id: returnItemAction?.details?.reason_id as string, + reason_id: typeof reasonId === "string" ? reasonId : undefined, }) } } else { @@ -405,7 +408,7 @@ export const ClaimCreateForm = ({ }) const onItemsSelected = async () => { - itemsToAdd.length && + if (itemsToAdd.length) { (await addInboundItem( { items: itemsToAdd.map((id) => ({ @@ -419,6 +422,7 @@ export const ClaimCreateForm = ({ }, } )) + } for (const itemToRemove of itemsToRemove) { const actionId = previewItems @@ -525,14 +529,12 @@ export const ClaimCreateForm = ({ const variantIds = inboundItems .map((item) => item?.variant_id) - .filter(Boolean) + .filter((id): id is string => Boolean(id)) - const variants = ( - await sdk.admin.productVariant.list({ - id: variantIds, - fields: "*inventory.location_levels", - }) - ).variants + const { variants } = (await sdk.admin.productVariant.list({ + id: variantIds, + fields: "*inventory.location_levels", + })) as ExtendedAdminProductVariantListResponse variants.forEach((variant) => { // TODO: fix this for inventory kits @@ -606,7 +608,7 @@ export const ClaimCreateForm = ({ i.item_id)} currencyCode={order.currency_code} onSelectionChange={(finalSelection) => { diff --git a/src/routes/orders/order-create-claim/components/claim-create-form/claim-inbound-item.tsx b/src/routes/orders/order-create-claim/components/claim-create-form/claim-inbound-item.tsx index 75f31f20..d2700f14 100644 --- a/src/routes/orders/order-create-claim/components/claim-create-form/claim-inbound-item.tsx +++ b/src/routes/orders/order-create-claim/components/claim-create-form/claim-inbound-item.tsx @@ -1,7 +1,7 @@ import { ChatBubble, DocumentText, XCircle, XMark } from "@medusajs/icons" -import { AdminOrderLineItem, HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { IconButton, Input, Text } from "@medusajs/ui" -import { UseFormReturn } from "react-hook-form" +import type { UseFormReturn } from "react-hook-form" import { useTranslation } from "react-i18next" import { ActionMenu } from "../../../../../components/common/action-menu" @@ -10,10 +10,11 @@ import { Thumbnail } from "../../../../../components/common/thumbnail" import { Combobox } from "../../../../../components/inputs/combobox" import { MoneyAmountCell } from "../../../../../components/table/table-cells/common/money-amount-cell" import { useReturnReasons } from "../../../../../hooks/api/return-reasons" +import { ExtendedAdminOrderLineItem } from "@custom-types/order" type OrderEditItemProps = { - item: AdminOrderLineItem - previewItem: AdminOrderLineItem + item: ExtendedAdminOrderLineItem + previewItem: ExtendedAdminOrderLineItem currencyCode: string index: number @@ -107,18 +108,18 @@ function ClaimInboundItem({ groups={[ { actions: [ - !showReturnReason && { + ...(!showReturnReason ? [{ label: t("actions.addReason"), onClick: () => form.setValue(`inbound_items.${index}.reason_id`, ""), icon: , - }, - !showNote && { + }] : []), + ...(!showNote? [{ label: t("actions.addNote"), onClick: () => form.setValue(`inbound_items.${index}.note`, ""), icon: , - }, + }] : []), { label: t("actions.remove"), onClick: onRemove, @@ -146,7 +147,7 @@ function ClaimInboundItem({ { + render={({ field: { value, onChange, ...field } }) => { return ( @@ -201,7 +202,7 @@ function ClaimInboundItem({ { + render={({ field: { ...field } }) => { return ( diff --git a/src/routes/orders/order-create-claim/components/claim-create-form/claim-outbound-section.tsx b/src/routes/orders/order-create-claim/components/claim-create-form/claim-outbound-section.tsx index 38187c39..0ae9c358 100644 --- a/src/routes/orders/order-create-claim/components/claim-create-form/claim-outbound-section.tsx +++ b/src/routes/orders/order-create-claim/components/claim-create-form/claim-outbound-section.tsx @@ -32,6 +32,7 @@ import { ItemPlaceholder } from "./item-placeholder" import { CreateClaimSchemaType } from "./schema" import { useOrderShippingOptions } from "../../../../../hooks/api/orders" import { getFormattedShippingOptionLocationName } from "../../../../../lib/shipping-options" +import { ExtendedAdminProductVariantListResponse } from "@custom-types/product" type ClaimOutboundSectionProps = { order: AdminOrder @@ -162,7 +163,7 @@ export const ClaimOutboundSection = ({ const showOutboundItemsPlaceholder = !outboundItems.length const onItemsSelected = async () => { - itemsToAdd.length && + if (itemsToAdd.length) { (await addOutboundItem( { items: itemsToAdd.map((variantId) => ({ @@ -176,6 +177,7 @@ export const ClaimOutboundSection = ({ }, } )) + } for (const itemToRemove of itemsToRemove) { const action = previewOutboundItems @@ -202,7 +204,7 @@ export const ClaimOutboundSection = ({ (a) => a.action === "SHIPPING_ADD" && !a.return_id ) - return action && !!!action?.return_id + return action && !!action?.return_id }) const promises = outboundShippingMethods @@ -238,6 +240,10 @@ export const ClaimOutboundSection = ({ const allItemsHaveLocation = outboundItems .map((i) => { + if (!i.variant_id) { + return true + } + const item = variantItemMap.get(i.variant_id) if (!item?.variant_id || !item?.variant) { return true @@ -267,14 +273,13 @@ export const ClaimOutboundSection = ({ const variantIds = outboundItems .map((item) => item?.variant_id) - .filter(Boolean) + .filter((id): id is string => Boolean(id)) - const variants = ( - await sdk.admin.productVariant.list({ - id: variantIds, - fields: "*inventory.location_levels", - }) - ).variants + + const { variants } = (await sdk.admin.productVariant.list({ + id: variantIds, + fields: "*inventory.location_levels", + })) as ExtendedAdminProductVariantListResponse variants.forEach((variant) => { ret[variant.id] = variant.inventory?.[0]?.location_levels || [] @@ -303,10 +308,10 @@ export const ClaimOutboundSection = ({ i.variant_id)} + selectedItems={outboundItems.map((i) => i.variant_id).filter((id): id is string => Boolean(id))} currencyCode={order.currency_code} onSelectionChange={(finalSelection) => { - const alreadySelected = outboundItems.map((i) => i.variant_id) + const alreadySelected = outboundItems.map((i) => i.variant_id).filter((id): id is string => Boolean(id)) itemsToAdd = finalSelection.filter( (selection) => !alreadySelected.includes(selection) @@ -345,11 +350,20 @@ export const ClaimOutboundSection = ({ {showOutboundItemsPlaceholder && } {outboundItems.map( - (item, index) => - variantOutboundMap.get(item.variant_id) && ( + (item, index) => { + if (!item.variant_id) { + return null + } + + const previewItem = variantOutboundMap.get(item.variant_id) + if (!previewItem) { + return null + } + + return ( { @@ -384,6 +398,7 @@ export const ClaimOutboundSection = ({ index={index} /> ) + } )} {!showOutboundItemsPlaceholder && (
diff --git a/src/routes/orders/order-create-claim/components/claim-create-form/schema.ts b/src/routes/orders/order-create-claim/components/claim-create-form/schema.ts index 0cc035bf..0cc64350 100644 --- a/src/routes/orders/order-create-claim/components/claim-create-form/schema.ts +++ b/src/routes/orders/order-create-claim/components/claim-create-form/schema.ts @@ -4,6 +4,7 @@ export const ClaimCreateSchema = z.object({ inbound_items: z.array( z.object({ item_id: z.string(), + variant_id: z.string().nullish(), quantity: z.number(), reason_id: z.string().nullish(), note: z.string().nullish(), @@ -11,7 +12,8 @@ export const ClaimCreateSchema = z.object({ ), outbound_items: z.array( z.object({ - item_id: z.string(), // TODO: variant id? + item_id: z.string(), + variant_id: z.string().nullish(), quantity: z.number(), }) ), diff --git a/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-create-form.tsx b/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-create-form.tsx index cc2602c5..067e6a5d 100644 --- a/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-create-form.tsx +++ b/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-create-form.tsx @@ -18,6 +18,7 @@ import { import { getStylizedAmount } from "../../../../../lib/money-amount-helpers" import { OrderEditItemsSection } from "./order-edit-items-section" import { CreateOrderEditSchemaType, OrderEditCreateSchema } from "./schema" +import { getErrorMessage } from "@utils/error-helper" type ReturnCreateFormProps = { order: AdminOrder @@ -78,7 +79,7 @@ export const OrderEditCreateForm = ({ handleSuccess() } catch (e) { toast.error(t("general.error"), { - description: e.message, + description: getErrorMessage(e), }) } }) diff --git a/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-item.tsx b/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-item.tsx index de1a957a..66ec1805 100644 --- a/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-item.tsx +++ b/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-item.tsx @@ -1,5 +1,6 @@ import { ArrowUturnLeft, DocumentSeries, XCircle } from "@medusajs/icons" import { AdminOrderLineItem } from "@medusajs/types" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" import { Badge, Input, Text, toast } from "@medusajs/ui" import { useTranslation } from "react-i18next" @@ -13,9 +14,10 @@ import { useUpdateOrderEditAddedItem, useUpdateOrderEditOriginalItem, } from "../../../../../hooks/api/order-edits" +import { getErrorMessage } from "@utils/error-helper" type OrderEditItemProps = { - item: AdminOrderLineItem + item: ExtendedAdminOrderLineItem currencyCode: string orderId: string } @@ -68,7 +70,7 @@ function OrderEditItem({ item, currencyCode, orderId }: OrderEditItemProps) { await updateOriginalItem({ quantity, itemId: item.id }) } } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) } } @@ -85,7 +87,7 @@ function OrderEditItem({ item, currencyCode, orderId }: OrderEditItemProps) { }) } } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) } } @@ -99,7 +101,7 @@ function OrderEditItem({ item, currencyCode, orderId }: OrderEditItemProps) { await undoAction(updateItemAction.id) // Remove action that updated items quantity to fulfilled quantity which makes it "removed" } } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) } } diff --git a/src/routes/orders/order-create-edit/order-edit-create.tsx b/src/routes/orders/order-create-edit/order-edit-create.tsx index 9a973db1..0cc4bac6 100644 --- a/src/routes/orders/order-create-edit/order-edit-create.tsx +++ b/src/routes/orders/order-create-edit/order-edit-create.tsx @@ -8,6 +8,7 @@ import { useOrder, useOrderPreview } from "../../../hooks/api/orders" import { DEFAULT_FIELDS } from "../order-detail/constants" import { OrderEditCreateForm } from "./components/order-edit-create-form" import { useCreateOrderEdit } from "../../../hooks/api/order-edits" +import { getErrorMessage } from "@utils/error-helper" let IS_REQUEST_RUNNING = false @@ -21,7 +22,7 @@ export const OrderEditCreate = () => { }) const { order: preview } = useOrderPreview(id!) - const { mutateAsync: createOrderEdit } = useCreateOrderEdit(order.id) + const { mutateAsync: createOrderEdit } = useCreateOrderEdit(order?.id ?? "") useEffect(() => { async function run() { @@ -45,7 +46,7 @@ export const OrderEditCreate = () => { order_id: preview.id, }) } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) navigate(`/orders/${preview.id}`, { replace: true }) } finally { IS_REQUEST_RUNNING = false diff --git a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-create-form.tsx b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-create-form.tsx index 2ff97fd6..e6ad1884 100644 --- a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-create-form.tsx +++ b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-create-form.tsx @@ -1,6 +1,6 @@ import { zodResolver } from "@hookform/resolvers/zod" import { PencilSquare } from "@medusajs/icons" -import { AdminExchange, AdminOrder, AdminOrderPreview } from "@medusajs/types" +import type { AdminOrderPreview } from "@medusajs/types" import { Button, CurrencyInput, @@ -25,6 +25,7 @@ import { CreateExchangeSchemaType, ExchangeCreateSchema } from "./schema" import { AdminReturn } from "@medusajs/types" import { KeyboundForm } from "../../../../../components/utilities/keybound-form/keybound-form.tsx" +import { getErrorMessage } from "@utils/error-helper" import { useCancelExchangeRequest, useExchangeConfirmRequest, @@ -34,10 +35,12 @@ import { import { currencies } from "../../../../../lib/data/currencies" import { ExchangeInboundSection } from "./exchange-inbound-section.tsx" import { ExchangeOutboundSection } from "./exchange-outbound-section" +import type { ExtendedAdminExchange } from "@custom-types/exchanges/common.ts" +import type { ExtendedAdminOrder } from "@custom-types/order/common.ts" type ReturnCreateFormProps = { - order: AdminOrder - exchange: AdminExchange + order: ExtendedAdminOrder + exchange: ExtendedAdminExchange preview: AdminOrderPreview orderReturn?: AdminReturn } @@ -139,16 +142,18 @@ export const ExchangeCreateForm = ({ const inboundAction = i.actions?.find( (a) => a.action === "RETURN_ITEM" ) + const reasonId = inboundAction?.details?.reason_id return { item_id: i.id, - variant_id: i.variant_id, quantity: i.detail.return_requested_quantity, note: inboundAction?.internal_note, - reason_id: inboundAction?.details?.reason_id as string | undefined, + reason_id: typeof reasonId === "string" ? reasonId : undefined, } }), - outbound_items: outboundPreviewItems.map((i) => ({ + outbound_items: outboundPreviewItems + .filter((i): i is typeof i & { variant_id: string } => !!i.variant_id) + .map((i) => ({ item_id: i.id, variant_id: i.variant_id, quantity: i.detail.quantity, @@ -178,13 +183,19 @@ export const ExchangeCreateForm = ({ useEffect(() => { if (inboundShipping) { - setCustomInboundShippingAmount(inboundShipping.total) + setCustomInboundShippingAmount({ + value: inboundShipping.total.toString(), + float: inboundShipping.total, + }) } }, [inboundShipping]) useEffect(() => { if (outboundShipping) { - setCustomOutboundShippingAmount(outboundShipping.total) + setCustomOutboundShippingAmount({ + value: outboundShipping.total.toString(), + float: outboundShipping.total, + }) } }, [outboundShipping]) @@ -212,7 +223,7 @@ export const ExchangeCreateForm = ({ handleSuccess() } catch (e) { toast.error(t("general.error"), { - description: e.message, + description: getErrorMessage(e), }) } }) diff --git a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-item.tsx b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-item.tsx index e9ae7f44..b3fa1c90 100644 --- a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-item.tsx +++ b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-item.tsx @@ -1,5 +1,5 @@ import { ChatBubble, DocumentText, XCircle, XMark } from "@medusajs/icons" -import { AdminOrderLineItem, HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { IconButton, Input, Text } from "@medusajs/ui" import { UseFormReturn } from "react-hook-form" import { useTranslation } from "react-i18next" @@ -10,10 +10,11 @@ import { Thumbnail } from "../../../../../components/common/thumbnail" import { Combobox } from "../../../../../components/inputs/combobox" import { MoneyAmountCell } from "../../../../../components/table/table-cells/common/money-amount-cell" import { useReturnReasons } from "../../../../../hooks/api/return-reasons" +import { ExtendedAdminOrderLineItem } from "@custom-types/order" type ExchangeInboundItemProps = { - item: AdminOrderLineItem - previewItem: AdminOrderLineItem + item: ExtendedAdminOrderLineItem + previewItem: ExtendedAdminOrderLineItem currencyCode: string index: number @@ -107,24 +108,24 @@ function ExchangeInboundItem({ groups={[ { actions: [ - !showReturnReason && { + ...(!showReturnReason ? [{ label: t("actions.addReason"), onClick: () => form.setValue(`inbound_items.${index}.reason_id`, ""), icon: , - }, - !showNote && { + }] : []), + ...(!showNote ? [{ label: t("actions.addNote"), onClick: () => form.setValue(`inbound_items.${index}.note`, ""), icon: , - }, + }] : []), { label: t("actions.remove"), onClick: onRemove, icon: , }, - ].filter(Boolean), + ], }, ]} /> @@ -146,7 +147,7 @@ function ExchangeInboundItem({ { + render={({ field: { value, onChange, ...field } }) => { return ( @@ -201,7 +202,7 @@ function ExchangeInboundItem({ { + render={({ field: { ...field } }) => { return ( diff --git a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-section.tsx b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-section.tsx index ad834598..4c70a085 100644 --- a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-section.tsx +++ b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-inbound-section.tsx @@ -1,6 +1,5 @@ import { AdminExchange, - AdminOrder, AdminOrderPreview, AdminReturn, InventoryLevelDTO, @@ -33,9 +32,11 @@ import { ItemPlaceholder } from "../../../order-create-claim/components/claim-cr import { AddExchangeInboundItemsTable } from "../add-exchange-inbound-items-table" import { ExchangeInboundItem } from "./exchange-inbound-item" import { CreateExchangeSchemaType } from "./schema" +import { ExtendedAdminProductVariantListResponse } from "@custom-types/product" +import type { ExtendedAdminOrder } from "@custom-types/order" type ExchangeInboundSectionProps = { - order: AdminOrder + order: ExtendedAdminOrder orderReturn?: AdminReturn exchange: AdminExchange preview: AdminOrderPreview @@ -67,7 +68,7 @@ export const ExchangeInboundSection = ({ */ const { mutateAsync: updateReturn } = useUpdateReturn( preview?.order_change?.return_id!, - order.id + order.id, ) const { mutateAsync: addInboundShipping } = useAddExchangeInboundShipping( @@ -165,12 +166,13 @@ export const ExchangeInboundSection = ({ const returnItemAction = i.actions?.find( (a) => a.action === "RETURN_ITEM" ) + const reasonId = returnItemAction?.details?.reason_id update(ind, { ...inboundItems[ind], quantity: i.detail.return_requested_quantity, note: returnItemAction?.internal_note, - reason_id: returnItemAction?.details?.reason_id as string, + reason_id: typeof reasonId === "string" ? reasonId : undefined, }) } } else { @@ -210,8 +212,8 @@ export const ExchangeInboundSection = ({ const showInboundItemsPlaceholder = !inboundItems.length const onItemsSelected = async () => { - itemsToAdd.length && - (await addInboundItem( + if (itemsToAdd.length) { + await addInboundItem( { items: itemsToAdd.map((id) => ({ id, @@ -223,7 +225,8 @@ export const ExchangeInboundSection = ({ toast.error(error.message) }, } - )) + ) + } for (const itemToRemove of itemsToRemove) { const actionId = previewInboundItems @@ -314,14 +317,12 @@ export const ExchangeInboundSection = ({ const variantIds = inboundItems .map((item) => item?.variant_id) - .filter(Boolean) + .filter((id): id is string => Boolean(id)) - const variants = ( - await sdk.admin.productVariant.list({ - id: variantIds, - fields: "*inventory.location_levels", - }) - ).variants + const { variants } = (await sdk.admin.productVariant.list({ + id: variantIds, + fields: "*inventory.location_levels", + })) as ExtendedAdminProductVariantListResponse variants.forEach((variant) => { ret[variant.id] = variant.inventory?.[0]?.location_levels || [] diff --git a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-item.tsx b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-item.tsx index 8a7de14a..946341cc 100644 --- a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-item.tsx +++ b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-item.tsx @@ -1,5 +1,5 @@ import { XCircle } from "@medusajs/icons" -import { AdminOrderLineItem, HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { Input, Text } from "@medusajs/ui" import { UseFormReturn } from "react-hook-form" import { useTranslation } from "react-i18next" @@ -9,9 +9,10 @@ import { Form } from "../../../../../components/common/form" import { Thumbnail } from "../../../../../components/common/thumbnail" import { MoneyAmountCell } from "../../../../../components/table/table-cells/common/money-amount-cell" import { CreateExchangeSchemaType } from "./schema" +import { ExtendedAdminOrderLineItem } from "@custom-types/order" type ExchangeOutboundItemProps = { - previewItem: AdminOrderLineItem + previewItem: ExtendedAdminOrderLineItem currencyCode: string index: number diff --git a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-section.tsx b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-section.tsx index 30bce488..df84f9c4 100644 --- a/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-section.tsx +++ b/src/routes/orders/order-create-exchange/components/exchange-create-form/exchange-outbound-section.tsx @@ -31,6 +31,7 @@ import { ExchangeOutboundItem } from "./exchange-outbound-item" import { useOrderShippingOptions } from "../../../../../hooks/api/orders" import { CreateExchangeSchemaType } from "./schema" import { getFormattedShippingOptionLocationName } from "../../../../../lib/shipping-options" +import type { ExtendedAdminProductVariantListResponse } from "@custom-types/product" type ExchangeOutboundSectionProps = { order: AdminOrder @@ -127,6 +128,10 @@ export const ExchangeOutboundSection = ({ const existingItemsMap: Record = {} previewOutboundItems.forEach((i) => { + if (!i.variant_id) { + return + } + const ind = outboundItems.findIndex((field) => field.item_id === i.id) existingItemsMap[i.id] = true @@ -161,8 +166,8 @@ export const ExchangeOutboundSection = ({ const showOutboundItemsPlaceholder = !outboundItems.length const onItemsSelected = async () => { - itemsToAdd.length && - (await addOutboundItem( + if (itemsToAdd.length) { + await addOutboundItem( { items: itemsToAdd.map((variantId) => ({ variant_id: variantId, @@ -174,7 +179,8 @@ export const ExchangeOutboundSection = ({ toast.error(error.message) }, } - )) + ) + } for (const itemToRemove of itemsToRemove) { const action = previewOutboundItems @@ -277,12 +283,10 @@ export const ExchangeOutboundSection = ({ .map((item) => item?.variant_id) .filter(Boolean) - const variants = ( - await sdk.admin.productVariant.list({ - id: variantIds, - fields: "*inventory.location_levels", - }) - ).variants + const { variants } = (await sdk.admin.productVariant.list({ + id: variantIds, + fields: "*inventory.location_levels", + })) as ExtendedAdminProductVariantListResponse variants.forEach((variant) => { ret[variant.id] = variant.inventory?.[0]?.location_levels || [] diff --git a/src/routes/orders/order-create-exchange/components/exchange-create-form/schema.ts b/src/routes/orders/order-create-exchange/components/exchange-create-form/schema.ts index 0b0ec703..1dc60906 100644 --- a/src/routes/orders/order-create-exchange/components/exchange-create-form/schema.ts +++ b/src/routes/orders/order-create-exchange/components/exchange-create-form/schema.ts @@ -4,6 +4,7 @@ export const ExchangeCreateSchema = z.object({ inbound_items: z.array( z.object({ item_id: z.string(), + variant_id: z.string().nullish(), quantity: z.number(), reason_id: z.string().nullish(), note: z.string().nullish(), @@ -13,6 +14,7 @@ export const ExchangeCreateSchema = z.object({ z.object({ item_id: z.string(), quantity: z.number(), + variant_id: z.string(), }) ), location_id: z.string().optional(), diff --git a/src/routes/orders/order-create-exchange/exchange-create.tsx b/src/routes/orders/order-create-exchange/exchange-create.tsx index 0ff0e637..d1251ef9 100644 --- a/src/routes/orders/order-create-exchange/exchange-create.tsx +++ b/src/routes/orders/order-create-exchange/exchange-create.tsx @@ -3,12 +3,13 @@ import { useEffect, useState } from "react" import { useTranslation } from "react-i18next" import { useNavigate, useParams } from "react-router-dom" -import { RouteFocusModal } from "../../../components/modals" -import { useCreateExchange, useExchange } from "../../../hooks/api/exchanges" -import { useOrder, useOrderPreview } from "../../../hooks/api/orders" -import { useReturn } from "../../../hooks/api/returns" +import { RouteFocusModal } from "@components/modals" +import { useCreateExchange, useExchange } from "@hooks/api/exchanges" +import { useOrder, useOrderPreview } from "@hooks/api/orders" +import { useReturn } from "@hooks/api/returns" import { DEFAULT_FIELDS } from "../order-detail/constants" import { ExchangeCreateForm } from "./components/exchange-create-form" +import { getErrorMessage } from "@utils/error-helper" let IS_REQUEST_RUNNING = false @@ -22,14 +23,14 @@ export const ExchangeCreate = () => { }) const { order: preview } = useOrderPreview(id!) - const [activeExchangeId, setActiveExchangeId] = useState() - const { mutateAsync: createExchange } = useCreateExchange(order.id) + const [activeExchangeId, setActiveExchangeId] = useState() + const { mutateAsync: createExchange } = useCreateExchange(order?.id ?? "") - const { exchange } = useExchange(activeExchangeId!, undefined, { + const { exchange } = useExchange(activeExchangeId || "", undefined, { enabled: !!activeExchangeId, }) - const { return: orderReturn } = useReturn(exchange?.return_id!, undefined, { + const { return: orderReturn } = useReturn(exchange?.return_id || "", undefined, { enabled: !!exchange?.return_id, }) @@ -56,10 +57,9 @@ export const ExchangeCreate = () => { const { exchange: createdExchange } = await createExchange({ order_id: preview.id, }) - setActiveExchangeId(createdExchange.id) } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) navigate(`/orders/${preview.id}`, { replace: true }) } finally { IS_REQUEST_RUNNING = false diff --git a/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx b/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx index ff75690a..96fa8220 100644 --- a/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx +++ b/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-form.tsx @@ -3,11 +3,10 @@ import { useEffect, useState } from "react" import { useTranslation } from "react-i18next" import * as zod from "zod" -import { AdminOrder, HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { Alert, Button, Select, Switch, toast } from "@medusajs/ui" import { useForm, useWatch } from "react-hook-form" -import { OrderLineItemDTO } from "@medusajs/types" import { Form } from "../../../../../components/common/form" import { RouteFocusModal, @@ -23,13 +22,15 @@ import { useShippingOptions, } from "../../../../../hooks/api" import { getReservationsLimitCount } from "../../../../../lib/orders" +import { getErrorMessage } from "@utils/error-helper" import { sdk } from "../../../../../lib/client" import { useComboboxData } from "../../../../../hooks/use-combobox-data" import { Combobox } from "../../../../../components/inputs/combobox" import { useDocumentDirection } from "../../../../../hooks/use-document-direction" +import type { ExtendedAdminOrder } from "@custom-types/order" type OrderCreateFulfillmentFormProps = { - order: AdminOrder + order: ExtendedAdminOrder requiresShipping: boolean } @@ -71,6 +72,7 @@ export function OrderCreateFulfillmentForm({ quantity: fulfillableItems.reduce( (acc, item) => { acc[item.id] = getFulfillableQuantity(item) + return acc }, {} as Record @@ -107,6 +109,7 @@ export function OrderCreateFulfillmentForm({ type: "manual", message: t("orders.fulfillment.error.noShippingOption"), }) + return } @@ -115,6 +118,7 @@ export function OrderCreateFulfillmentForm({ type: "manual", message: t("orders.fulfillment.error.noLocation"), }) + return } @@ -134,8 +138,9 @@ export function OrderCreateFulfillmentForm({ const itemShippingProfileMap = order.items.reduce((acc, item) => { acc[item.id] = item.variant?.product?.shipping_profile?.id + return acc - }, {} as any) + }, {} as Record) items = items.filter( ({ id }) => itemShippingProfileMap[id] === selectedShippingProfileId @@ -155,7 +160,7 @@ export function OrderCreateFulfillmentForm({ toast.success(t("orders.fulfillment.toast.created")) handleSuccess(`/orders/${order.id}`) } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) } }) @@ -210,7 +215,8 @@ export function OrderCreateFulfillmentForm({ const quantityMap = itemsToFulfill.reduce( (acc, item) => { - acc[item.id] = getFulfillableQuantity(item as OrderLineItemDTO) + acc[item.id] = getFulfillableQuantity(item) + return acc }, {} as Record @@ -360,7 +366,7 @@ export function OrderCreateFulfillmentForm({ disabled={ requiresShipping && !isShippingProfileMatching } - reservations={reservations} + reservations={reservations ?? []} /> ) })} @@ -371,7 +377,6 @@ export function OrderCreateFulfillmentForm({ variant="error" dismissible={false} className="flex items-center" - classNameInner="flex justify-between flex-1 items-center" > {form.formState.errors.root.message} diff --git a/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-item.tsx b/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-item.tsx index f7b0ebad..567397c8 100644 --- a/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-item.tsx +++ b/src/routes/orders/order-create-fulfillment/components/order-create-fulfillment-form/order-create-fulfillment-item.tsx @@ -11,9 +11,10 @@ import { useProductVariant } from "../../../../../hooks/api/products" import { getFulfillableQuantity } from "../../../../../lib/order-item" import { CreateFulfillmentSchema } from "./constants" import { InformationCircleSolid } from "@medusajs/icons" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" type OrderEditItemProps = { - item: HttpTypes.AdminOrderLineItem + item: ExtendedAdminOrderLineItem currencyCode: string locationId?: string onItemRemove: (itemId: string) => void @@ -32,13 +33,13 @@ export function OrderCreateFulfillmentItem({ const { t } = useTranslation() const { variant } = useProductVariant( - item.product_id, - item.variant_id, + item.product_id ?? "", + item.variant_id ?? "", { fields: "*inventory,*inventory.location_levels,*inventory_items", }, { - enabled: !!item.variant, + enabled: !!item.variant_id && !!item.product_id, } ) @@ -213,7 +214,7 @@ export function OrderCreateFulfillmentItem({ field.onChange(val) - if (!isNaN(val)) { + if (val !== null && !isNaN(val)) { if (val < minValue || val > maxValue) { form.setError(`quantity.${item.id}`, { type: "manual", diff --git a/src/routes/orders/order-create-refund/components/create-refund-form/create-refund-form.tsx b/src/routes/orders/order-create-refund/components/create-refund-form/create-refund-form.tsx index 7262fb5e..98b48ae0 100644 --- a/src/routes/orders/order-create-refund/components/create-refund-form/create-refund-form.tsx +++ b/src/routes/orders/order-create-refund/components/create-refund-form/create-refund-form.tsx @@ -1,5 +1,5 @@ import { zodResolver } from "@hookform/resolvers/zod" -import { HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { Button, CurrencyInput, @@ -12,6 +12,7 @@ import { useEffect, useMemo, useState } from "react" import { formatValue } from "react-currency-input-field" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" +import i18n from "i18next" import { useSearchParams } from "react-router-dom" import * as zod from "zod" import { Form } from "../../../../../components/common/form" @@ -23,17 +24,27 @@ import { formatCurrency } from "../../../../../lib/format-currency" import { getLocaleAmount } from "../../../../../lib/money-amount-helpers" import { getPaymentsFromOrder } from "../../../../../lib/orders" import { useDocumentDirection } from "../../../../../hooks/use-document-direction" -import { formatProvider } from "../../../../../lib/format-provider.ts" +import { formatProvider } from "../../../../../lib/format-provider" type CreateRefundFormProps = { order: HttpTypes.AdminOrder } +// If amount.float is sent as 0 or undefined, then full refund is made. Making the amount field non nullable to avoid user confusion. const CreateRefundSchema = zod.object({ - amount: zod.object({ - value: zod.string().or(zod.number()), - float: zod.number().or(zod.null()), - }), + amount: zod + .object({ + value: zod.string(), + float: zod.number(), + }) + .refine( + (data) => { + return data.value && data.value.trim() !== "" && data.float > 0 + }, + { + message: i18n.t('orders.payment.refundAmountWarning'), + } + ), note: zod.string().optional(), refund_reason_id: zod.string().optional(), }) @@ -51,7 +62,6 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { const payments = getPaymentsFromOrder(order) const payment = payments.find((p) => p.id === paymentId) const paymentAmount = payment?.amount || 0 - const currency = useMemo( () => currencies[order.currency_code.toUpperCase()], [order.currency_code] @@ -85,22 +95,43 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { }) }, [payment?.id || ""]) - const { mutateAsync, isPending } = useRefundPayment(order.id, payment?.id!) + const { mutateAsync, isPending } = useRefundPayment( + order.id, + payment?.id ?? "", + ) const handleSubmit = form.handleSubmit(async (data) => { + if (!payment || !paymentId) { + toast.error(t("orders.payment.selectPaymentToRefund")) + + return + } + + await mutateAsync( { - amount: data.amount.float!, + amount: data.amount.float, note: data.note, refund_reason_id: data.refund_reason_id, }, { onSuccess: () => { + if (!payment?.currency_code) { + toast.success( + t("orders.payment.refundPaymentSuccess", { + amount: data.amount.float + }) + ) + handleSuccess() + + return + } + toast.success( t("orders.payment.refundPaymentSuccess", { amount: formatCurrency( - data.amount.float!, - payment?.currency_code! + data.amount.float, + payment.currency_code ), }) ) @@ -181,7 +212,7 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { payment!.currency_code )} -  -  + - (#{payment!.id.substring(23)})
)} @@ -191,7 +222,7 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { name="amount" rules={{ required: true, - min: 0, + min: 0.01, max: paymentAmount, }} render={({ field: { onChange, ...field } }) => { @@ -202,22 +233,27 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { - onChange({ + onValueChange={(_value, _name, values) => { + const newValue = { value: values?.value ?? "", - float: values?.float ?? null, - }) - } - autoFocus + float: values?.float ?? 0, + } + onChange(newValue) + }} + onBlur={() => { + field.onBlur() + form.trigger("amount") + }} /> @@ -263,7 +299,7 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => { { return ( diff --git a/src/routes/orders/order-create-return/components/add-return-items-table/add-return-items-table.tsx b/src/routes/orders/order-create-return/components/add-return-items-table/add-return-items-table.tsx index c081f397..b0002fbf 100644 --- a/src/routes/orders/order-create-return/components/add-return-items-table/add-return-items-table.tsx +++ b/src/routes/orders/order-create-return/components/add-return-items-table/add-return-items-table.tsx @@ -10,11 +10,11 @@ import { import { useTranslation } from "react-i18next" import { _DataTable } from "../../../../../components/table/data-table" import { useDataTable } from "../../../../../hooks/use-data-table" -import { getStylizedAmount } from "../../../../../lib/money-amount-helpers" import { getReturnableQuantity } from "../../../../../lib/rma" import { useReturnItemTableColumns } from "./use-return-item-table-columns" import { useReturnItemTableFilters } from "./use-return-item-table-filters" import { useReturnItemTableQuery } from "./use-return-item-table-query" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" const PAGE_SIZE = 50 const PREFIX = "rit" @@ -22,7 +22,7 @@ const PREFIX = "rit" type AddReturnItemsTableProps = { onSelectionChange: (ids: string[]) => void selectedItems: string[] - items: AdminOrderLineItem[] + items: ExtendedAdminOrderLineItem[] currencyCode: string } @@ -37,6 +37,7 @@ export const AddReturnItemsTable = ({ const [rowSelection, setRowSelection] = useState( selectedItems.reduce((acc, id) => { acc[id] = true + return acc }, {} as RowSelectionState) ) @@ -66,7 +67,7 @@ export const AddReturnItemsTable = ({ returnable_quantity, } = searchParams - let results: AdminOrderLineItem[] = items + let results = items if (q) { results = results.filter((i) => { @@ -98,7 +99,6 @@ export const AddReturnItemsTable = ({ results, returnable_quantity, "returnable_quantity", - currencyCode ) } @@ -107,7 +107,6 @@ export const AddReturnItemsTable = ({ results, refundable_amount, "refundable_amount", - currencyCode ) } @@ -165,7 +164,7 @@ export const AddReturnItemsTable = ({ } const sortItems = ( - items: AdminOrderLineItem[], + items: ExtendedAdminOrderLineItem[], field: string, direction: "asc" | "desc" ) => { @@ -196,12 +195,13 @@ const sortItems = ( if (aValue > bValue) { return direction === "asc" ? 1 : -1 } + return 0 }) } const filterByDate = ( - items: AdminOrderLineItem[], + items: ExtendedAdminOrderLineItem[], date: DateComparisonOperator, field: "created_at" | "updated_at" ) => { @@ -240,10 +240,9 @@ const defaultOperators = { } const filterByNumber = ( - items: AdminOrderLineItem[], + items: ExtendedAdminOrderLineItem[], value: NumericalComparisonOperator | number, field: "returnable_quantity" | "refundable_amount", - currency_code: string ) => { const { eq, gt, lt, gte, lte } = typeof value === "object" @@ -252,7 +251,7 @@ const filterByNumber = ( return items.filter((i) => { const returnableQuantity = i.quantity - (i.returned_quantity || 0) - const refundableAmount = getStylizedAmount(i.refundable || 0, currency_code) + const refundableAmount = i.refundable || 0 const itemValue = field === "returnable_quantity" ? returnableQuantity : refundableAmount diff --git a/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx b/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx index 1457660b..94ba979a 100644 --- a/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx +++ b/src/routes/orders/order-create-return/components/return-create-form/return-create-form.tsx @@ -1,11 +1,11 @@ import { zodResolver } from "@hookform/resolvers/zod" import { PencilSquare } from "@medusajs/icons" -import { - AdminOrder, +import type { AdminOrderPreview, AdminReturn, InventoryLevelDTO, } from "@medusajs/types" +import type { ExtendedAdminProductVariantListResponse } from "@custom-types/product" import { Alert, Button, @@ -27,6 +27,7 @@ import { useRouteModal, useStackedModal, } from "../../../../../components/modals" +import { getErrorMessage } from "@utils/error-helper" import { Form } from "../../../../../components/common/form" import { Combobox } from "../../../../../components/inputs/combobox" @@ -51,9 +52,10 @@ import { ReturnShippingPlaceholder } from "../../../common/placeholders" import { AddReturnItemsTable } from "../add-return-items-table" import { ReturnItem } from "./return-item" import { ReturnCreateSchema, ReturnCreateSchemaType } from "./schema" +import type { ExtendedAdminOrder } from "@custom-types/order" type ReturnCreateFormProps = { - order: AdminOrder + order: ExtendedAdminOrder activeReturn: AdminReturn preview: AdminOrderPreview } @@ -175,15 +177,19 @@ export const ReturnCreateForm = ({ ) return Promise.resolve({ - items: previewItems.map((i) => ({ - item_id: i.id, - quantity: i.detail.return_requested_quantity, - note: i.actions?.find((a) => a.action === "RETURN_ITEM") - ?.internal_note, - reason_id: i.actions?.find((a) => a.action === "RETURN_ITEM")?.details - ?.reason_id, - })), - option_id: method ? method.shipping_option_id : "", + items: previewItems.map((i) => { + const returnAction = i.actions?.find((a) => a.action === "RETURN_ITEM") + const reasonId = returnAction?.details?.reason_id + + return { + item_id: i.id, + variant_id: i.variant_id, + quantity: i.detail.return_requested_quantity, + note: returnAction?.internal_note, + reason_id: typeof reasonId === "string" ? reasonId : undefined, + } + }), + option_id: method ? method.shipping_option_id : null, location_id: activeReturn?.location_id, send_notification: false, }) @@ -221,12 +227,13 @@ export const ReturnCreateForm = ({ const returnItemAction = i.actions?.find( (a) => a.action === "RETURN_ITEM" ) + const reasonId = returnItemAction?.details?.reason_id update(ind, { ...items[ind], quantity: i.detail.return_requested_quantity, note: returnItemAction?.internal_note, - reason_id: returnItemAction?.details?.reason_id, + reason_id: typeof reasonId === "string" ? reasonId : undefined, }) } } else { @@ -249,7 +256,7 @@ export const ReturnCreateForm = ({ if (method) { form.setValue("option_id", method.shipping_option_id!) } else { - form.setValue("option_id", "") + form.setValue("option_id", null) } }, [preview.shipping_methods]) @@ -277,8 +284,7 @@ export const ReturnCreateForm = ({ handleSuccess() } catch (e) { toast.error(t("general.error"), { - description: e.message, - dismissLabel: t("actions.close"), + description: getErrorMessage(e), }) } }) @@ -294,17 +300,18 @@ export const ReturnCreateForm = ({ setIsOpen("items", false) } - const onLocationChange = async (selectedLocationId: string) => { + const onLocationChange = async (selectedLocationId?: string | null) => { await updateReturnRequest({ location_id: selectedLocationId }) } const onShippingOptionChange = async ( selectedOptionId: string | undefined ) => { - const promises = preview.shipping_methods + const actionIds = preview.shipping_methods .map((s) => s.actions?.find((a) => a.action === "SHIPPING_ADD")?.id) - .filter(Boolean) - .map(deleteReturnShipping) + .filter((id): id is string => Boolean(id)) + + const promises = actionIds.map((id) => deleteReturnShipping(id)) await Promise.all(promises) @@ -315,7 +322,7 @@ export const ReturnCreateForm = ({ useEffect(() => { if (isShippingPriceEdit) { - document.getElementById("js-shipping-input").focus() + document?.getElementById("js-shipping-input")?.focus() } }, [isShippingPriceEdit]) @@ -356,33 +363,22 @@ export const ReturnCreateForm = ({ return ret } - ( - await Promise.all( - items.map(async (_i) => { - const item = itemsMap.get(_i.item_id) - - if (!item.variant_id) { - return undefined - } - return await sdk.admin.product.retrieveVariant( - item.product_id, - item.variant_id, - { fields: "*inventory,*inventory.location_levels" } - ) - }) - ) - ) - .filter((it) => it?.variant) - .forEach((item) => { - const { variant } = item - const levels = variant.inventory[0]?.location_levels + const variantIds = items + .map((item) => item?.variant_id) + .filter((id): id is string => Boolean(id)) - if (!levels) { - return - } + if (!variantIds.length) { + return ret + } - ret[variant.id] = levels - }) + const { variants } = (await sdk.admin.productVariant.list({ + id: variantIds, + fields: "*inventory.location_levels", + })) as ExtendedAdminProductVariantListResponse + + variants.forEach((variant) => { + ret[variant.id] = variant.inventory?.[0]?.location_levels || [] + }) return ret } @@ -472,11 +468,19 @@ export const ReturnCreateForm = ({ )} {items .filter((item) => !!previewItemsMap.get(item.item_id)) - .map((item, index) => ( + .map((item, index) => { + const orderItem = itemsMap.get(item.item_id) + const previewItem = previewItemsMap.get(item.item_id) + + if (!orderItem || !previewItem) { + return null + } + + return ( { @@ -513,7 +517,8 @@ export const ReturnCreateForm = ({ }} index={index} /> - ))} + ) + })} {!showPlaceholder && (
{/* LOCATION*/} @@ -581,7 +586,7 @@ export const ReturnCreateForm = ({ { onChange(v) onShippingOptionChange(v) @@ -663,21 +668,24 @@ export const ReturnCreateForm = ({ id="js-shipping-input" onBlur={() => { let actionId + let shippingOptionId preview.shipping_methods.forEach((s) => { if (s.actions) { for (const a of s.actions) { if (a.action === "SHIPPING_ADD") { actionId = a.id + shippingOptionId = s.shipping_option_id } } } }) - if (actionId) { + if (actionId && shippingOptionId) { updateReturnShipping({ actionId, - custom_amount: customShippingAmount.float, + shipping_option_id: shippingOptionId, + custom_amount: customShippingAmount.float ?? undefined, }) } setIsShippingPriceEdit(false) diff --git a/src/routes/orders/order-create-return/components/return-create-form/return-item.tsx b/src/routes/orders/order-create-return/components/return-create-form/return-item.tsx index 420cbda5..ce95e3fa 100644 --- a/src/routes/orders/order-create-return/components/return-create-form/return-item.tsx +++ b/src/routes/orders/order-create-return/components/return-create-form/return-item.tsx @@ -1,8 +1,8 @@ import { useTranslation } from "react-i18next" import { IconButton, Input, Text } from "@medusajs/ui" -import { UseFormReturn } from "react-hook-form" -import { HttpTypes, AdminOrderLineItem } from "@medusajs/types" +import type { UseFormReturn } from "react-hook-form" +import type { HttpTypes } from "@medusajs/types" import { ChatBubble, DocumentText, XCircle, XMark } from "@medusajs/icons" import { Thumbnail } from "../../../../../components/common/thumbnail" @@ -11,10 +11,11 @@ import { Form } from "../../../../../components/common/form" import { ActionMenu } from "../../../../../components/common/action-menu" import { Combobox } from "../../../../../components/inputs/combobox" import { useReturnReasons } from "../../../../../hooks/api/return-reasons" +import { ExtendedAdminOrderLineItem } from "@custom-types/order" type OrderEditItemProps = { - item: AdminOrderLineItem - previewItem: AdminOrderLineItem + item: ExtendedAdminOrderLineItem + previewItem: ExtendedAdminOrderLineItem currencyCode: string index: number @@ -109,17 +110,17 @@ function ReturnItem({ groups={[ { actions: [ - !showReturnReason && { + ...(!showReturnReason ? [{ label: t("actions.addReason"), onClick: () => form.setValue(`items.${index}.reason_id`, ""), icon: , - }, - !showNote && { + }] : []), + ...(!showNote ? [{ label: t("actions.addNote"), onClick: () => form.setValue(`items.${index}.note`, ""), icon: , - }, + }] : []), { label: t("actions.remove"), onClick: onRemove, @@ -147,7 +148,7 @@ function ReturnItem({ { + render={({ field: { value, onChange, ...field } }) => { return ( @@ -201,7 +202,7 @@ function ReturnItem({ { + render={({ field: { onChange, ...field } }) => { return ( diff --git a/src/routes/orders/order-create-return/components/return-create-form/schema.ts b/src/routes/orders/order-create-return/components/return-create-form/schema.ts index 709495ec..8d9c96c7 100644 --- a/src/routes/orders/order-create-return/components/return-create-form/schema.ts +++ b/src/routes/orders/order-create-return/components/return-create-form/schema.ts @@ -4,13 +4,14 @@ export const ReturnCreateSchema = z.object({ items: z.array( z.object({ item_id: z.string(), + variant_id: z.string().nullish(), quantity: z.number(), - reason_id: z.string().optional().nullable(), - note: z.string().optional().nullable(), + reason_id: z.string().nullish(), + note: z.string().nullish(), }) ), location_id: z.string().optional(), - option_id: z.string(), + option_id: z.string().nullish(), send_notification: z.boolean().optional(), // TODO: implement this receive_now: z.boolean().optional(), diff --git a/src/routes/orders/order-create-return/return-create.tsx b/src/routes/orders/order-create-return/return-create.tsx index 4b20e866..8374318b 100644 --- a/src/routes/orders/order-create-return/return-create.tsx +++ b/src/routes/orders/order-create-return/return-create.tsx @@ -10,6 +10,7 @@ import { ReturnCreateForm } from "./components/return-create-form" import { useOrder, useOrderPreview } from "../../../hooks/api/orders" import { useInitiateReturn, useReturn } from "../../../hooks/api/returns" import { DEFAULT_FIELDS } from "../order-detail/constants" +import { getErrorMessage } from "@utils/error-helper" let IS_REQUEST_RUNNING = false @@ -25,11 +26,11 @@ export const ReturnCreate = () => { const { order: preview } = useOrderPreview(id!, undefined, {}) - const [activeReturnId, setActiveReturnId] = useState() + const [activeReturnId, setActiveReturnId] = useState() - const { mutateAsync: initiateReturn } = useInitiateReturn(order.id) + const { mutateAsync: initiateReturn } = useInitiateReturn(order?.id ?? "") - const { return: activeReturn } = useReturn(activeReturnId, undefined, { + const { return: activeReturn } = useReturn(activeReturnId ?? "", undefined, { enabled: !!activeReturnId, }) @@ -43,7 +44,9 @@ export const ReturnCreate = () => { if (preview.order_change.change_type === "return_request") { setActiveReturnId(preview.order_change.return_id) } else { - navigate(`/orders/${order.id}`, { replace: true }) + if (order?.id) { + navigate(`/orders/${order.id}`, { replace: true }) + } toast.error(t("orders.returns.activeChangeError")) } @@ -53,11 +56,13 @@ export const ReturnCreate = () => { IS_REQUEST_RUNNING = true try { - const orderReturn = await initiateReturn({ order_id: order.id }) + const orderReturn = await initiateReturn({ order_id: order?.id ?? "" }) setActiveReturnId(orderReturn.id) } catch (e) { - navigate(`/orders/${order.id}`, { replace: true }) - toast.error(e.message) + if (order?.id) { + navigate(`/orders/${order.id}`, { replace: true }) + } + toast.error(getErrorMessage(e)) } finally { IS_REQUEST_RUNNING = false } diff --git a/src/routes/orders/order-create-shipment/components/order-create-shipment-form/order-create-shipment-form.tsx b/src/routes/orders/order-create-shipment/components/order-create-shipment-form/order-create-shipment-form.tsx index 4945df8c..6439c4b4 100644 --- a/src/routes/orders/order-create-shipment/components/order-create-shipment-form/order-create-shipment-form.tsx +++ b/src/routes/orders/order-create-shipment/components/order-create-shipment-form/order-create-shipment-form.tsx @@ -2,7 +2,6 @@ import { zodResolver } from "@hookform/resolvers/zod" import { useTranslation } from "react-i18next" import * as zod from "zod" -import { AdminFulfillment, AdminOrder } from "@medusajs/types" import { Button, Heading, Input, Switch, toast } from "@medusajs/ui" import { useFieldArray, useForm } from "react-hook-form" @@ -14,10 +13,11 @@ import { import { KeyboundForm } from "../../../../../components/utilities/keybound-form" import { useCreateOrderShipment } from "../../../../../hooks/api" import { CreateShipmentSchema } from "./constants" +import { ExtendedAdminOrder, ExtendedAdminOrderFulfillment } from "@custom-types/order" type OrderCreateFulfillmentFormProps = { - order: AdminOrder - fulfillment: AdminFulfillment + order: ExtendedAdminOrder + fulfillment: ExtendedAdminOrderFulfillment } export function OrderCreateShipmentForm({ @@ -32,7 +32,7 @@ export function OrderCreateShipmentForm({ const form = useForm>({ defaultValues: { - send_notification: !order.no_notification, + send_notification: !order?.no_notification, }, resolver: zodResolver(CreateShipmentSchema), }) diff --git a/src/routes/orders/order-create-shipment/order-create-shipment.tsx b/src/routes/orders/order-create-shipment/order-create-shipment.tsx index bf90b0f5..c03b943e 100644 --- a/src/routes/orders/order-create-shipment/order-create-shipment.tsx +++ b/src/routes/orders/order-create-shipment/order-create-shipment.tsx @@ -1,12 +1,14 @@ import { useParams } from "react-router-dom" -import { HttpTypes } from "@medusajs/types" -import { RouteFocusModal } from "../../../components/modals" -import { useOrder } from "../../../hooks/api/orders" +import { useOrder } from "@/hooks/api/orders" import { OrderCreateShipmentForm } from "./components/order-create-shipment-form" +import { toast } from "@medusajs/ui" +import { useTranslation } from "react-i18next" +import { RouteFocusModal } from "@components/modals" export function OrderCreateShipment() { const { id, f_id } = useParams() + const { t } = useTranslation() const { order, isLoading, isError, error } = useOrder(id!, { fields: "*fulfillments,*fulfillments.items,*fulfillments.labels", @@ -17,13 +19,19 @@ export function OrderCreateShipment() { } const ready = !isLoading && order + const fulfillment = order?.fulfillments.find((f) => f.id === f_id) + + if (!fulfillment) { + toast.error(t("orders.shipment.toastFulfillmentNotFound")) + throw new Error("Fulfillment not found") + } return ( {ready && ( f.id === f_id)} + fulfillment={fulfillment} /> )} diff --git a/src/routes/orders/order-detail/breadcrumb.tsx b/src/routes/orders/order-detail/breadcrumb.tsx index 36ca4db2..ddd1aace 100644 --- a/src/routes/orders/order-detail/breadcrumb.tsx +++ b/src/routes/orders/order-detail/breadcrumb.tsx @@ -1,9 +1,9 @@ -import { HttpTypes } from "@medusajs/types" -import { UIMatch } from "react-router-dom" -import { useOrder } from "../../../hooks/api" +import type { UIMatch } from "react-router-dom" +import { useOrder } from "@hooks/api" import { DEFAULT_FIELDS } from "./constants" +import type { ExtendedAdminOrderResponse } from "@custom-types/order" -type OrderDetailBreadcrumbProps = UIMatch +type OrderDetailBreadcrumbProps = UIMatch export const OrderDetailBreadcrumb = (props: OrderDetailBreadcrumbProps) => { const { id } = props.params || {} diff --git a/src/routes/orders/order-detail/components/order-active-edit-section/order-active-edit-section.tsx b/src/routes/orders/order-detail/components/order-active-edit-section/order-active-edit-section.tsx index ac56d189..10e5380b 100644 --- a/src/routes/orders/order-detail/components/order-active-edit-section/order-active-edit-section.tsx +++ b/src/routes/orders/order-detail/components/order-active-edit-section/order-active-edit-section.tsx @@ -8,60 +8,27 @@ import { useConfirmOrderEdit, } from "../../../../../hooks/api/order-edits" import { useMemo } from "react" -import { HttpTypes } from "@medusajs/types" +import type { HttpTypes } from "@medusajs/types" import { Thumbnail } from "../../../../../components/common/thumbnail" import { useNavigate } from "react-router-dom" +import { getErrorMessage } from "@utils/error-helper" +import type { ExtendedAdminOrder } from "@custom-types/order" type OrderActiveEditSectionProps = { - order: HttpTypes.AdminOrder - quantity: number -} - -function EditItem({ - item, - quantity, -}: { - item: HttpTypes.AdminOrderLineItem - quantity: number -}) { - return ( -
-
-
- {quantity}x -
- - - - - {item.title} - - - {item.variant_sku && " · "} - - {item.variant_sku && ( -
- {item.variant_sku} - -
- )} -
-
- ) + order: ExtendedAdminOrder } export const OrderActiveEditSection = ({ - order, + order }: OrderActiveEditSectionProps) => { const { t } = useTranslation() const navigate = useNavigate() - const { order: orderPreview } = useOrderPreview(order.id) const { mutateAsync: cancelOrderEdit } = useCancelOrderEdit(order.id) const { mutateAsync: confirmOrderEdit } = useConfirmOrderEdit(order.id) - const isPending = orderPreview.order_change?.status === "pending" + const isPending = orderPreview?.order_change?.status === "pending" const [addedItems, removedItems] = useMemo(() => { const added = [] @@ -74,6 +41,7 @@ export const OrderActiveEditSection = ({ if (!originalItem) { added.push({ item: currentItem, quantity: currentItem.quantity }) + return } @@ -101,7 +69,7 @@ export const OrderActiveEditSection = ({ toast.success(t("orders.edits.toast.confirmedSuccessfully")) } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) } } @@ -111,7 +79,7 @@ export const OrderActiveEditSection = ({ toast.success(t("orders.edits.toast.canceledSuccessfully")) } catch (e) { - toast.error(e.message) + toast.error(getErrorMessage(e)) } } @@ -197,3 +165,28 @@ export const OrderActiveEditSection = ({
) } + +const EditItem = ({ item, quantity }: { item: HttpTypes.AdminOrderLineItem, quantity: number }) => ( +
+
+
+ {quantity}x +
+ + + + + {item.title} + + + {item.variant_sku && " · "} + + {item.variant_sku && ( +
+ {item.variant_sku} + +
+ )} +
+
+ ) \ No newline at end of file diff --git a/src/routes/orders/order-detail/components/order-activity-section/activity-items.tsx b/src/routes/orders/order-detail/components/order-activity-section/activity-items.tsx index 97bea76d..c2b5dd53 100644 --- a/src/routes/orders/order-detail/components/order-activity-section/activity-items.tsx +++ b/src/routes/orders/order-detail/components/order-activity-section/activity-items.tsx @@ -1,20 +1,18 @@ -import { - AdminClaim, - AdminExchange, - AdminOrderLineItem, - AdminReturn, -} from "@medusajs/types" import { Popover, Text } from "@medusajs/ui" import { useState } from "react" import { useTranslation } from "react-i18next" import { Thumbnail } from "../../../../../components/common/thumbnail" +import type { ExtendedAdminExchange } from "../../../../../types/exchanges" +import type { ExtendedAdminOrderLineItem } from "@custom-types/order" +import type { ExtendedAdminClaim } from "@custom-types/claims" +import type { ExtendedAdminReturn } from "@custom-types/returns" type ActivityItemsProps = { itemsToSend?: - | AdminClaim["additional_items"] - | AdminExchange["additional_items"] - itemsToReturn?: AdminReturn["items"] - itemsMap?: Map + | ExtendedAdminClaim["additional_items"] + | ExtendedAdminExchange["additional_items"] + itemsToReturn?: ExtendedAdminReturn["items"] + itemsMap?: Map title: string } diff --git a/src/routes/orders/order-detail/components/order-activity-section/order-activity-section.tsx b/src/routes/orders/order-detail/components/order-activity-section/order-activity-section.tsx index 14b19108..82fbbfeb 100644 --- a/src/routes/orders/order-detail/components/order-activity-section/order-activity-section.tsx +++ b/src/routes/orders/order-detail/components/order-activity-section/order-activity-section.tsx @@ -1,10 +1,10 @@ -import { AdminOrder } from "@medusajs/types" import { Container, Heading } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { OrderTimeline } from "./order-timeline" +import type { ExtendedAdminOrder } from "@custom-types/order" type OrderActivityProps = { - order: AdminOrder + order: ExtendedAdminOrder } export const OrderActivitySection = ({ order }: OrderActivityProps) => { diff --git a/src/routes/orders/order-detail/components/order-activity-section/order-note-form.tsx b/src/routes/orders/order-detail/components/order-activity-section/order-note-form.tsx index a2ff3afe..cab9aebe 100644 --- a/src/routes/orders/order-detail/components/order-activity-section/order-note-form.tsx +++ b/src/routes/orders/order-detail/components/order-activity-section/order-note-form.tsx @@ -5,20 +5,21 @@ import { useRef } from "react" import { useForm } from "react-hook-form" import { z } from "zod" -import { AdminOrder } from "@medusajs/types" import { useTranslation } from "react-i18next" -import { Form } from "../../../../../components/common/form" -import { KeyboundForm } from "../../../../../components/utilities/keybound-form" +import { Form } from "@components/common/form" +import { KeyboundForm } from "@components/utilities/keybound-form" -type OrderNoteFormProps = { - order: AdminOrder -} +// TODO: Re-add when we have support for notes, commented out for now + +// type OrderNoteFormProps = { +// order: ExtendedAdminOrder +// } const OrderNoteSchema = z.object({ value: z.string().min(1), }) -export const OrderNoteForm = ({ order }: OrderNoteFormProps) => { +export const OrderNoteForm = () => { const { t } = useTranslation() const textareaRef = useRef(null) @@ -29,23 +30,23 @@ export const OrderNoteForm = ({ order }: OrderNoteFormProps) => { resolver: zodResolver(OrderNoteSchema), }) - const { mutateAsync, isLoading } = {} + // const { mutateAsync, isLoading } = {} - const handleSubmit = form.handleSubmit(async (values) => { - mutateAsync( - { - resource_id: order.id, - resource_type: "order", - value: values.value, - }, - { - onSuccess: () => { - form.reset() - handleResetSize() - }, - } - ) - }) + // const handleSubmit = form.handleSubmit(async (values) => { + // mutateAsync( + // { + // resource_id: order.id, + // resource_type: "order", + // value: values.value, + // }, + // { + // onSuccess: () => { + // form.reset() + // handleResetSize() + // }, + // } + // ) + // }) const handleResize = () => { const textarea = textareaRef.current @@ -55,17 +56,19 @@ export const OrderNoteForm = ({ order }: OrderNoteFormProps) => { } } - const handleResetSize = () => { - const textarea = textareaRef.current - if (textarea) { - textarea.style.height = "auto" - } - } + // const handleResetSize = () => { + // const textarea = textareaRef.current + // if (textarea) { + // textarea.style.height = "auto" + // } + // } return (
- +
{
{ } type Activity = { - title: string - timestamp: string | Date + title: string | ReactNode + timestamp: string | Date | null children?: ReactNode - itemsToSend?: ( - | AdminClaim["additional_items"] - | AdminExchange["additional_items"] - )[] - itemsToReturn?: AdminReturn["items"] - itemsMap?: Map + itemsToSend?: + | ExtendedAdminClaim["additional_items"] + | ExtendedAdminExchange["additional_items"] + itemsToReturn?: ExtendedAdminReturn["items"] + itemsMap?: Map } -const useActivityItems = (order: AdminOrder): Activity[] => { +const useActivityItems = (order: ExtendedAdminOrder): Activity[] => { const { t } = useTranslation() const { order_changes: orderChanges = [] } = useOrderChanges(order.id, { @@ -130,7 +131,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => { }) const rmaChanges = orderChanges.filter( - (oc) => !NON_RMA_CHANGE_TYPES.includes(oc.change_type) + (oc) => oc.change_type && !NON_RMA_CHANGE_TYPES.includes(oc.change_type) ) const missingLineItemIds = getMissingLineItemIds(order, rmaChanges) @@ -147,13 +148,18 @@ const useActivityItems = (order: AdminOrder): Activity[] => { ) const itemsMap = useMemo(() => { - const _itemsMap = new Map(order?.items?.map((i) => [i.id, i])) + const _itemsMap = new Map( + (order?.items || []).map((i) => [i.id, i as ExtendedAdminOrderLineItem]) + ) for (const id of missingLineItemIds) { - const i = removedLineItems.find((i) => i.item.id === id) + const i = removedLineItems.find((item) => item.item.id === id) if (i) { - _itemsMap.set(id, { ...i.item, quantity: i.quantity }) // copy quantity from OrderItem to OrderLineItem + const quantity = (i as { quantity?: number }).quantity + if (quantity !== undefined) { + _itemsMap.set(id, { ...i.item, quantity } as ExtendedAdminOrderLineItem) // copy quantity from OrderItem to OrderLineItem + } } } @@ -174,10 +180,10 @@ const useActivityItems = (order: AdminOrder): Activity[] => { order_id: order.id, fields: "*additional_items", }) - + const payments = getPaymentsFromOrder(order) - const notes = [] + const notes: { created_at: string; value: string; author_id: string }[] = [] const isLoading = false // const { notes, isLoading, isError, error } = useNotes( // { @@ -274,7 +280,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => { title: t("orders.activity.events.fulfillment.shipped"), timestamp: fulfillment.shipped_at, children: ( - + ), }) } @@ -287,7 +293,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => { } } - const returnMap = new Map() + const returnMap = new Map() for (const ret of returns) { returnMap.set(ret.id, ret) @@ -324,7 +330,7 @@ const useActivityItems = (order: AdminOrder): Activity[] => { timestamp: ret.received_at, itemsToReturn: ret?.items, itemsMap, - children: , + children: , }) } } @@ -379,20 +385,35 @@ const useActivityItems = (order: AdminOrder): Activity[] => { continue } + const editId = edit.id.slice(-7) + + let editTitle: string + if (edit.status === "requested") { + editTitle = t("orders.activity.events.edit.requested", { editId }) + } else if (edit.status === "confirmed") { + editTitle = t("orders.activity.events.edit.confirmed", { editId }) + } else if (edit.status === "declined") { + editTitle = t("orders.activity.events.edit.declined", { editId }) + } else if (edit.status === "canceled") { + editTitle = t("orders.activity.events.edit.canceled", { editId }) + } else { + editTitle = t("orders.activity.events.edit.pending", { editId }) + } + + const timestamp = + edit.status === "requested" + ? edit.requested_at + : edit.status === "confirmed" + ? edit.confirmed_at + : edit.status === "declined" + ? edit.declined_at + : edit.status === "canceled" + ? edit.canceled_at + : edit.created_at + items.push({ - title: t(`orders.activity.events.edit.${edit.status}`, { - editId: edit.id.slice(-7), - }), - timestamp: - edit.status === "requested" - ? edit.requested_at - : edit.status === "confirmed" - ? edit.confirmed_at - : edit.status === "declined" - ? edit.declined_at - : edit.status === "canceled" - ? edit.canceled_at - : edit.created_at, + title: editTitle, + timestamp: timestamp, children: isConfirmed ? : null, }) } @@ -432,64 +453,75 @@ const useActivityItems = (order: AdminOrder): Activity[] => { (oc) => oc.change_type === "update_order" )) { const updateType = update.actions[0]?.details?.type - if (updateType === "shipping_address") { + const actionDetails = update.actions[0]?.details as Record | undefined + const oldAddress = actionDetails?.old as HttpTypes.AdminOrderAddress | null | undefined + const newAddress = actionDetails?.new as HttpTypes.AdminOrderAddress | null | undefined + items.push({ title: ( ), timestamp: update.created_at, children: (
- {t("fields.by")} + {t("fields.by")}
), }) } if (updateType === "billing_address") { + const actionDetails = update.actions[0]?.details as Record | undefined + const oldAddress = actionDetails?.old as HttpTypes.AdminOrderAddress | null | undefined + const newAddress = actionDetails?.new as HttpTypes.AdminOrderAddress | null | undefined + items.push({ title: ( ), timestamp: update.created_at, children: (
- {t("fields.by")} + {t("fields.by")}
), }) } if (updateType === "email") { + const actionDetails = update.actions[0]?.details as Record | undefined + const oldEmail = actionDetails?.old as string | null | undefined + const newEmail = actionDetails?.new as string | null | undefined + items.push({ title: ( ), timestamp: update.created_at, children: (
- {t("fields.by")} + {t("fields.by")}
), }) @@ -507,12 +539,15 @@ const useActivityItems = (order: AdminOrder): Activity[] => { if (order.canceled_at) { items.push({ title: t("orders.activity.events.canceled.title"), - timestamp: order.canceled_at, + timestamp: order.canceled_at }) } const sortedActivities = items.sort((a, b) => { - return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() + const timestampA = a.timestamp ? new Date(a.timestamp).getTime() : 0 + const timestampB = b.timestamp ? new Date(b.timestamp).getTime() : 0 + + return timestampB - timestampA }) const createdAt = { @@ -539,14 +574,14 @@ const useActivityItems = (order: AdminOrder): Activity[] => { } type OrderActivityItemProps = PropsWithChildren<{ - title: string - timestamp: string | Date + title: string | ReactNode + timestamp: string | Date | null isFirst?: boolean itemsToSend?: - | AdminClaim["additional_items"] - | AdminExchange["additional_items"] - itemsToReturn?: AdminReturn["items"] - itemsMap?: Map + | ExtendedAdminClaim["additional_items"] + | ExtendedAdminExchange["additional_items"] + itemsToReturn?: ExtendedAdminReturn["items"] + itemsMap?: Map }> const OrderActivityItem = ({ @@ -576,7 +611,7 @@ const OrderActivityItem = ({ })} >
- {itemsToSend?.length || itemsToReturn?.length ? ( + {(itemsToSend?.length || itemsToReturn?.length) && typeof title === "string" ? ( { const { t } = useTranslation() @@ -756,7 +791,7 @@ const ReturnBody = ({ isCreated, isReceived, }: { - orderReturn: AdminReturn + orderReturn: ExtendedAdminReturn isCreated: boolean isReceived?: boolean }) => { @@ -785,7 +820,7 @@ const ReturnBody = ({ }) } - const numberOfItems = orderReturn.items.reduce((acc, item) => { + const numberOfItems = (orderReturn.items || []).reduce((acc, item) => { return acc + (isReceived ? item.received_quantity : item.quantity) // TODO: revisit when we add dismissed quantity on ReturnItem }, 0) @@ -817,8 +852,8 @@ const ClaimBody = ({ claim, claimReturn, }: { - claim: AdminClaim - claimReturn?: AdminReturn + claim: ExtendedAdminClaim + claimReturn?: ExtendedAdminReturn }) => { const prompt = usePrompt() const { t } = useTranslation() @@ -890,8 +925,8 @@ const ExchangeBody = ({ exchange, exchangeReturn, }: { - exchange: AdminExchange - exchangeReturn?: AdminReturn + exchange: ExtendedAdminExchange + exchangeReturn?: ExtendedAdminReturn }) => { const prompt = usePrompt() const { t } = useTranslation() @@ -962,7 +997,7 @@ const ExchangeBody = ({ ) } -const OrderEditBody = ({ edit }: { edit: AdminOrderChange }) => { +const OrderEditBody = ({ edit }: { edit: ExtendedAdminOrderChange }) => { const { t } = useTranslation() const [itemsAdded, itemsRemoved] = useMemo( @@ -990,7 +1025,7 @@ const OrderEditBody = ({ edit }: { edit: AdminOrderChange }) => { const TransferOrderRequestBody = ({ transfer, }: { - transfer: AdminOrderChange + transfer: ExtendedAdminOrderChange }) => { const prompt = usePrompt() const { t } = useTranslation() @@ -1028,7 +1063,7 @@ const TransferOrderRequestBody = ({ return (
- {t("orders.activity.from")}: {action.details?.original_email} + {t("orders.activity.from")}: {(action.details as { original_email?: string })?.original_email || ""} @@ -1054,7 +1089,7 @@ const TransferOrderRequestBody = ({ /** * Returns count of added and removed item quantity */ -function countItemsChange(actions: AdminOrderChange["actions"]) { +function countItemsChange(actions: ExtendedAdminOrderChange["actions"]) { let added = 0 let removed = 0 @@ -1079,7 +1114,7 @@ function countItemsChange(actions: AdminOrderChange["actions"]) { /** * Get IDs of missing line items that were removed from the order. */ -function getMissingLineItemIds(order: AdminOrder, changes: AdminOrderChange[]) { +function getMissingLineItemIds(order: ExtendedAdminOrder, changes: ExtendedAdminOrderChange[]) { if (!changes?.length) { return [] } @@ -1089,15 +1124,13 @@ function getMissingLineItemIds(order: AdminOrder, changes: AdminOrderChange[]) { changes.forEach((change) => { change.actions.forEach((action) => { - if (!action.details?.reference_id) { + const referenceId = action.details?.reference_id + if (!referenceId || typeof referenceId !== "string") { return } - if ( - (action.details.reference_id as string).startsWith("ordli_") && - !existingItemsMap.has(action.details.reference_id as string) - ) { - retIds.add(action.details.reference_id as string) + if (referenceId.startsWith("ordli_") && !existingItemsMap.has(referenceId)) { + retIds.add(referenceId) } }) }) diff --git a/src/routes/orders/order-detail/components/order-customer-section/order-customer-section.tsx b/src/routes/orders/order-detail/components/order-customer-section/order-customer-section.tsx index a0f2bbbc..bd796830 100644 --- a/src/routes/orders/order-detail/components/order-customer-section/order-customer-section.tsx +++ b/src/routes/orders/order-detail/components/order-customer-section/order-customer-section.tsx @@ -1,12 +1,12 @@ import { Container, Heading } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { ArrowPath, CurrencyDollar, Envelope, FlyingBox } from "@medusajs/icons" -import { ActionMenu } from "../../../../../components/common/action-menu" -import { CustomerInfo } from "../../../../../components/common/customer-info" -import { HttpTypes } from "@medusajs/types" +import { ActionMenu } from "@components/common/action-menu" +import { CustomerInfo } from "@components/common/customer-info" +import type{ ExtendedAdminOrder } from "@custom-types/order" type OrderCustomerSectionProps = { - order: HttpTypes.AdminOrder + order: ExtendedAdminOrder } export const OrderCustomerSection = ({ order }: OrderCustomerSectionProps) => { diff --git a/src/routes/orders/order-detail/components/order-fulfillment-section/order-fulfillment-section.tsx b/src/routes/orders/order-detail/components/order-fulfillment-section/order-fulfillment-section.tsx index 4c198bd3..cc8d10c8 100644 --- a/src/routes/orders/order-detail/components/order-fulfillment-section/order-fulfillment-section.tsx +++ b/src/routes/orders/order-detail/components/order-fulfillment-section/order-fulfillment-section.tsx @@ -1,11 +1,8 @@ import { Buildings, XCircle } from "@medusajs/icons" import { - AdminOrder, - AdminOrderFulfillment, AdminOrderLineItem, - HttpTypes, - OrderLineItemDTO, } from "@medusajs/types" +import { ExtendedAdminOrder, ExtendedAdminOrderFulfillment } from "@custom-types/order" import { Button, Container, @@ -33,7 +30,7 @@ import { getLocaleAmount } from "../../../../../lib/money-amount-helpers" import { FulfillmentSetType } from "../../../../locations/common/constants" type OrderFulfillmentSectionProps = { - order: AdminOrder + order: ExtendedAdminOrder } export const OrderFulfillmentSection = ({ @@ -55,7 +52,7 @@ const UnfulfilledItem = ({ item, currencyCode, }: { - item: OrderLineItemDTO & { variant: HttpTypes.AdminProductVariant } + item: AdminOrderLineItem currencyCode: string }) => { return ( @@ -101,7 +98,7 @@ const UnfulfilledItem = ({
- {getLocaleAmount(item.subtotal || 0, currencyCode)} + {getLocaleAmount(Number(item.subtotal || 0), currencyCode)}
@@ -109,7 +106,7 @@ const UnfulfilledItem = ({ ) } -const UnfulfilledItemBreakdown = ({ order }: { order: AdminOrder }) => { +const UnfulfilledItemBreakdown = ({ order }: { order: ExtendedAdminOrder }) => { // Create an array of order items that haven't been fulfilled or at least not fully fulfilled const unfulfilledItemsWithShipping = order.items!.filter( (i) => i.requires_shipping && i.detail.fulfilled_quantity < i.quantity @@ -145,7 +142,7 @@ const UnfulfilledItemDisplay = ({ unfulfilledItems, requiresShipping = false, }: { - order: AdminOrder + order: ExtendedAdminOrder unfulfilledItems: AdminOrderLineItem[] requiresShipping: boolean }) => { @@ -204,8 +201,8 @@ const Fulfillment = ({ order, index, }: { - fulfillment: AdminOrderFulfillment - order: AdminOrder + fulfillment: ExtendedAdminOrderFulfillment + order: ExtendedAdminOrder index: number }) => { const { t } = useTranslation() @@ -215,7 +212,7 @@ const Fulfillment = ({ const showLocation = !!fulfillment.location_id const isPickUpFulfillment = - fulfillment.shipping_option?.service_zone.fulfillment_set.type === + fulfillment.shipping_option?.service_zone?.fulfillment_set?.type === FulfillmentSetType.Pickup const { stock_location, isError, error } = useStockLocation( @@ -294,6 +291,7 @@ const Fulfillment = ({ const handleCancel = async () => { if (fulfillment.shipped_at) { toast.warning(t("orders.fulfillment.toast.fulfillmentShipped")) + return } @@ -365,8 +363,8 @@ const Fulfillment = ({ {t("orders.fulfillment.itemsLabel")}
    - {fulfillment.items.map((f_item) => ( -
  • + {fulfillment.items?.map((f_item) => ( +
  • {f_item.quantity}x {f_item.title} diff --git a/src/routes/orders/order-detail/components/order-general-section/order-general-section.tsx b/src/routes/orders/order-detail/components/order-general-section/order-general-section.tsx index 307aa818..2f9c032b 100644 --- a/src/routes/orders/order-detail/components/order-general-section/order-general-section.tsx +++ b/src/routes/orders/order-detail/components/order-general-section/order-general-section.tsx @@ -1,5 +1,4 @@ import { XCircle } from "@medusajs/icons" -import { HttpTypes } from "@medusajs/types" import { Container, Copy, @@ -18,9 +17,10 @@ import { getOrderFulfillmentStatus, getOrderPaymentStatus, } from "../../../../../lib/order-helpers" +import type { ExtendedAdminOrder } from "@custom-types/order" type OrderGeneralSectionProps = { - order: HttpTypes.AdminOrder + order: ExtendedAdminOrder } export const OrderGeneralSection = ({ order }: OrderGeneralSectionProps) => { @@ -93,7 +93,7 @@ export const OrderGeneralSection = ({ order }: OrderGeneralSectionProps) => { ) } -const FulfillmentBadge = ({ order }: { order: HttpTypes.AdminOrder }) => { +const FulfillmentBadge = ({ order }: { order: ExtendedAdminOrder }) => { const { t } = useTranslation() const { label, color } = getOrderFulfillmentStatus( @@ -108,7 +108,7 @@ const FulfillmentBadge = ({ order }: { order: HttpTypes.AdminOrder }) => { ) } -const PaymentBadge = ({ order }: { order: HttpTypes.AdminOrder }) => { +const PaymentBadge = ({ order }: { order: ExtendedAdminOrder }) => { const { t } = useTranslation() const { label, color } = getOrderPaymentStatus(t, order.payment_status) @@ -120,7 +120,7 @@ const PaymentBadge = ({ order }: { order: HttpTypes.AdminOrder }) => { ) } -const OrderBadge = ({ order }: { order: HttpTypes.AdminOrder }) => { +const OrderBadge = ({ order }: { order: ExtendedAdminOrder }) => { const { t } = useTranslation() const orderStatus = getCanceledOrderStatus(t, order.status) diff --git a/src/routes/orders/order-detail/components/order-payment-section/order-payment-section.tsx b/src/routes/orders/order-detail/components/order-payment-section/order-payment-section.tsx index b0037845..4c3125ed 100644 --- a/src/routes/orders/order-detail/components/order-payment-section/order-payment-section.tsx +++ b/src/routes/orders/order-detail/components/order-payment-section/order-payment-section.tsx @@ -1,5 +1,5 @@ import { ArrowDownRightMini, DocumentText, XCircle } from "@medusajs/icons" -import type { AdminOrder, AdminPayment, HttpTypes, OrderCreditLineDTO } from "@medusajs/types" +import type { AdminPayment, HttpTypes, OrderCreditLineDTO } from "@medusajs/types" import { Badge, Button, @@ -25,9 +25,10 @@ import { getOrderPaymentStatus } from "@lib/order-helpers" import { getPaymentsFromOrder } from "@lib/orders" import { getTotalCaptured, getTotalPending } from "@lib/payment" import { getLoyaltyPlugin } from "@lib/plugins" +import type { ExtendedAdminOrder, ExtendedAdminRefund } from "@custom-types/order" type OrderPaymentSectionProps = { - order: HttpTypes.AdminOrder + order: ExtendedAdminOrder plugins: HttpTypes.AdminPlugin[] } @@ -40,7 +41,7 @@ export const OrderPaymentSection = ({ const refunds = payments .map((payment) => payment?.refunds) .flat(1) - .filter(Boolean) as HttpTypes.AdminRefund[] + .filter(Boolean) as ExtendedAdminRefund[] return ( @@ -78,7 +79,7 @@ const Refund = ({ refund, currencyCode, }: { - refund: HttpTypes.AdminRefund + refund: ExtendedAdminRefund currencyCode: string }) => { const { t } = useTranslation() @@ -129,9 +130,9 @@ const Payment = ({ refunds, currencyCode, }: { - order: HttpTypes.AdminOrder + order: ExtendedAdminOrder payment: HttpTypes.AdminPayment - refunds: HttpTypes.AdminRefund[] + refunds: ExtendedAdminRefund[] currencyCode: string }) => { const { t } = useTranslation() @@ -360,9 +361,9 @@ const PaymentBreakdown = ({ currencyCode, plugins, }: { - order: HttpTypes.AdminOrder + order: ExtendedAdminOrder payments: HttpTypes.AdminPayment[] - refunds: HttpTypes.AdminRefund[] + refunds: ExtendedAdminRefund[] currencyCode: string plugins: HttpTypes.AdminPlugin[] }) => { @@ -392,7 +393,7 @@ const PaymentBreakdown = ({ return { event: entry, type } }) as ( | { type: "payment"; event: HttpTypes.AdminPayment } - | { type: "refund"; event: HttpTypes.AdminRefund } + | { type: "refund"; event: ExtendedAdminRefund } | { type: "credit_line_refund" event: OrderCreditLineDTO @@ -438,7 +439,7 @@ const PaymentBreakdown = ({ ) } -const Total = ({ order }: { order: AdminOrder }) => { +const Total = ({ order }: { order: ExtendedAdminOrder }) => { const { t } = useTranslation() const totalPending = getTotalPending(order.payment_collections) diff --git a/src/routes/orders/order-detail/components/order-remaining-orders-group-section/order-remaining-orders-group-section.tsx b/src/routes/orders/order-detail/components/order-remaining-orders-group-section/order-remaining-orders-group-section.tsx index 25afb965..c63fcf86 100644 --- a/src/routes/orders/order-detail/components/order-remaining-orders-group-section/order-remaining-orders-group-section.tsx +++ b/src/routes/orders/order-detail/components/order-remaining-orders-group-section/order-remaining-orders-group-section.tsx @@ -29,6 +29,7 @@ export const OrderRemainingOrdersGroupSection = () => { order.items.length > 1 ? `${order.items[0].subtitle} + ${order.items.length - 1} more` : order.items[0].subtitle; + return (