feat(dashboard): Cancel claims and exchanges (#8958)

**What**
- add "Cancel" functionality for claims and exchanges timeline events
This commit is contained in:
Frane Polić authored and GitHub committed 2024-09-03 12:54:44 +00:00
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"
} }
@@ -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
@@ -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>
@@ -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}>
@@ -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
@@ -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>
) )
} }