Dashboards e widgets
mad-metric-card
mad-db-metric-card
mad-kpi-card
mad-kpi-strip
mad-stat-grid
mad-progress
Grid de KPIs (auto-query)
mad-stat-grid organizando mad-db-metric-card — cada card faz a própria agregação, zero PHP.
Pedidos
150
SQL Debug — metric_42b86f1e
With inlined binds
select count(tutor_pedidos.id) as total from "tutor_pedidos"
Prepared statement
select count(tutor_pedidos.id) as total from "tutor_pedidos"
Receita
R$ 689.954,82
SQL Debug — metric_6353e922
With inlined binds
select sum(tutor_pedidos.valor_total) as total from "tutor_pedidos"
Prepared statement
select sum(tutor_pedidos.valor_total) as total from "tutor_pedidos"
Ticket médio
R$ 4.599,70
SQL Debug — metric_b4a31536
With inlined binds
select avg(tutor_pedidos.valor_total) as total from "tutor_pedidos"
Prepared statement
select avg(tutor_pedidos.valor_total) as total from "tutor_pedidos"
Clientes cadastrados
40
SQL Debug — metric_883f12c1
With inlined binds
select count(tutor_clientes.id) as total from "tutor_clientes"
Prepared statement
select count(tutor_clientes.id) as total from "tutor_clientes"
resources/views/tutor/examples/dashboards-metricas/grid-kpis-db.blade.php
<mad-stat-grid :cols="4">
<mad-db-metric-card name="metricas_kpi_pedidos" model="TutorDemoPedido"
total="count" label="Pedidos" icon="shopping-cart" format="integer" />
<mad-db-metric-card name="metricas_kpi_receita" model="TutorDemoPedido"
field="valor_total" total="sum" label="Receita" icon="circle-dollar-sign" format="money:R$" variant="success" />
<mad-db-metric-card name="metricas_kpi_ticket" model="TutorDemoPedido"
field="valor_total" total="avg" label="Ticket médio" icon="receipt" format="money:R$" />
<mad-db-metric-card name="metricas_kpi_clientes" model="TutorDemoCliente"
total="count" label="Clientes cadastrados" icon="users" format="integer" variant="info" />
</mad-stat-grid>
Valor calculado em PHP
mad-metric-card quando o número não é uma agregação simples de 1 tabela — o cálculo mora num método público do controller.
Ticket médio (calculado em PHP)
R$ 4.599,70
+4,2%
vs período anterior
Taxa de entrega
49.3%
resources/views/tutor/examples/dashboards-metricas/metric-card-manual.blade.php
@php($__component = \Mad\Component\MadRenderContext::getComponent())
<mad-form-grid :cols="2">
<mad-metric-card name="ticket_medio_manual" label="Ticket médio (calculado em PHP)"
:value="$__component->ticketMedio()" icon="calculator" variant="info"
trend="+4,2%" trend-label="vs período anterior" />
<mad-metric-card name="taxa_entrega_manual" label="Taxa de entrega"
:value="$__component->taxaEntregaPercentual() . '%'" icon="package-check" variant="success" />
</mad-form-grid>
app/control/Tutor/TutorDashboardsMetricas.php
public function ticketMedio(): string
{
$media = (float) (TutorDemoPedido::query()->avg('valor_total') ?? 0);
return 'R$ ' . number_format($media, 2, ',', '.');
}
Faixa de KPIs estilo BI
mad-kpi-strip + mad-kpi-card: valor grande, pill de variação, sparkline SVG e barra de progresso — tudo sem JS.
Receita total
↑ 12,4%
R$ 689.954,82
vs período anterior
Ticket médio
R$ 4.599,70
Meta: R$ 320,00
Taxa de entrega
↓ 2,1%
49.3%
pedidos cancelados no período
resources/views/tutor/examples/dashboards-metricas/kpi-strip.blade.php
@php($__component = \Mad\Component\MadRenderContext::getComponent())
<mad-kpi-strip :cols="3">
<mad-kpi-card label="Receita total" :value="$__component->receitaTotalFormatada()"
icon="circle-dollar-sign" trend="+12,4%" trend-direction="up" trend-label="vs período anterior"
:spark="$__component->receitaMensal()" />
<mad-kpi-card label="Ticket médio" :value="$__component->ticketMedio()"
icon="receipt" :progress="62" goal="Meta: R$ 320,00" />
<mad-kpi-card label="Taxa de entrega" :value="$__component->taxaEntregaPercentual() . '%'"
icon="truck" trend="-2,1%" trend-direction="down" :trend-invert="true"
trend-label="pedidos cancelados no período" />
</mad-kpi-strip>
app/control/Tutor/TutorDashboardsMetricas.php
/** Receita agrupada por mês (Y-m) — série curta pro sparkline do mad-kpi-card. */
public function receitaMensal(): array
{
return TutorDemoPedido::query()
->orderBy('dt_pedido')
->get(['dt_pedido', 'valor_total'])
->groupBy(fn ($p) => substr((string) $p->dt_pedido, 0, 7))
->map(fn ($grupo) => (float) $grupo->sum('valor_total'))
->values()
->all();
}
Barra de progresso
mad-progress em variantes e tamanhos — indicador simples de meta/percentual.
Meta do mês (68%)
Devoluções (34%)
SLA de entrega (91%)
Cancelamentos (12%)
resources/views/tutor/examples/dashboards-metricas/progress.blade.php
<mad-form-grid :cols="2">
<mad-progress :value="68" label="Meta do mês (68%)" variant="success" />
<mad-progress :value="34" label="Devoluções (34%)" variant="warning" size="sm" />
<mad-progress :value="91" label="SLA de entrega (91%)" variant="info" size="lg" />
<mad-progress :value="12" label="Cancelamentos (12%)" variant="danger" />
</mad-form-grid>
Código-fonte completo da página
app/control/Tutor/TutorDashboardsMetricas.php
<?php
namespace App\Control\Tutor;
use App\Models\TutorDemo\TutorDemoPedido;
use App\Support\Tutor\TutorDemoSeed;
use App\Support\Tutor\TutorPage;
/**
* TutorDashboardsMetricas — página "Métricas" do catálogo.
*
* mad-stat-grid + mad-db-metric-card não precisam de PHP (auto-query). Os
* métodos abaixo só existem para os exemplos que precisam de um valor
* CALCULADO (mad-metric-card, mad-kpi-card) — nunca @php com query Eloquent
* direto no blade (R038/universal.md).
*/
class TutorDashboardsMetricas extends TutorPage
{
protected string $catalogKey = 'dashboards_metricas';
public function mount(array $params = []): void
{
TutorDemoSeed::ensure();
}
public function ticketMedio(): string
{
$media = (float) (TutorDemoPedido::query()->avg('valor_total') ?? 0);
return 'R$ ' . number_format($media, 2, ',', '.');
}
public function receitaTotalFormatada(): string
{
$total = (float) (TutorDemoPedido::query()->sum('valor_total') ?? 0);
return 'R$ ' . number_format($total, 2, ',', '.');
}
public function taxaEntregaPercentual(): float
{
$total = TutorDemoPedido::query()->count();
if ($total === 0) {
return 0.0;
}
$entregues = TutorDemoPedido::query()
->join('tutor_estados_pedido as te', 'te.id', '=', 'tutor_pedidos.estado_id')
->where('te.nome', '=', 'Entregue')
->count();
return round(($entregues / $total) * 100, 1);
}
/** Receita agrupada por mês (Y-m) — série curta pro sparkline do mad-kpi-card. */
public function receitaMensal(): array
{
return TutorDemoPedido::query()
->orderBy('dt_pedido')
->get(['dt_pedido', 'valor_total'])
->groupBy(fn ($p) => substr((string) $p->dt_pedido, 0, 7))
->map(fn ($grupo) => (float) $grupo->sum('valor_total'))
->values()
->all();
}
}
resources/views/tutor/dashboards/metricas.blade.php
<x-tutor-page page="dashboards_metricas">
<x-tutor-demo demo="tutor.examples.dashboards-metricas.grid-kpis-db"
title="Grid de KPIs (auto-query)" desc="mad-stat-grid organizando mad-db-metric-card — cada card faz a própria agregação, zero PHP." />
<x-tutor-demo demo="tutor.examples.dashboards-metricas.metric-card-manual"
title="Valor calculado em PHP" desc="mad-metric-card quando o número não é uma agregação simples de 1 tabela — o cálculo mora num método público do controller."
php="TutorDashboardsMetricas::ticketMedio" />
<x-tutor-demo demo="tutor.examples.dashboards-metricas.kpi-strip"
title="Faixa de KPIs estilo BI" desc="mad-kpi-strip + mad-kpi-card: valor grande, pill de variação, sparkline SVG e barra de progresso — tudo sem JS."
php="TutorDashboardsMetricas::receitaMensal" />
<x-tutor-demo demo="tutor.examples.dashboards-metricas.progress"
title="Barra de progresso" desc="mad-progress em variantes e tamanhos — indicador simples de meta/percentual." />
</x-tutor-page>