Skip to content
Brok UI

Loading…

No results

Dashboard

Open + Pro variants

Full dashboard screens — KPI stats, charts, tables and activity feeds across finance, commerce, support, analytics and observability.

2 of 12

Preview

resources/views/pages/dashboard-spending.blade.php Blade
@props([
    'name' => 'Alex',
    'stats' => null,
    'ranges' => null,
    'categories' => null,
    'transactions' => null,
])

{{--
    Dashboard Spending — content-only finance dashboard (drop into an app
    shell such as app-shell-assistant for the sidebar/AI rail; this page owns
    none of that chrome). A welcome header, a four-up KPI tray row, a
    revenue-vs-expense comparison chart, and a two-column spending-breakdown
    + transactions-list row.

    The sample figures agree with each other: chart-comparison's own bundled
    "Last 30 days" totals (Revenue $8,750.00, Expense $1,852.00) are echoed
    in the KPI row, net profit is revenue minus expense, cash flow is net
    profit less a stated pending-receivables gap, and the spending-breakdown
    categories below sum to the same $1,852.00 total expense.
--}}

@php
    // Fixed inline icon set for the KPI tray headers — hand-authored, trusted
    // markup (not user data), safe to print unescaped in the loop below.
    $icons = [
        'bar-chart' => '<path d="M3 3v18h18"/><path d="M8 17V9"/><path d="M13 17V5"/><path d="M18 17v-7"/>',
        'coin' => '<circle cx="12" cy="12" r="10"/><path d="M14.8 9A2 2 0 0 0 13 8h-2a2 2 0 0 0 0 4h2a2 2 0 0 1 0 4h-2a2 2 0 0 1-1.8-1"/><path d="M12 6v2"/><path d="M12 16v2"/>',
        'trending-up' => '<path d="M22 7 13.5 15.5 8.5 10.5 2 17"/><path d="M16 7h6v6"/>',
        'swap' => '<path d="m17 3 4 4-4 4"/><path d="M21 7H9"/><path d="m7 21-4-4 4-4"/><path d="M3 17h12"/>',
    ];

    // Revenue and expense mirror blocks/chart-comparison's own bundled 30-day
    // sample one-for-one, so the KPI row and the chart panel underneath never
    // disagree. Net profit is revenue minus expense; cash flow is net profit
    // less a stated pending-receivables gap (both spelled out in the
    // description so the figures read as derived, not arbitrary).
    $stats ??= [
        ['title' => __('Total revenue'), 'icon' => 'bar-chart', 'value' => '$8,750.00', 'delta' => '+12%', 'description' => __('vs last month')],
        ['title' => __('Total expense'), 'icon' => 'coin', 'value' => '$1,852.00', 'delta' => '-3%', 'description' => __('vs last month'), 'inverse' => true],
        ['title' => __('Net profit'), 'icon' => 'trending-up', 'value' => '$6,898.00', 'delta' => '+16.9%', 'description' => __('Revenue minus expense')],
        ['title' => __('Cash flow'), 'icon' => 'swap', 'value' => '$6,240.00', 'delta' => '+17.1%', 'description' => __('Net profit less pending receivables')],
    ];

    // Spending-breakdown categories are a subset of the same $1,852.00 total
    // expense above (45% / 30% / 25% of it), not a separate, disagreeing figure.
    $categories ??= [
        ['name' => __('Housing'), 'percent' => 45, 'amount' => '$833.40', 'icon' => 'home'],
        ['name' => __('Food & Dining'), 'percent' => 30, 'amount' => '$555.60', 'icon' => 'utensils'],
        ['name' => __('Transport'), 'percent' => 25, 'amount' => '$463.00', 'icon' => 'car'],
    ];
@endphp

<main id="main-content" 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">
        {{-- Welcome header --}}
        <div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
            <h1 class="text-2xl font-bold tracking-tight">{{ __('Welcome back, :name', ['name' => $name]) }}</h1>
            <x-ui.button size="sm">
                <svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="M5 12h14"/></svg>
                {{ __('Add new') }}
            </x-ui.button>
        </div>

        {{-- KPI tray row --}}
        <div data-slot="dashboard-spending-kpis" class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            @foreach ($stats as $stat)
                <x-ui.tray :title="$stat['title']">
                    <x-slot:icon>
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{!! $icons[$stat['icon']] ?? '' !!}</svg>
                    </x-slot:icon>
                    <x-ui.stat
                        variant="plain"
                        :value="$stat['value']"
                        :delta="$stat['delta']"
                        :description="$stat['description'] ?? null"
                        :inverse="$stat['inverse'] ?? false"
                    />
                </x-ui.tray>
            @endforeach
        </div>

        {{-- Revenue vs. expense comparison --}}
        <x-blocks.chart-comparison :ranges="$ranges" />

        {{-- Spending breakdown + transactions --}}
        <div class="grid gap-6 lg:grid-cols-2">
            <x-blocks.metrics-breakdown :categories="$categories" total="$1,852.00" delta="-3%" />
            <x-blocks.transactions-list :transactions="$transactions" />
        </div>
    </div>
</main>

Installation

terminal
php artisan ui:add pages/dashboard-spending

Registry contract

Install confidence

php artisan ui:add pages/dashboard-spending 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.0.1
License
open
Stability
stable
Contract
v1
Foundation
≥ 1.0.0
Type Generated target
blade resources/views/pages/dashboard-spending.blade.php

Registry dependencies

tray stat button blocks/chart-comparison blocks/metrics-breakdown blocks/transactions-list

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.

dashboard-spending.md
# Brok UI page: Dashboard Spending (`dashboard-spending`)

A spending dashboard: a welcome header with an 'Add new' action, a four-up KPI tray row (revenue, expense, net profit, cash flow), a revenue-vs-expense comparison chart, and a two-column spending breakdown plus transactions panel.

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-spending
```

## Render it

```blade
<x-pages.dashboard-spending />
```

## Props

- `name` (string, default `Alex`) — First name used in the 'Welcome back, :name' heading.
- `stats` (mixed|null, default `null`) — Four KPI tray tiles ({title, icon, value, delta, description, inverse?}); null falls back to sample data that ties to the chart/breakdown below (revenue $8,750, expense $1,852, net profit $6,898, cash flow $6,240).
- `ranges` (mixed|null, default `null`) — Forwarded to blocks/chart-comparison's `ranges` prop; null renders its bundled sample.
- `categories` (mixed|null, default `null`) — Forwarded to blocks/metrics-breakdown's `categories` prop; null falls back to a Housing/Food & Dining/Transport split that sums to the sample total expense.
- `transactions` (mixed|null, default `null`) — Forwarded to blocks/transactions-list's `transactions` prop; null renders its bundled sample.

## Use when

- A finance/spending overview screen needs a welcome header, four KPI tiles framed in trays, a revenue-vs-expense comparison chart, and a spending breakdown alongside a transactions panel.
- The screen is dropped into an app shell (see app-shell-assistant) rather than owning its own sidebar/AI rail — this page is content-only.

## Avoid when

- A general KPI-and-sales-chart overview is enough; use dashboard-overview instead.
- The page needs its own sidebar navigation or AI rail; compose app-shell-assistant around this page instead.

## Rules

- Render the installed page with `<x-pages.dashboard-spending />` 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-spending
- Registry JSON (files, props, contract): https://brokui.dev/r/open/pages/dashboard-spending.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

  • A finance/spending overview screen needs a welcome header, four KPI tiles framed in trays, a revenue-vs-expense comparison chart, and a spending breakdown alongside a transactions panel.
  • The screen is dropped into an app shell (see app-shell-assistant) rather than owning its own sidebar/AI rail — this page is content-only.

Avoid when

  • A general KPI-and-sales-chart overview is enough; use dashboard-overview instead.
  • The page needs its own sidebar navigation or AI rail; compose app-shell-assistant around this page 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:

resources/views/welcome.blade.php Blade
<x-pages.dashboard-spending />

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.

resources/views/pages/dashboard-spending.blade.php Blade
@props([
    'name' => 'Alex',
    'stats' => null,
    'ranges' => null,
    'categories' => null,
    'transactions' => null,
])

{{--
    Dashboard Spending — content-only finance dashboard (drop into an app
    shell such as app-shell-assistant for the sidebar/AI rail; this page owns
    none of that chrome). A welcome header, a four-up KPI tray row, a
    revenue-vs-expense comparison chart, and a two-column spending-breakdown
    + transactions-list row.

    The sample figures agree with each other: chart-comparison's own bundled
    "Last 30 days" totals (Revenue $8,750.00, Expense $1,852.00) are echoed
    in the KPI row, net profit is revenue minus expense, cash flow is net
    profit less a stated pending-receivables gap, and the spending-breakdown
    categories below sum to the same $1,852.00 total expense.
--}}

@php
    // Fixed inline icon set for the KPI tray headers — hand-authored, trusted
    // markup (not user data), safe to print unescaped in the loop below.
    $icons = [
        'bar-chart' => '<path d="M3 3v18h18"/><path d="M8 17V9"/><path d="M13 17V5"/><path d="M18 17v-7"/>',
        'coin' => '<circle cx="12" cy="12" r="10"/><path d="M14.8 9A2 2 0 0 0 13 8h-2a2 2 0 0 0 0 4h2a2 2 0 0 1 0 4h-2a2 2 0 0 1-1.8-1"/><path d="M12 6v2"/><path d="M12 16v2"/>',
        'trending-up' => '<path d="M22 7 13.5 15.5 8.5 10.5 2 17"/><path d="M16 7h6v6"/>',
        'swap' => '<path d="m17 3 4 4-4 4"/><path d="M21 7H9"/><path d="m7 21-4-4 4-4"/><path d="M3 17h12"/>',
    ];

    // Revenue and expense mirror blocks/chart-comparison's own bundled 30-day
    // sample one-for-one, so the KPI row and the chart panel underneath never
    // disagree. Net profit is revenue minus expense; cash flow is net profit
    // less a stated pending-receivables gap (both spelled out in the
    // description so the figures read as derived, not arbitrary).
    $stats ??= [
        ['title' => __('Total revenue'), 'icon' => 'bar-chart', 'value' => '$8,750.00', 'delta' => '+12%', 'description' => __('vs last month')],
        ['title' => __('Total expense'), 'icon' => 'coin', 'value' => '$1,852.00', 'delta' => '-3%', 'description' => __('vs last month'), 'inverse' => true],
        ['title' => __('Net profit'), 'icon' => 'trending-up', 'value' => '$6,898.00', 'delta' => '+16.9%', 'description' => __('Revenue minus expense')],
        ['title' => __('Cash flow'), 'icon' => 'swap', 'value' => '$6,240.00', 'delta' => '+17.1%', 'description' => __('Net profit less pending receivables')],
    ];

    // Spending-breakdown categories are a subset of the same $1,852.00 total
    // expense above (45% / 30% / 25% of it), not a separate, disagreeing figure.
    $categories ??= [
        ['name' => __('Housing'), 'percent' => 45, 'amount' => '$833.40', 'icon' => 'home'],
        ['name' => __('Food & Dining'), 'percent' => 30, 'amount' => '$555.60', 'icon' => 'utensils'],
        ['name' => __('Transport'), 'percent' => 25, 'amount' => '$463.00', 'icon' => 'car'],
    ];
@endphp

<main id="main-content" 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">
        {{-- Welcome header --}}
        <div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
            <h1 class="text-2xl font-bold tracking-tight">{{ __('Welcome back, :name', ['name' => $name]) }}</h1>
            <x-ui.button size="sm">
                <svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14"/><path d="M5 12h14"/></svg>
                {{ __('Add new') }}
            </x-ui.button>
        </div>

        {{-- KPI tray row --}}
        <div data-slot="dashboard-spending-kpis" class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            @foreach ($stats as $stat)
                <x-ui.tray :title="$stat['title']">
                    <x-slot:icon>
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{!! $icons[$stat['icon']] ?? '' !!}</svg>
                    </x-slot:icon>
                    <x-ui.stat
                        variant="plain"
                        :value="$stat['value']"
                        :delta="$stat['delta']"
                        :description="$stat['description'] ?? null"
                        :inverse="$stat['inverse'] ?? false"
                    />
                </x-ui.tray>
            @endforeach
        </div>

        {{-- Revenue vs. expense comparison --}}
        <x-blocks.chart-comparison :ranges="$ranges" />

        {{-- Spending breakdown + transactions --}}
        <div class="grid gap-6 lg:grid-cols-2">
            <x-blocks.metrics-breakdown :categories="$categories" total="$1,852.00" delta="-3%" />
            <x-blocks.transactions-list :transactions="$transactions" />
        </div>
    </div>
</main>

Ownership & lifecycle

Owner, release state, review evidence and adoption for this item.
Owner
Platform UI (@JoshJML)
Current version
1.0.1
Status
Stable
License
open
Deprecation
Not deprecated
Contract
v1
Foundation
≥ 1.0.0