@spree/seller-dashboard 1.0.0-beta.7 → 1.0.0-rc.1
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/dist/vite-plugin/index.js +6 -1
- package/package.json +5 -5
- package/src/components/orders/post-sale-cards.tsx +14 -1
- package/src/components/orders/post-sale-create-dialogs.tsx +2 -1
- package/src/components/orders/returns-card.tsx +27 -6
- package/src/components/seller-switcher.tsx +1 -1
- package/src/locales/ar.json +8 -1
- package/src/locales/de.json +8 -1
- package/src/locales/en.json +8 -1
- package/src/locales/fr.json +8 -1
- package/src/locales/pl.json +8 -1
- package/src/locales/zh-CN.json +8 -1
- package/src/nav/default.ts +3 -3
- package/src/nav/settings.ts +4 -4
- package/src/pages/order.tsx +2 -1
- package/src/pages/payout.tsx +18 -15
- package/src/pages/product.tsx +23 -4
- package/src/pages/profile.tsx +8 -2
- package/src/routeTree.gen.ts +185 -185
- package/src/vite/index.ts +6 -1
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import {
|
|
4
4
|
spreeDashboardPlugin as spreeDashboardCorePlugin
|
|
5
5
|
} from "@spree/dashboard-core/vite";
|
|
6
|
+
import { linkedPackagePath } from "@spree/dashboard-core/vite/discover";
|
|
6
7
|
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
|
|
7
8
|
import { index, layout, physical, rootRoute, route } from "@tanstack/virtual-file-routes";
|
|
8
9
|
function spreeSellerDashboardPlugin(options = {}) {
|
|
@@ -23,7 +24,11 @@ function spreeSellerDashboardPlugin(options = {}) {
|
|
|
23
24
|
function sellerRouterPlugin(hostRoot, options) {
|
|
24
25
|
const fromHost = createRequire(path.join(hostRoot, "package.json"));
|
|
25
26
|
const shellEntry = fromHost.resolve("@spree/seller-dashboard");
|
|
26
|
-
const shellRoutesDir =
|
|
27
|
+
const shellRoutesDir = linkedPackagePath(
|
|
28
|
+
hostRoot,
|
|
29
|
+
"@spree/seller-dashboard",
|
|
30
|
+
path.join(path.dirname(shellEntry), "routes")
|
|
31
|
+
);
|
|
27
32
|
const virtualRouteConfig = rootRoute("__root.tsx", [
|
|
28
33
|
route("/login", "login.tsx"),
|
|
29
34
|
route("/forgot-password", "forgot-password.tsx"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spree/seller-dashboard",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Spree marketplace seller panel — the seller-facing counterpart to the admin dashboard.",
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"react-hook-form": "^7.65.0",
|
|
50
50
|
"react-i18next": "^17.0.8",
|
|
51
51
|
"zod": "^4.4.3",
|
|
52
|
-
"@spree/dashboard-core": "1.0.0-
|
|
53
|
-
"@spree/dashboard-ui": "1.0.0-
|
|
54
|
-
"@spree/seller-sdk": "1.0.0-
|
|
52
|
+
"@spree/dashboard-core": "1.0.0-rc.1",
|
|
53
|
+
"@spree/dashboard-ui": "1.0.0-rc.1",
|
|
54
|
+
"@spree/seller-sdk": "1.0.0-rc.1"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"react": "^19.0.0",
|
|
58
58
|
"react-dom": "^19.0.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@biomejs/biome": "2.4.
|
|
61
|
+
"@biomejs/biome": "^2.4.14",
|
|
62
62
|
"@types/node": "^25.6.0",
|
|
63
63
|
"@types/react": "^19.2.2",
|
|
64
64
|
"@types/react-dom": "^19.2.1",
|
|
@@ -109,7 +109,20 @@ export function ExchangesCard({ order }: { order: Order }) {
|
|
|
109
109
|
)}
|
|
110
110
|
{exchange.status === 'received' && (
|
|
111
111
|
<DropdownMenuItem
|
|
112
|
-
onClick={() =>
|
|
112
|
+
onClick={async () => {
|
|
113
|
+
// A dearer replacement leaves the customer owing the
|
|
114
|
+
// difference, which fulfilling puts on the order.
|
|
115
|
+
if (
|
|
116
|
+
Number(exchange.price_difference) > 0 &&
|
|
117
|
+
!(await confirm({
|
|
118
|
+
message: t('orders.post_sale.exchanges.balance_due_confirm'),
|
|
119
|
+
confirmLabel: t('orders.post_sale.exchanges.fulfill'),
|
|
120
|
+
}))
|
|
121
|
+
) {
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
fulfill.mutate({ exchangeId: exchange.id })
|
|
125
|
+
}}
|
|
113
126
|
>
|
|
114
127
|
{t('orders.post_sale.exchanges.fulfill')}
|
|
115
128
|
</DropdownMenuItem>
|
|
@@ -137,7 +137,8 @@ export function CreateClaimDialog({
|
|
|
137
137
|
id: item.id,
|
|
138
138
|
label: unitLabel(item),
|
|
139
139
|
quantity: item.quantity,
|
|
140
|
-
|
|
140
|
+
discountedAmount: item.discounted_amount,
|
|
141
|
+
additionalTaxTotal: item.additional_tax_total,
|
|
141
142
|
}))}
|
|
142
143
|
currencySymbol={currencySymbol}
|
|
143
144
|
reasonField={<ClaimReasonField value={reasonId} onChange={setReasonId} />}
|
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
DropdownMenuTrigger,
|
|
15
15
|
ReturnReceiveDialog,
|
|
16
16
|
ReturnRefundDialog,
|
|
17
|
+
returnOwesNothing,
|
|
18
|
+
returnRefundSummary,
|
|
17
19
|
StatusBadge,
|
|
18
20
|
useConfirm,
|
|
19
21
|
} from '@spree/dashboard-ui'
|
|
@@ -114,7 +116,9 @@ export function ReturnsCard({ order }: { order: Order }) {
|
|
|
114
116
|
)}
|
|
115
117
|
{returnRecord.status === 'received' && (
|
|
116
118
|
<DropdownMenuItem onClick={() => setRefunding(returnRecord)}>
|
|
117
|
-
{
|
|
119
|
+
{returnOwesNothing(returnRecord.refundable_total)
|
|
120
|
+
? t('admin.pages.orders.detail.returns.actions.complete')
|
|
121
|
+
: t('orders.post_sale.returns.refund')}
|
|
118
122
|
</DropdownMenuItem>
|
|
119
123
|
)}
|
|
120
124
|
<DropdownMenuSeparator />
|
|
@@ -134,11 +138,7 @@ export function ReturnsCard({ order }: { order: Order }) {
|
|
|
134
138
|
{returnRecord.return_line_items?.map((line) => (
|
|
135
139
|
<ReturnLineRow key={line.id} line={line} />
|
|
136
140
|
))}
|
|
137
|
-
<
|
|
138
|
-
{t('orders.post_sale.returns.refund_total', {
|
|
139
|
-
amount: returnRecord.display_refund_total,
|
|
140
|
-
})}
|
|
141
|
-
</p>
|
|
141
|
+
<RefundSummary returnRecord={returnRecord} />
|
|
142
142
|
</CardContent>
|
|
143
143
|
</Card>
|
|
144
144
|
))
|
|
@@ -165,6 +165,22 @@ export function ReturnsCard({ order }: { order: Order }) {
|
|
|
165
165
|
)
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
function RefundSummary({ returnRecord }: { returnRecord: Return }) {
|
|
169
|
+
const { t } = useTranslation()
|
|
170
|
+
const summary = returnRefundSummary(returnRecord)
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<p className="text-muted-foreground text-sm">
|
|
174
|
+
{summary.kind === 'owed' &&
|
|
175
|
+
t('orders.post_sale.returns.refund_total', { amount: summary.amount })}
|
|
176
|
+
{summary.kind === 'refunded' &&
|
|
177
|
+
t('orders.post_sale.returns.refunded', { amount: summary.amount })}
|
|
178
|
+
{summary.kind === 'refunded_short' &&
|
|
179
|
+
t('orders.post_sale.returns.refunded_of', { amount: summary.amount, total: summary.total })}
|
|
180
|
+
</p>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
168
184
|
function ReturnLineRow({ line }: { line: ReturnLineItem }) {
|
|
169
185
|
const { t } = useTranslation()
|
|
170
186
|
const label = lineLabel(line.name, line.variant, line.variant_id)
|
|
@@ -244,6 +260,11 @@ function RefundDialog({
|
|
|
244
260
|
return (
|
|
245
261
|
<ReturnRefundDialog
|
|
246
262
|
refundableTotal={returnRecord.refundable_total}
|
|
263
|
+
refundTaxTotal={
|
|
264
|
+
Number(returnRecord.refund_tax_total) > 0
|
|
265
|
+
? returnRecord.display_refund_tax_total
|
|
266
|
+
: undefined
|
|
267
|
+
}
|
|
247
268
|
currencySymbol={currencySymbol}
|
|
248
269
|
onClose={() => onOpenChange(false)}
|
|
249
270
|
pending={refund.isPending}
|
|
@@ -80,7 +80,7 @@ export function SellerSwitcher() {
|
|
|
80
80
|
return (
|
|
81
81
|
<SidebarMenu>
|
|
82
82
|
<SidebarMenuItem className="flex h-rail-header-height items-center">
|
|
83
|
-
<div className="flex w-full items-center gap-2
|
|
83
|
+
<div className="flex w-full items-center gap-2 ">{header}</div>
|
|
84
84
|
</SidebarMenuItem>
|
|
85
85
|
</SidebarMenu>
|
|
86
86
|
)
|
package/src/locales/ar.json
CHANGED
|
@@ -136,7 +136,8 @@
|
|
|
136
136
|
"returns": {
|
|
137
137
|
"actions": {
|
|
138
138
|
"receive": "استلام العناصر",
|
|
139
|
-
"refund": "رد المبلغ"
|
|
139
|
+
"refund": "رد المبلغ",
|
|
140
|
+
"complete": "إكمال المرتجع"
|
|
140
141
|
},
|
|
141
142
|
"create_title": "إرجاع جديد",
|
|
142
143
|
"location": "الإرجاع إلى",
|
|
@@ -147,12 +148,15 @@
|
|
|
147
148
|
"receive_title": "استلام العناصر المرتجعة",
|
|
148
149
|
"received_quantity": "المستلَم",
|
|
149
150
|
"refund_amount": "المبلغ",
|
|
151
|
+
"refund_includes_tax": "يشمل المبلغ الكامل ضريبة بقيمة {{tax}}. عند رد مبلغ أقل، تُرد الضريبة بالنسبة نفسها.",
|
|
150
152
|
"refund_method": "رد المبلغ إلى",
|
|
151
153
|
"refund_methods": {
|
|
152
154
|
"original_payment": "وسيلة الدفع الأصلية",
|
|
153
155
|
"store_credit": "رصيد المتجر"
|
|
154
156
|
},
|
|
155
157
|
"refund_title": "رد مبلغ الإرجاع",
|
|
158
|
+
"complete_title": "إكمال المرتجع",
|
|
159
|
+
"nothing_owed": "لا يوجد أي مبلغ مستحق على هذا المرتجع، لذلك لن يُسترد أي مبلغ. يؤدي إكماله إلى إغلاق المرتجع.",
|
|
156
160
|
"resellable": "قابل لإعادة البيع"
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -520,6 +524,7 @@
|
|
|
520
524
|
"cancel_message": "يُبلَّغ العميل بأنه لن يمضي قدمًا.",
|
|
521
525
|
"cancel_title": "إلغاء هذا الاستبدال؟",
|
|
522
526
|
"fulfill": "إرسال البديل",
|
|
527
|
+
"balance_due_confirm": "البديل أغلى من المنتج المُعاد. يؤدي إرساله إلى إضافة الفرق إلى الطلب كرصيد مستحق. لا يتم خصم أي مبلغ تلقائيًا.",
|
|
523
528
|
"price_difference": "فرق السعر: {{amount}}",
|
|
524
529
|
"receive": "استلام",
|
|
525
530
|
"title": "الاستبدالات"
|
|
@@ -535,6 +540,8 @@
|
|
|
535
540
|
"receive": "استلام",
|
|
536
541
|
"refund": "رد المبلغ",
|
|
537
542
|
"refund_total": "إجمالي الاسترداد: {{amount}}",
|
|
543
|
+
"refunded": "تم الاسترداد: {{amount}}",
|
|
544
|
+
"refunded_of": "تم الاسترداد: {{amount}} من {{total}}",
|
|
538
545
|
"title": "المرتجعات"
|
|
539
546
|
},
|
|
540
547
|
"statuses": {
|
package/src/locales/de.json
CHANGED
|
@@ -136,7 +136,8 @@
|
|
|
136
136
|
"returns": {
|
|
137
137
|
"actions": {
|
|
138
138
|
"receive": "Artikel annehmen",
|
|
139
|
-
"refund": "Erstatten"
|
|
139
|
+
"refund": "Erstatten",
|
|
140
|
+
"complete": "Retoure abschließen"
|
|
140
141
|
},
|
|
141
142
|
"create_title": "Neue Rücksendung",
|
|
142
143
|
"location": "Zurück an",
|
|
@@ -147,12 +148,15 @@
|
|
|
147
148
|
"receive_title": "Rücksendung annehmen",
|
|
148
149
|
"received_quantity": "Erhalten",
|
|
149
150
|
"refund_amount": "Betrag",
|
|
151
|
+
"refund_includes_tax": "Der volle Betrag enthält {{tax}} Steuern. Bei einem kleineren Betrag wird die Steuer anteilig erstattet.",
|
|
150
152
|
"refund_method": "Erstatten auf",
|
|
151
153
|
"refund_methods": {
|
|
152
154
|
"original_payment": "Ursprüngliche Zahlung",
|
|
153
155
|
"store_credit": "Guthaben"
|
|
154
156
|
},
|
|
155
157
|
"refund_title": "Rücksendung erstatten",
|
|
158
|
+
"complete_title": "Retoure abschließen",
|
|
159
|
+
"nothing_owed": "Für diese Retoure ist nichts geschuldet, daher wird kein Geld erstattet. Mit dem Abschließen wird die Retoure geschlossen.",
|
|
156
160
|
"resellable": "Wiederverkäuflich"
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -516,6 +520,7 @@
|
|
|
516
520
|
"cancel_message": "Der Kunde erfährt, dass es nicht weitergeht.",
|
|
517
521
|
"cancel_title": "Diesen Umtausch abbrechen?",
|
|
518
522
|
"fulfill": "Ersatz senden",
|
|
523
|
+
"balance_due_confirm": "Der Ersatz kostet mehr als die zurückgesendete Ware. Beim Versand wird die Differenz der Bestellung als offener Betrag hinzugefügt. Es wird nichts automatisch belastet.",
|
|
519
524
|
"price_difference": "Preisdifferenz: {{amount}}",
|
|
520
525
|
"receive": "Annehmen",
|
|
521
526
|
"title": "Umtausch"
|
|
@@ -531,6 +536,8 @@
|
|
|
531
536
|
"receive": "Annehmen",
|
|
532
537
|
"refund": "Erstatten",
|
|
533
538
|
"refund_total": "Erstattung gesamt: {{amount}}",
|
|
539
|
+
"refunded": "Erstattet: {{amount}}",
|
|
540
|
+
"refunded_of": "Erstattet: {{amount}} von {{total}}",
|
|
534
541
|
"title": "Rücksendungen"
|
|
535
542
|
},
|
|
536
543
|
"statuses": {
|
package/src/locales/en.json
CHANGED
|
@@ -155,10 +155,14 @@
|
|
|
155
155
|
"resellable": "Resellable",
|
|
156
156
|
"actions": {
|
|
157
157
|
"receive": "Receive items",
|
|
158
|
-
"refund": "Refund"
|
|
158
|
+
"refund": "Refund",
|
|
159
|
+
"complete": "Complete return"
|
|
159
160
|
},
|
|
160
161
|
"refund_title": "Refund return",
|
|
162
|
+
"complete_title": "Complete return",
|
|
163
|
+
"nothing_owed": "Nothing is owed on this return, so no money goes back. Completing it closes the return.",
|
|
161
164
|
"refund_amount": "Amount",
|
|
165
|
+
"refund_includes_tax": "The full amount includes {{tax}} of tax. A smaller amount gives back tax in the same proportion.",
|
|
162
166
|
"refund_method": "Refund to",
|
|
163
167
|
"refund_methods": {
|
|
164
168
|
"original_payment": "Original payment",
|
|
@@ -516,6 +520,7 @@
|
|
|
516
520
|
"title": "Exchanges",
|
|
517
521
|
"receive": "Receive",
|
|
518
522
|
"fulfill": "Send replacement",
|
|
523
|
+
"balance_due_confirm": "The replacement costs more than what came back. Sending it adds the difference to the order as a balance due. Nothing is charged automatically.",
|
|
519
524
|
"price_difference": "Price difference: {{amount}}",
|
|
520
525
|
"cancel_title": "Cancel this exchange?",
|
|
521
526
|
"cancel_message": "The customer is told it will not go ahead."
|
|
@@ -531,6 +536,8 @@
|
|
|
531
536
|
"receive": "Receive",
|
|
532
537
|
"refund": "Refund",
|
|
533
538
|
"refund_total": "Refund total: {{amount}}",
|
|
539
|
+
"refunded": "Refunded: {{amount}}",
|
|
540
|
+
"refunded_of": "Refunded: {{amount}} of {{total}}",
|
|
534
541
|
"title": "Returns"
|
|
535
542
|
},
|
|
536
543
|
"statuses": {
|
package/src/locales/fr.json
CHANGED
|
@@ -136,7 +136,8 @@
|
|
|
136
136
|
"returns": {
|
|
137
137
|
"actions": {
|
|
138
138
|
"receive": "Réceptionner les articles",
|
|
139
|
-
"refund": "Rembourser"
|
|
139
|
+
"refund": "Rembourser",
|
|
140
|
+
"complete": "Clôturer le retour"
|
|
140
141
|
},
|
|
141
142
|
"create_title": "Nouveau retour",
|
|
142
143
|
"location": "Retourner à",
|
|
@@ -147,12 +148,15 @@
|
|
|
147
148
|
"receive_title": "Réceptionner les articles retournés",
|
|
148
149
|
"received_quantity": "Reçu",
|
|
149
150
|
"refund_amount": "Montant",
|
|
151
|
+
"refund_includes_tax": "Le montant total comprend {{tax}} de taxes. Un montant inférieur rembourse les taxes dans la même proportion.",
|
|
150
152
|
"refund_method": "Rembourser sur",
|
|
151
153
|
"refund_methods": {
|
|
152
154
|
"original_payment": "Paiement d’origine",
|
|
153
155
|
"store_credit": "Avoir"
|
|
154
156
|
},
|
|
155
157
|
"refund_title": "Rembourser le retour",
|
|
158
|
+
"complete_title": "Clôturer le retour",
|
|
159
|
+
"nothing_owed": "Rien n'est dû sur ce retour, donc aucun remboursement n'est effectué. Le clôturer ferme le retour.",
|
|
156
160
|
"resellable": "Revendable"
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -516,6 +520,7 @@
|
|
|
516
520
|
"cancel_message": "Le client est informé que cela n’aura pas lieu.",
|
|
517
521
|
"cancel_title": "Annuler cet échange ?",
|
|
518
522
|
"fulfill": "Envoyer le remplacement",
|
|
523
|
+
"balance_due_confirm": "Le remplacement coûte plus cher que l'article retourné. Son envoi ajoute la différence à la commande comme solde dû. Rien n'est débité automatiquement.",
|
|
519
524
|
"price_difference": "Différence de prix : {{amount}}",
|
|
520
525
|
"receive": "Réceptionner",
|
|
521
526
|
"title": "Échanges"
|
|
@@ -531,6 +536,8 @@
|
|
|
531
536
|
"receive": "Réceptionner",
|
|
532
537
|
"refund": "Rembourser",
|
|
533
538
|
"refund_total": "Total du remboursement : {{amount}}",
|
|
539
|
+
"refunded": "Remboursé : {{amount}}",
|
|
540
|
+
"refunded_of": "Remboursé : {{amount}} sur {{total}}",
|
|
534
541
|
"title": "Retours"
|
|
535
542
|
},
|
|
536
543
|
"statuses": {
|
package/src/locales/pl.json
CHANGED
|
@@ -136,7 +136,8 @@
|
|
|
136
136
|
"returns": {
|
|
137
137
|
"actions": {
|
|
138
138
|
"receive": "Przyjmij pozycje",
|
|
139
|
-
"refund": "Zwrot pieniędzy"
|
|
139
|
+
"refund": "Zwrot pieniędzy",
|
|
140
|
+
"complete": "Zakończ zwrot"
|
|
140
141
|
},
|
|
141
142
|
"create_title": "Nowy zwrot",
|
|
142
143
|
"location": "Zwrot do",
|
|
@@ -147,12 +148,15 @@
|
|
|
147
148
|
"receive_title": "Przyjmij zwrócone pozycje",
|
|
148
149
|
"received_quantity": "Przyjęto",
|
|
149
150
|
"refund_amount": "Kwota",
|
|
151
|
+
"refund_includes_tax": "Pełna kwota zawiera {{tax}} podatku. Przy mniejszej kwocie podatek zostanie zwrócony proporcjonalnie.",
|
|
150
152
|
"refund_method": "Zwrot na",
|
|
151
153
|
"refund_methods": {
|
|
152
154
|
"original_payment": "Pierwotna płatność",
|
|
153
155
|
"store_credit": "Kredyt sklepowy"
|
|
154
156
|
},
|
|
155
157
|
"refund_title": "Zwrot pieniędzy za zwrot",
|
|
158
|
+
"complete_title": "Zakończ zwrot",
|
|
159
|
+
"nothing_owed": "Z tytułu tego zwrotu nic nie jest należne, więc pieniądze nie zostaną zwrócone. Zakończenie zamyka zwrot.",
|
|
156
160
|
"resellable": "Do ponownej sprzedaży"
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -518,6 +522,7 @@
|
|
|
518
522
|
"cancel_message": "Klient dostanie informację, że sprawa nie będzie kontynuowana.",
|
|
519
523
|
"cancel_title": "Anulować tę wymianę?",
|
|
520
524
|
"fulfill": "Wyślij wymianę",
|
|
525
|
+
"balance_due_confirm": "Zamiennik kosztuje więcej niż zwrócony towar. Jego wysłanie doda różnicę do zamówienia jako kwotę do zapłaty. Nic nie zostanie pobrane automatycznie.",
|
|
521
526
|
"price_difference": "Różnica w cenie: {{amount}}",
|
|
522
527
|
"receive": "Przyjmij",
|
|
523
528
|
"title": "Wymiany"
|
|
@@ -533,6 +538,8 @@
|
|
|
533
538
|
"receive": "Przyjmij",
|
|
534
539
|
"refund": "Zwrot pieniędzy",
|
|
535
540
|
"refund_total": "Łączny zwrot: {{amount}}",
|
|
541
|
+
"refunded": "Zwrócono: {{amount}}",
|
|
542
|
+
"refunded_of": "Zwrócono: {{amount}} z {{total}}",
|
|
536
543
|
"title": "Zwroty"
|
|
537
544
|
},
|
|
538
545
|
"statuses": {
|
package/src/locales/zh-CN.json
CHANGED
|
@@ -136,7 +136,8 @@
|
|
|
136
136
|
"returns": {
|
|
137
137
|
"actions": {
|
|
138
138
|
"receive": "接收商品",
|
|
139
|
-
"refund": "退款"
|
|
139
|
+
"refund": "退款",
|
|
140
|
+
"complete": "完成退货"
|
|
140
141
|
},
|
|
141
142
|
"create_title": "新建退货",
|
|
142
143
|
"location": "退回至",
|
|
@@ -147,12 +148,15 @@
|
|
|
147
148
|
"receive_title": "接收退货商品",
|
|
148
149
|
"received_quantity": "已接收",
|
|
149
150
|
"refund_amount": "金额",
|
|
151
|
+
"refund_includes_tax": "全额包含 {{tax}} 税费。退款金额较小时,税费按相同比例退还。",
|
|
150
152
|
"refund_method": "退款至",
|
|
151
153
|
"refund_methods": {
|
|
152
154
|
"original_payment": "原支付方式",
|
|
153
155
|
"store_credit": "店铺余额"
|
|
154
156
|
},
|
|
155
157
|
"refund_title": "退货退款",
|
|
158
|
+
"complete_title": "完成退货",
|
|
159
|
+
"nothing_owed": "此退货没有应退金额,因此不会退款。完成后该退货将关闭。",
|
|
156
160
|
"resellable": "可再次销售"
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -515,6 +519,7 @@
|
|
|
515
519
|
"cancel_message": "客户会收到不再继续处理的通知。",
|
|
516
520
|
"cancel_title": "取消此换货?",
|
|
517
521
|
"fulfill": "寄出替换件",
|
|
522
|
+
"balance_due_confirm": "替换商品比退回的商品更贵。发出替换商品会将差额作为待付余额添加到订单中。不会自动扣款。",
|
|
518
523
|
"price_difference": "差价:{{amount}}",
|
|
519
524
|
"receive": "接收",
|
|
520
525
|
"title": "换货"
|
|
@@ -530,6 +535,8 @@
|
|
|
530
535
|
"receive": "接收",
|
|
531
536
|
"refund": "退款",
|
|
532
537
|
"refund_total": "退款合计:{{amount}}",
|
|
538
|
+
"refunded": "已退款:{{amount}}",
|
|
539
|
+
"refunded_of": "已退款:{{amount}} / {{total}}",
|
|
533
540
|
"title": "退货"
|
|
534
541
|
},
|
|
535
542
|
"statuses": {
|
package/src/nav/default.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasVisibleSettingsEntries, i18n, nav } from '@spree/dashboard-core'
|
|
1
|
+
import { hasVisibleSettingsEntries, i18n, nav, Subject } from '@spree/dashboard-core'
|
|
2
2
|
import {
|
|
3
3
|
BanknoteIcon,
|
|
4
4
|
ClipboardCheckIcon,
|
|
@@ -50,7 +50,7 @@ nav.add({
|
|
|
50
50
|
path: '/products',
|
|
51
51
|
icon: TagIcon,
|
|
52
52
|
position: 110,
|
|
53
|
-
subject:
|
|
53
|
+
subject: Subject.Product,
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
nav.add({
|
|
@@ -59,7 +59,7 @@ nav.add({
|
|
|
59
59
|
path: '/orders',
|
|
60
60
|
icon: PackageIcon,
|
|
61
61
|
position: 120,
|
|
62
|
-
subject:
|
|
62
|
+
subject: Subject.Order,
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
// The seller's own books. Two entries rather than one because they answer
|
package/src/nav/settings.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i18n, settingsNav } from '@spree/dashboard-core'
|
|
1
|
+
import { i18n, Subject, settingsNav } from '@spree/dashboard-core'
|
|
2
2
|
import {
|
|
3
3
|
PackageIcon,
|
|
4
4
|
ScrollTextIcon,
|
|
@@ -44,7 +44,7 @@ settingsNav.add({
|
|
|
44
44
|
position: 100,
|
|
45
45
|
// The seller-branch subject the API's `/me` serializes. A member without
|
|
46
46
|
// stock permission never sees the entry.
|
|
47
|
-
subject:
|
|
47
|
+
subject: Subject.StockLocation,
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
// How this seller's goods ship. Beside stock locations because the two are
|
|
@@ -60,7 +60,7 @@ settingsNav.add({
|
|
|
60
60
|
position: 200,
|
|
61
61
|
// The seller-branch subject the API's `/me` serializes. A member without
|
|
62
62
|
// delivery permission never sees the entry.
|
|
63
|
-
subject:
|
|
63
|
+
subject: Subject.DeliveryMethod,
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
// What this seller packs their goods into. Beside the other two because the
|
|
@@ -77,7 +77,7 @@ settingsNav.add({
|
|
|
77
77
|
position: 300,
|
|
78
78
|
// The seller-branch subject the API's `/me` serializes. A member without
|
|
79
79
|
// packaging permission never sees the entry.
|
|
80
|
-
subject:
|
|
80
|
+
subject: Subject.PackageType,
|
|
81
81
|
})
|
|
82
82
|
|
|
83
83
|
// Who runs this seller. Under settings rather than in the main rail, matching
|
package/src/pages/order.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatStoreDateTime, PageHeader } from '@spree/dashboard-core'
|
|
1
|
+
import { formatStoreDateTime, PageHeader, Slot } from '@spree/dashboard-core'
|
|
2
2
|
import { DropdownMenuItem, ResourceLayout, StatusBadge } from '@spree/dashboard-ui'
|
|
3
3
|
import { XCircleIcon } from '@spree/dashboard-ui/icons'
|
|
4
4
|
import { useParams } from '@tanstack/react-router'
|
|
@@ -113,6 +113,7 @@ export function OrderPage() {
|
|
|
113
113
|
<OrderCustomerCard order={order} />
|
|
114
114
|
<SpecialInstructionsCard order={order} />
|
|
115
115
|
<InternalNoteCard order={order} />
|
|
116
|
+
<Slot name="seller.order.form_sidebar" context={{ order }} />
|
|
116
117
|
</>
|
|
117
118
|
}
|
|
118
119
|
/>
|
package/src/pages/payout.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatStoreDateTime, PageHeader } from '@spree/dashboard-core'
|
|
1
|
+
import { formatStoreDateTime, PageHeader, Slot } from '@spree/dashboard-core'
|
|
2
2
|
import {
|
|
3
3
|
Card,
|
|
4
4
|
CardHeader,
|
|
@@ -134,20 +134,23 @@ export function PayoutPage() {
|
|
|
134
134
|
</Card>
|
|
135
135
|
}
|
|
136
136
|
sidebar={
|
|
137
|
-
|
|
138
|
-
<
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
{
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
137
|
+
<>
|
|
138
|
+
<Card>
|
|
139
|
+
<CardHeader>
|
|
140
|
+
<CardTitle>{t('payouts.detail.settlement')}</CardTitle>
|
|
141
|
+
</CardHeader>
|
|
142
|
+
<div className="flex flex-col gap-3 px-6 pb-6">
|
|
143
|
+
<ReadRow label={t('payouts.columns.amount')}>{payout.display_amount}</ReadRow>
|
|
144
|
+
<ReadRow label={t('payouts.columns.reference')}>{payout.reference}</ReadRow>
|
|
145
|
+
<ReadRow label={t('payouts.detail.period')}>
|
|
146
|
+
{payout.period_start && payout.period_end
|
|
147
|
+
? `${formatStoreDateTime(payout.period_start, timezone)} – ${formatStoreDateTime(payout.period_end, timezone)}`
|
|
148
|
+
: null}
|
|
149
|
+
</ReadRow>
|
|
150
|
+
</div>
|
|
151
|
+
</Card>
|
|
152
|
+
<Slot name="seller.payout.form_sidebar" context={{ payout }} />
|
|
153
|
+
</>
|
|
151
154
|
}
|
|
152
155
|
/>
|
|
153
156
|
)
|
package/src/pages/product.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
2
2
|
import {
|
|
3
3
|
CategorizationCard,
|
|
4
|
+
extensionFormValues,
|
|
5
|
+
extensionSubmitValues,
|
|
4
6
|
GeneralCard,
|
|
5
7
|
InventoryCard,
|
|
6
8
|
MediaCard,
|
|
@@ -12,6 +14,7 @@ import {
|
|
|
12
14
|
type ProductFormValues,
|
|
13
15
|
productFormSchema,
|
|
14
16
|
productToFormValues,
|
|
17
|
+
Slot,
|
|
15
18
|
VariantsCard,
|
|
16
19
|
variantToWirePayload,
|
|
17
20
|
} from '@spree/dashboard-core'
|
|
@@ -88,7 +91,7 @@ export function ProductPage({ mode }: { mode: 'new' | 'edit' }) {
|
|
|
88
91
|
// The operator's defaults, which seed one placeholder variant — without
|
|
89
92
|
// it the Prices and Inventory cards render no row, so a seller could not
|
|
90
93
|
// price or stock a new listing at all.
|
|
91
|
-
defaultValues: newProductFormDefaults(),
|
|
94
|
+
defaultValues: { ...newProductFormDefaults(), ...extensionFormValues('seller.product', null) },
|
|
92
95
|
})
|
|
93
96
|
|
|
94
97
|
// Reset once the record arrives, so the inputs show what was last saved
|
|
@@ -102,12 +105,22 @@ export function ProductPage({ mode }: { mode: 'new' | 'edit' }) {
|
|
|
102
105
|
if (!product) return
|
|
103
106
|
if (form.formState.isDirty) return
|
|
104
107
|
|
|
105
|
-
form.reset(
|
|
108
|
+
form.reset({
|
|
109
|
+
...productToFormValues(product as PanelProduct, product.media),
|
|
110
|
+
...extensionFormValues('seller.product', product),
|
|
111
|
+
})
|
|
106
112
|
}, [product, form])
|
|
107
113
|
|
|
108
114
|
const save = useMutation({
|
|
109
|
-
mutationFn: (
|
|
115
|
+
mutationFn: ({
|
|
116
|
+
values,
|
|
117
|
+
extensionValues,
|
|
118
|
+
}: {
|
|
119
|
+
values: ProductFormValues
|
|
120
|
+
extensionValues: Record<string, unknown>
|
|
121
|
+
}) => {
|
|
110
122
|
const payload: ProductParams = {
|
|
123
|
+
...extensionValues,
|
|
111
124
|
name: values.name,
|
|
112
125
|
description: values.description,
|
|
113
126
|
slug: values.slug || undefined,
|
|
@@ -165,7 +178,12 @@ export function ProductPage({ mode }: { mode: 'new' | 'edit' }) {
|
|
|
165
178
|
|
|
166
179
|
async function onSubmit(values: ProductFormValues) {
|
|
167
180
|
try {
|
|
168
|
-
|
|
181
|
+
// Raw form state, not `values`: the Zod parse strips keys the schema
|
|
182
|
+
// doesn't know, which is every field a slot widget registered.
|
|
183
|
+
await save.mutateAsync({
|
|
184
|
+
values,
|
|
185
|
+
extensionValues: extensionSubmitValues('seller.product', form),
|
|
186
|
+
})
|
|
169
187
|
} catch (err) {
|
|
170
188
|
if (!mapSpreeErrorsToForm(err, form.setError)) {
|
|
171
189
|
toastManager.add({
|
|
@@ -241,6 +259,7 @@ export function ProductPage({ mode }: { mode: 'new' | 'edit' }) {
|
|
|
241
259
|
/>
|
|
242
260
|
)}
|
|
243
261
|
<CategorizationCard form={form} />
|
|
262
|
+
<Slot name="seller.product.form_sidebar" context={{ product, mode }} />
|
|
244
263
|
</>
|
|
245
264
|
}
|
|
246
265
|
/>
|
package/src/pages/profile.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PageHeader } from '@spree/dashboard-core'
|
|
1
|
+
import { PageHeader, Slot } from '@spree/dashboard-core'
|
|
2
2
|
import {
|
|
3
3
|
Button,
|
|
4
4
|
Card,
|
|
@@ -84,7 +84,12 @@ export function ProfilePage() {
|
|
|
84
84
|
<>
|
|
85
85
|
<ResourceLayout
|
|
86
86
|
header={<PageHeader title={profile.name} subtitle={t('profile.subtitle')} />}
|
|
87
|
-
main={
|
|
87
|
+
main={
|
|
88
|
+
<>
|
|
89
|
+
<BrandCard profile={profile} onEdit={() => setEditing(true)} />
|
|
90
|
+
<Slot name="seller.profile.form_main" context={{ profile }} />
|
|
91
|
+
</>
|
|
92
|
+
}
|
|
88
93
|
sidebar={
|
|
89
94
|
<>
|
|
90
95
|
<StandingCard profile={profile} />
|
|
@@ -95,6 +100,7 @@ export function ProfilePage() {
|
|
|
95
100
|
<SellerAddressCard profile={profile} />
|
|
96
101
|
<SellerReturnsLocationCard />
|
|
97
102
|
<SettlementCard profile={profile} />
|
|
103
|
+
<Slot name="seller.profile.form_sidebar" context={{ profile }} />
|
|
98
104
|
</>
|
|
99
105
|
}
|
|
100
106
|
/>
|
package/src/routeTree.gen.ts
CHANGED
|
@@ -9,40 +9,34 @@
|
|
|
9
9
|
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
10
|
|
|
11
11
|
import { Route as rootRouteImport } from './routes/__root'
|
|
12
|
-
import { Route as resetPasswordRouteImport } from './routes/reset-password'
|
|
13
|
-
import { Route as loginRouteImport } from './routes/login'
|
|
14
|
-
import { Route as forgotPasswordRouteImport } from './routes/forgot-password'
|
|
15
12
|
import { Route as authenticatedRouteImport } from './routes/_authenticated'
|
|
13
|
+
import { Route as forgotPasswordRouteImport } from './routes/forgot-password'
|
|
14
|
+
import { Route as loginRouteImport } from './routes/login'
|
|
15
|
+
import { Route as resetPasswordRouteImport } from './routes/reset-password'
|
|
16
16
|
import { Route as authenticatedIndexRouteImport } from './routes/_authenticated/index'
|
|
17
|
-
import { Route as acceptInvitationDotinvitationIdRouteImport } from './routes/accept-invitation.$invitationId'
|
|
18
17
|
import { Route as authenticatedSellerIdRouteImport } from './routes/_authenticated/$sellerId'
|
|
18
|
+
import { Route as acceptInvitationDotinvitationIdRouteImport } from './routes/accept-invitation.$invitationId'
|
|
19
19
|
import { Route as IndexRouteImport } from './routes/_authenticated/$sellerId/index'
|
|
20
|
-
import { Route as SettingsRouteImport } from './routes/_authenticated/$sellerId/settings'
|
|
21
|
-
import { Route as ProfileRouteImport } from './routes/_authenticated/$sellerId/profile'
|
|
22
20
|
import { Route as OnboardingRouteImport } from './routes/_authenticated/$sellerId/onboarding'
|
|
23
|
-
import { Route as
|
|
24
|
-
import { Route as
|
|
25
|
-
import { Route as PayoutsIndexRouteImport } from './routes/_authenticated/$sellerId/payouts/index'
|
|
26
|
-
import { Route as OrdersIndexRouteImport } from './routes/_authenticated/$sellerId/orders/index'
|
|
21
|
+
import { Route as ProfileRouteImport } from './routes/_authenticated/$sellerId/profile'
|
|
22
|
+
import { Route as SettingsRouteImport } from './routes/_authenticated/$sellerId/settings'
|
|
27
23
|
import { Route as EarningsIndexRouteImport } from './routes/_authenticated/$sellerId/earnings/index'
|
|
28
|
-
import { Route as
|
|
29
|
-
import { Route as SettingsStockLocationsRouteImport } from './routes/_authenticated/$sellerId/settings/stock-locations'
|
|
30
|
-
import { Route as SettingsPoliciesRouteImport } from './routes/_authenticated/$sellerId/settings/policies'
|
|
31
|
-
import { Route as SettingsPackageTypesRouteImport } from './routes/_authenticated/$sellerId/settings/package-types'
|
|
32
|
-
import { Route as SettingsDeliveryMethodsRouteImport } from './routes/_authenticated/$sellerId/settings/delivery-methods'
|
|
33
|
-
import { Route as ProductsNewRouteImport } from './routes/_authenticated/$sellerId/products/new'
|
|
34
|
-
import { Route as ProductsProductIdRouteImport } from './routes/_authenticated/$sellerId/products/$productId'
|
|
35
|
-
import { Route as PayoutsPayoutIdRouteImport } from './routes/_authenticated/$sellerId/payouts/$payoutId'
|
|
24
|
+
import { Route as OrdersIndexRouteImport } from './routes/_authenticated/$sellerId/orders/index'
|
|
36
25
|
import { Route as OrdersOrderIdRouteImport } from './routes/_authenticated/$sellerId/orders/$orderId'
|
|
26
|
+
import { Route as PayoutsIndexRouteImport } from './routes/_authenticated/$sellerId/payouts/index'
|
|
27
|
+
import { Route as PayoutsPayoutIdRouteImport } from './routes/_authenticated/$sellerId/payouts/$payoutId'
|
|
28
|
+
import { Route as ProductsIndexRouteImport } from './routes/_authenticated/$sellerId/products/index'
|
|
29
|
+
import { Route as ProductsProductIdRouteImport } from './routes/_authenticated/$sellerId/products/$productId'
|
|
30
|
+
import { Route as ProductsNewRouteImport } from './routes/_authenticated/$sellerId/products/new'
|
|
31
|
+
import { Route as SettingsIndexRouteImport } from './routes/_authenticated/$sellerId/settings/index'
|
|
32
|
+
import { Route as SettingsDeliveryMethodsRouteImport } from './routes/_authenticated/$sellerId/settings/delivery-methods'
|
|
33
|
+
import { Route as SettingsPackageTypesRouteImport } from './routes/_authenticated/$sellerId/settings/package-types'
|
|
34
|
+
import { Route as SettingsPoliciesRouteImport } from './routes/_authenticated/$sellerId/settings/policies'
|
|
35
|
+
import { Route as SettingsStockLocationsRouteImport } from './routes/_authenticated/$sellerId/settings/stock-locations'
|
|
36
|
+
import { Route as SettingsTeamRouteImport } from './routes/_authenticated/$sellerId/settings/team'
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
id: '/
|
|
40
|
-
path: '/reset-password',
|
|
41
|
-
getParentRoute: () => rootRouteImport,
|
|
42
|
-
} as any)
|
|
43
|
-
const loginRoute = loginRouteImport.update({
|
|
44
|
-
id: '/login',
|
|
45
|
-
path: '/login',
|
|
38
|
+
const authenticatedRoute = authenticatedRouteImport.update({
|
|
39
|
+
id: '/_authenticated',
|
|
46
40
|
getParentRoute: () => rootRouteImport,
|
|
47
41
|
} as any)
|
|
48
42
|
const forgotPasswordRoute = forgotPasswordRouteImport.update({
|
|
@@ -50,8 +44,14 @@ const forgotPasswordRoute = forgotPasswordRouteImport.update({
|
|
|
50
44
|
path: '/forgot-password',
|
|
51
45
|
getParentRoute: () => rootRouteImport,
|
|
52
46
|
} as any)
|
|
53
|
-
const
|
|
54
|
-
id: '/
|
|
47
|
+
const loginRoute = loginRouteImport.update({
|
|
48
|
+
id: '/login',
|
|
49
|
+
path: '/login',
|
|
50
|
+
getParentRoute: () => rootRouteImport,
|
|
51
|
+
} as any)
|
|
52
|
+
const resetPasswordRoute = resetPasswordRouteImport.update({
|
|
53
|
+
id: '/reset-password',
|
|
54
|
+
path: '/reset-password',
|
|
55
55
|
getParentRoute: () => rootRouteImport,
|
|
56
56
|
} as any)
|
|
57
57
|
const authenticatedIndexRoute = authenticatedIndexRouteImport.update({
|
|
@@ -59,25 +59,25 @@ const authenticatedIndexRoute = authenticatedIndexRouteImport.update({
|
|
|
59
59
|
path: '/',
|
|
60
60
|
getParentRoute: () => authenticatedRoute,
|
|
61
61
|
} as any)
|
|
62
|
+
const authenticatedSellerIdRoute = authenticatedSellerIdRouteImport.update({
|
|
63
|
+
id: '/$sellerId',
|
|
64
|
+
path: '/$sellerId',
|
|
65
|
+
getParentRoute: () => authenticatedRoute,
|
|
66
|
+
} as any)
|
|
62
67
|
const acceptInvitationDotinvitationIdRoute =
|
|
63
68
|
acceptInvitationDotinvitationIdRouteImport.update({
|
|
64
69
|
id: '/accept-invitation/$invitationId',
|
|
65
70
|
path: '/accept-invitation/$invitationId',
|
|
66
71
|
getParentRoute: () => rootRouteImport,
|
|
67
72
|
} as any)
|
|
68
|
-
const authenticatedSellerIdRoute = authenticatedSellerIdRouteImport.update({
|
|
69
|
-
id: '/$sellerId',
|
|
70
|
-
path: '/$sellerId',
|
|
71
|
-
getParentRoute: () => authenticatedRoute,
|
|
72
|
-
} as any)
|
|
73
73
|
const IndexRoute = IndexRouteImport.update({
|
|
74
74
|
id: '/',
|
|
75
75
|
path: '/',
|
|
76
76
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
77
77
|
} as any)
|
|
78
|
-
const
|
|
79
|
-
id: '/
|
|
80
|
-
path: '/
|
|
78
|
+
const OnboardingRoute = OnboardingRouteImport.update({
|
|
79
|
+
id: '/onboarding',
|
|
80
|
+
path: '/onboarding',
|
|
81
81
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
82
82
|
} as any)
|
|
83
83
|
const ProfileRoute = ProfileRouteImport.update({
|
|
@@ -85,19 +85,24 @@ const ProfileRoute = ProfileRouteImport.update({
|
|
|
85
85
|
path: '/profile',
|
|
86
86
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
87
87
|
} as any)
|
|
88
|
-
const
|
|
89
|
-
id: '/
|
|
90
|
-
path: '/
|
|
88
|
+
const SettingsRoute = SettingsRouteImport.update({
|
|
89
|
+
id: '/settings',
|
|
90
|
+
path: '/settings',
|
|
91
91
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
92
92
|
} as any)
|
|
93
|
-
const
|
|
94
|
-
id: '/',
|
|
95
|
-
path: '/',
|
|
96
|
-
getParentRoute: () =>
|
|
93
|
+
const EarningsIndexRoute = EarningsIndexRouteImport.update({
|
|
94
|
+
id: '/earnings/',
|
|
95
|
+
path: '/earnings/',
|
|
96
|
+
getParentRoute: () => authenticatedSellerIdRoute,
|
|
97
97
|
} as any)
|
|
98
|
-
const
|
|
99
|
-
id: '/
|
|
100
|
-
path: '/
|
|
98
|
+
const OrdersIndexRoute = OrdersIndexRouteImport.update({
|
|
99
|
+
id: '/orders/',
|
|
100
|
+
path: '/orders/',
|
|
101
|
+
getParentRoute: () => authenticatedSellerIdRoute,
|
|
102
|
+
} as any)
|
|
103
|
+
const OrdersOrderIdRoute = OrdersOrderIdRouteImport.update({
|
|
104
|
+
id: '/orders/$orderId',
|
|
105
|
+
path: '/orders/$orderId',
|
|
101
106
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
102
107
|
} as any)
|
|
103
108
|
const PayoutsIndexRoute = PayoutsIndexRouteImport.update({
|
|
@@ -105,29 +110,34 @@ const PayoutsIndexRoute = PayoutsIndexRouteImport.update({
|
|
|
105
110
|
path: '/payouts/',
|
|
106
111
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
107
112
|
} as any)
|
|
108
|
-
const
|
|
109
|
-
id: '/
|
|
110
|
-
path: '/
|
|
113
|
+
const PayoutsPayoutIdRoute = PayoutsPayoutIdRouteImport.update({
|
|
114
|
+
id: '/payouts/$payoutId',
|
|
115
|
+
path: '/payouts/$payoutId',
|
|
111
116
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
112
117
|
} as any)
|
|
113
|
-
const
|
|
114
|
-
id: '/
|
|
115
|
-
path: '/
|
|
118
|
+
const ProductsIndexRoute = ProductsIndexRouteImport.update({
|
|
119
|
+
id: '/products/',
|
|
120
|
+
path: '/products/',
|
|
116
121
|
getParentRoute: () => authenticatedSellerIdRoute,
|
|
117
122
|
} as any)
|
|
118
|
-
const
|
|
119
|
-
id: '/
|
|
120
|
-
path: '/
|
|
121
|
-
getParentRoute: () =>
|
|
123
|
+
const ProductsProductIdRoute = ProductsProductIdRouteImport.update({
|
|
124
|
+
id: '/products/$productId',
|
|
125
|
+
path: '/products/$productId',
|
|
126
|
+
getParentRoute: () => authenticatedSellerIdRoute,
|
|
122
127
|
} as any)
|
|
123
|
-
const
|
|
124
|
-
id: '/
|
|
125
|
-
path: '/
|
|
128
|
+
const ProductsNewRoute = ProductsNewRouteImport.update({
|
|
129
|
+
id: '/products/new',
|
|
130
|
+
path: '/products/new',
|
|
131
|
+
getParentRoute: () => authenticatedSellerIdRoute,
|
|
132
|
+
} as any)
|
|
133
|
+
const SettingsIndexRoute = SettingsIndexRouteImport.update({
|
|
134
|
+
id: '/',
|
|
135
|
+
path: '/',
|
|
126
136
|
getParentRoute: () => SettingsRoute,
|
|
127
137
|
} as any)
|
|
128
|
-
const
|
|
129
|
-
id: '/
|
|
130
|
-
path: '/
|
|
138
|
+
const SettingsDeliveryMethodsRoute = SettingsDeliveryMethodsRouteImport.update({
|
|
139
|
+
id: '/delivery-methods',
|
|
140
|
+
path: '/delivery-methods',
|
|
131
141
|
getParentRoute: () => SettingsRoute,
|
|
132
142
|
} as any)
|
|
133
143
|
const SettingsPackageTypesRoute = SettingsPackageTypesRouteImport.update({
|
|
@@ -135,30 +145,20 @@ const SettingsPackageTypesRoute = SettingsPackageTypesRouteImport.update({
|
|
|
135
145
|
path: '/package-types',
|
|
136
146
|
getParentRoute: () => SettingsRoute,
|
|
137
147
|
} as any)
|
|
138
|
-
const
|
|
139
|
-
id: '/
|
|
140
|
-
path: '/
|
|
148
|
+
const SettingsPoliciesRoute = SettingsPoliciesRouteImport.update({
|
|
149
|
+
id: '/policies',
|
|
150
|
+
path: '/policies',
|
|
141
151
|
getParentRoute: () => SettingsRoute,
|
|
142
152
|
} as any)
|
|
143
|
-
const
|
|
144
|
-
id: '/
|
|
145
|
-
path: '/
|
|
146
|
-
getParentRoute: () =>
|
|
147
|
-
} as any)
|
|
148
|
-
const ProductsProductIdRoute = ProductsProductIdRouteImport.update({
|
|
149
|
-
id: '/products/$productId',
|
|
150
|
-
path: '/products/$productId',
|
|
151
|
-
getParentRoute: () => authenticatedSellerIdRoute,
|
|
152
|
-
} as any)
|
|
153
|
-
const PayoutsPayoutIdRoute = PayoutsPayoutIdRouteImport.update({
|
|
154
|
-
id: '/payouts/$payoutId',
|
|
155
|
-
path: '/payouts/$payoutId',
|
|
156
|
-
getParentRoute: () => authenticatedSellerIdRoute,
|
|
153
|
+
const SettingsStockLocationsRoute = SettingsStockLocationsRouteImport.update({
|
|
154
|
+
id: '/stock-locations',
|
|
155
|
+
path: '/stock-locations',
|
|
156
|
+
getParentRoute: () => SettingsRoute,
|
|
157
157
|
} as any)
|
|
158
|
-
const
|
|
159
|
-
id: '/
|
|
160
|
-
path: '/
|
|
161
|
-
getParentRoute: () =>
|
|
158
|
+
const SettingsTeamRoute = SettingsTeamRouteImport.update({
|
|
159
|
+
id: '/team',
|
|
160
|
+
path: '/team',
|
|
161
|
+
getParentRoute: () => SettingsRoute,
|
|
162
162
|
} as any)
|
|
163
163
|
|
|
164
164
|
export interface FileRoutesByFullPath {
|
|
@@ -329,18 +329,11 @@ export interface RootRouteChildren {
|
|
|
329
329
|
|
|
330
330
|
declare module '@tanstack/react-router' {
|
|
331
331
|
interface FileRoutesByPath {
|
|
332
|
-
'/
|
|
333
|
-
id: '/
|
|
334
|
-
path: '
|
|
335
|
-
fullPath: '/
|
|
336
|
-
preLoaderRoute: typeof
|
|
337
|
-
parentRoute: typeof rootRouteImport
|
|
338
|
-
}
|
|
339
|
-
'/login': {
|
|
340
|
-
id: '/login'
|
|
341
|
-
path: '/login'
|
|
342
|
-
fullPath: '/login'
|
|
343
|
-
preLoaderRoute: typeof loginRouteImport
|
|
332
|
+
'/_authenticated': {
|
|
333
|
+
id: '/_authenticated'
|
|
334
|
+
path: ''
|
|
335
|
+
fullPath: '/'
|
|
336
|
+
preLoaderRoute: typeof authenticatedRouteImport
|
|
344
337
|
parentRoute: typeof rootRouteImport
|
|
345
338
|
}
|
|
346
339
|
'/forgot-password': {
|
|
@@ -350,11 +343,18 @@ declare module '@tanstack/react-router' {
|
|
|
350
343
|
preLoaderRoute: typeof forgotPasswordRouteImport
|
|
351
344
|
parentRoute: typeof rootRouteImport
|
|
352
345
|
}
|
|
353
|
-
'/
|
|
354
|
-
id: '/
|
|
355
|
-
path: ''
|
|
356
|
-
fullPath: '/'
|
|
357
|
-
preLoaderRoute: typeof
|
|
346
|
+
'/login': {
|
|
347
|
+
id: '/login'
|
|
348
|
+
path: '/login'
|
|
349
|
+
fullPath: '/login'
|
|
350
|
+
preLoaderRoute: typeof loginRouteImport
|
|
351
|
+
parentRoute: typeof rootRouteImport
|
|
352
|
+
}
|
|
353
|
+
'/reset-password': {
|
|
354
|
+
id: '/reset-password'
|
|
355
|
+
path: '/reset-password'
|
|
356
|
+
fullPath: '/reset-password'
|
|
357
|
+
preLoaderRoute: typeof resetPasswordRouteImport
|
|
358
358
|
parentRoute: typeof rootRouteImport
|
|
359
359
|
}
|
|
360
360
|
'/_authenticated/': {
|
|
@@ -364,13 +364,6 @@ declare module '@tanstack/react-router' {
|
|
|
364
364
|
preLoaderRoute: typeof authenticatedIndexRouteImport
|
|
365
365
|
parentRoute: typeof authenticatedRoute
|
|
366
366
|
}
|
|
367
|
-
'/accept-invitation/$invitationId': {
|
|
368
|
-
id: '/accept-invitation/$invitationId'
|
|
369
|
-
path: '/accept-invitation/$invitationId'
|
|
370
|
-
fullPath: '/accept-invitation/$invitationId'
|
|
371
|
-
preLoaderRoute: typeof acceptInvitationDotinvitationIdRouteImport
|
|
372
|
-
parentRoute: typeof rootRouteImport
|
|
373
|
-
}
|
|
374
367
|
'/_authenticated/$sellerId': {
|
|
375
368
|
id: '/_authenticated/$sellerId'
|
|
376
369
|
path: '/$sellerId'
|
|
@@ -378,6 +371,13 @@ declare module '@tanstack/react-router' {
|
|
|
378
371
|
preLoaderRoute: typeof authenticatedSellerIdRouteImport
|
|
379
372
|
parentRoute: typeof authenticatedRoute
|
|
380
373
|
}
|
|
374
|
+
'/accept-invitation/$invitationId': {
|
|
375
|
+
id: '/accept-invitation/$invitationId'
|
|
376
|
+
path: '/accept-invitation/$invitationId'
|
|
377
|
+
fullPath: '/accept-invitation/$invitationId'
|
|
378
|
+
preLoaderRoute: typeof acceptInvitationDotinvitationIdRouteImport
|
|
379
|
+
parentRoute: typeof rootRouteImport
|
|
380
|
+
}
|
|
381
381
|
'/_authenticated/$sellerId/': {
|
|
382
382
|
id: '/_authenticated/$sellerId/'
|
|
383
383
|
path: '/'
|
|
@@ -385,11 +385,11 @@ declare module '@tanstack/react-router' {
|
|
|
385
385
|
preLoaderRoute: typeof IndexRouteImport
|
|
386
386
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
387
387
|
}
|
|
388
|
-
'/_authenticated/$sellerId/
|
|
389
|
-
id: '/_authenticated/$sellerId/
|
|
390
|
-
path: '/
|
|
391
|
-
fullPath: '/$sellerId/
|
|
392
|
-
preLoaderRoute: typeof
|
|
388
|
+
'/_authenticated/$sellerId/onboarding': {
|
|
389
|
+
id: '/_authenticated/$sellerId/onboarding'
|
|
390
|
+
path: '/onboarding'
|
|
391
|
+
fullPath: '/$sellerId/onboarding'
|
|
392
|
+
preLoaderRoute: typeof OnboardingRouteImport
|
|
393
393
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
394
394
|
}
|
|
395
395
|
'/_authenticated/$sellerId/profile': {
|
|
@@ -399,25 +399,32 @@ declare module '@tanstack/react-router' {
|
|
|
399
399
|
preLoaderRoute: typeof ProfileRouteImport
|
|
400
400
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
401
401
|
}
|
|
402
|
-
'/_authenticated/$sellerId/
|
|
403
|
-
id: '/_authenticated/$sellerId/
|
|
404
|
-
path: '/
|
|
405
|
-
fullPath: '/$sellerId/
|
|
406
|
-
preLoaderRoute: typeof
|
|
402
|
+
'/_authenticated/$sellerId/settings': {
|
|
403
|
+
id: '/_authenticated/$sellerId/settings'
|
|
404
|
+
path: '/settings'
|
|
405
|
+
fullPath: '/$sellerId/settings'
|
|
406
|
+
preLoaderRoute: typeof SettingsRouteImport
|
|
407
407
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
408
408
|
}
|
|
409
|
-
'/_authenticated/$sellerId/
|
|
410
|
-
id: '/_authenticated/$sellerId/
|
|
411
|
-
path: '/'
|
|
412
|
-
fullPath: '/$sellerId/
|
|
413
|
-
preLoaderRoute: typeof
|
|
414
|
-
parentRoute: typeof
|
|
409
|
+
'/_authenticated/$sellerId/earnings/': {
|
|
410
|
+
id: '/_authenticated/$sellerId/earnings/'
|
|
411
|
+
path: '/earnings'
|
|
412
|
+
fullPath: '/$sellerId/earnings/'
|
|
413
|
+
preLoaderRoute: typeof EarningsIndexRouteImport
|
|
414
|
+
parentRoute: typeof authenticatedSellerIdRoute
|
|
415
415
|
}
|
|
416
|
-
'/_authenticated/$sellerId/
|
|
417
|
-
id: '/_authenticated/$sellerId/
|
|
418
|
-
path: '/
|
|
419
|
-
fullPath: '/$sellerId/
|
|
420
|
-
preLoaderRoute: typeof
|
|
416
|
+
'/_authenticated/$sellerId/orders/': {
|
|
417
|
+
id: '/_authenticated/$sellerId/orders/'
|
|
418
|
+
path: '/orders'
|
|
419
|
+
fullPath: '/$sellerId/orders/'
|
|
420
|
+
preLoaderRoute: typeof OrdersIndexRouteImport
|
|
421
|
+
parentRoute: typeof authenticatedSellerIdRoute
|
|
422
|
+
}
|
|
423
|
+
'/_authenticated/$sellerId/orders/$orderId': {
|
|
424
|
+
id: '/_authenticated/$sellerId/orders/$orderId'
|
|
425
|
+
path: '/orders/$orderId'
|
|
426
|
+
fullPath: '/$sellerId/orders/$orderId'
|
|
427
|
+
preLoaderRoute: typeof OrdersOrderIdRouteImport
|
|
421
428
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
422
429
|
}
|
|
423
430
|
'/_authenticated/$sellerId/payouts/': {
|
|
@@ -427,39 +434,46 @@ declare module '@tanstack/react-router' {
|
|
|
427
434
|
preLoaderRoute: typeof PayoutsIndexRouteImport
|
|
428
435
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
429
436
|
}
|
|
430
|
-
'/_authenticated/$sellerId/
|
|
431
|
-
id: '/_authenticated/$sellerId/
|
|
432
|
-
path: '/
|
|
433
|
-
fullPath: '/$sellerId/
|
|
434
|
-
preLoaderRoute: typeof
|
|
437
|
+
'/_authenticated/$sellerId/payouts/$payoutId': {
|
|
438
|
+
id: '/_authenticated/$sellerId/payouts/$payoutId'
|
|
439
|
+
path: '/payouts/$payoutId'
|
|
440
|
+
fullPath: '/$sellerId/payouts/$payoutId'
|
|
441
|
+
preLoaderRoute: typeof PayoutsPayoutIdRouteImport
|
|
435
442
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
436
443
|
}
|
|
437
|
-
'/_authenticated/$sellerId/
|
|
438
|
-
id: '/_authenticated/$sellerId/
|
|
439
|
-
path: '/
|
|
440
|
-
fullPath: '/$sellerId/
|
|
441
|
-
preLoaderRoute: typeof
|
|
444
|
+
'/_authenticated/$sellerId/products/': {
|
|
445
|
+
id: '/_authenticated/$sellerId/products/'
|
|
446
|
+
path: '/products'
|
|
447
|
+
fullPath: '/$sellerId/products/'
|
|
448
|
+
preLoaderRoute: typeof ProductsIndexRouteImport
|
|
442
449
|
parentRoute: typeof authenticatedSellerIdRoute
|
|
443
450
|
}
|
|
444
|
-
'/_authenticated/$sellerId/
|
|
445
|
-
id: '/_authenticated/$sellerId/
|
|
446
|
-
path: '/
|
|
447
|
-
fullPath: '/$sellerId/
|
|
448
|
-
preLoaderRoute: typeof
|
|
449
|
-
parentRoute: typeof
|
|
451
|
+
'/_authenticated/$sellerId/products/$productId': {
|
|
452
|
+
id: '/_authenticated/$sellerId/products/$productId'
|
|
453
|
+
path: '/products/$productId'
|
|
454
|
+
fullPath: '/$sellerId/products/$productId'
|
|
455
|
+
preLoaderRoute: typeof ProductsProductIdRouteImport
|
|
456
|
+
parentRoute: typeof authenticatedSellerIdRoute
|
|
450
457
|
}
|
|
451
|
-
'/_authenticated/$sellerId/
|
|
452
|
-
id: '/_authenticated/$sellerId/
|
|
453
|
-
path: '/
|
|
454
|
-
fullPath: '/$sellerId/
|
|
455
|
-
preLoaderRoute: typeof
|
|
458
|
+
'/_authenticated/$sellerId/products/new': {
|
|
459
|
+
id: '/_authenticated/$sellerId/products/new'
|
|
460
|
+
path: '/products/new'
|
|
461
|
+
fullPath: '/$sellerId/products/new'
|
|
462
|
+
preLoaderRoute: typeof ProductsNewRouteImport
|
|
463
|
+
parentRoute: typeof authenticatedSellerIdRoute
|
|
464
|
+
}
|
|
465
|
+
'/_authenticated/$sellerId/settings/': {
|
|
466
|
+
id: '/_authenticated/$sellerId/settings/'
|
|
467
|
+
path: '/'
|
|
468
|
+
fullPath: '/$sellerId/settings/'
|
|
469
|
+
preLoaderRoute: typeof SettingsIndexRouteImport
|
|
456
470
|
parentRoute: typeof SettingsRoute
|
|
457
471
|
}
|
|
458
|
-
'/_authenticated/$sellerId/settings/
|
|
459
|
-
id: '/_authenticated/$sellerId/settings/
|
|
460
|
-
path: '/
|
|
461
|
-
fullPath: '/$sellerId/settings/
|
|
462
|
-
preLoaderRoute: typeof
|
|
472
|
+
'/_authenticated/$sellerId/settings/delivery-methods': {
|
|
473
|
+
id: '/_authenticated/$sellerId/settings/delivery-methods'
|
|
474
|
+
path: '/delivery-methods'
|
|
475
|
+
fullPath: '/$sellerId/settings/delivery-methods'
|
|
476
|
+
preLoaderRoute: typeof SettingsDeliveryMethodsRouteImport
|
|
463
477
|
parentRoute: typeof SettingsRoute
|
|
464
478
|
}
|
|
465
479
|
'/_authenticated/$sellerId/settings/package-types': {
|
|
@@ -469,40 +483,26 @@ declare module '@tanstack/react-router' {
|
|
|
469
483
|
preLoaderRoute: typeof SettingsPackageTypesRouteImport
|
|
470
484
|
parentRoute: typeof SettingsRoute
|
|
471
485
|
}
|
|
472
|
-
'/_authenticated/$sellerId/settings/
|
|
473
|
-
id: '/_authenticated/$sellerId/settings/
|
|
474
|
-
path: '/
|
|
475
|
-
fullPath: '/$sellerId/settings/
|
|
476
|
-
preLoaderRoute: typeof
|
|
486
|
+
'/_authenticated/$sellerId/settings/policies': {
|
|
487
|
+
id: '/_authenticated/$sellerId/settings/policies'
|
|
488
|
+
path: '/policies'
|
|
489
|
+
fullPath: '/$sellerId/settings/policies'
|
|
490
|
+
preLoaderRoute: typeof SettingsPoliciesRouteImport
|
|
477
491
|
parentRoute: typeof SettingsRoute
|
|
478
492
|
}
|
|
479
|
-
'/_authenticated/$sellerId/
|
|
480
|
-
id: '/_authenticated/$sellerId/
|
|
481
|
-
path: '/
|
|
482
|
-
fullPath: '/$sellerId/
|
|
483
|
-
preLoaderRoute: typeof
|
|
484
|
-
parentRoute: typeof
|
|
485
|
-
}
|
|
486
|
-
'/_authenticated/$sellerId/products/$productId': {
|
|
487
|
-
id: '/_authenticated/$sellerId/products/$productId'
|
|
488
|
-
path: '/products/$productId'
|
|
489
|
-
fullPath: '/$sellerId/products/$productId'
|
|
490
|
-
preLoaderRoute: typeof ProductsProductIdRouteImport
|
|
491
|
-
parentRoute: typeof authenticatedSellerIdRoute
|
|
492
|
-
}
|
|
493
|
-
'/_authenticated/$sellerId/payouts/$payoutId': {
|
|
494
|
-
id: '/_authenticated/$sellerId/payouts/$payoutId'
|
|
495
|
-
path: '/payouts/$payoutId'
|
|
496
|
-
fullPath: '/$sellerId/payouts/$payoutId'
|
|
497
|
-
preLoaderRoute: typeof PayoutsPayoutIdRouteImport
|
|
498
|
-
parentRoute: typeof authenticatedSellerIdRoute
|
|
493
|
+
'/_authenticated/$sellerId/settings/stock-locations': {
|
|
494
|
+
id: '/_authenticated/$sellerId/settings/stock-locations'
|
|
495
|
+
path: '/stock-locations'
|
|
496
|
+
fullPath: '/$sellerId/settings/stock-locations'
|
|
497
|
+
preLoaderRoute: typeof SettingsStockLocationsRouteImport
|
|
498
|
+
parentRoute: typeof SettingsRoute
|
|
499
499
|
}
|
|
500
|
-
'/_authenticated/$sellerId/
|
|
501
|
-
id: '/_authenticated/$sellerId/
|
|
502
|
-
path: '/
|
|
503
|
-
fullPath: '/$sellerId/
|
|
504
|
-
preLoaderRoute: typeof
|
|
505
|
-
parentRoute: typeof
|
|
500
|
+
'/_authenticated/$sellerId/settings/team': {
|
|
501
|
+
id: '/_authenticated/$sellerId/settings/team'
|
|
502
|
+
path: '/team'
|
|
503
|
+
fullPath: '/$sellerId/settings/team'
|
|
504
|
+
preLoaderRoute: typeof SettingsTeamRouteImport
|
|
505
|
+
parentRoute: typeof SettingsRoute
|
|
506
506
|
}
|
|
507
507
|
}
|
|
508
508
|
}
|
package/src/vite/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type SpreeDashboardPluginOptions as CoreOptions,
|
|
5
5
|
spreeDashboardPlugin as spreeDashboardCorePlugin,
|
|
6
6
|
} from '@spree/dashboard-core/vite'
|
|
7
|
+
import { linkedPackagePath } from '@spree/dashboard-core/vite/discover'
|
|
7
8
|
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
|
|
8
9
|
import { index, layout, physical, rootRoute, route } from '@tanstack/virtual-file-routes'
|
|
9
10
|
import type { PluginOption } from 'vite'
|
|
@@ -60,7 +61,11 @@ function sellerRouterPlugin(hostRoot: string, options: SpreeSellerDashboardPlugi
|
|
|
60
61
|
// `@spree/seller-dashboard` lives (workspace symlink or npm install). The
|
|
61
62
|
// `.` export maps to a file in src/, so `routes/` is its sibling.
|
|
62
63
|
const shellEntry = fromHost.resolve('@spree/seller-dashboard')
|
|
63
|
-
const shellRoutesDir =
|
|
64
|
+
const shellRoutesDir = linkedPackagePath(
|
|
65
|
+
hostRoot,
|
|
66
|
+
'@spree/seller-dashboard',
|
|
67
|
+
path.join(path.dirname(shellEntry), 'routes'),
|
|
68
|
+
)
|
|
64
69
|
|
|
65
70
|
const virtualRouteConfig = rootRoute('__root.tsx', [
|
|
66
71
|
route('/login', 'login.tsx'),
|