feat(dashboard): Cancel claims and exchanges (#8958)
**What** - add "Cancel" functionality for claims and exchanges timeline events
This commit is contained in:
1 parent
e49d004fef
commit
685779ec7d
6 files changed
+103
-18
No files matched your search
@@ -969,7 +969,6 @@
|
|||||||
"create": "Create Claim",
|
"create": "Create Claim",
|
||||||
"confirm": "Confirm Claim",
|
"confirm": "Confirm Claim",
|
||||||
"confirmText": "You are about to confirm a Claim. This action cannot be undone.",
|
"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",
|
||||||
@@ -983,6 +982,10 @@
|
|||||||
"successToast": "Claim was successfully canceled."
|
"successToast": "Claim was successfully canceled."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cancel": {
|
||||||
|
"title": "Cancel Claim",
|
||||||
|
"description": "Are you sure you want to cancel the claim?"
|
||||||
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"onlyReturnShippingOptions": "This list will consist of only return shipping options."
|
"onlyReturnShippingOptions": "This list will consist of only return shipping options."
|
||||||
},
|
},
|
||||||
@@ -1000,7 +1003,6 @@
|
|||||||
"manage": "Manage Exchange",
|
"manage": "Manage Exchange",
|
||||||
"confirm": "Confirm Exchange",
|
"confirm": "Confirm Exchange",
|
||||||
"confirmText": "You are about to confirm an Exchange. This action cannot be undone.",
|
"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",
|
||||||
@@ -1013,6 +1015,10 @@
|
|||||||
"successToast": "Exchange was successfully canceled."
|
"successToast": "Exchange was successfully canceled."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cancel": {
|
||||||
|
"title": "Cancel Exchange",
|
||||||
|
"description": "Are you sure you want to cancel the exchange?"
|
||||||
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"onlyReturnShippingOptions": "This list will consist of only return shipping options."
|
"onlyReturnShippingOptions": "This list will consist of only return shipping options."
|
||||||
},
|
},
|
||||||
@@ -1160,16 +1166,17 @@
|
|||||||
},
|
},
|
||||||
"claim": {
|
"claim": {
|
||||||
"created": "Claim #{{claimId}} requested",
|
"created": "Claim #{{claimId}} requested",
|
||||||
|
"canceled": "Claim #{{claimId}} canceled",
|
||||||
"itemsInbound": "{{count}} item to return",
|
"itemsInbound": "{{count}} item to return",
|
||||||
"itemsOutbound": "{{count}} item to send"
|
"itemsOutbound": "{{count}} item to send"
|
||||||
},
|
},
|
||||||
"exchange": {
|
"exchange": {
|
||||||
"created": "Exchange #{{exchangeId}} requested",
|
"created": "Exchange #{{exchangeId}} requested",
|
||||||
|
"canceled": "Exchange #{{exchangeId}} canceled",
|
||||||
"itemsInbound": "{{count}} item to return",
|
"itemsInbound": "{{count}} item to return",
|
||||||
"itemsOutbound": "{{count}} item to send"
|
"itemsOutbound": "{{count}} item to send"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
"requested": "Order edit #{{editId}} requested",
|
|
||||||
"requested": "Order edit #{{editId}} requested",
|
"requested": "Order edit #{{editId}} requested",
|
||||||
"confirmed": "Order edit #{{editId}} confirmed"
|
"confirmed": "Order edit #{{editId}} confirmed"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1003,7 +1003,7 @@ export const ClaimCreateForm = ({
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
{t("orders.claims.cancel")}
|
{t("orders.claims.cancel.title")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
+1
-1
@@ -522,7 +522,7 @@ export const ExchangeCreateForm = ({
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
{t("orders.exchanges.cancel")}
|
{t("orders.exchanges.cancel.title")}
|
||||||
</Button>
|
</Button>
|
||||||
</RouteFocusModal.Close>
|
</RouteFocusModal.Close>
|
||||||
|
|
||||||
|
|||||||
+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("orders.claims.cancel")}
|
{t("orders.claims.cancel.title")}
|
||||||
</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("orders.exchanges.cancel")}
|
{t("orders.exchanges.cancel.title")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
+89
-11
@@ -16,8 +16,11 @@ import {
|
|||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
|
||||||
import { AdminOrderLineItem } from "@medusajs/types"
|
import { AdminOrderLineItem } from "@medusajs/types"
|
||||||
import { useClaims } from "../../../../../hooks/api/claims"
|
import { useCancelClaim, useClaims } from "../../../../../hooks/api/claims"
|
||||||
import { useExchanges } from "../../../../../hooks/api/exchanges"
|
import {
|
||||||
|
useCancelExchange,
|
||||||
|
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 { useDate } from "../../../../../hooks/use-date"
|
||||||
import { getStylizedAmount } from "../../../../../lib/money-amount-helpers"
|
import { getStylizedAmount } from "../../../../../lib/money-amount-helpers"
|
||||||
@@ -283,10 +286,15 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
|
|||||||
const claimReturn = returnMap.get(claim.return_id!)
|
const claimReturn = returnMap.get(claim.return_id!)
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
title: t("orders.activity.events.claim.created", {
|
title: t(
|
||||||
claimId: claim.id.slice(-7),
|
claim.canceled_at
|
||||||
}),
|
? "orders.activity.events.claim.canceled"
|
||||||
timestamp: claim.created_at,
|
: "orders.activity.events.claim.created",
|
||||||
|
{
|
||||||
|
claimId: claim.id.slice(-7),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
timestamp: claim.canceled_at || claim.created_at,
|
||||||
itemsToSend: claim.additional_items,
|
itemsToSend: claim.additional_items,
|
||||||
itemsToReturn: claimReturn?.items,
|
itemsToReturn: claimReturn?.items,
|
||||||
itemsMap,
|
itemsMap,
|
||||||
@@ -298,10 +306,15 @@ const useActivityItems = (order: AdminOrder): Activity[] => {
|
|||||||
const exchangeReturn = returnMap.get(exchange.return_id!)
|
const exchangeReturn = returnMap.get(exchange.return_id!)
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
title: t("orders.activity.events.exchange.created", {
|
title: t(
|
||||||
exchangeId: exchange.id.slice(-7),
|
exchange.canceled_at
|
||||||
}),
|
? "orders.activity.events.exchange.canceled"
|
||||||
timestamp: exchange.created_at,
|
: "orders.activity.events.exchange.created",
|
||||||
|
{
|
||||||
|
exchangeId: exchange.id.slice(-7),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
timestamp: exchange.canceled_at || exchange.created_at,
|
||||||
itemsToSend: exchange.additional_items,
|
itemsToSend: exchange.additional_items,
|
||||||
itemsToReturn: exchangeReturn?.items,
|
itemsToReturn: exchangeReturn?.items,
|
||||||
itemsMap,
|
itemsMap,
|
||||||
@@ -428,7 +441,7 @@ const OrderActivityItem = ({
|
|||||||
<Text
|
<Text
|
||||||
size="small"
|
size="small"
|
||||||
leading="compact"
|
leading="compact"
|
||||||
className="text-ui-fg-subtle"
|
className="text-ui-fg-subtle text-right"
|
||||||
>
|
>
|
||||||
{getRelativeDate(timestamp)}
|
{getRelativeDate(timestamp)}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -647,8 +660,28 @@ const ClaimBody = ({
|
|||||||
claim: AdminClaim
|
claim: AdminClaim
|
||||||
claimReturn?: AdminReturn
|
claimReturn?: AdminReturn
|
||||||
}) => {
|
}) => {
|
||||||
|
const prompt = usePrompt()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const isCanceled = !!claim.created_at
|
||||||
|
|
||||||
|
const { mutateAsync: cancelClaim } = useCancelClaim(claim.id, claim.order_id)
|
||||||
|
|
||||||
|
const onCancel = async () => {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("orders.claims.cancel.title"),
|
||||||
|
description: t("orders.claims.cancel.description"),
|
||||||
|
confirmText: t("actions.confirm"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await cancelClaim()
|
||||||
|
}
|
||||||
|
|
||||||
const outboundItems = (claim.additional_items || []).reduce(
|
const outboundItems = (claim.additional_items || []).reduce(
|
||||||
(acc, item) => (acc + item.quantity) as number,
|
(acc, item) => (acc + item.quantity) as number,
|
||||||
0
|
0
|
||||||
@@ -676,6 +709,17 @@ const ClaimBody = ({
|
|||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{!isCanceled && (
|
||||||
|
<Button
|
||||||
|
onClick={onCancel}
|
||||||
|
className="text-ui-fg-subtle h-auto px-0 leading-none hover:bg-transparent"
|
||||||
|
variant="transparent"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{t("actions.cancel")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -687,8 +731,31 @@ const ExchangeBody = ({
|
|||||||
exchange: AdminExchange
|
exchange: AdminExchange
|
||||||
exchangeReturn?: AdminReturn
|
exchangeReturn?: AdminReturn
|
||||||
}) => {
|
}) => {
|
||||||
|
const prompt = usePrompt()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const isCanceled = !!exchange.canceled_at
|
||||||
|
|
||||||
|
const { mutateAsync: cancelExchange } = useCancelExchange(
|
||||||
|
exchange.id,
|
||||||
|
exchange.order_id
|
||||||
|
)
|
||||||
|
|
||||||
|
const onCancel = async () => {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("orders.exchanges.cancel.title"),
|
||||||
|
description: t("orders.exchanges.cancel.description"),
|
||||||
|
confirmText: t("actions.confirm"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await cancelExchange()
|
||||||
|
}
|
||||||
|
|
||||||
const outboundItems = (exchange.additional_items || []).reduce(
|
const outboundItems = (exchange.additional_items || []).reduce(
|
||||||
(acc, item) => (acc + item.quantity) as number,
|
(acc, item) => (acc + item.quantity) as number,
|
||||||
0
|
0
|
||||||
@@ -716,6 +783,17 @@ const ExchangeBody = ({
|
|||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{!isCanceled && (
|
||||||
|
<Button
|
||||||
|
onClick={onCancel}
|
||||||
|
className="text-ui-fg-subtle h-auto px-0 leading-none hover:bg-transparent"
|
||||||
|
variant="transparent"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{t("actions.cancel")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user