@spree/seller-dashboard 6.0.3 → 6.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -23
- package/src/api-client.ts +2 -0
- package/src/components/account-dialog.tsx +1 -1
- package/src/components/centered-message.tsx +1 -1
- package/src/components/finance/balance-summary.tsx +1 -1
- package/src/components/orders/fulfillment-deliveries.tsx +1 -1
- package/src/components/orders/fulfillments-card.tsx +30 -20
- package/src/components/orders/order-cards.tsx +115 -102
- package/src/components/orders/order-payment-card.tsx +2 -3
- package/src/components/orders/post-sale-cards.tsx +79 -47
- package/src/components/orders/post-sale-create-dialogs.tsx +15 -0
- package/src/components/orders/returns-card.tsx +44 -36
- package/src/components/orders/shipping-label-row.tsx +1 -1
- package/src/components/orders/use-product-link.tsx +10 -0
- package/src/components/product-status-card.tsx +2 -2
- package/src/components/seller-address-card.tsx +2 -2
- package/src/components/seller-returns-location-card.tsx +2 -7
- package/src/components/seller-switcher.tsx +1 -1
- package/src/hooks/use-fulfillments.ts +33 -22
- package/src/hooks/use-profile.ts +38 -0
- package/src/locales/ar.json +35 -31
- package/src/locales/de.json +35 -31
- package/src/locales/en.json +35 -31
- package/src/locales/fr.json +35 -31
- package/src/locales/ja.json +35 -31
- package/src/locales/pl.json +35 -31
- package/src/locales/vi.json +35 -31
- package/src/locales/zh-CN.json +35 -31
- package/src/nav/default.ts +0 -10
- package/src/nav/settings.ts +53 -0
- package/src/pages/delivery-methods.tsx +47 -49
- package/src/pages/forgot-password.tsx +5 -5
- package/src/pages/general-settings.tsx +233 -0
- package/src/pages/home.tsx +1 -1
- package/src/pages/login.tsx +3 -3
- package/src/pages/onboarding.tsx +26 -23
- package/src/pages/order.tsx +2 -1
- package/src/pages/orders.tsx +8 -15
- package/src/pages/payout.tsx +7 -4
- package/src/pages/payouts.tsx +23 -2
- package/src/pages/policies.tsx +12 -8
- package/src/pages/product.tsx +18 -4
- package/src/pages/products.tsx +0 -4
- package/src/pages/profile-settings.tsx +221 -0
- package/src/pages/reset-password.tsx +3 -3
- package/src/pages/seller-picker.tsx +1 -1
- package/src/pages/taxes.tsx +40 -0
- package/src/pages/team.tsx +1 -1
- package/src/routeTree.gen.ts +63 -0
- package/src/routes/_authenticated/$sellerId/profile.tsx +5 -3
- package/src/routes/_authenticated/$sellerId/settings/general.tsx +6 -0
- package/src/routes/_authenticated/$sellerId/settings/profile.tsx +6 -0
- package/src/routes/_authenticated/$sellerId/settings/taxes.tsx +6 -0
- package/src/routes/_authenticated/$sellerId/settings.tsx +3 -7
- package/src/schemas/account.ts +1 -1
- package/src/tables/products.tsx +6 -5
- package/src/components/read-row.tsx +0 -16
- package/src/components/seller-business-card.tsx +0 -152
- package/src/pages/profile.tsx +0 -395
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spree/seller-dashboard",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Spree marketplace seller panel — the seller-facing counterpart to the admin dashboard.",
|
|
@@ -36,44 +36,44 @@
|
|
|
36
36
|
"LICENSE"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@hookform/resolvers": "^
|
|
40
|
-
"@tanstack/router-plugin": "^1.
|
|
39
|
+
"@hookform/resolvers": "^7.0.5",
|
|
40
|
+
"@tanstack/router-plugin": "^1.169.0",
|
|
41
41
|
"@tanstack/virtual-file-routes": "^1.162.0",
|
|
42
42
|
"zod": "^4.6.7",
|
|
43
|
-
"@spree/
|
|
44
|
-
"@spree/
|
|
43
|
+
"@spree/seller-sdk": "6.0.4",
|
|
44
|
+
"@spree/core": "^6.0.4"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@tanstack/react-query": "^5.104.5",
|
|
48
|
-
"@tanstack/react-router": "^1.170.
|
|
49
|
-
"i18next": "^26.5.3",
|
|
48
|
+
"@tanstack/react-router": "^1.170.46",
|
|
49
|
+
"i18next": "^26.5.3 || ^27.0.0",
|
|
50
50
|
"react": "^19.3.1",
|
|
51
51
|
"react-dom": "^19.3.1",
|
|
52
52
|
"react-hook-form": "^7.90.0",
|
|
53
|
-
"react-i18next": "^17.1.0",
|
|
54
|
-
"@spree/dashboard-core": "^6.0.
|
|
55
|
-
"@spree/
|
|
56
|
-
"@spree/
|
|
53
|
+
"react-i18next": "^17.1.0 || ^18.0.0",
|
|
54
|
+
"@spree/dashboard-core": "^6.0.4",
|
|
55
|
+
"@spree/admin-sdk": "^6.0.4",
|
|
56
|
+
"@spree/dashboard-ui": "^6.0.4"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@biomejs/biome": "^2.
|
|
60
|
-
"@tanstack/react-query": "^5.
|
|
61
|
-
"@tanstack/react-router": "^1.170.
|
|
62
|
-
"@types/node": "^26.6.
|
|
59
|
+
"@biomejs/biome": "^2.6.6",
|
|
60
|
+
"@tanstack/react-query": "^5.107.1",
|
|
61
|
+
"@tanstack/react-router": "^1.170.46",
|
|
62
|
+
"@types/node": "^26.6.6",
|
|
63
63
|
"@types/react": "^19.2.14",
|
|
64
64
|
"@types/react-dom": "^19.2.3",
|
|
65
|
-
"@vitejs/plugin-react": "^6.0
|
|
66
|
-
"i18next": "^
|
|
65
|
+
"@vitejs/plugin-react": "^6.3.0",
|
|
66
|
+
"i18next": "^27.1.1",
|
|
67
67
|
"react": "^19.3.1",
|
|
68
68
|
"react-dom": "^19.3.1",
|
|
69
|
-
"react-hook-form": "^7.
|
|
70
|
-
"react-i18next": "^
|
|
69
|
+
"react-hook-form": "^7.91.0",
|
|
70
|
+
"react-i18next": "^18.0.1",
|
|
71
71
|
"tsup": "^9.0.0",
|
|
72
72
|
"typescript": "~7.0.2",
|
|
73
|
-
"vite": "^8.3.
|
|
74
|
-
"@spree/
|
|
75
|
-
"@spree/
|
|
76
|
-
"@spree/dashboard-ui": "6.0.
|
|
73
|
+
"vite": "^8.3.7",
|
|
74
|
+
"@spree/admin-sdk": "6.0.4",
|
|
75
|
+
"@spree/dashboard-core": "6.0.4",
|
|
76
|
+
"@spree/dashboard-ui": "6.0.4"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"build": "pnpm generate:routes && tsup",
|
package/src/api-client.ts
CHANGED
|
@@ -146,6 +146,8 @@ export function createSellerApiClient({
|
|
|
146
146
|
update: (id, params) => sellerClient().packageTypes.update(id, params),
|
|
147
147
|
delete: (id) => sellerClient().packageTypes.delete(id),
|
|
148
148
|
},
|
|
149
|
+
deleteProductMedia: (productId, mediaId) =>
|
|
150
|
+
sellerClient().products.media.delete(productId, mediaId),
|
|
149
151
|
digitalAssets: {
|
|
150
152
|
list: (productId, params) => sellerClient().products.digitalAssets.list(productId, params),
|
|
151
153
|
// Sellers upload files only, so a file is the one thing a new asset must carry.
|
|
@@ -175,7 +175,7 @@ function AccountForm({
|
|
|
175
175
|
<form onSubmit={form.handleSubmit(onSubmit)} className="contents">
|
|
176
176
|
<DialogBody className="flex flex-col gap-4">
|
|
177
177
|
{errors.root?.message && (
|
|
178
|
-
<p className="text-destructive text-
|
|
178
|
+
<p className="text-destructive text-base" role="alert">
|
|
179
179
|
{errors.root.message}
|
|
180
180
|
</p>
|
|
181
181
|
)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Full-height placeholder for the panel's loading and error states. */
|
|
2
2
|
export function CenteredMessage({ children }: { children: React.ReactNode }) {
|
|
3
3
|
return (
|
|
4
|
-
<div className="flex min-h-screen items-center justify-center text-muted-foreground text-
|
|
4
|
+
<div className="flex min-h-screen items-center justify-center text-muted-foreground text-base">
|
|
5
5
|
{children}
|
|
6
6
|
</div>
|
|
7
7
|
)
|
|
@@ -51,7 +51,7 @@ export function BalanceSummary({ balances }: { balances: Balance[] }) {
|
|
|
51
51
|
</CardHeader>
|
|
52
52
|
<CardContent className="flex flex-col gap-3">
|
|
53
53
|
<span className="text-2xl font-semibold tabular-nums">{held(balance.balance)}</span>
|
|
54
|
-
<dl className="flex flex-col gap-1 text-
|
|
54
|
+
<dl className="flex flex-col gap-1 text-base">
|
|
55
55
|
<Figure label={t('earnings.balance.earned')} value={sold(balance.earned)} />
|
|
56
56
|
{balance.converted && (
|
|
57
57
|
<Figure label={t('earnings.balance.payable')} value={held(balance.payable)} />
|
|
@@ -50,7 +50,7 @@ export function FulfillmentDeliveries({
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
return (
|
|
53
|
-
<CardContent className="flex flex-col gap-2 border-border-subtle border-b py-3 text-
|
|
53
|
+
<CardContent className="mx-4 px-0 flex flex-col gap-2 border-border-subtle border-b py-3.5 text-base">
|
|
54
54
|
{deliveries.map((delivery) => (
|
|
55
55
|
<div key={delivery.id} className="flex flex-wrap items-center justify-between gap-2">
|
|
56
56
|
<div className="flex min-w-0 flex-wrap items-center gap-2">
|
|
@@ -4,11 +4,8 @@ import {
|
|
|
4
4
|
Badge,
|
|
5
5
|
Button,
|
|
6
6
|
Card,
|
|
7
|
-
CardAction,
|
|
8
7
|
CardContent,
|
|
9
8
|
CardFooter,
|
|
10
|
-
CardHeader,
|
|
11
|
-
CardTitle,
|
|
12
9
|
DropdownMenu,
|
|
13
10
|
DropdownMenuContent,
|
|
14
11
|
DropdownMenuItem,
|
|
@@ -16,6 +13,10 @@ import {
|
|
|
16
13
|
DropdownMenuTrigger,
|
|
17
14
|
FulfillmentItemList,
|
|
18
15
|
FulfillmentPanel,
|
|
16
|
+
Section,
|
|
17
|
+
SectionActions,
|
|
18
|
+
SectionHeader,
|
|
19
|
+
SectionTitle,
|
|
19
20
|
StatusBadge,
|
|
20
21
|
useConfirm,
|
|
21
22
|
} from '@spree/dashboard-ui'
|
|
@@ -41,6 +42,7 @@ import { FulfillmentFulfillForm } from './fulfillment-fulfill-form'
|
|
|
41
42
|
import { FulfillmentLabelUploadDialog } from './fulfillment-label-upload-dialog'
|
|
42
43
|
import { FulfillmentSplitDialog } from './fulfillment-split-dialog'
|
|
43
44
|
import { ShippingLabelRow } from './shipping-label-row'
|
|
45
|
+
import { useProductLink } from './use-product-link'
|
|
44
46
|
|
|
45
47
|
// A parcel that has not gone out is the only one still to ship or cancel.
|
|
46
48
|
// Reading these off "not unfulfilled" once badged a canceled parcel as a
|
|
@@ -54,14 +56,14 @@ export function FulfillmentsCard({ order }: { order: Order }) {
|
|
|
54
56
|
const fulfillments = order.fulfillments ?? []
|
|
55
57
|
|
|
56
58
|
return (
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
<
|
|
59
|
+
<Section>
|
|
60
|
+
<SectionHeader>
|
|
61
|
+
<SectionTitle>
|
|
60
62
|
<TruckIcon className="size-4" />
|
|
61
63
|
{t('orders.fulfillments.title')}
|
|
62
64
|
{fulfillments.length > 0 && <Badge variant="outline">{fulfillments.length}</Badge>}
|
|
63
|
-
</
|
|
64
|
-
<
|
|
65
|
+
</SectionTitle>
|
|
66
|
+
<SectionActions>
|
|
65
67
|
{order.fulfillment_status && (
|
|
66
68
|
<StatusBadge
|
|
67
69
|
status={order.fulfillment_status}
|
|
@@ -70,25 +72,30 @@ export function FulfillmentsCard({ order }: { order: Order }) {
|
|
|
70
72
|
})}
|
|
71
73
|
/>
|
|
72
74
|
)}
|
|
73
|
-
</
|
|
74
|
-
</
|
|
75
|
+
</SectionActions>
|
|
76
|
+
</SectionHeader>
|
|
75
77
|
|
|
76
78
|
{fulfillments.length === 0 ? (
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
|
|
79
|
+
<Card>
|
|
80
|
+
<CardContent>
|
|
81
|
+
<p className="py-8 text-center text-muted-foreground">
|
|
82
|
+
{t('orders.fulfillments.empty')}
|
|
83
|
+
</p>
|
|
84
|
+
</CardContent>
|
|
85
|
+
</Card>
|
|
80
86
|
) : (
|
|
81
|
-
<
|
|
87
|
+
<div className="flex flex-col gap-4">
|
|
82
88
|
{fulfillments.map((fulfillment) => (
|
|
83
89
|
<FulfillmentRow key={fulfillment.id} order={order} fulfillment={fulfillment} />
|
|
84
90
|
))}
|
|
85
|
-
</
|
|
91
|
+
</div>
|
|
86
92
|
)}
|
|
87
|
-
</
|
|
93
|
+
</Section>
|
|
88
94
|
)
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
function FulfillmentRow({ order, fulfillment }: { order: Order; fulfillment: Fulfillment }) {
|
|
98
|
+
const productLink = useProductLink()
|
|
92
99
|
const orderId = order.id
|
|
93
100
|
const { t } = useTranslation()
|
|
94
101
|
const confirm = useConfirm()
|
|
@@ -187,7 +194,7 @@ function FulfillmentRow({ order, fulfillment }: { order: Order; fulfillment: Ful
|
|
|
187
194
|
}
|
|
188
195
|
>
|
|
189
196
|
{fulfillment.delivery_method_name && (
|
|
190
|
-
<CardContent className="flex items-center justify-between border-border-subtle border-b py-3 text-
|
|
197
|
+
<CardContent className="mx-4 px-0 flex items-center justify-between border-border-subtle border-b py-3.5 text-base">
|
|
191
198
|
<span className="text-muted-foreground">{fulfillment.delivery_method_name}</span>
|
|
192
199
|
</CardContent>
|
|
193
200
|
)}
|
|
@@ -214,10 +221,13 @@ function FulfillmentRow({ order, fulfillment }: { order: Order; fulfillment: Ful
|
|
|
214
221
|
/>
|
|
215
222
|
) : (
|
|
216
223
|
<>
|
|
217
|
-
<FulfillmentItemList
|
|
224
|
+
<FulfillmentItemList
|
|
225
|
+
productLink={productLink}
|
|
226
|
+
rows={fulfillmentItemRows(fulfillment, order.items ?? [])}
|
|
227
|
+
/>
|
|
218
228
|
|
|
219
229
|
{shippable && (
|
|
220
|
-
<CardFooter className="justify-end gap-2 py-3">
|
|
230
|
+
<CardFooter className="justify-end gap-2 py-3.5">
|
|
221
231
|
<Button type="button" size="sm" onClick={() => setFulfilling(true)}>
|
|
222
232
|
<TruckIcon data-icon="inline-start" />
|
|
223
233
|
{t('orders.fulfill')}
|
|
@@ -226,7 +236,7 @@ function FulfillmentRow({ order, fulfillment }: { order: Order; fulfillment: Ful
|
|
|
226
236
|
)}
|
|
227
237
|
|
|
228
238
|
{!shippable && deliveries.length === 0 && (
|
|
229
|
-
<CardFooter className="justify-end gap-2 py-3">
|
|
239
|
+
<CardFooter className="justify-end gap-2 py-3.5">
|
|
230
240
|
<Button
|
|
231
241
|
type="button"
|
|
232
242
|
size="sm"
|
|
@@ -11,16 +11,21 @@ import {
|
|
|
11
11
|
Button,
|
|
12
12
|
Card,
|
|
13
13
|
CardAction,
|
|
14
|
+
CardContent,
|
|
14
15
|
CardHeader,
|
|
15
16
|
CardTitle,
|
|
17
|
+
CurrencyLabel,
|
|
16
18
|
cn,
|
|
17
19
|
DropdownMenu,
|
|
18
20
|
DropdownMenuContent,
|
|
19
21
|
DropdownMenuItem,
|
|
20
22
|
DropdownMenuTrigger,
|
|
23
|
+
Section,
|
|
24
|
+
SectionHeader,
|
|
25
|
+
SectionTitle,
|
|
21
26
|
Separator,
|
|
22
27
|
} from '@spree/dashboard-ui'
|
|
23
|
-
import { EllipsisVerticalIcon, PencilIcon } from '@spree/dashboard-ui/icons'
|
|
28
|
+
import { EllipsisVerticalIcon, PencilIcon, ReceiptTextIcon } from '@spree/dashboard-ui/icons'
|
|
24
29
|
import type { Order, OrderAddressParams } from '@spree/seller-sdk'
|
|
25
30
|
import { type ReactNode, useState } from 'react'
|
|
26
31
|
import { useTranslation } from 'react-i18next'
|
|
@@ -33,21 +38,17 @@ function SummaryRow({
|
|
|
33
38
|
value,
|
|
34
39
|
bold,
|
|
35
40
|
danger,
|
|
36
|
-
highlight,
|
|
37
41
|
}: {
|
|
38
42
|
label: string
|
|
39
43
|
value: ReactNode
|
|
40
44
|
bold?: boolean
|
|
41
45
|
danger?: boolean
|
|
42
|
-
highlight?: boolean
|
|
43
46
|
}) {
|
|
44
47
|
return (
|
|
45
|
-
<div
|
|
46
|
-
className={
|
|
47
|
-
>
|
|
48
|
-
<span className="text-sm">{label}</span>
|
|
48
|
+
<div className="flex items-center justify-between py-3 first:pt-0 last:pb-0">
|
|
49
|
+
<span className="text-base">{label}</span>
|
|
49
50
|
<span
|
|
50
|
-
className={cn('text-
|
|
51
|
+
className={cn('text-base tabular-nums', bold && 'font-bold', danger && 'text-destructive')}
|
|
51
52
|
>
|
|
52
53
|
{value}
|
|
53
54
|
</span>
|
|
@@ -84,87 +85,96 @@ export function OrderSummaryCard({ order }: { order: Order }) {
|
|
|
84
85
|
const placed = Boolean(order.completed_at)
|
|
85
86
|
|
|
86
87
|
return (
|
|
87
|
-
<
|
|
88
|
-
<
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/>
|
|
97
|
-
{order.completed_at && (
|
|
88
|
+
<Section>
|
|
89
|
+
<SectionHeader>
|
|
90
|
+
<SectionTitle>
|
|
91
|
+
<ReceiptTextIcon className="size-4" />
|
|
92
|
+
{t('orders.summary.title')}
|
|
93
|
+
</SectionTitle>
|
|
94
|
+
</SectionHeader>
|
|
95
|
+
<Card>
|
|
96
|
+
<CardContent className="flex flex-col">
|
|
98
97
|
<SummaryRow
|
|
99
|
-
label={t('orders.summary.
|
|
100
|
-
value={formatDate(order.
|
|
98
|
+
label={t('orders.summary.created_at')}
|
|
99
|
+
value={formatDate(order.created_at, timezone)}
|
|
101
100
|
/>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{order.canceled_at && (
|
|
105
|
-
<>
|
|
106
|
-
<Separator />
|
|
101
|
+
{order.completed_at && (
|
|
107
102
|
<SummaryRow
|
|
108
|
-
label={t('orders.summary.
|
|
109
|
-
value={formatDate(order.
|
|
103
|
+
label={t('orders.summary.completed_at')}
|
|
104
|
+
value={formatDate(order.completed_at, timezone)}
|
|
110
105
|
/>
|
|
111
|
-
|
|
106
|
+
)}
|
|
107
|
+
|
|
108
|
+
{order.canceled_at && (
|
|
109
|
+
<>
|
|
110
|
+
<Separator />
|
|
112
111
|
<SummaryRow
|
|
113
|
-
label={t('orders.summary.
|
|
114
|
-
value={order.
|
|
112
|
+
label={t('orders.summary.canceled_at')}
|
|
113
|
+
value={formatDate(order.canceled_at, timezone)}
|
|
115
114
|
/>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
115
|
+
{order.cancel_reason_name && (
|
|
116
|
+
<SummaryRow
|
|
117
|
+
label={t('orders.summary.cancel_reason')}
|
|
118
|
+
value={order.cancel_reason_name}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
{order.cancel_note && (
|
|
122
|
+
<SummaryRow label={t('orders.summary.cancel_note')} value={order.cancel_note} />
|
|
123
|
+
)}
|
|
124
|
+
</>
|
|
125
|
+
)}
|
|
122
126
|
|
|
123
|
-
|
|
127
|
+
<Separator />
|
|
124
128
|
|
|
125
|
-
|
|
129
|
+
<SummaryRow
|
|
130
|
+
label={t('orders.summary.currency')}
|
|
131
|
+
value={<CurrencyLabel code={order.currency} />}
|
|
132
|
+
/>
|
|
126
133
|
|
|
127
|
-
|
|
134
|
+
<Separator />
|
|
128
135
|
|
|
129
|
-
|
|
136
|
+
<SummaryRow label={t('orders.summary.subtotal')} value={money(order.item_total)} />
|
|
130
137
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
138
|
+
{isPositiveMoney(order.delivery_total) && (
|
|
139
|
+
<SummaryRow label={t('orders.summary.shipping')} value={money(order.delivery_total)} />
|
|
140
|
+
)}
|
|
134
141
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
142
|
+
{!isZeroMoney(order.discount_total) && (
|
|
143
|
+
<SummaryRow
|
|
144
|
+
label={t('orders.summary.promotions')}
|
|
145
|
+
value={money(order.discount_total)}
|
|
146
|
+
/>
|
|
147
|
+
)}
|
|
138
148
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
{!isZeroMoney(order.adjustment_total) && (
|
|
150
|
+
<SummaryRow
|
|
151
|
+
label={t('orders.summary.adjustments')}
|
|
152
|
+
value={money(order.adjustment_total)}
|
|
153
|
+
/>
|
|
154
|
+
)}
|
|
145
155
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
{isPositiveMoney(order.included_tax_total) && (
|
|
157
|
+
<SummaryRow
|
|
158
|
+
label={t('orders.summary.tax_included')}
|
|
159
|
+
value={money(order.included_tax_total)}
|
|
160
|
+
/>
|
|
161
|
+
)}
|
|
152
162
|
|
|
153
|
-
|
|
163
|
+
{/* Shown on a placed order even at zero, so "no tax was charged" reads
|
|
154
164
|
as an answer rather than a missing row. */}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
{(isPositiveMoney(order.additional_tax_total) ||
|
|
166
|
+
(placed && isZeroMoney(order.included_tax_total))) && (
|
|
167
|
+
<SummaryRow
|
|
168
|
+
label={t('orders.summary.tax_additional')}
|
|
169
|
+
value={money(order.additional_tax_total)}
|
|
170
|
+
/>
|
|
171
|
+
)}
|
|
162
172
|
|
|
163
|
-
|
|
173
|
+
<Separator />
|
|
164
174
|
|
|
165
|
-
|
|
175
|
+
<SummaryRow label={t('orders.summary.total')} value={money(order.total)} bold />
|
|
166
176
|
|
|
167
|
-
|
|
177
|
+
{/* What the marketplace charged the seller on this sale. Below the
|
|
168
178
|
order total because it is not part of what the buyer paid — it is
|
|
169
179
|
billed to the seller separately.
|
|
170
180
|
|
|
@@ -180,45 +190,48 @@ export function OrderSummaryCard({ order }: { order: Order }) {
|
|
|
180
190
|
Shown on every placed order, including one whose fee came to
|
|
181
191
|
zero: a zero-rated or exempt rate is an answer the seller needs,
|
|
182
192
|
and every order here is a seller's by definition. */}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
{placed && (
|
|
194
|
+
<>
|
|
195
|
+
<Separator />
|
|
186
196
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
<SummaryRow
|
|
198
|
+
label={t('orders.summary.commission_fee')}
|
|
199
|
+
value={money(order.commission_amount_total)}
|
|
200
|
+
/>
|
|
201
|
+
|
|
202
|
+
{isPositiveMoney(order.commission_tax_total) && (
|
|
203
|
+
<SummaryRow
|
|
204
|
+
label={t('orders.summary.commission_tax')}
|
|
205
|
+
value={money(order.commission_tax_total)}
|
|
206
|
+
/>
|
|
207
|
+
)}
|
|
191
208
|
|
|
192
|
-
{isPositiveMoney(order.commission_tax_total) && (
|
|
193
209
|
<SummaryRow
|
|
194
|
-
label={t('orders.summary.
|
|
195
|
-
value={money(order.
|
|
210
|
+
label={t('orders.summary.commission_total')}
|
|
211
|
+
value={money(order.commission_total)}
|
|
212
|
+
bold
|
|
196
213
|
/>
|
|
197
|
-
|
|
214
|
+
</>
|
|
215
|
+
)}
|
|
198
216
|
|
|
199
|
-
|
|
200
|
-
label={t('orders.summary.commission_total')}
|
|
201
|
-
value={money(order.commission_total)}
|
|
202
|
-
bold
|
|
203
|
-
/>
|
|
204
|
-
</>
|
|
205
|
-
)}
|
|
217
|
+
<Separator />
|
|
206
218
|
|
|
207
|
-
|
|
219
|
+
{/* What has been paid and what is still owed, set apart together. */}
|
|
208
220
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
<div className="-mx-2 rounded-lg bg-accent/50 px-2 py-3">
|
|
222
|
+
<SummaryRow
|
|
223
|
+
label={t('orders.summary.payment_total')}
|
|
224
|
+
value={money(order.payment_total)}
|
|
225
|
+
/>
|
|
226
|
+
<SummaryRow
|
|
227
|
+
label={t('orders.summary.outstanding_balance')}
|
|
228
|
+
value={money(order.amount_due)}
|
|
229
|
+
danger={outstanding}
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
</CardContent>
|
|
233
|
+
</Card>
|
|
234
|
+
</Section>
|
|
222
235
|
)
|
|
223
236
|
}
|
|
224
237
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatMoney, useMoneyLocale } from '@spree/dashboard-core'
|
|
1
|
+
import { formatMoney, ReadRow, useMoneyLocale } from '@spree/dashboard-core'
|
|
2
2
|
import {
|
|
3
3
|
Card,
|
|
4
4
|
CardAction,
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
import { CreditCardIcon } from '@spree/dashboard-ui/icons'
|
|
18
18
|
import type { Order } from '@spree/seller-sdk'
|
|
19
19
|
import { useTranslation } from 'react-i18next'
|
|
20
|
-
import { ReadRow } from '../read-row'
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* What the buyer paid for this order.
|
|
@@ -64,7 +63,7 @@ export function OrderPaymentCard({ order }: { order: Order }) {
|
|
|
64
63
|
{splits.length > 0 && (
|
|
65
64
|
<>
|
|
66
65
|
<Separator />
|
|
67
|
-
<p className="px-6 pt-4 text-
|
|
66
|
+
<p className="px-6 pt-4 text-base text-muted-foreground">
|
|
68
67
|
{t('orders.payment.share_help')}
|
|
69
68
|
</p>
|
|
70
69
|
<Table>
|