clusev/resources/views/livewire/versions/index.blade.php

107 lines
7.0 KiB
PHP

@php
$tone = fn (string $t): string => ['feat' => 'accent', 'fix' => 'cyan', 'security' => 'accent'][$t] ?? 'neutral';
$label = fn (string $t): string => ['feat' => 'Feature', 'fix' => 'Fix', 'chore' => 'Wartung', 'security' => 'Sicherheit', 'perf' => 'Tempo', 'style' => 'Design'][$t] ?? ucfirst($t);
$repoHost = parse_url($repository, PHP_URL_HOST);
$repoPath = trim((string) parse_url($repository, PHP_URL_PATH), '/');
@endphp
<div class="space-y-5">
{{-- Header --}}
<div class="flex flex-wrap items-end justify-between gap-3">
<div>
<p class="font-mono text-[11px] uppercase tracking-[0.2em] text-accent-text">Version</p>
<h2 class="mt-0.5 font-display text-xl font-semibold text-ink sm:text-2xl">Version &amp; Releases</h2>
</div>
<x-btn variant="secondary" wire:click="checkUpdates" wire:target="checkUpdates" wire:loading.attr="disabled">
<svg wire:loading wire:target="checkUpdates" class="h-3.5 w-3.5 animate-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M21 12a9 9 0 1 1-6.219-8.56" stroke-linecap="round" /></svg>
<x-icon name="rotate" class="h-3.5 w-3.5" wire:loading.remove wire:target="checkUpdates" />
Nach Updates suchen
</x-btn>
</div>
{{-- Honest status banner no fake "update available" --}}
<div class="flex flex-wrap items-center gap-4 rounded-xl border border-line bg-surface p-5 shadow-panel">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-xl border border-accent/25 bg-accent/10 text-accent-text"><x-icon name="tag" class="h-6 w-6" /></span>
<div class="min-w-0 flex-1">
<p class="flex flex-wrap items-center gap-2 font-display text-base font-semibold text-ink">
Clusev <span class="font-mono text-accent-text">v{{ $version }}</span>
<x-badge tone="neutral">Entwicklung</x-badge>
</p>
<p class="mt-0.5 font-mono text-[11px] leading-relaxed text-ink-3">Aktueller Entwicklungsstand noch kein getaggtes Release, kein Release-Kanal konfiguriert. Aktualisierung läuft über den Deploy (Image ziehen + migrieren).</p>
</div>
@if ($lastChecked)
<span class="shrink-0 font-mono text-[11px] text-ink-4">geprüft {{ $lastChecked }}</span>
@endif
</div>
<div class="grid grid-cols-1 gap-5 lg:grid-cols-[minmax(0,1fr)_300px]">
{{-- Changelog timeline --}}
<x-panel title="Änderungsprotokoll" :subtitle="count($groups) . ' Tage'" :padded="false">
<div class="px-4 py-4 sm:px-5">
@forelse ($groups as $g)
<div class="flex gap-4 pb-6 last:pb-0">
<div class="flex flex-col items-center">
<span @class(['mt-1 h-2.5 w-2.5 shrink-0 rounded-full', 'bg-accent' => $loop->first, 'bg-ink-4' => ! $loop->first])></span>
@unless ($loop->last)<span class="mt-1 w-px flex-1 bg-line"></span>@endunless
</div>
<div class="-mt-0.5 min-w-0 flex-1">
<p class="font-mono text-xs text-ink-3">{{ $g['date'] }}</p>
<ul class="mt-2 space-y-2">
@foreach ($g['items'] as $it)
<li class="flex items-start gap-2.5">
<x-badge :tone="$tone($it['type'])" class="mt-0.5 shrink-0">{{ $label($it['type']) }}</x-badge>
<span class="text-sm leading-relaxed text-ink-2">{{ $it['text'] }}</span>
</li>
@endforeach
</ul>
</div>
</div>
@empty
<p class="font-mono text-[11px] text-ink-3">Kein Änderungsprotokoll gefunden.</p>
@endforelse
</div>
</x-panel>
{{-- Aside --}}
<div class="space-y-5">
<x-panel title="Installiert" :padded="false">
<div class="space-y-3 px-4 py-4 sm:px-5">
<div class="flex items-baseline gap-2">
<span class="font-display text-2xl font-bold text-ink">v{{ $version }}</span>
<span class="inline-flex items-center gap-1.5 font-mono text-[11px] text-online"><x-status-dot status="online" />läuft</span>
</div>
<dl class="space-y-2 font-mono text-[11px]">
<div class="flex items-center justify-between gap-3"><dt class="text-ink-4">Build</dt><dd class="text-ink-2">{{ $build['sha'] ?? '—' }}</dd></div>
<div class="flex items-center justify-between gap-3"><dt class="text-ink-4">Branch</dt><dd class="truncate text-ink-2">{{ $build['branch'] }}</dd></div>
<div class="flex items-center justify-between gap-3"><dt class="text-ink-4">Kanal</dt><dd class="text-ink-2">{{ $channel }}</dd></div>
<div class="flex items-center justify-between gap-3"><dt class="text-ink-4">Lizenz</dt><dd class="text-ink-2">{{ $license }}</dd></div>
</dl>
</div>
</x-panel>
<x-panel title="Aktualisierung" :padded="false">
<div class="space-y-3 px-4 py-4 sm:px-5">
<p class="font-mono text-[11px] leading-relaxed text-ink-3">Updates kommen über den Deploy neues Image ziehen und Migrationen anwenden:</p>
<pre class="overflow-x-auto rounded-md border border-line bg-void px-3 py-2.5 font-mono text-[11px] leading-relaxed text-ink-2">docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
artisan migrate --force</pre>
</div>
</x-panel>
<x-panel title="Projekt" :padded="false">
<div class="space-y-3 px-4 py-4 sm:px-5">
<a href="{{ $repository }}" target="_blank" rel="noopener noreferrer" class="flex items-center gap-3 rounded-md border border-line bg-inset px-3 py-2.5 transition-colors hover:border-accent/30">
<span class="grid h-8 w-8 shrink-0 place-items-center rounded-md bg-raised text-ink-3"><x-icon name="git-branch" class="h-4 w-4" /></span>
<span class="min-w-0 flex-1">
<span class="block truncate font-mono text-xs text-ink">{{ $repoPath }}</span>
<span class="block truncate font-mono text-[11px] text-ink-3">{{ $repoHost }}</span>
</span>
<x-icon name="chevron-left" class="h-4 w-4 shrink-0 rotate-180 text-ink-4" />
</a>
<p class="flex items-center gap-2 font-mono text-[11px] text-ink-3"><x-icon name="shield" class="h-3.5 w-3.5 shrink-0 text-cyan" /> Open Core · {{ $license }}</p>
</div>
</x-panel>
</div>
</div>
</div>