Data display
Status Page code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/status-page.blade.php
@props([
'services' => [],
'overall' => null,
'title' => null,
'updatedAt' => null,
'period' => '90 days',
])
@php
/*
| Service status board. A coloured overall banner sits above a list of
| services, each with a status badge, an optional uptime percentage and an
| uptime history strip (see <x-ui.uptime-bar>). When `overall` is omitted it
| is derived from the worst service status.
|
| Each service: ['name' => ?, 'status' => 'operational', 'description' => ?,
| 'uptime' => '99.99%', 'days' => [...]]
| Statuses: operational, degraded, partial, major, maintenance
|
| Usage:
| <x-ui.status-page updated-at="2 minutes ago" :services="[
| ['name' => 'API', 'status' => 'operational', 'uptime' => '99.99%', 'days' => array_fill(0, 90, 'operational')],
| ['name' => 'Dashboard', 'status' => 'degraded', 'uptime' => '99.41%', 'days' => [...]],
| ]" />
*/
$meta = [
'operational' => ['variant' => 'green', 'icon' => 'check-circle', 'label' => 'Operational', 'banner' => 'All systems operational', 'rank' => 0,
'tint' => 'bg-green-50 text-green-700 dark:bg-green-950/40 dark:text-green-300', 'iconColor' => 'text-green-500'],
'maintenance' => ['variant' => 'blue', 'icon' => 'wrench', 'label' => 'Maintenance', 'banner' => 'Maintenance in progress', 'rank' => 1,
'tint' => 'bg-accent-50 text-accent-700 dark:bg-accent-950/40 dark:text-accent-300', 'iconColor' => 'text-accent-500'],
'degraded' => ['variant' => 'amber', 'icon' => 'warning', 'label' => 'Degraded', 'banner' => 'Degraded performance', 'rank' => 2,
'tint' => 'bg-amber-50 text-amber-700 dark:bg-amber-950/40 dark:text-amber-300', 'iconColor' => 'text-amber-500'],
'partial' => ['variant' => 'amber', 'icon' => 'warning-circle', 'label' => 'Partial outage', 'banner' => 'Partial system outage', 'rank' => 3,
'tint' => 'bg-amber-50 text-amber-700 dark:bg-amber-950/40 dark:text-amber-300', 'iconColor' => 'text-amber-500'],
'major' => ['variant' => 'red', 'icon' => 'x-circle', 'label' => 'Major outage', 'banner' => 'Major system outage', 'rank' => 4,
'tint' => 'bg-red-50 text-red-700 dark:bg-red-950/40 dark:text-red-300', 'iconColor' => 'text-red-500'],
];
$resolvedOverall = $overall;
if ($resolvedOverall === null) {
$worstRank = collect($services)
->map(fn (array $service): int => $meta[$service['status'] ?? 'operational']['rank'] ?? 0)
->max() ?? 0;
$rankToKey = collect($meta)->mapWithKeys(fn (array $m, string $key): array => [$m['rank'] => $key]);
$resolvedOverall = $rankToKey[$worstRank] ?? 'operational';
}
$overallMeta = $meta[$resolvedOverall] ?? $meta['operational'];
$bannerTitle = $title ?? $overallMeta['banner'];
@endphp
<div {{ $attributes->merge(['class' => 'overflow-hidden rounded-2xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900']) }}>
{{-- Overall banner --}}
<div class="flex items-center gap-3 p-5 {{ $overallMeta['tint'] }}">
<x-ui.icon :name="$overallMeta['icon']" weight="fill" size="2xl" :class="$overallMeta['iconColor']" />
<div class="min-w-0 flex-1">
<p class="text-base font-semibold">{{ $bannerTitle }}</p>
@if ($updatedAt)
<p class="text-sm opacity-80">Last updated {{ $updatedAt }}</p>
@endif
</div>
</div>
{{-- Services --}}
<ul class="divide-y divide-gray-100 dark:divide-gray-800">
@foreach ($services as $service)
@php
$serviceStatus = $service['status'] ?? 'operational';
$serviceMeta = $meta[$serviceStatus] ?? $meta['operational'];
@endphp
<li class="p-5">
<div class="flex items-center justify-between gap-3">
<div class="min-w-0">
<p class="truncate text-sm font-medium text-gray-900 dark:text-white">{{ $service['name'] ?? '' }}</p>
@if (! empty($service['description']))
<p class="mt-0.5 truncate text-sm text-gray-500 dark:text-gray-400">{{ $service['description'] }}</p>
@endif
</div>
<div class="flex shrink-0 items-center gap-3">
@if (! empty($service['uptime']))
<span class="hidden text-xs tabular-nums text-gray-400 dark:text-gray-500 sm:inline">{{ $service['uptime'] }}</span>
@endif
<x-ui.badge :variant="$serviceMeta['variant']" :icon="$serviceMeta['icon']" size="sm">{{ $serviceMeta['label'] }}</x-ui.badge>
</div>
</div>
@if (! empty($service['days']))
<div class="mt-3">
<x-ui.uptime-bar :days="$service['days']" size="sm" />
<div class="mt-1.5 flex items-center justify-between text-[11px] text-gray-400 dark:text-gray-500">
<span>{{ $period }} ago</span>
@if (! empty($service['uptime']))
<span class="tabular-nums">{{ $service['uptime'] }} uptime</span>
@endif
<span>Today</span>
</div>
</div>
@endif
</li>
@endforeach
</ul>
{{-- Legend --}}
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 border-t border-gray-200 bg-gray-50/60 px-5 py-3 text-xs text-gray-500 dark:border-gray-800 dark:bg-gray-900/40 dark:text-gray-400">
@foreach (['operational' => 'bg-green-500', 'degraded' => 'bg-amber-400', 'partial' => 'bg-amber-500', 'major' => 'bg-red-500', 'maintenance' => 'bg-accent-400'] as $key => $swatch)
<span class="inline-flex items-center gap-1.5">
<span class="h-2.5 w-2.5 rounded-sm {{ $swatch }}"></span>
{{ $meta[$key]['label'] }}
</span>
@endforeach
</div>
</div>