Skip to content

Admin dashboard

The back office of Grange, a shop that does not exist. A rail, an app bar, four figures, a filter row and a table with an action on every row, all on one screen and all at the same size, which is the arrangement that shows whether a size ladder actually holds.

The whole screen is one file: docs/.vitepress/demos/examples/dashboard.tsx. It is live, search the table, filter it by channel or status, tick some rows and the bulk actions appear.

Composition

BlockComponentsWorth noticing
RailPlList PlListItem PlIcon PlBadge PlPill PlCard PlProgressLinearrender={<nav />} makes the list a real landmark, selected marks the current row, and the unread count sits in endIcon
App barPlToolbar PlBreadcrumb PlBadge PlIconButton PlTooltip PlAvatarposition="sticky" keeps the actions reachable while the page scrolls under them
AlertPlAlertOne thing needs attention, said once, at the top, with its own action
FiguresPlCard PlTypography PlProgressLinear PlProgressCircularA bar for progress towards a target, a ring where the figure is a share of a whole
FiltersPlTextField PlSelect PlDateRangePicker PlSegmentedButtonAt size="sm" the field, the select and the range picker are the same height, so the row keeps one baseline
TablePlTable PlCheckbox PlChip PlMenu PlIconButton PlPaginationSelect-all is an indeterminate checkbox in the header cell, and every row carries its own PlMenu
Bulk actionsPlButton PlModal PlToastThey appear only with a selection; the destructive one confirms in a PlModal and reports with an undoable toast
Bottom rowPlCard PlTimeline PlSwitch PlDividerWhat happened, and what reaches you, the same card at the same elevation, twice
SettingsPlDrawer PlSelect PlSwitchThe settings that do not belong on the screen, in a sheet that slides over it

Notes

  • The status filter is a PlSegmentedButton rather than PlTabs. Nothing below it is a panel, it is the same table either way, and a segmented button is one value out of four.
  • Filtering is ordinary React state. PlTable renders whatever it is handed and shows empty when that is nothing.
  • Every row action has an accessible name that says which row it belongs to, because label on the trigger PlIconButton includes the order id.
  • The bulk-action PlModal passes modal="trap-focus". A fully modal dialog makes the page behind it inert, which is right in an app and wrong inside a documentation preview.

Next

Released under the MIT License