Dashboard
Full dashboard screens — KPI stats, charts, tables and activity feeds across finance, commerce, support, analytics and observability.
Preview
@props([
'title' => 'Analytics',
'subtitle' => 'Performance across your workspace for the last 30 days.',
'kpis' => null,
'channels' => null,
'rows' => null,
])
@php
$kpis ??= [
['label' => 'Total visitors', 'value' => '48,210', 'delta' => '+12.4%', 'tone' => 'success'],
['label' => 'Conversion rate', 'value' => '3.8%', 'delta' => '+0.6%', 'tone' => 'success'],
['label' => 'Avg. session', 'value' => '4m 12s', 'delta' => '-3.1%', 'tone' => 'warning'],
['label' => 'Bounce rate', 'value' => '38.2%', 'delta' => '-1.4%', 'tone' => 'success'],
];
// Sparkline-style bars (height percentages) — illustrative, swap for a chart lib.
$channels ??= [22, 40, 33, 58, 47, 65, 52, 78, 70, 88, 74, 96];
$rows ??= [
['page' => '/pricing', 'views' => '12,430', 'rate' => '5.2%', 'tone' => 'success'],
['page' => '/docs/installation', 'views' => '9,118', 'rate' => '4.1%', 'tone' => 'success'],
['page' => '/blog/launch', 'views' => '6,742', 'rate' => '2.0%', 'tone' => 'warning'],
['page' => '/changelog', 'views' => '3,905', 'rate' => '1.3%', 'tone' => 'destructive'],
];
@endphp
<section data-surface="admin" {{ $attributes->merge(['class' => 'min-h-svh bg-background p-4 text-foreground sm:p-6 lg:p-8']) }}>
<div class="mx-auto max-w-7xl space-y-6">
<div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
<div>
<h1 class="text-2xl font-bold tracking-tight">{{ __($title) }}</h1>
<p class="mt-2 text-muted-foreground">{{ __($subtitle) }}</p>
</div>
<div class="flex gap-2">
<x-ui.button variant="outline" size="sm">{{ __('Last 30 days') }}</x-ui.button>
<x-ui.button size="sm">{{ __('Export') }}</x-ui.button>
</div>
</div>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
@foreach ($kpis as $kpi)
<x-ui.card>
<x-ui.card.header class="gap-2">
<x-ui.card.description>{{ __($kpi['label']) }}</x-ui.card.description>
<div class="flex items-center justify-between gap-2">
<x-ui.card.title class="text-2xl">{{ $kpi['value'] }}</x-ui.card.title>
<x-ui.badge :variant="$kpi['tone'] ?? 'default'">{{ $kpi['delta'] }}</x-ui.badge>
</div>
</x-ui.card.header>
</x-ui.card>
@endforeach
</div>
<div class="grid gap-6 lg:grid-cols-[2fr_1fr]">
<x-ui.card>
<x-ui.card.header>
<x-ui.card.title>{{ __('Visitors over time') }}</x-ui.card.title>
<x-ui.card.description>{{ __('Daily unique visitors.') }}</x-ui.card.description>
</x-ui.card.header>
<x-ui.card.content>
<div class="flex h-40 items-end gap-2" role="img" aria-label="{{ __('Bar chart of visitors over time') }}">
@foreach ($channels as $h)
<div class="flex-1 rounded-t bg-primary/80" style="height: {{ $h }}%"></div>
@endforeach
</div>
</x-ui.card.content>
</x-ui.card>
<x-ui.card>
<x-ui.card.header>
<x-ui.card.title>{{ __('Traffic sources') }}</x-ui.card.title>
</x-ui.card.header>
<x-ui.card.content class="space-y-4 text-sm">
@foreach (['Organic' => 62, 'Referral' => 24, 'Direct' => 14] as $label => $pct)
<div>
<div class="mb-2 flex items-center justify-between">
<span>{{ __($label) }}</span>
<span class="text-muted-foreground">{{ $pct }}%</span>
</div>
<x-ui.progress :value="$pct" :label="__(':label progress', ['label' => $label])" />
</div>
@endforeach
</x-ui.card.content>
</x-ui.card>
</div>
<x-ui.card>
<x-ui.card.header>
<x-ui.card.title>{{ __('Top pages') }}</x-ui.card.title>
<x-ui.card.description>{{ __('Most visited pages and their conversion rate.') }}</x-ui.card.description>
</x-ui.card.header>
<x-ui.card.content>
<x-ui.table>
<x-ui.table.header>
<x-ui.table.row>
<x-ui.table.head>{{ __('Page') }}</x-ui.table.head>
<x-ui.table.head class="text-end">{{ __('Views') }}</x-ui.table.head>
<x-ui.table.head class="text-end">{{ __('Conversion') }}</x-ui.table.head>
</x-ui.table.row>
</x-ui.table.header>
<x-ui.table.body>
@foreach ($rows as $row)
<x-ui.table.row>
<x-ui.table.cell class="font-medium">{{ $row['page'] }}</x-ui.table.cell>
<x-ui.table.cell class="text-end tabular-nums">{{ $row['views'] }}</x-ui.table.cell>
<x-ui.table.cell class="text-end">
<x-ui.badge :variant="$row['tone'] ?? 'default'">{{ $row['rate'] }}</x-ui.badge>
</x-ui.table.cell>
</x-ui.table.row>
@endforeach
</x-ui.table.body>
</x-ui.table>
</x-ui.card.content>
</x-ui.card>
</div>
</section>
Installation
php artisan ui:add pages/dashboard-traffic
Registry contract
Install confidence
php artisan ui:add pages/dashboard-traffic
writes only the generated targets below. The CLI validates each file hash before writing and
prompts before replacing local changes unless --force is used.
- Version
- 1.2.2
- License
- open
- Stability
- stable
- Contract
- v1
- Foundation
- ≥ 1.0.0
| Type | Generated target |
|---|---|
| blade | resources/views/pages/dashboard-traffic.blade.php |
Registry dependencies
Package dependencies
composer: jml/brok:^0.2
Use with AI
A brief for your coding agent: what the page is, the install command, how to render it, its props and the rules. Copy it, or open a prompt about this page in an assistant.
# Brok UI page: Analytics Dashboard (`dashboard-traffic`)
An analytics dashboard with KPI cards, a bar chart, traffic-source meters, and a top-pages table.
Brok UI is a Laravel Blade registry. `ui:add` copies this page into the app as plain Blade the app owns; it composes installed `<brok:*>` primitives and semantic design tokens.
## Install
```bash
php artisan ui:add pages/dashboard-traffic
```
## Render it
```blade
<x-pages.dashboard-traffic />
```
## Props
- `title` (string, default `Analytics`) — Section heading.
- `subtitle` (string, default `Performance across your workspace for the last 30 days.`) — Supporting copy under the heading.
- `kpis` (mixed|null, default `null`) — KPI cards ({label, value, delta, tone}); null falls back to sample data.
- `channels` (mixed|null, default `null`) — Sparkline-style bar height percentages for the visitors chart; null falls back to sample data.
- `rows` (mixed|null, default `null`) — Top-pages table rows ({page, views, rate, tone}); null falls back to sample data.
## Use when
- An admin analytics dashboard screen with KPI cards, a bar chart, traffic-source meters and a top-pages table.
- It composes primitives directly (button, card, badge, table, progress) rather than marketing blocks.
## Avoid when
- Needing a finance, support or commerce dashboard; use dashboard-dense-kpi, dashboard-support or dashboard-commerce instead. Needing richer visitor and Core Web Vitals charts; use dashboard-analytics instead.
## Rules
- Render the installed page with `<x-pages.dashboard-traffic />` and pass data through its props; edit the copied file only for structural changes.
- Keep the semantic design tokens (`bg-background`, `text-muted-foreground`); never swap in raw colour utilities.
- Keep the `data-slot` attributes and the logical (start/end) spacing so the markup still mirrors under `dir="rtl"`.
## Links
- Docs: https://brokui.dev/pages/dashboard-traffic
- Registry JSON (files, props, contract): https://brokui.dev/r/open/pages/dashboard-traffic.json
Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.
Guidance
Use when
- An admin analytics dashboard screen with KPI cards, a bar chart, traffic-source meters and a top-pages table.
- It composes primitives directly (button, card, badge, table, progress) rather than marketing blocks.
Avoid when
- Needing a finance, support or commerce dashboard; use dashboard-dense-kpi, dashboard-support or dashboard-commerce instead. Needing richer visitor and Core Web Vitals charts; use dashboard-analytics instead.
Anti-patterns
- Do not replace semantic props with conflicting utility classes.
- Do not remove labels, focus styles, or state attributes.
Usage
Render the page as a component, or wire it to a route. Pass data where useful:
<x-pages.dashboard-traffic />
Built from blocks & primitives
This page composes installed <brok:*> primitives and semantic design
tokens only — it does not reimplement any primitive. Re-theme it (light, dark, admin, customer) by
editing CSS variables; flip the preview to RTL to confirm it mirrors.
Source
The exact, editable file ui:add writes
into your app. The preview above renders this same source — there are no preview-only pages.
@props([
'title' => 'Analytics',
'subtitle' => 'Performance across your workspace for the last 30 days.',
'kpis' => null,
'channels' => null,
'rows' => null,
])
@php
$kpis ??= [
['label' => 'Total visitors', 'value' => '48,210', 'delta' => '+12.4%', 'tone' => 'success'],
['label' => 'Conversion rate', 'value' => '3.8%', 'delta' => '+0.6%', 'tone' => 'success'],
['label' => 'Avg. session', 'value' => '4m 12s', 'delta' => '-3.1%', 'tone' => 'warning'],
['label' => 'Bounce rate', 'value' => '38.2%', 'delta' => '-1.4%', 'tone' => 'success'],
];
// Sparkline-style bars (height percentages) — illustrative, swap for a chart lib.
$channels ??= [22, 40, 33, 58, 47, 65, 52, 78, 70, 88, 74, 96];
$rows ??= [
['page' => '/pricing', 'views' => '12,430', 'rate' => '5.2%', 'tone' => 'success'],
['page' => '/docs/installation', 'views' => '9,118', 'rate' => '4.1%', 'tone' => 'success'],
['page' => '/blog/launch', 'views' => '6,742', 'rate' => '2.0%', 'tone' => 'warning'],
['page' => '/changelog', 'views' => '3,905', 'rate' => '1.3%', 'tone' => 'destructive'],
];
@endphp
<section data-surface="admin" {{ $attributes->merge(['class' => 'min-h-svh bg-background p-4 text-foreground sm:p-6 lg:p-8']) }}>
<div class="mx-auto max-w-7xl space-y-6">
<div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
<div>
<h1 class="text-2xl font-bold tracking-tight">{{ __($title) }}</h1>
<p class="mt-2 text-muted-foreground">{{ __($subtitle) }}</p>
</div>
<div class="flex gap-2">
<x-ui.button variant="outline" size="sm">{{ __('Last 30 days') }}</x-ui.button>
<x-ui.button size="sm">{{ __('Export') }}</x-ui.button>
</div>
</div>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
@foreach ($kpis as $kpi)
<x-ui.card>
<x-ui.card.header class="gap-2">
<x-ui.card.description>{{ __($kpi['label']) }}</x-ui.card.description>
<div class="flex items-center justify-between gap-2">
<x-ui.card.title class="text-2xl">{{ $kpi['value'] }}</x-ui.card.title>
<x-ui.badge :variant="$kpi['tone'] ?? 'default'">{{ $kpi['delta'] }}</x-ui.badge>
</div>
</x-ui.card.header>
</x-ui.card>
@endforeach
</div>
<div class="grid gap-6 lg:grid-cols-[2fr_1fr]">
<x-ui.card>
<x-ui.card.header>
<x-ui.card.title>{{ __('Visitors over time') }}</x-ui.card.title>
<x-ui.card.description>{{ __('Daily unique visitors.') }}</x-ui.card.description>
</x-ui.card.header>
<x-ui.card.content>
<div class="flex h-40 items-end gap-2" role="img" aria-label="{{ __('Bar chart of visitors over time') }}">
@foreach ($channels as $h)
<div class="flex-1 rounded-t bg-primary/80" style="height: {{ $h }}%"></div>
@endforeach
</div>
</x-ui.card.content>
</x-ui.card>
<x-ui.card>
<x-ui.card.header>
<x-ui.card.title>{{ __('Traffic sources') }}</x-ui.card.title>
</x-ui.card.header>
<x-ui.card.content class="space-y-4 text-sm">
@foreach (['Organic' => 62, 'Referral' => 24, 'Direct' => 14] as $label => $pct)
<div>
<div class="mb-2 flex items-center justify-between">
<span>{{ __($label) }}</span>
<span class="text-muted-foreground">{{ $pct }}%</span>
</div>
<x-ui.progress :value="$pct" :label="__(':label progress', ['label' => $label])" />
</div>
@endforeach
</x-ui.card.content>
</x-ui.card>
</div>
<x-ui.card>
<x-ui.card.header>
<x-ui.card.title>{{ __('Top pages') }}</x-ui.card.title>
<x-ui.card.description>{{ __('Most visited pages and their conversion rate.') }}</x-ui.card.description>
</x-ui.card.header>
<x-ui.card.content>
<x-ui.table>
<x-ui.table.header>
<x-ui.table.row>
<x-ui.table.head>{{ __('Page') }}</x-ui.table.head>
<x-ui.table.head class="text-end">{{ __('Views') }}</x-ui.table.head>
<x-ui.table.head class="text-end">{{ __('Conversion') }}</x-ui.table.head>
</x-ui.table.row>
</x-ui.table.header>
<x-ui.table.body>
@foreach ($rows as $row)
<x-ui.table.row>
<x-ui.table.cell class="font-medium">{{ $row['page'] }}</x-ui.table.cell>
<x-ui.table.cell class="text-end tabular-nums">{{ $row['views'] }}</x-ui.table.cell>
<x-ui.table.cell class="text-end">
<x-ui.badge :variant="$row['tone'] ?? 'default'">{{ $row['rate'] }}</x-ui.badge>
</x-ui.table.cell>
</x-ui.table.row>
@endforeach
</x-ui.table.body>
</x-ui.table>
</x-ui.card.content>
</x-ui.card>
</div>
</section>
Ownership & lifecycle
Owner, release state, review evidence and adoption for this item.
- Owner
- Platform UI (@JoshJML)
- Current version
-
1.2.2 - Status
- Stable
- License
-
open - Deprecation
- Not deprecated
- Contract
-
v1 - Foundation
-
≥ 1.0.0