Back to Pages
Minimal Dashboards A minimal dashboard layout example for financial applications.
Default LBBW Dark Light
System
How to Use
How to Use Minimal
Please ensure that the aFP Design System and the associated CSS are installed.

Requirements

This page uses the design tokens and utilities from the design system. In addition, the following items should be implemented to use this page properly.

Chart.js Native Styles

Code

<div class="afp-height:size-100 afp-background:surface-lowered afp-overflow-auto">

  <!-- SIDEBAR -->
  <div class="afp-height:size-100 afp-position-fixed afp-background:body afp-padding-x:space-xl" style="width: 20rem; z-index: var(--afp-z-critical)">
    <div class="afp-split:column afp-height:size-100 afp-padding-y:space-l">
      <div class="afp-stack afp-gap-xl afp-width:size-100">
        <div class="afp-cluster">
          <div class="afp-cluster afp-align-center afp-gap-xs">
            <afp-icon name="egg-fried" style="--afp-icon-size: 1.5rem;"></afp-icon>
            <h3><b>EggBank</b></h3>
          </div>

          <afp-input placeholder="Search..." hidelabel>
            <afp-icon slot="input-prefix" name="search"></afp-icon>
            <div class="afp-cluster" slot="input-suffix">
              <kbd>Ctrl+K</kbd>
            </div>
          </afp-input>
        </div>

        <div class="afp-cluster">
          <b class="afp-caption-m">MENU</b>
          <afp-navigation style="--afp-navigation-item-color: var(--afp-color-text); --afp-navigation-item-hover-color: var(--afp-color-text); --afp-navigation-item-hover: var(--afp-color-surface-elevated); --afp-navigation-item-active: var(--afp-color-surface-elevated); --afp-navigation-item-active-weight: var(--afp-font-weight-semibold);">
            <afp-navigation-item active><afp-icon name="collection"></afp-icon>Dashboard</afp-navigation-item>
            <afp-navigation-item details>
              <afp-icon name="arrow-left-right"></afp-icon>Transactions
              <!-- Matches table: 2 pending -->
              <afp-badge slot="details" variant="brand" shape="pill">2</afp-badge>
            </afp-navigation-item>
            <afp-navigation-item><afp-icon name="wallet"></afp-icon>Wallet</afp-navigation-item>
            <afp-navigation-item><afp-icon name="file-earmark"></afp-icon>Invoices</afp-navigation-item>
            <afp-navigation-item><afp-icon name="cash-coin"></afp-icon>Budgeting</afp-navigation-item>
            <afp-navigation-item><afp-icon name="pie-chart"></afp-icon>Reports</afp-navigation-item>
          </afp-navigation>
        </div>
      </div>

      <!-- USER CARD -->
      <div class="afp-stack afp-width:size-100">
        <afp-card appearance="filled">
          <div class="afp-split">
            <div class="afp-cluster afp-align-center afp-gap-s">
              <afp-avatar size="small" shape="pill" image="https://picsum.photos/100" style="--afp-avatar-border-width: 0"></afp-avatar>
              <div class="afp-stack afp-gap-3xs">
                <b class="afp-heading-s">John Doe</b>
                <small class="afp-caption-s">john.doe@adesso.de</small>
              </div>
            </div>

            <afp-dropdown keep>
              <afp-button slot="trigger" appearance="filled" variant="neutral">
                <afp-icon name="gear"></afp-icon>
              </afp-button>

              <afp-dropdown-item><afp-icon name="person"></afp-icon>Profile</afp-dropdown-item>
              <afp-dropdown-item><afp-icon name="sliders"></afp-icon>Preferences</afp-dropdown-item>
              <afp-dropdown-item>
                <afp-icon name="bell"></afp-icon>
                Notifications
                <!-- Matches top bell badge -->
                <afp-badge slot="details" variant="brand" shape="pill">23</afp-badge>
              </afp-dropdown-item>
              <hr/>
              <afp-dropdown-item style="color: var(--afp-color-error-500)"><afp-icon name="box-arrow-right"></afp-icon>Sign out</afp-dropdown-item>
            </afp-dropdown>
          </div>
        </afp-card>
      </div>
    </div>
  </div>

  <!-- MAIN CONTENT -->
  <div style="padding: var(--afp-size-s) var(--afp-size-s) var(--afp-size-s) calc(20rem + var(--afp-size-s));">
    <div class="afp-split afp-align-start" style="flex-wrap: nowrap;">

      <h2>Dashboard</h2>

      <div class="afp-cluster afp-align-center afp-gap-xs" style="flex-wrap: nowrap;">

        <afp-dropdown style="--afp-dropdown-max-height: 20rem">
          <afp-button slot="trigger" appearance="outlined" variant="brand" caret>Custom Dashboard</afp-button>

          <afp-dropdown-item checked>Custom Dashboard</afp-dropdown-item>
          <afp-dropdown-item>Default</afp-dropdown-item>
          <hr/>
          <afp-dropdown-item><afp-icon name="plus-lg"></afp-icon>Create dashboard</afp-dropdown-item>
        </afp-dropdown>

        <!-- Top icons -->
        <afp-button slot="trigger" appearance="plain" variant="neutral">
          <afp-icon name="bell"></afp-icon>
        </afp-button>
      </div>
    </div>

    <div class="afp-padding-top:space-l">

      <div class="afp-flank:end afp-align-start" style="--afp-flank-size: 30%;">
        <div class="afp-stack">
          <!-- KPI ROW -->
          <div class="afp-grid">

            <!-- BALANCE -->
            <afp-card appearance="default" variant="brand" header>
              <div class="afp-split" slot="header">
                <afp-icon name="piggy-bank" style="--afp-icon-size: 2rem"></afp-icon>

                <!-- More sensible actions than "Refresh" -->
                <afp-dropdown>
                  <afp-button slot="trigger" appearance="default" variant="brand">
                    <afp-icon name="three-dots-vertical"></afp-icon>
                  </afp-button>
                  <afp-dropdown-item><afp-icon name="box-arrow-in-up-right"></afp-icon>View details</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="download"></afp-icon>Export statement</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="arrow-repeat"></afp-icon>Sync now</afp-dropdown-item>
                </afp-dropdown>
              </div>
              <b><small>Balance</small></b>
              <h2 class="afp-margin-bottom:space-3xs">$2,190.19</h2>
              <small>Last updated: 10:37 AM</small>
            </afp-card>

            <!-- INCOME -->
            <afp-card appearance="plain" header>
              <div class="afp-split" slot="header">
                <afp-icon name="cash-coin" style="--afp-icon-size: 2rem"></afp-icon>
                <afp-dropdown>
                  <afp-button slot="trigger" appearance="plain" variant="neutral">
                    <afp-icon name="three-dots-vertical"></afp-icon>
                  </afp-button>
                  <afp-dropdown-item><afp-icon name="calendar3"></afp-icon>Change period</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="funnel"></afp-icon>Filter sources</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="arrow-repeat"></afp-icon>Sync now</afp-dropdown-item>
                </afp-dropdown>
              </div>
              <b><small>Income (MTD)</small></b>
              <h2 class="afp-margin-bottom:space-3xs">$510.00</h2>
              <small>+$82.50 vs last month</small>
            </afp-card>

            <!-- SAVINGS -->
            <afp-card appearance="plain" header>
              <div class="afp-split" slot="header">
                <afp-icon name="safe" style="--afp-icon-size: 2rem"></afp-icon>
                <afp-dropdown>
                  <afp-button slot="trigger" appearance="plain" variant="neutral">
                    <afp-icon name="three-dots-vertical"></afp-icon>
                  </afp-button>
                  <afp-dropdown-item><afp-icon name="plus-lg"></afp-icon>Add funds</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="arrow-left-right"></afp-icon>Move to checking</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="sliders"></afp-icon>Auto-save rules</afp-dropdown-item>
                </afp-dropdown>
              </div>
              <b><small>Savings</small></b>
              <h2 class="afp-margin-bottom:space-3xs">$1,807.59</h2>
              <small>$150.00 added this month</small>
            </afp-card>

          </div>

          <!-- CHARTS ROW -->
          <div class="afp-grid">
            <afp-card appearance="plain" header>
              <div class="afp-split" slot="header">
                <b>Finances</b>
                <afp-dropdown>
                  <afp-button slot="trigger" appearance="plain" variant="neutral">
                    <afp-icon name="three-dots-vertical"></afp-icon>
                  </afp-button>
                  <afp-dropdown-item><afp-icon name="calendar3"></afp-icon>Time range</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="funnel"></afp-icon>Filter</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="box-arrow-in-up-right"></afp-icon>Open report</afp-dropdown-item>
                </afp-dropdown>
              </div>
              <canvas id="chart1" style="max-width: 100%"></canvas>
            </afp-card>

            <afp-card appearance="plain" header>
              <div class="afp-split" slot="header">
                <b>All Expenses</b>
                <afp-dropdown>
                  <afp-button slot="trigger" appearance="plain" variant="neutral">
                    <afp-icon name="three-dots-vertical"></afp-icon>
                  </afp-button>
                  <afp-dropdown-item><afp-icon name="calendar3"></afp-icon>Time range</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="funnel"></afp-icon>Categories</afp-dropdown-item>
                  <afp-dropdown-item><afp-icon name="box-arrow-in-up-right"></afp-icon>Open report</afp-dropdown-item>
                </afp-dropdown>
              </div>
              <canvas id="chart2" style="max-width: 100%"></canvas>
            </afp-card>
          </div>

          <!-- TRANSACTIONS -->
          <div class="afp-grid">
            <afp-card appearance="plain" header>
              <div class="afp-split" slot="header">
                <b>Transactions</b>

                <div class="afp-cluster" style="flex-wrap: nowrap;">
                  <afp-input placeholder="Search transactions" hidelabel></afp-input>
                  <afp-dropdown>
                    <afp-button slot="trigger" appearance="plain" variant="neutral">
                      <afp-icon name="three-dots-vertical"></afp-icon>
                    </afp-button>
                    <afp-dropdown-item><afp-icon name="funnel"></afp-icon>Filter</afp-dropdown-item>
                    <afp-dropdown-item><afp-icon name="sort-down"></afp-icon>Sort</afp-dropdown-item>
                    <afp-dropdown-item><afp-icon name="arrow-repeat"></afp-icon>Sync now</afp-dropdown-item>
                  </afp-dropdown>
                </div>
              </div>

              <table>
                <tbody class="afp-body-m">
                <!-- 2 Pending rows -> matches sidebar badge "2" -->
                <tr>
                  <td class="afp-cluster afp-align-center afp-gap-xs">
                    <afp-avatar shape="pill" size="small" image="https://picsum.photos/100?1"></afp-avatar>
                    Cameron Williamson
                  </td>
                  <td>Figma</td>
                  <td>02/12/25</td>
                  <td>10:37 AM</td>
                  <td>$17.12</td>
                  <td style="text-align: center">
                    <afp-badge appearance="filled" variant="brand">Pending</afp-badge>
                  </td>
                  <td style="text-align: right">
                    <afp-button appearance="filled" size="small" variant="neutral">
                      <afp-icon name="eye"></afp-icon>
                    </afp-button>
                  </td>
                </tr>

                <tr>
                  <td class="afp-cluster afp-align-center afp-gap-xs">
                    <afp-avatar shape="pill" size="small" image="https://picsum.photos/100?2"></afp-avatar>
                    Savannah Nguyen
                  </td>
                  <td>Adobe XD</td>
                  <td>02/13/25</td>
                  <td>09:12 AM</td>
                  <td>$24.99</td>
                  <td style="text-align: center">
                    <afp-badge appearance="filled" variant="success">Completed</afp-badge>
                  </td>
                  <td style="text-align: right">
                    <afp-button appearance="filled" size="small" variant="neutral">
                      <afp-icon name="eye"></afp-icon>
                    </afp-button>
                  </td>
                </tr>

                <tr>
                  <td class="afp-cluster afp-align-center afp-gap-xs">
                    <afp-avatar shape="pill" size="small" image="https://picsum.photos/100?3"></afp-avatar>
                    Jerome Bell
                  </td>
                  <td>Sketch</td>
                  <td>02/14/25</td>
                  <td>03:45 PM</td>
                  <td>$8.50</td>
                  <td style="text-align: center">
                    <afp-badge appearance="filled" variant="warning">In Review</afp-badge>
                  </td>
                  <td style="text-align: right">
                    <afp-button appearance="filled" size="small" variant="neutral">
                      <afp-icon name="eye"></afp-icon>
                    </afp-button>
                  </td>
                </tr>

                <tr>
                  <td class="afp-cluster afp-align-center afp-gap-xs">
                    <afp-avatar shape="pill" size="small" image="https://picsum.photos/100?4"></afp-avatar>
                    Kristin Watson
                  </td>
                  <td>Notion</td>
                  <td>02/15/25</td>
                  <td>11:08 AM</td>
                  <td>$42.00</td>
                  <td style="text-align: center">
                    <afp-badge appearance="filled" variant="brand">Pending</afp-badge>
                  </td>
                  <td style="text-align: right">
                    <afp-button appearance="filled" size="small" variant="neutral">
                      <afp-icon name="eye"></afp-icon>
                    </afp-button>
                  </td>
                </tr>
                </tbody>
              </table>
            </afp-card>
          </div>
        </div>

        <!-- RIGHT COLUMN -->
        <div class="afp-stack">

          <!-- BUDGET CONTROL -->
          <afp-card appearance="plain" header>
            <div class="afp-split" slot="header">
              <b>Budget Control</b>
              <afp-dropdown>
                <afp-button slot="trigger" appearance="plain" variant="neutral">
                  <afp-icon name="gear"></afp-icon>
                </afp-button>
                <afp-dropdown-item><afp-icon name="pencil-square"></afp-icon>Edit limit</afp-dropdown-item>
                <afp-dropdown-item><afp-icon name="bell"></afp-icon>Set alerts</afp-dropdown-item>
                <afp-dropdown-item><afp-icon name="arrow-counterclockwise"></afp-icon>Reset month</afp-dropdown-item>
              </afp-dropdown>
            </div>

            <small>Monthly Transaction Limit</small>
            <div class="afp-stack">
              <div class="afp-cluster afp-align-center afp-gap-2xs">
                <h3 style="margin: 0">$72.40</h3>
                <small>of $100</small>
              </div>
              <afp-progress-bar variant="brand" value="72"></afp-progress-bar>
              <afp-alert id="closeableAlert" variant="warning" appearance="filled" open icon closeable>
                <afp-icon slot="icon" name="exclamation-triangle"></afp-icon>
                <p class="afp-body-m">You’re approaching your monthly limit.</p>
              </afp-alert>
            </div>
          </afp-card>

          <!-- QUICK TRANSFER -->
          <afp-card appearance="plain" header>
            <b slot="header">Quick Transfer</b>

            <afp-radio-group orientation="horizontal" style="--afp-radio-card-padding: var(--afp-space-2xs)">
              <afp-radio-card variant="brand" value="user1" noindicator><afp-avatar id="user1" shape="pill" size="small" image="https://picsum.photos/100?1"></afp-avatar></afp-radio-card>
              <afp-radio-card variant="brand" value="user2" noindicator><afp-avatar id="user2" shape="pill" size="small" image="https://picsum.photos/100?2"></afp-avatar></afp-radio-card>
              <afp-radio-card variant="brand" value="user3" noindicator><afp-avatar id="user3" shape="pill" size="small" image="https://picsum.photos/100?3"></afp-avatar></afp-radio-card>
              <afp-radio-card variant="brand" value="user4" noindicator><afp-avatar id="user4" shape="pill" size="small" image="https://picsum.photos/100?4"></afp-avatar></afp-radio-card>

              <afp-tooltip for="user1" placement="top">Cameron Williamson</afp-tooltip>
              <afp-tooltip for="user2" placement="top">Savannah Nguyen</afp-tooltip>
              <afp-tooltip for="user3" placement="top">Jerome Bell</afp-tooltip>
              <afp-tooltip for="user4" placement="top">Kristin Watson</afp-tooltip>
            </afp-radio-group>

            <afp-input type="decimal" placeholder="Amount" hidelabel style="margin-top: var(--afp-space-m);">
              <afp-icon slot="input-prefix" name="currency-dollar" style="--afp-icon-size: 1rem"></afp-icon>
            </afp-input>

            <div class="afp-cluster afp-gap-s" style="margin-top: var(--afp-space-m);">
              <afp-button appearance="default" variant="neutral">Transfer Now</afp-button>
              <afp-button appearance="filled" variant="neutral">Save as Draft</afp-button>
            </div>
          </afp-card>
        </div>
      </div>
    </div>
  </div>

  <!-- CHARTS -->
  <script>
    // Finances (Revenue vs Last Year) – USD + English labels
    const valuesLine = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    const valueLine1 = [320, 410, 380, 520, 610, 590, 640, 720, 810, 860, 790, 900]; // Revenue
    const valueLine2 = [280, 350, 340, 460, 520, 540, 560, 610, 700, 740, 710, 780]; // Last Year

    const ctx1 = document.getElementById('chart1');

    new Chart(ctx1, {
      type: "line",
      data: {
        labels: valuesLine,
        datasets: [
          {
            label: 'Revenue',
            data: valueLine1,
            borderColor: 'rgb(100,115,159)',
            backgroundColor: 'rgb(100,115,159,0.20)',
            fill: true,
            tension: 0.3,
            pointRadius: 3
          },
          {
            label: 'Last Year',
            data: valueLine2,
            borderColor: 'rgb(255,90,123)',
            backgroundColor: 'rgba(255,90,123,0.20)',
            fill: true,
            tension: 0.3,
            pointRadius: 3
          }
        ]
      },
      options: {
        responsive: true,
        plugins: {
          legend: { position: 'bottom' },
          tooltip: {
            callbacks: {
              label: (ctx) => ` ${ctx.dataset.label}: $${ctx.parsed.y}`
            }
          }
        },
        scales: {
          y: {
            beginAtZero: true,
            ticks: { callback: (value) => '$' + value }
          }
        }
      }
    });
  </script>

  <script>
    // All Expenses – USD categories
    const valuesBar = ["Shopping", "Workspace", "Food", "Entertainment"];
    const valueBar  = [310, 190, 140, 90];
    const barColors = ["#2c4075", "#435ab1", "#8995cc", "#b7c8dd"];

    const ctx2 = document.getElementById('chart2');

    new Chart(ctx2, {
      type: "bar",
      data: {
        labels: valuesBar,
        datasets: [{
          backgroundColor: barColors,
          data: valueBar
        }]
      },
      options: {
        plugins: {
          legend: { display: false },
          tooltip: {
            callbacks: {
              label: (ctx) => `$${ctx.parsed.y}`
            }
          }
        },
        scales: {
          y: {
            beginAtZero: true,
            ticks: { callback: (value) => '$' + value }
          }
        }
      }
    });
  </script>
</div>
Close

EggBank

Ctrl+K
MENU Dashboard Transactions 2 Wallet Invoices Budgeting Reports
John Doe john.doe@adesso.de
Profile Preferences Notifications 23
Sign out

Dashboard

Custom Dashboard Custom Dashboard Default
Create dashboard
View details Export statement Sync now
Balance

$2,190.19

Last updated: 10:37 AM
Change period Filter sources Sync now
Income (MTD)

$510.00

+$82.50 vs last month
Add funds Move to checking Auto-save rules
Savings

$1,807.59

$150.00 added this month
Finances Time range Filter Open report
All Expenses Time range Categories Open report
Transactions
Filter Sort Sync now
Cameron Williamson Figma 02/12/25 10:37 AM $17.12 Pending
Savannah Nguyen Adobe XD 02/13/25 09:12 AM $24.99 Completed
Jerome Bell Sketch 02/14/25 03:45 PM $8.50 In Review
Kristin Watson Notion 02/15/25 11:08 AM $42.00 Pending
Budget Control Edit limit Set alerts Reset month
Monthly Transaction Limit

$72.40

of $100

You’re approaching your monthly limit.

Quick Transfer Cameron Williamson Savannah Nguyen Jerome Bell Kristin Watson
Transfer Now Save as Draft