Content & marketing
Deploy Console code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/deploy-console.blade.php
@props([
'repository' => 'harbour/app',
'branch' => 'main',
'commit' => '7f3c2e1',
'environment' => 'Production',
])
@php
/*
| Deploy console hero mockup. An alternative to the classic dashboard
| window: a release pipeline mid-flight. Left column shows the pipeline
| stages, right column tails the deploy log, and a canary strip across
| the bottom tracks the rollout. All static markup — no JS, no images.
|
| Usage (drop into a hero media slot):
| <x-ui.deploy-console />
| <x-ui.deploy-console repository="acme/api" branch="release" commit="09fe41c" />
*/
$steps = [
['state' => 'done', 'label' => 'Build', 'meta' => '832 modules via Vite', 'time' => '48s'],
['state' => 'done', 'label' => 'Tests', 'meta' => '312 passed · 0 failed', 'time' => '2m 04s'],
['state' => 'running', 'label' => 'Canary', 'meta' => '25% of traffic', 'time' => 'running'],
['state' => 'queued', 'label' => 'Promote', 'meta' => 'waits on canary health', 'time' => 'queued'],
];
@endphp
<x-ui.window variant="app" title="Deploy — {{ $repository }}" flush {{ $attributes->merge(['class' => 'deploy-console text-left']) }}>
{{-- Release header: ref being shipped and where it's going. --}}
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 border-b border-gray-200 px-5 py-3 dark:border-gray-800">
<span class="flex items-center gap-1.5 text-sm font-medium text-gray-700 dark:text-gray-200">
<x-ui.icon name="git-branch" size="base" class="text-gray-400" />
{{ $branch }}
</span>
<span class="font-mono text-xs text-gray-400">{{ $commit }}</span>
<span class="text-xs text-gray-400">“Tune cache headers for feed endpoints”</span>
<span class="ml-auto flex items-center gap-2">
<x-ui.badge variant="brand" size="sm">{{ $environment }}</x-ui.badge>
<x-ui.badge variant="green" size="sm" dot>Healthy</x-ui.badge>
</span>
</div>
<div class="grid lg:grid-cols-[0.85fr_1.3fr]">
{{-- Pipeline stages --}}
<div class="border-b border-gray-200 p-5 dark:border-gray-800 lg:border-b-0 lg:border-r">
<p class="text-xs font-semibold uppercase tracking-[0.14em] text-gray-400">Pipeline</p>
<ul class="mt-4 space-y-1">
@foreach ($steps as $step)
<li @class([
'flex items-center gap-3 rounded-lg px-2 py-2.5',
'bg-brand-50/70 ring-1 ring-brand-200 dark:bg-brand-950/40 dark:ring-brand-900' => $step['state'] === 'running',
])>
@if ($step['state'] === 'done')
<x-ui.icon name="check-circle" weight="fill" size="lg" class="shrink-0 text-green-500" />
@elseif ($step['state'] === 'running')
<x-ui.icon name="circle-notch" weight="bold" size="lg" class="shrink-0 text-brand-500 motion-safe:animate-spin" />
@else
<x-ui.icon name="circle-dashed" size="lg" class="shrink-0 text-gray-300 dark:text-gray-600" />
@endif
<span class="min-w-0 flex-1">
<span class="block text-sm font-medium text-gray-900 dark:text-white">{{ $step['label'] }}</span>
<span class="block truncate text-xs text-gray-400">{{ $step['meta'] }}</span>
</span>
<span class="shrink-0 font-mono text-[11px] tabular-nums text-gray-400">{{ $step['time'] }}</span>
</li>
@endforeach
</ul>
</div>
{{-- Log tail: constant dark surface, like an editor pane. --}}
<div class="bg-gray-950 p-5 font-mono text-xs leading-relaxed" aria-label="Deploy log">
<div class="space-y-1.5 whitespace-nowrap">
<p><span class="text-gray-600">14:02:11</span> <span class="text-brand-300">build</span> <span class="text-gray-300">Compiling assets with Vite…</span></p>
<p><span class="text-gray-600">14:02:59</span> <span class="text-brand-300">build</span> <span class="text-green-400">✓</span> <span class="text-gray-300"><span class="text-amber-200">832</span> modules transformed in <span class="text-amber-200">48s</span></span></p>
<p><span class="text-gray-600">14:03:02</span> <span class="text-brand-300">test</span> <span class="text-gray-300">Running suite (Pest, parallel ×4)</span></p>
<p><span class="text-gray-600">14:05:06</span> <span class="text-brand-300">test</span> <span class="text-green-400">✓</span> <span class="text-gray-300"><span class="text-amber-200">312</span> passed, <span class="text-amber-200">0</span> failed</span></p>
<p><span class="text-gray-600">14:05:10</span> <span class="text-brand-300">deploy</span> <span class="text-gray-300">Releasing <span class="text-green-300">{{ $commit }}</span> to canary (<span class="text-amber-200">25%</span>)</span></p>
<p><span class="text-gray-600">14:05:31</span> <span class="text-brand-300">watch</span> <span class="text-gray-300">p95 <span class="text-amber-200">182ms</span> · error rate <span class="text-amber-200">0.00%</span></span></p>
<p><span class="text-gray-600">14:06:02</span> <span class="text-brand-300">watch</span> <span class="text-gray-400">canary tracking stable — no regressions detected</span><span class="ml-1 inline-block h-3 w-1.5 translate-y-0.5 bg-gray-500 motion-safe:animate-dot-pulse"></span></p>
</div>
</div>
</div>
{{-- Canary strip: rollout progress plus a latency comparison. --}}
<div class="flex flex-wrap items-center gap-x-6 gap-y-3 border-t border-gray-200 px-5 py-4 dark:border-gray-800">
<div class="min-w-44 flex-1">
<div class="flex items-center justify-between text-xs">
<span class="font-medium text-gray-700 dark:text-gray-200">Canary rollout</span>
<span class="tabular-nums text-gray-400">25% → 100%</span>
</div>
<div class="mt-2 h-1.5 overflow-hidden rounded-full bg-gray-100 dark:bg-gray-800">
<div class="h-full w-1/4 rounded-full bg-brand-500"></div>
</div>
</div>
<dl class="flex items-center gap-5 text-xs">
<div>
<dt class="text-gray-400">p95 canary</dt>
<dd class="mt-0.5 font-semibold tabular-nums text-gray-900 dark:text-white">182ms</dd>
</div>
<div>
<dt class="text-gray-400">p95 stable</dt>
<dd class="mt-0.5 font-semibold tabular-nums text-gray-900 dark:text-white">176ms</dd>
</div>
<div>
<dt class="text-gray-400">Promotes in</dt>
<dd class="mt-0.5 font-semibold tabular-nums text-gray-900 dark:text-white">12m</dd>
</div>
</dl>
</div>
</x-ui.window>