@mercurjs/docs 2.2.0-canary.51 → 2.2.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.
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Add a button to order details"
|
|
3
|
+
description: "Drop a 'Copy link' button onto the vendor order detail page with a widget — no forking, no page override."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The order detail page is a built-in panel screen you don't own. To add a small piece of UI to it — a button, a badge, a note — you don't copy the page. You drop a **widget** at one of its zones, and the SDK renders your component there while the rest of the page keeps working exactly as shipped.
|
|
7
|
+
|
|
8
|
+
This tutorial adds a **"Copy link"** button to the order summary section that copies a link to the order.
|
|
9
|
+
|
|
10
|
+
<Info>
|
|
11
|
+
**Additive, not a replacement.** A widget layers your component onto a built-in page at a documented zone. Reach for it first whenever you just want to *add* something to an existing screen.
|
|
12
|
+
</Info>
|
|
13
|
+
|
|
14
|
+
## Add the button
|
|
15
|
+
|
|
16
|
+
<Steps>
|
|
17
|
+
<Step title="Create the widget file">
|
|
18
|
+
Drop a file under `src/widgets/`. Export the component as the **default** and a `config` built with `defineWidgetConfig`. Target `orders.detail.summary.after` — your component renders in the order summary section footer and receives the loaded order as `data`.
|
|
19
|
+
|
|
20
|
+
```tsx apps/vendor/src/widgets/order-copy-link.tsx
|
|
21
|
+
import { defineWidgetConfig } from "@mercurjs/dashboard-sdk"
|
|
22
|
+
import type { HttpTypes } from "@medusajs/types"
|
|
23
|
+
import { Button, Container, toast } from "@medusajs/ui"
|
|
24
|
+
|
|
25
|
+
export const config = defineWidgetConfig({
|
|
26
|
+
zone: "orders.detail.summary.after",
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const OrderCopyLink = ({ data: order }: { data?: HttpTypes.AdminOrder }) => {
|
|
30
|
+
if (!order) return null
|
|
31
|
+
|
|
32
|
+
const orderLink = `${window.location.origin}/orders/${order.id}`
|
|
33
|
+
|
|
34
|
+
const handleCopy = async () => {
|
|
35
|
+
try {
|
|
36
|
+
await navigator.clipboard.writeText(orderLink)
|
|
37
|
+
toast.success("Link copied")
|
|
38
|
+
} catch {
|
|
39
|
+
toast.error("Couldn't copy the link")
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Container className="flex items-center justify-end p-3">
|
|
45
|
+
<Button size="small" variant="secondary" onClick={handleCopy}>
|
|
46
|
+
Copy link
|
|
47
|
+
</Button>
|
|
48
|
+
</Container>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default OrderCopyLink
|
|
53
|
+
```
|
|
54
|
+
</Step>
|
|
55
|
+
<Step title="Understand the zone id">
|
|
56
|
+
A zone id is `<domain>.<view>.<slot>.<placement>`. The last segment is the placement:
|
|
57
|
+
|
|
58
|
+
| Placement | Effect |
|
|
59
|
+
|-----------|--------|
|
|
60
|
+
| `before` | Renders before the built-in content of the zone |
|
|
61
|
+
| `after` | Renders after the built-in content |
|
|
62
|
+
|
|
63
|
+
Multiple `before` / `after` widgets on the same zone stack in registration order.
|
|
64
|
+
</Step>
|
|
65
|
+
<Step title="Reload the panel">
|
|
66
|
+
Start the project (`bun run dev`) and open any order in the vendor portal. Widget files hot-reload — the "Copy link" button appears in the summary section footer, and the rest of the page is untouched.
|
|
67
|
+
</Step>
|
|
68
|
+
</Steps>
|
|
69
|
+
|
|
70
|
+
## Order detail zones
|
|
71
|
+
|
|
72
|
+
Zones mounted on the vendor order detail page:
|
|
73
|
+
|
|
74
|
+
| Zone | Where it renders |
|
|
75
|
+
|------|------------------|
|
|
76
|
+
| `orders.detail.summary.before` / `.after` | Inside the order summary section (around its footer) |
|
|
77
|
+
| `orders.detail.main.before` / `.after` | Around the main column (summary, payment, fulfillment) |
|
|
78
|
+
| `orders.detail.side.before` / `.after` | Around the sidebar (customer, activity) |
|
|
79
|
+
|
|
80
|
+
Each is passed the loaded `order` as `data`. The full, valid set is typed as `WidgetZoneId` and generated from the panel's own zone hosts — let your editor autocomplete `zone:` to see every option. A zone no page renders can't be targeted and won't type-check.
|
|
81
|
+
|
|
82
|
+
## Verify
|
|
83
|
+
|
|
84
|
+
1. Open an order — the "Copy link" button renders in the summary section footer.
|
|
85
|
+
2. Click it — the link is copied and a toast appears.
|
|
86
|
+
3. Change the zone to `orders.detail.side.before` and reload — the button moves to the top of the sidebar.
|
|
87
|
+
4. Set `zone: "not.a.zone"` — `tsc` (`bun run lint`) fails with a "not assignable to `WidgetZoneId`" error.
|
|
88
|
+
5. Delete the file — the button disappears; nothing else changed.
|
|
89
|
+
|
|
90
|
+
## FAQ
|
|
91
|
+
|
|
92
|
+
<AccordionGroup>
|
|
93
|
+
<Accordion title="What can I read from the order?">
|
|
94
|
+
The zone passes the loaded order as `data` (`HttpTypes.AdminOrder`) — id, display id, totals, items, `payment_collections`, customer, and more. Build the link (or any UI) from it.
|
|
95
|
+
</Accordion>
|
|
96
|
+
<Accordion title="Can a block ship this instead of the host app?">
|
|
97
|
+
Yes. Put the same file in a [block](/rc/learn/blocks)'s `vendor_ui` entry under `src/widgets/`; installing the block adds the button with no wiring.
|
|
98
|
+
</Accordion>
|
|
99
|
+
<Accordion title="Can I render more than a button?">
|
|
100
|
+
The zone renders any React component — a badge, an action menu, a whole section. You have the full order in `data`.
|
|
101
|
+
</Accordion>
|
|
102
|
+
</AccordionGroup>
|
|
103
|
+
|
|
104
|
+
## Next steps
|
|
105
|
+
|
|
106
|
+
<CardGroup cols={2}>
|
|
107
|
+
<Card title="Add a widget" href="/rc/resources/tutorials/add-a-widget">
|
|
108
|
+
The general widget model and the full list of zones.
|
|
109
|
+
</Card>
|
|
110
|
+
<Card title="Extend forms and tables" href="/rc/resources/tutorials/extend-forms-and-tables">
|
|
111
|
+
Add validated fields and columns with defineCustomFieldsConfig.
|
|
112
|
+
</Card>
|
|
113
|
+
</CardGroup>
|
package/llms.txt
CHANGED
|
@@ -37,6 +37,7 @@ package (`node_modules/@mercurjs/docs/`).
|
|
|
37
37
|
- [Stripe Connect Integration](content/resources/integrations/stripe-connect.mdx) — Set up Stripe Connect for marketplace payments and seller payouts — from Stripe Dashboard configuration to the full end-to-end payment lifecycle.
|
|
38
38
|
- [Add a feature with a block](content/resources/tutorials/add-a-block.mdx) — Install the reviews block end-to-end and see it live across the admin, vendor, and storefront surfaces.
|
|
39
39
|
- [Add a widget](content/resources/tutorials/add-a-widget.mdx) — Inject a React component at a named zone on a built-in panel page with defineWidgetConfig — no forking.
|
|
40
|
+
- [Add a button to order details](content/resources/tutorials/add-order-detail-button.mdx) — Drop a 'Copy link' button onto the vendor order detail page with a widget — no forking, no page override.
|
|
40
41
|
- [Create attributes and variant axes](content/resources/tutorials/attributes-and-variant-axes.mdx) — Build the attribute catalog: a filterable attribute, a variant axis backed by a native product option, and an inline product-scoped axis.
|
|
41
42
|
- [Build your own block](content/resources/tutorials/build-a-block.mdx) — Author a reusable feature as a block — backend, panel UI, and docs — build it into a registry, and install it into any Mercur project.
|
|
42
43
|
- [Configure commissions](content/resources/tutorials/configure-commissions.mdx) — Set the global commission, add scoped rules for categories and sellers, and confirm the right rate lands on an order.
|