diff --git a/packages/admin-next/dashboard/src/i18n/translations/en.json b/packages/admin-next/dashboard/src/i18n/translations/en.json index b28791dc73..5e38b2f603 100644 --- a/packages/admin-next/dashboard/src/i18n/translations/en.json +++ b/packages/admin-next/dashboard/src/i18n/translations/en.json @@ -1039,7 +1039,8 @@ "payment": { "awaiting": "Awaiting payment", "captured": "Payment captured", - "canceled": "Payment canceled" + "canceled": "Payment canceled", + "refunded": "Payment refunded" }, "fulfillment": { "created": "Items fulfilled", @@ -1057,6 +1058,16 @@ "note": { "comment": "Comment", "byLine": "by {{author}}" + }, + "claim": { + "created": "Claim #{{claimId}} requested", + "itemsInbound": "{{count}} item to return", + "itemsOutbound": "{{count}} item to send" + }, + "exchange": { + "created": "Exchange #{{exchangeId}} requested", + "itemsInbound": "{{count}} item to return", + "itemsOutbound": "{{count}} item to send" } } } diff --git a/packages/admin-next/dashboard/src/routes/orders/order-detail/components/order-activity-section/order-timeline.tsx b/packages/admin-next/dashboard/src/routes/orders/order-detail/components/order-activity-section/order-timeline.tsx index c85b5b8789..9d72c9700c 100644 --- a/packages/admin-next/dashboard/src/routes/orders/order-detail/components/order-activity-section/order-timeline.tsx +++ b/packages/admin-next/dashboard/src/routes/orders/order-detail/components/order-activity-section/order-timeline.tsx @@ -5,12 +5,21 @@ import { PropsWithChildren, ReactNode, useMemo, useState } from "react" import { Link } from "react-router-dom" import { XMarkMini } from "@medusajs/icons" -import { AdminFulfillment, AdminOrder, AdminReturn } from "@medusajs/types" +import { + AdminClaim, + AdminExchange, + AdminFulfillment, + AdminOrder, + AdminReturn, +} from "@medusajs/types" import { useTranslation } from "react-i18next" +import { useClaims } from "../../../../../hooks/api/claims" +import { useExchanges } from "../../../../../hooks/api/exchanges" +import { useReturns } from "../../../../../hooks/api/returns" import { useDate } from "../../../../../hooks/use-date" import { getStylizedAmount } from "../../../../../lib/money-amount-helpers" -import { useReturns } from "../../../../../hooks/api/returns" +import { getPaymentsFromOrder } from "../order-payment-section" type OrderTimelineProps = { order: AdminOrder @@ -86,6 +95,18 @@ const useActivityItems = (order: AdminOrder) => { fields: "+received_at,*items", }) + const { claims = [] } = useClaims({ + order_id: order.id, + fields: "*additional_items", + }) + + const { exchanges = [] } = useExchanges({ + order_id: order.id, + fields: "*additional_items", + }) + + const payments = getPaymentsFromOrder(order) + const notes = [] const isLoading = false // const { notes, isLoading, isError, error } = useNotes( @@ -110,43 +131,60 @@ const useActivityItems = (order: AdminOrder) => { const items: Activity[] = [] - // for (const payment of order.payments) { - // items.push({ - // title: t("orders.activity.events.payment.awaiting"), - // timestamp: payment.created_at, - // children: ( - // - // {getStylizedAmount(payment.amount, payment.currency_code)} - // - // ), - // }) - // - // if (payment.canceled_at) { - // items.push({ - // title: t("orders.activity.events.payment.canceled"), - // timestamp: payment.canceled_at, - // children: ( - // - // {getStylizedAmount(payment.amount, payment.currency_code)} - // - // ), - // }) - // } - // - // if (payment.captured_at) { - // items.push({ - // title: t("orders.activity.events.payment.captured"), - // timestamp: payment.captured_at, - // children: ( - // - // {getStylizedAmount(payment.amount, payment.currency_code)} - // - // ), - // }) - // } - // } + for (const payment of payments) { + const amount = payment.amount as number - for (const fulfillment of order.fulfillments) { + items.push({ + title: t("orders.activity.events.payment.awaiting"), + timestamp: payment.created_at!, + children: ( + + {getStylizedAmount(amount, payment.currency_code)} + + ), + }) + + if (payment.canceled_at) { + items.push({ + title: t("orders.activity.events.payment.canceled"), + timestamp: payment.canceled_at, + children: ( + + {getStylizedAmount(amount, payment.currency_code)} + + ), + }) + } + + if (payment.captured_at) { + items.push({ + title: t("orders.activity.events.payment.captured"), + timestamp: payment.captured_at, + children: ( + + {getStylizedAmount(amount, payment.currency_code)} + + ), + }) + } + + for (const refund of payment.refunds || []) { + items.push({ + title: t("orders.activity.events.payment.refunded"), + timestamp: refund.created_at, + children: ( + + {getStylizedAmount( + refund.amount as number, + payment.currency_code + )} + + ), + }) + } + } + + for (const fulfillment of order.fulfillments || []) { items.push({ title: t("orders.activity.events.fulfillment.created"), timestamp: fulfillment.created_at, @@ -171,7 +209,15 @@ const useActivityItems = (order: AdminOrder) => { } } + const returnMap = new Map() + for (const ret of returns) { + returnMap.set(ret.id, ret) + + if (ret.claim_id || ret.exchange_id) { + continue + } + // Always display created action items.push({ title: t("orders.activity.events.return.created", { @@ -192,6 +238,32 @@ const useActivityItems = (order: AdminOrder) => { } } + for (const claim of claims) { + const claimReturn = returnMap.get(claim.return_id!) + + items.push({ + title: t("orders.activity.events.claim.created", { + claimId: claim.id.slice(-7), + }), + timestamp: claim.created_at, + children: , + }) + } + + for (const exchange of exchanges) { + const exchangeReturn = returnMap.get(exchange.return_id!) + + items.push({ + title: t("orders.activity.events.exchange.created", { + exchangeId: exchange.id.slice(-7), + }), + timestamp: exchange.created_at, + children: ( + + ), + }) + } + // for (const note of notes || []) { // items.push({ // title: t("orders.activity.events.note.comment"), @@ -431,3 +503,83 @@ const ReturnBody = ({ orderReturn }: { orderReturn: AdminReturn }) => { ) } + +const ClaimBody = ({ + claim, + claimReturn, +}: { + claim: AdminClaim + claimReturn?: AdminReturn +}) => { + const { t } = useTranslation() + + const outboundItems = (claim.additional_items || []).reduce( + (acc, item) => (acc + item.quantity) as number, + 0 + ) + + const inboundItems = (claimReturn?.items || []).reduce( + (acc, item) => acc + item.quantity, + 0 + ) + + return ( +
+ {outboundItems > 0 && ( + + {t("orders.activity.events.claim.itemsInbound", { + count: outboundItems, + })} + + )} + + {inboundItems > 0 && ( + + {t("orders.activity.events.claim.itemsOutbound", { + count: inboundItems, + })} + + )} +
+ ) +} + +const ExchangeBody = ({ + exchange, + exchangeReturn, +}: { + exchange: AdminExchange + exchangeReturn?: AdminReturn +}) => { + const { t } = useTranslation() + + const outboundItems = (exchange.additional_items || []).reduce( + (acc, item) => (acc + item.quantity) as number, + 0 + ) + + const inboundItems = (exchangeReturn?.items || []).reduce( + (acc, item) => acc + item.quantity, + 0 + ) + + return ( +
+ {outboundItems > 0 && ( + + {t("orders.activity.events.exchange.itemsInbound", { + count: outboundItems, + })} + + )} + + {inboundItems > 0 && ( + + {t("orders.activity.events.exchange.itemsOutbound", { + count: inboundItems, + })} + + )} +
+ ) +}