docs: added documentation for admin components (#9491)
- Documented common admin components with design that matches the admin. - Updated existing admin customization snippets to match the admin's design. Closes DOCS-964
This commit is contained in:
1 parent
e3dc9eaf0c
commit
74b286b701
22 files changed
+2385
-241
No files matched your search
@@ -18,3 +18,9 @@ You can customize the admin dashboard by:
|
||||
Medusa provides a Medusa UI package to facilitate your admin development through ready-made components and ensure a consistent design between your customizations and the dashboard’s design.
|
||||
|
||||
Refer to the [Medusa UI documentation](https://docs.medusajs.com/ui) to learn how to install it and use its components.
|
||||
|
||||
---
|
||||
|
||||
## Admin Components List
|
||||
|
||||
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-component) to find common components.
|
||||
@@ -41,7 +41,7 @@ const ProductWidget = () => {
|
||||
}, [loading])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Container className="divide-y p-0">
|
||||
{loading && <span>Loading...</span>}
|
||||
{!loading && <span>You have {productsCount} Product(s).</span>}
|
||||
</Container>
|
||||
@@ -78,7 +78,7 @@ import { Link } from "react-router-dom"
|
||||
// The widget
|
||||
const ProductWidget = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Container className="divide-y p-0">
|
||||
<Link to={"/orders"}>View Orders</Link>
|
||||
</Container>
|
||||
)
|
||||
|
||||
@@ -21,10 +21,16 @@ A UI route is created in a file named `page.tsx` under the `src/admin/routes` di
|
||||
For example, create the file `src/admin/routes/custom/page.tsx` with the following content:
|
||||
|
||||
```tsx title="src/admin/routes/custom/page.tsx"
|
||||
import { Container } from "@medusajs/ui"
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
|
||||
const CustomPage = () => {
|
||||
return <Container>This is my custom route</Container>
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">This is my custom route</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomPage
|
||||
@@ -59,17 +65,23 @@ A UI route file can export a configuration object that indicates a new item must
|
||||
For example:
|
||||
|
||||
export const highlights = [
|
||||
["14", "label", "The label of the UI route's sidebar item."],
|
||||
["15", "icon", "The icon of the UI route's sidebar item."]
|
||||
["16", "label", "The label of the UI route's sidebar item."],
|
||||
["17", "icon", "The icon of the UI route's sidebar item."]
|
||||
]
|
||||
|
||||
```tsx title="src/admin/routes/custom/page.tsx" highlights={[["21"], ["22"], ["23"], ["24"], ["25"], ["26"]]}
|
||||
```tsx title="src/admin/routes/custom/page.tsx" highlights={highlights}
|
||||
import { defineRouteConfig } from "@medusajs/admin-sdk"
|
||||
import { ChatBubbleLeftRight } from "@medusajs/icons"
|
||||
import { Container } from "@medusajs/ui"
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
|
||||
const CustomPage = () => {
|
||||
return <Container>This is my custom route</Container>
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">This is my custom route</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export const config = defineRouteConfig({
|
||||
@@ -101,8 +113,10 @@ import { Container, Heading } from "@medusajs/ui"
|
||||
|
||||
const CustomSettingPage = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Heading level="h1">Custom Setting Page</Heading>
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h1">Custom Setting Page</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -124,14 +138,20 @@ A UI route can accept path parameters if the name of any of the directories in i
|
||||
|
||||
For example, create the file `src/admin/routes/custom/[id]/page.tsx` with the following content:
|
||||
|
||||
```tsx title="src/admin/routes/custom/[id]/page.tsx" highlights={[["5", "", "Retrieve the path parameter."], ["7", "{id}", "Show the path parameter."]]}
|
||||
```tsx title="src/admin/routes/custom/[id]/page.tsx" highlights={[["5", "", "Retrieve the path parameter."], ["10", "{id}", "Show the path parameter."]]}
|
||||
import { useParams } from "react-router-dom"
|
||||
import { Container } from "@medusajs/ui"
|
||||
|
||||
const CustomPage = () => {
|
||||
const { id } = useParams()
|
||||
|
||||
return <Container>Passed ID: {id}</Container>
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h1">Passed ID: {id}</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomPage
|
||||
@@ -140,3 +160,9 @@ export default CustomPage
|
||||
You access the passed parameter using `react-router-dom`'s [useParams hook](https://reactrouter.com/en/main/hooks/use-params).
|
||||
|
||||
If you run the Medusa application and go to `localhost:9000/app/custom/123`, you'll see `123` printed in the page.
|
||||
|
||||
---
|
||||
|
||||
## Admin Components List
|
||||
|
||||
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-component) to find common components.
|
||||
@@ -24,7 +24,7 @@ For example, create the file `src/admin/widgets/product-widget.tsx` with the fol
|
||||
|
||||
export const widgetHighlights = [
|
||||
["5", "ProductWidget", "The React component of the product widget."],
|
||||
["15", "zone", "The zone to inject the widget to."]
|
||||
["17", "zone", "The zone to inject the widget to."]
|
||||
]
|
||||
|
||||
```tsx title="src/admin/widgets/product-widget.tsx" highlights={widgetHighlights}
|
||||
@@ -34,8 +34,10 @@ import { Container, Heading } from "@medusajs/ui"
|
||||
// The widget
|
||||
const ProductWidget = () => {
|
||||
return (
|
||||
<Container>
|
||||
<Heading level="h2">Product Widget</Heading>
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">Product Widget</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -85,7 +87,7 @@ For example:
|
||||
export const detailHighlights = [
|
||||
["10", "data", "Receive the data as a prop."],
|
||||
["11", "AdminProduct", "Pass the expected type of `data` as a type argument."],
|
||||
["15", "data.title"]
|
||||
["16", "data.title", "Show the product's title."]
|
||||
]
|
||||
|
||||
```tsx title="src/admin/widgets/product-widget.tsx" highlights={detailHighlights}
|
||||
@@ -101,10 +103,12 @@ const ProductWidget = ({
|
||||
data,
|
||||
}: DetailWidgetProps<AdminProduct>) => {
|
||||
return (
|
||||
<Container>
|
||||
<Heading level="h2">
|
||||
Product Widget {data.title}
|
||||
</Heading>
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">
|
||||
Product Widget {data.title}
|
||||
</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,12 +24,15 @@ For example, create the file `src/admin/widgets/product-widget.tsx` with the fol
|
||||
|
||||
```tsx title="src/admin/widgets/product-widget.tsx"
|
||||
import { defineWidgetConfig } from "@medusajs/admin-sdk"
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
|
||||
const ProductWidget = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2>Product Widget</h2>
|
||||
</div>
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">Product Widget</Heading>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -42,6 +45,8 @@ export default ProductWidget
|
||||
|
||||
This inserts a widget with the text “Product Widget” at the beginning of a product’s details page.
|
||||
|
||||
In your widget, use custom components from the [Medusa UI package](https://docs.medusajs.com/ui).
|
||||
|
||||
### Test the Widget
|
||||
|
||||
To test out the widget, start the Medusa application:
|
||||
@@ -51,3 +56,9 @@ npm run dev
|
||||
```
|
||||
|
||||
Then, open a product’s details page in the Medusa Admin. You’ll find your custom widget at the top of the page.
|
||||
|
||||
---
|
||||
|
||||
## Admin Components List
|
||||
|
||||
To build admin customizations that match the Medusa Admin's designs and layouts, refer to [this guide](!resources!/admin-component) to find common components.
|
||||
@@ -116,24 +116,28 @@ const BrandsPage = () => {
|
||||
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Heading level="h2">Brands</Heading>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>ID</Table.HeaderCell>
|
||||
<Table.HeaderCell>Name</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{brands.map((brand) => (
|
||||
<Table.Row key={brand.id}>
|
||||
<Table.Cell>{brand.id}</Table.Cell>
|
||||
<Table.Cell>{brand.name}</Table.Cell>
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">Brands</Heading>
|
||||
</div>
|
||||
<div className="flex h-full flex-col overflow-hidden !border-t-0">
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>ID</Table.HeaderCell>
|
||||
<Table.HeaderCell>Name</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{brands.map((brand) => (
|
||||
<Table.Row key={brand.id}>
|
||||
<Table.Cell>{brand.id}</Table.Cell>
|
||||
<Table.Cell>{brand.name}</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -147,6 +151,12 @@ This adds a new page in the admin at `http://localhost:9000/app/brands`.
|
||||
|
||||
In the UI route's component, you retrieve the brands from the `/admin/brands` API route. You show the brands in a table.
|
||||
|
||||
<Note>
|
||||
|
||||
Admin customizations can use the [Medusa UI package](!ui!) to align your customizations with the admin's design. Also, [this guide](!resources!/admin-components) includes examples of common components in the Medusa Admin.
|
||||
|
||||
</Note>
|
||||
|
||||
### Add UI Route to the Sidebar
|
||||
|
||||
To add the UI route to the sidebar, replace the `TODO` at the end of the file with the following:
|
||||
|
||||
@@ -29,7 +29,7 @@ export const highlights = [
|
||||
["7", "data", "Receive the product's details as a prop"],
|
||||
["9", "brand", "A state variable to store the brand"],
|
||||
["19", "fetch", "Retrieve the brand of a product using the custom API route"],
|
||||
["39", "zone", "Show the widget at the top of the product details page."]
|
||||
["41", "zone", "Show the widget at the top of the product details page."]
|
||||
]
|
||||
|
||||
```tsx title="src/admin/widgets/product-brand.tsx" highlights={highlights}
|
||||
@@ -62,8 +62,10 @@ const ProductBrandWidget = ({
|
||||
}, [loading])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Heading level="h2">Brand</Heading>
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading level="h2">Brand</Heading>
|
||||
</div>
|
||||
{loading && <span>Loading...</span>}
|
||||
{brand && <span>Name: {brand.name}</span>}
|
||||
</Container>
|
||||
@@ -91,7 +93,7 @@ In the widget, you fetch the product's brand from the `/admin/products/:id/brand
|
||||
|
||||
<Note>
|
||||
|
||||
Admin customizations can use the [Medusa UI package](!ui!) to align your customizations with the admin's design.
|
||||
Admin customizations can use the [Medusa UI package](!ui!) to align your customizations with the admin's design. Also, [this guide](!resources!/admin-components) includes examples of common components in the Medusa Admin.
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
Reference in new issue
Block a user