fix(dashboard,js-sdk): fixes from rma flows testing (#8826)
This commit is contained in:
1 parent
2ee374fafc
commit
c72b4847b9
15 files changed
+335
-30
No files matched your search
@@ -848,6 +848,9 @@
|
|||||||
},
|
},
|
||||||
"edits": {
|
"edits": {
|
||||||
"title": "Edit order",
|
"title": "Edit order",
|
||||||
|
"confirm": "Confirm Edit",
|
||||||
|
"confirmText": "You are about to confirm an Order Edit. This action cannot be undone.",
|
||||||
|
"cancel": "Cancel Edit",
|
||||||
"currentItems": "Current items",
|
"currentItems": "Current items",
|
||||||
"currentItemsDescription": "Adjust item quantity or remove.",
|
"currentItemsDescription": "Adjust item quantity or remove.",
|
||||||
"addItemsDescription": "You can add new items to the order.",
|
"addItemsDescription": "You can add new items to the order.",
|
||||||
@@ -874,6 +877,8 @@
|
|||||||
},
|
},
|
||||||
"returns": {
|
"returns": {
|
||||||
"create": "Create Return",
|
"create": "Create Return",
|
||||||
|
"confirm": "Confirm Return",
|
||||||
|
"confirmText": "You are about to confirm a Return. This action cannot be undone.",
|
||||||
"inbound": "Inbound",
|
"inbound": "Inbound",
|
||||||
"outbound": "Outbound",
|
"outbound": "Outbound",
|
||||||
"sendNotification": "Send notification",
|
"sendNotification": "Send notification",
|
||||||
@@ -903,7 +908,7 @@
|
|||||||
},
|
},
|
||||||
"receive": {
|
"receive": {
|
||||||
"action": "Receive items",
|
"action": "Receive items",
|
||||||
"receive": "Return {{label}}",
|
"receiveItems": "{{ returnType }} {{ id }}",
|
||||||
"restockAll": "Restock all items",
|
"restockAll": "Restock all items",
|
||||||
"itemsLabel": "Items received",
|
"itemsLabel": "Items received",
|
||||||
"title": "Receive items for #{{returnId}}",
|
"title": "Receive items for #{{returnId}}",
|
||||||
@@ -928,6 +933,9 @@
|
|||||||
},
|
},
|
||||||
"claims": {
|
"claims": {
|
||||||
"create": "Create Claim",
|
"create": "Create Claim",
|
||||||
|
"confirm": "Confirm Claim",
|
||||||
|
"confirmText": "You are about to confirm a Claim. This action cannot be undone.",
|
||||||
|
"cancel": "Cancel Claim",
|
||||||
"manage": "Manage Claim",
|
"manage": "Manage Claim",
|
||||||
"outbound": "Outbound",
|
"outbound": "Outbound",
|
||||||
"outboundItemAdded": "{{itemsCount}}x added through claim",
|
"outboundItemAdded": "{{itemsCount}}x added through claim",
|
||||||
@@ -956,6 +964,9 @@
|
|||||||
"exchanges": {
|
"exchanges": {
|
||||||
"create": "Create Exchange",
|
"create": "Create Exchange",
|
||||||
"manage": "Manage Exchange",
|
"manage": "Manage Exchange",
|
||||||
|
"confirm": "Confirm Exchange",
|
||||||
|
"confirmText": "You are about to confirm an Exchange. This action cannot be undone.",
|
||||||
|
"cancel": "Cancel Exchange",
|
||||||
"outbound": "Outbound",
|
"outbound": "Outbound",
|
||||||
"outboundItemAdded": "{{itemsCount}}x added through exchange",
|
"outboundItemAdded": "{{itemsCount}}x added through exchange",
|
||||||
"outboundTotal": "Outbound total",
|
"outboundTotal": "Outbound total",
|
||||||
@@ -1003,7 +1014,7 @@
|
|||||||
"shipment": {
|
"shipment": {
|
||||||
"title": "Mark fulfillment shipped",
|
"title": "Mark fulfillment shipped",
|
||||||
"trackingNumber": "Tracking number",
|
"trackingNumber": "Tracking number",
|
||||||
"addTracking": "Add additional tracking number",
|
"addTracking": "Add tracking number",
|
||||||
"sendNotification": "Send notification",
|
"sendNotification": "Send notification",
|
||||||
"sendNotificationHint": "Notify the customer about this shipment.",
|
"sendNotificationHint": "Notify the customer about this shipment.",
|
||||||
"toastCreated": "Shipment created successfully."
|
"toastCreated": "Shipment created successfully."
|
||||||
@@ -1078,6 +1089,10 @@
|
|||||||
"deleteButtonText": "Delete comment"
|
"deleteButtonText": "Delete comment"
|
||||||
},
|
},
|
||||||
"events": {
|
"events": {
|
||||||
|
"common": {
|
||||||
|
"toReturn": "To return",
|
||||||
|
"toSend": "To send"
|
||||||
|
},
|
||||||
"placed": {
|
"placed": {
|
||||||
"title": "Order placed",
|
"title": "Order placed",
|
||||||
"fromSalesChannel": "from {{salesChannel}}"
|
"fromSalesChannel": "from {{salesChannel}}"
|
||||||
|
|||||||
+19
-2
@@ -15,6 +15,7 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Text,
|
Text,
|
||||||
toast,
|
toast,
|
||||||
|
usePrompt,
|
||||||
} from "@medusajs/ui"
|
} from "@medusajs/ui"
|
||||||
import { useEffect, useMemo, useState } from "react"
|
import { useEffect, useMemo, useState } from "react"
|
||||||
import { useFieldArray, useForm } from "react-hook-form"
|
import { useFieldArray, useForm } from "react-hook-form"
|
||||||
@@ -305,8 +306,21 @@ export const ClaimCreateForm = ({
|
|||||||
|
|
||||||
const showInboundItemsPlaceholder = !inboundItems.length
|
const showInboundItemsPlaceholder = !inboundItems.length
|
||||||
const shippingOptionId = form.watch("inbound_option_id")
|
const shippingOptionId = form.watch("inbound_option_id")
|
||||||
|
const prompt = usePrompt()
|
||||||
|
|
||||||
const handleSubmit = form.handleSubmit(async (data) => {
|
const handleSubmit = form.handleSubmit(async (data) => {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("general.areYouSure"),
|
||||||
|
description: t("orders.claims.confirmText"),
|
||||||
|
confirmText: t("actions.continue"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
variant: "confirmation",
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await confirmClaimRequest(
|
await confirmClaimRequest(
|
||||||
{ no_notification: !data.send_notification },
|
{ no_notification: !data.send_notification },
|
||||||
{
|
{
|
||||||
@@ -518,6 +532,7 @@ export const ClaimCreateForm = ({
|
|||||||
{t("actions.cancel")}
|
{t("actions.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
key="submit-button"
|
key="submit-button"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -859,6 +874,8 @@ export const ClaimCreateForm = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="p-8" />
|
||||||
</div>
|
</div>
|
||||||
</RouteFocusModal.Body>
|
</RouteFocusModal.Body>
|
||||||
<RouteFocusModal.Footer>
|
<RouteFocusModal.Footer>
|
||||||
@@ -871,7 +888,7 @@ export const ClaimCreateForm = ({
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
{t("actions.cancel")}
|
{t("orders.claims.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
<Button
|
<Button
|
||||||
@@ -881,7 +898,7 @@ export const ClaimCreateForm = ({
|
|||||||
size="small"
|
size="small"
|
||||||
isLoading={isRequestLoading}
|
isLoading={isRequestLoading}
|
||||||
>
|
>
|
||||||
{t("actions.save")}
|
{t("orders.claims.confirm")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+21
-5
@@ -1,6 +1,6 @@
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
import { zodResolver } from "@hookform/resolvers/zod"
|
||||||
import { AdminOrder, AdminOrderPreview } from "@medusajs/types"
|
import { AdminOrder, AdminOrderPreview } from "@medusajs/types"
|
||||||
import { Button, Heading, Input, Switch, toast } from "@medusajs/ui"
|
import { Button, Heading, Input, Switch, toast, usePrompt } from "@medusajs/ui"
|
||||||
import { useForm } from "react-hook-form"
|
import { useForm } from "react-hook-form"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
|
||||||
@@ -10,13 +10,13 @@ import {
|
|||||||
} from "../../../../../components/modals"
|
} from "../../../../../components/modals"
|
||||||
|
|
||||||
import { Form } from "../../../../../components/common/form"
|
import { Form } from "../../../../../components/common/form"
|
||||||
import { getStylizedAmount } from "../../../../../lib/money-amount-helpers"
|
|
||||||
import { CreateOrderEditSchemaType, OrderEditCreateSchema } from "./schema"
|
|
||||||
import {
|
import {
|
||||||
useCancelOrderEdit,
|
useCancelOrderEdit,
|
||||||
useRequestOrderEdit,
|
useRequestOrderEdit,
|
||||||
} from "../../../../../hooks/api/order-edits"
|
} from "../../../../../hooks/api/order-edits"
|
||||||
|
import { getStylizedAmount } from "../../../../../lib/money-amount-helpers"
|
||||||
import { OrderEditItemsSection } from "./order-edit-items-section"
|
import { OrderEditItemsSection } from "./order-edit-items-section"
|
||||||
|
import { CreateOrderEditSchemaType, OrderEditCreateSchema } from "./schema"
|
||||||
|
|
||||||
type ReturnCreateFormProps = {
|
type ReturnCreateFormProps = {
|
||||||
order: AdminOrder
|
order: AdminOrder
|
||||||
@@ -55,8 +55,22 @@ export const OrderEditCreateForm = ({
|
|||||||
resolver: zodResolver(OrderEditCreateSchema),
|
resolver: zodResolver(OrderEditCreateSchema),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const prompt = usePrompt()
|
||||||
|
|
||||||
const handleSubmit = form.handleSubmit(async (data) => {
|
const handleSubmit = form.handleSubmit(async (data) => {
|
||||||
try {
|
try {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("general.areYouSure"),
|
||||||
|
description: t("orders.edits.confirmText"),
|
||||||
|
confirmText: t("actions.continue"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
variant: "confirmation",
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await requestOrderEdit()
|
await requestOrderEdit()
|
||||||
|
|
||||||
toast.success(t("orders.edits.createSuccessToast"))
|
toast.success(t("orders.edits.createSuccessToast"))
|
||||||
@@ -185,6 +199,8 @@ export const OrderEditCreateForm = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="p-8" />
|
||||||
</div>
|
</div>
|
||||||
</RouteFocusModal.Body>
|
</RouteFocusModal.Body>
|
||||||
<RouteFocusModal.Footer>
|
<RouteFocusModal.Footer>
|
||||||
@@ -192,7 +208,7 @@ export const OrderEditCreateForm = ({
|
|||||||
<div className="flex items-center justify-end gap-x-2">
|
<div className="flex items-center justify-end gap-x-2">
|
||||||
<RouteFocusModal.Close asChild>
|
<RouteFocusModal.Close asChild>
|
||||||
<Button type="button" variant="secondary" size="small">
|
<Button type="button" variant="secondary" size="small">
|
||||||
{t("actions.cancel")}
|
{t("orders.edits.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
<Button
|
<Button
|
||||||
@@ -202,7 +218,7 @@ export const OrderEditCreateForm = ({
|
|||||||
size="small"
|
size="small"
|
||||||
isLoading={isRequestRunning}
|
isLoading={isRequestRunning}
|
||||||
>
|
>
|
||||||
{t("actions.save")}
|
{t("orders.edits.confirm")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+19
-2
@@ -8,6 +8,7 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
Switch,
|
Switch,
|
||||||
toast,
|
toast,
|
||||||
|
usePrompt,
|
||||||
} from "@medusajs/ui"
|
} from "@medusajs/ui"
|
||||||
import { useEffect, useMemo, useState } from "react"
|
import { useEffect, useMemo, useState } from "react"
|
||||||
import { useForm } from "react-hook-form"
|
import { useForm } from "react-hook-form"
|
||||||
@@ -148,9 +149,22 @@ export const ExchangeCreateForm = ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const shippingOptionId = form.watch("inbound_option_id")
|
const shippingOptionId = form.watch("inbound_option_id")
|
||||||
|
const prompt = usePrompt()
|
||||||
|
|
||||||
const handleSubmit = form.handleSubmit(async (data) => {
|
const handleSubmit = form.handleSubmit(async (data) => {
|
||||||
try {
|
try {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("general.areYouSure"),
|
||||||
|
description: t("orders.exchanges.confirmText"),
|
||||||
|
confirmText: t("actions.continue"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
variant: "confirmation",
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await confirmExchangeRequest({ no_notification: !data.send_notification })
|
await confirmExchangeRequest({ no_notification: !data.send_notification })
|
||||||
|
|
||||||
handleSuccess()
|
handleSuccess()
|
||||||
@@ -390,6 +404,8 @@ export const ExchangeCreateForm = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="p-8" />
|
||||||
</div>
|
</div>
|
||||||
</RouteFocusModal.Body>
|
</RouteFocusModal.Body>
|
||||||
<RouteFocusModal.Footer>
|
<RouteFocusModal.Footer>
|
||||||
@@ -402,9 +418,10 @@ export const ExchangeCreateForm = ({
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
{t("actions.cancel")}
|
{t("orders.exchanges.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
key="submit-button"
|
key="submit-button"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -412,7 +429,7 @@ export const ExchangeCreateForm = ({
|
|||||||
size="small"
|
size="small"
|
||||||
isLoading={isRequestLoading}
|
isLoading={isRequestLoading}
|
||||||
>
|
>
|
||||||
{t("actions.save")}
|
{t("orders.exchanges.confirm")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+18
-2
@@ -10,6 +10,7 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Text,
|
Text,
|
||||||
toast,
|
toast,
|
||||||
|
usePrompt,
|
||||||
} from "@medusajs/ui"
|
} from "@medusajs/ui"
|
||||||
import { useEffect, useMemo, useState } from "react"
|
import { useEffect, useMemo, useState } from "react"
|
||||||
import { useFieldArray, useForm } from "react-hook-form"
|
import { useFieldArray, useForm } from "react-hook-form"
|
||||||
@@ -240,9 +241,22 @@ export const ReturnCreateForm = ({
|
|||||||
const showPlaceholder = !items.length
|
const showPlaceholder = !items.length
|
||||||
const locationId = form.watch("location_id")
|
const locationId = form.watch("location_id")
|
||||||
const shippingOptionId = form.watch("option_id")
|
const shippingOptionId = form.watch("option_id")
|
||||||
|
const prompt = usePrompt()
|
||||||
|
|
||||||
const handleSubmit = form.handleSubmit(async (data) => {
|
const handleSubmit = form.handleSubmit(async (data) => {
|
||||||
try {
|
try {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("general.areYouSure"),
|
||||||
|
description: t("orders.returns.confirmText"),
|
||||||
|
confirmText: t("actions.continue"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
variant: "confirmation",
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await confirmReturnRequest({ no_notification: !data.send_notification })
|
await confirmReturnRequest({ no_notification: !data.send_notification })
|
||||||
|
|
||||||
handleSuccess()
|
handleSuccess()
|
||||||
@@ -702,6 +716,8 @@ export const ReturnCreateForm = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="p-8" />
|
||||||
</div>
|
</div>
|
||||||
</RouteFocusModal.Body>
|
</RouteFocusModal.Body>
|
||||||
<RouteFocusModal.Footer>
|
<RouteFocusModal.Footer>
|
||||||
@@ -709,7 +725,7 @@ export const ReturnCreateForm = ({
|
|||||||
<div className="flex items-center justify-end gap-x-2">
|
<div className="flex items-center justify-end gap-x-2">
|
||||||
<RouteFocusModal.Close asChild>
|
<RouteFocusModal.Close asChild>
|
||||||
<Button type="button" variant="secondary" size="small">
|
<Button type="button" variant="secondary" size="small">
|
||||||
{t("actions.cancel")}
|
{t("orders.returns.cancel.title")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
<Button
|
<Button
|
||||||
@@ -719,7 +735,7 @@ export const ReturnCreateForm = ({
|
|||||||
size="small"
|
size="small"
|
||||||
isLoading={isRequestLoading}
|
isLoading={isRequestLoading}
|
||||||
>
|
>
|
||||||
{t("actions.save")}
|
{t("orders.returns.confirm")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ export const ActiveOrderClaimSection = ({
|
|||||||
|
|
||||||
<div className="flex items-center justify-end gap-x-2 rounded-b-xl px-4 py-4">
|
<div className="flex items-center justify-end gap-x-2 rounded-b-xl px-4 py-4">
|
||||||
<Button size="small" variant="secondary" onClick={onCancelClaim}>
|
<Button size="small" variant="secondary" onClick={onCancelClaim}>
|
||||||
{t("actions.cancel")}
|
{t("orders.claims.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button size="small" variant="secondary" onClick={onContinueClaim}>
|
<Button size="small" variant="secondary" onClick={onContinueClaim}>
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ export const ActiveOrderExchangeSection = ({
|
|||||||
|
|
||||||
<div className="flex items-center justify-end gap-x-2 rounded-b-xl px-4 py-4">
|
<div className="flex items-center justify-end gap-x-2 rounded-b-xl px-4 py-4">
|
||||||
<Button size="small" variant="secondary" onClick={onCancelExchange}>
|
<Button size="small" variant="secondary" onClick={onCancelExchange}>
|
||||||
{t("actions.cancel")}
|
{t("orders.exchanges.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ export const ActiveOrderReturnSection = ({
|
|||||||
|
|
||||||
<div className="flex items-center justify-end gap-x-2 rounded-b-xl px-4 py-4">
|
<div className="flex items-center justify-end gap-x-2 rounded-b-xl px-4 py-4">
|
||||||
<Button size="small" variant="secondary" onClick={onCancelReturn}>
|
<Button size="small" variant="secondary" onClick={onCancelReturn}>
|
||||||
{t("actions.cancel")}
|
{t("orders.returns.cancel.title")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button size="small" variant="secondary" onClick={onContinueReturn}>
|
<Button size="small" variant="secondary" onClick={onContinueReturn}>
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ const CopyPaymentLink = React.forwardRef<any, CopyPaymentLinkProps>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setText("CopyPaymentLink")
|
setText("Copy")
|
||||||
}, 500)
|
}, 500)
|
||||||
}, [done])
|
}, [done])
|
||||||
|
|
||||||
|
|||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
type ActivityItemsProps = {
|
||||||
|
itemsToSend?:
|
||||||
|
| AdminClaim["additional_items"]
|
||||||
|
| AdminExchange["additional_items"]
|
||||||
|
itemsToReturn?: AdminReturn["items"]
|
||||||
|
itemsMap?: Map<string, AdminOrderLineItem>
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function ActivityItems(props: ActivityItemsProps) {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
const itemsToSend = props.itemsToSend
|
||||||
|
const itemsToReturn = props.itemsToReturn
|
||||||
|
const itemsMap = props.itemsMap
|
||||||
|
const title = props.title
|
||||||
|
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
setOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!itemsToSend?.length && !itemsToReturn?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover open={open}>
|
||||||
|
<Popover.Trigger
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
autoFocus={false}
|
||||||
|
>
|
||||||
|
<Text size="small" leading="compact" weight="plus">
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</Popover.Trigger>
|
||||||
|
|
||||||
|
<Popover.Content
|
||||||
|
align="center"
|
||||||
|
side="top"
|
||||||
|
className="bg-ui-bg-component p-0"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
{!!itemsToSend?.length && (
|
||||||
|
<div className="p-3">
|
||||||
|
<div className="txt-compact-small-plus">
|
||||||
|
{t("orders.activity.events.common.toSend")}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
{itemsToSend?.map((item) => {
|
||||||
|
const originalItem = itemsMap?.get(item.item_id)!
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-1 items-center gap-x-3"
|
||||||
|
key={item.id}
|
||||||
|
>
|
||||||
|
<Text size="small" className="text-ui-fg-subtle">
|
||||||
|
{item.quantity}x
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Thumbnail
|
||||||
|
src={originalItem?.variant?.product?.thumbnail}
|
||||||
|
/>
|
||||||
|
<div className="">
|
||||||
|
<Text className="txt-compact-small text-ui-fg-subtle">
|
||||||
|
{`${originalItem?.variant?.title} · ${originalItem?.variant?.product?.title}`}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div className="flex flex-1 flex-row items-center gap-2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!!itemsToReturn?.length && (
|
||||||
|
<div className="border-t-2 border-dotted p-3">
|
||||||
|
<div className="txt-compact-small-plus">
|
||||||
|
{t("orders.activity.events.common.toReturn")}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
{itemsToReturn?.map((item) => {
|
||||||
|
const originalItem = itemsMap?.get(item.item_id)!
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-1 items-center gap-x-3"
|
||||||
|
key={item.id}
|
||||||
|
>
|
||||||
|
<Text size="small" className="text-ui-fg-subtle">
|
||||||
|
{item.quantity}x
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Thumbnail
|
||||||
|
src={originalItem?.variant?.product?.thumbnail}
|
||||||
|
/>
|
||||||
|
<div className="">
|
||||||
|
<Text className="txt-compact-small text-ui-fg-subtle">
|
||||||
|
{`${originalItem?.variant?.title} · ${originalItem?.variant?.product?.title}`}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div className="flex flex-1 flex-row items-center gap-2"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Popover.Content>
|
||||||
|
</Popover>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ActivityItems
|
||||||
+58
-6
@@ -1,4 +1,4 @@
|
|||||||
import { IconButton, Text, Tooltip, clx, usePrompt, Button } from "@medusajs/ui"
|
import { Button, IconButton, Text, Tooltip, clx, usePrompt } from "@medusajs/ui"
|
||||||
import * as Collapsible from "@radix-ui/react-collapsible"
|
import * as Collapsible from "@radix-ui/react-collapsible"
|
||||||
|
|
||||||
import { PropsWithChildren, ReactNode, useMemo, useState } from "react"
|
import { PropsWithChildren, ReactNode, useMemo, useState } from "react"
|
||||||
@@ -14,12 +14,14 @@ import {
|
|||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
|
||||||
|
import { AdminOrderLineItem } from "@medusajs/types"
|
||||||
import { useClaims } from "../../../../../hooks/api/claims"
|
import { useClaims } from "../../../../../hooks/api/claims"
|
||||||
import { useExchanges } from "../../../../../hooks/api/exchanges"
|
import { useExchanges } from "../../../../../hooks/api/exchanges"
|
||||||
import { useCancelReturn, useReturns } from "../../../../../hooks/api/returns"
|
import { useCancelReturn, useReturns } from "../../../../../hooks/api/returns"
|
||||||
|
import { useDate } from "../../../../../hooks/use-date"
|
||||||
import { getStylizedAmount } from "../../../../../lib/money-amount-helpers"
|
import { getStylizedAmount } from "../../../../../lib/money-amount-helpers"
|
||||||
import { getPaymentsFromOrder } from "../order-payment-section"
|
import { getPaymentsFromOrder } from "../order-payment-section"
|
||||||
import { useDate } from "../../../../../hooks/use-date"
|
import ActivityItems from "./activity-items"
|
||||||
|
|
||||||
type OrderTimelineProps = {
|
type OrderTimelineProps = {
|
||||||
order: AdminOrder
|
order: AdminOrder
|
||||||
@@ -43,6 +45,9 @@ export const OrderTimeline = ({ order }: OrderTimelineProps) => {
|
|||||||
title={item.title}
|
title={item.title}
|
||||||
timestamp={item.timestamp}
|
timestamp={item.timestamp}
|
||||||
isFirst={index === items.length - 1}
|
isFirst={index === items.length - 1}
|
||||||
|
itemsToSend={item.itemsToSend}
|
||||||
|
itemsToReturn={item.itemsToReturn}
|
||||||
|
itemsMap={item.itemsMap}
|
||||||
>
|
>
|
||||||
{item.children}
|
{item.children}
|
||||||
</OrderActivityItem>
|
</OrderActivityItem>
|
||||||
@@ -64,6 +69,9 @@ export const OrderTimeline = ({ order }: OrderTimelineProps) => {
|
|||||||
key={index}
|
key={index}
|
||||||
title={item.title}
|
title={item.title}
|
||||||
timestamp={item.timestamp}
|
timestamp={item.timestamp}
|
||||||
|
itemsToSend={item.itemsToSend}
|
||||||
|
itemsToReturn={item.itemsToReturn}
|
||||||
|
itemsMap={item.itemsMap}
|
||||||
>
|
>
|
||||||
{item.children}
|
{item.children}
|
||||||
</OrderActivityItem>
|
</OrderActivityItem>
|
||||||
@@ -74,6 +82,9 @@ export const OrderTimeline = ({ order }: OrderTimelineProps) => {
|
|||||||
title={firstItem.title}
|
title={firstItem.title}
|
||||||
timestamp={firstItem.timestamp}
|
timestamp={firstItem.timestamp}
|
||||||
isFirst
|
isFirst
|
||||||
|
itemsToSend={firstItem.itemsToSend}
|
||||||
|
itemsToReturn={firstItem.itemsToReturn}
|
||||||
|
itemsMap={firstItem.itemsMap}
|
||||||
>
|
>
|
||||||
{firstItem.children}
|
{firstItem.children}
|
||||||
</OrderActivityItem>
|
</OrderActivityItem>
|
||||||
@@ -85,10 +96,20 @@ type Activity = {
|
|||||||
title: string
|
title: string
|
||||||
timestamp: string | Date
|
timestamp: string | Date
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
|
itemsToSend?: (
|
||||||
|
| AdminClaim["additional_items"]
|
||||||
|
| AdminExchange["additional_items"]
|
||||||
|
)[]
|
||||||
|
itemsToReturn?: AdminReturn["items"]
|
||||||
|
itemsMap?: Map<string, AdminOrderLineItem>
|
||||||
}
|
}
|
||||||
|
|
||||||
const useActivityItems = (order: AdminOrder) => {
|
const useActivityItems = (order: AdminOrder): Activity[] => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const itemsMap = useMemo(
|
||||||
|
() => new Map(order?.items?.map((i) => [i.id, i])),
|
||||||
|
[order.items]
|
||||||
|
)
|
||||||
|
|
||||||
const { returns = [] } = useReturns({
|
const { returns = [] } = useReturns({
|
||||||
order_id: order.id,
|
order_id: order.id,
|
||||||
@@ -224,6 +245,8 @@ const useActivityItems = (order: AdminOrder) => {
|
|||||||
returnId: ret.id.slice(-7),
|
returnId: ret.id.slice(-7),
|
||||||
}),
|
}),
|
||||||
timestamp: ret.created_at,
|
timestamp: ret.created_at,
|
||||||
|
itemsToReturn: ret?.items,
|
||||||
|
itemsMap,
|
||||||
children: <ReturnBody orderReturn={ret} isCreated={!ret.canceled_at} />,
|
children: <ReturnBody orderReturn={ret} isCreated={!ret.canceled_at} />,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -242,6 +265,8 @@ const useActivityItems = (order: AdminOrder) => {
|
|||||||
returnId: ret.id.slice(-7),
|
returnId: ret.id.slice(-7),
|
||||||
}),
|
}),
|
||||||
timestamp: ret.received_at,
|
timestamp: ret.received_at,
|
||||||
|
itemsToReturn: ret?.items,
|
||||||
|
itemsMap,
|
||||||
children: <ReturnBody orderReturn={ret} isReceived />,
|
children: <ReturnBody orderReturn={ret} isReceived />,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -255,6 +280,9 @@ const useActivityItems = (order: AdminOrder) => {
|
|||||||
claimId: claim.id.slice(-7),
|
claimId: claim.id.slice(-7),
|
||||||
}),
|
}),
|
||||||
timestamp: claim.created_at,
|
timestamp: claim.created_at,
|
||||||
|
itemsToSend: claim.additional_items,
|
||||||
|
itemsToReturn: claimReturn?.items,
|
||||||
|
itemsMap,
|
||||||
children: <ClaimBody claim={claim} claimReturn={claimReturn} />,
|
children: <ClaimBody claim={claim} claimReturn={claimReturn} />,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -267,6 +295,9 @@ const useActivityItems = (order: AdminOrder) => {
|
|||||||
exchangeId: exchange.id.slice(-7),
|
exchangeId: exchange.id.slice(-7),
|
||||||
}),
|
}),
|
||||||
timestamp: exchange.created_at,
|
timestamp: exchange.created_at,
|
||||||
|
itemsToSend: exchange.additional_items,
|
||||||
|
itemsToReturn: exchangeReturn?.items,
|
||||||
|
itemsMap,
|
||||||
children: (
|
children: (
|
||||||
<ExchangeBody exchange={exchange} exchangeReturn={exchangeReturn} />
|
<ExchangeBody exchange={exchange} exchangeReturn={exchangeReturn} />
|
||||||
),
|
),
|
||||||
@@ -310,6 +341,11 @@ type OrderActivityItemProps = PropsWithChildren<{
|
|||||||
title: string
|
title: string
|
||||||
timestamp: string | Date
|
timestamp: string | Date
|
||||||
isFirst?: boolean
|
isFirst?: boolean
|
||||||
|
itemsToSend?:
|
||||||
|
| AdminClaim["additional_items"]
|
||||||
|
| AdminExchange["additional_items"]
|
||||||
|
itemsToReturn?: AdminReturn["items"]
|
||||||
|
itemsMap?: Map<string, AdminOrderLineItem>
|
||||||
}>
|
}>
|
||||||
|
|
||||||
const OrderActivityItem = ({
|
const OrderActivityItem = ({
|
||||||
@@ -317,6 +353,9 @@ const OrderActivityItem = ({
|
|||||||
timestamp,
|
timestamp,
|
||||||
isFirst = false,
|
isFirst = false,
|
||||||
children,
|
children,
|
||||||
|
itemsToSend,
|
||||||
|
itemsToReturn,
|
||||||
|
itemsMap,
|
||||||
}: OrderActivityItemProps) => {
|
}: OrderActivityItemProps) => {
|
||||||
const { getFullDate, getRelativeDate } = useDate()
|
const { getFullDate, getRelativeDate } = useDate()
|
||||||
|
|
||||||
@@ -336,9 +375,19 @@ const OrderActivityItem = ({
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Text size="small" leading="compact" weight="plus">
|
{itemsToSend?.length || itemsToReturn?.length ? (
|
||||||
{title}
|
<ActivityItems
|
||||||
</Text>
|
key={title}
|
||||||
|
title={title}
|
||||||
|
itemsToSend={itemsToSend}
|
||||||
|
itemsToReturn={itemsToReturn}
|
||||||
|
itemsMap={itemsMap}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text size="small" leading="compact" weight="plus">
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
{timestamp && (
|
{timestamp && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={getFullDate({ date: timestamp, includeTime: true })}
|
content={getFullDate({ date: timestamp, includeTime: true })}
|
||||||
@@ -403,6 +452,9 @@ const OrderActivityCollapsible = ({
|
|||||||
key={index}
|
key={index}
|
||||||
title={item.title}
|
title={item.title}
|
||||||
timestamp={item.timestamp}
|
timestamp={item.timestamp}
|
||||||
|
itemsToSend={item.itemsToSend}
|
||||||
|
itemsToReturn={item.itemsToReturn}
|
||||||
|
itemsMap={item.itemsMap}
|
||||||
>
|
>
|
||||||
{item.children}
|
{item.children}
|
||||||
</OrderActivityItem>
|
</OrderActivityItem>
|
||||||
|
|||||||
+24
-7
@@ -191,13 +191,29 @@ export const OrderSummarySection = ({ order }: OrderSummarySectionProps) => {
|
|||||||
<ButtonMenu
|
<ButtonMenu
|
||||||
groups={[
|
groups={[
|
||||||
{
|
{
|
||||||
actions: receivableReturns.map((r) => ({
|
actions: receivableReturns.map((r) => {
|
||||||
label: t("orders.returns.receive.receive", {
|
let id = r.id
|
||||||
label: `#${r.id.slice(-7)}`,
|
let returnType = "Return"
|
||||||
}),
|
|
||||||
icon: <ArrowLongRight />,
|
if (r.exchange_id) {
|
||||||
to: `/orders/${order.id}/returns/${r.id}/receive`,
|
id = r.exchange_id
|
||||||
})),
|
returnType = "Exchange"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.claim_id) {
|
||||||
|
id = r.claim_id
|
||||||
|
returnType = "Claim"
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: t("orders.returns.receive.receiveItems", {
|
||||||
|
id: `#${id.slice(-7)}`,
|
||||||
|
returnType,
|
||||||
|
}),
|
||||||
|
icon: <ArrowLongRight />,
|
||||||
|
to: `/orders/${order.id}/returns/${r.id}/receive`,
|
||||||
|
}
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
@@ -640,6 +656,7 @@ const ClaimBreakdown = ({
|
|||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<ArrowDownRightMini className="text-ui-fg-muted" />
|
<ArrowDownRightMini className="text-ui-fg-muted" />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
{t(`orders.claims.outboundItemAdded`, {
|
{t(`orders.claims.outboundItemAdded`, {
|
||||||
itemsCount: items.reduce(
|
itemsCount: items.reduce(
|
||||||
|
|||||||
@@ -34,6 +34,22 @@ export const OrderDetail = () => {
|
|||||||
initialData,
|
initialData,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: Retrieve endpoints don't have an order ability, so a JS sort until this is available
|
||||||
|
if (order) {
|
||||||
|
order.items = order.items.sort((itemA, itemB) => {
|
||||||
|
if (itemA.created_at > itemB.created_at) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemA.created_at < itemB.created_at) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const { order: orderPreview, isLoading: isPreviewLoading } = useOrderPreview(
|
const { order: orderPreview, isLoading: isPreviewLoading } = useOrderPreview(
|
||||||
id!
|
id!
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export class Order {
|
|||||||
return await this.client.fetch<HttpTypes.AdminOrderPreviewResponse>(
|
return await this.client.fetch<HttpTypes.AdminOrderPreviewResponse>(
|
||||||
`/admin/orders/${id}/preview`,
|
`/admin/orders/${id}/preview`,
|
||||||
{
|
{
|
||||||
|
query,
|
||||||
headers,
|
headers,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ export interface AdminOrder extends BaseOrder {
|
|||||||
fulfillments?: BaseOrderFulfillment[]
|
fulfillments?: BaseOrderFulfillment[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AdminOrderLineItem extends BaseOrderLineItem {}
|
||||||
|
|
||||||
export interface AdminOrderFulfillment extends BaseOrderFulfillment {}
|
export interface AdminOrderFulfillment extends BaseOrderFulfillment {}
|
||||||
|
|
||||||
export interface AdminOrderLineItem extends BaseOrderLineItem {}
|
export interface AdminOrderLineItem extends BaseOrderLineItem {}
|
||||||
|
|||||||
Reference in new issue
Block a user