220 lines
11 KiB
PHP
220 lines
11 KiB
PHP
<div wire:poll.10s="loadData" class="#glass-card #p-5">
|
||
{{-- Header --}}
|
||
<div class="flex items-center justify-between mb-4">
|
||
<h3 class="card-title text-lg">Dienste & Status</h3>
|
||
<span class="text-xs text-white/60">aktualisiert: {{ $updatedAtHuman ?? '–' }}</span>
|
||
</div>
|
||
|
||
{{-- CPU / RAM / Load / Uptime --}}
|
||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
||
{{-- CPU --}}
|
||
<div class="glass-card p-4 flex flex-col justify-between min-h-[140px]">
|
||
<div>
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div
|
||
class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-cpu text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] tracking-wide uppercase text-white/70">CPU</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-2xl font-semibold">{{ is_numeric($cpuPercent) ? $cpuPercent.'%' : '–' }}</div>
|
||
</div>
|
||
<div class="mt-3 rounded bg-white/5 p-1">
|
||
<div class="grid" style="grid-template-columns: repeat({{ $barSegments }}, minmax(0,1fr)); gap: 4px;">
|
||
@foreach($cpuSeg as $cls)
|
||
<div class="h-2 rounded {{ $cls }}"></div>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- RAM --}}
|
||
<div class="glass-card p-4 flex flex-col justify-between min-h-[140px]">
|
||
<div>
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div
|
||
class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-memory text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] tracking-wide uppercase text-white/70">RAM</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-2xl font-semibold">{{ is_numeric($ramPercent) ? $ramPercent.'%' : '–' }}</div>
|
||
@if($ramSummary)
|
||
<div class="text-[11px] text-white/50 mt-0.5">{{ $ramSummary }}</div>
|
||
@endif
|
||
</div>
|
||
<div class="mt-3 rounded bg-white/5 p-1">
|
||
<div class="grid" style="grid-template-columns: repeat({{ $barSegments }}, minmax(0,1fr)); gap: 4px;">
|
||
@foreach($ramSeg as $cls)
|
||
<div class="h-2 rounded {{ $cls }}"></div>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Load --}}
|
||
<div class="glass-card p-4 flex flex-col justify-between min-h-[140px]">
|
||
<div>
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div
|
||
class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-activity text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] tracking-wide uppercase text-white/70">Load</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-2xl font-semibold">{{ $loadBadgeText }}</div>
|
||
</div>
|
||
|
||
<div class="mt-3 flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
@foreach($loadDots as $d)
|
||
<div class="flex items-center gap-1 text-[11px] text-white/50">
|
||
<span class="w-2 h-2 rounded-full {{ $d['cls'] }}"></span>
|
||
<span>{{ $d['label'] }}</span>
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Uptime --}}
|
||
<div class="glass-card p-4 flex flex-col justify-between min-h-[140px]">
|
||
<div>
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div
|
||
class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="{{ $uptimeIcon }} text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] tracking-wide uppercase text-white/70">Uptime</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-2xl font-semibold">{{ $uptimeText ?? '–' }}</div>
|
||
</div>
|
||
|
||
<div class="mt-3 flex flex-wrap gap-2">
|
||
@foreach($uptimeChips as $c)
|
||
<span class="px-2 py-0.5 rounded-full text-xs bg-white/5 border border-white/10 text-white/70">
|
||
<span class="font-semibold text-white/90">{{ $c['v'] }}</span> {{ $c['u'] }}
|
||
</span>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
{{-- Dienste & Storage: kompakt & bündig --}}
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div class="glass-card relative p-4 max-h-fit">
|
||
{{-- Inhalt: Donut links, Zahlen rechts – stacked auf kleineren Screens --}}
|
||
<div class="grid grid-cols-1 items-center">
|
||
{{-- Donut --}}
|
||
<div class="flex items-center justify-between -mb-3">
|
||
<div
|
||
class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-hard-drives text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] tracking-wide uppercase text-white/70">Storage</span>
|
||
</div>
|
||
<a href="#"
|
||
class="inline-flex items-center gap-1 rounded-full border border-white/10 bg-white/5 px-2 py-0.5 text-[10px] text-white/70 hover:text-white hover:border-white/20 transition">
|
||
Details <i class="ph ph-caret-right text-[12px]"></i>
|
||
</a>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-center">
|
||
<div class="relative"
|
||
style="width: {{ $diskInnerSize + 80 }}px; height: {{ $diskInnerSize + 80 }}px;">
|
||
{{-- Innerer grauer Kreis --}}
|
||
<div
|
||
class="absolute inset-[36px] rounded-full bg-white/[0.04] backdrop-blur-sm ring-1 ring-white/10"></div>
|
||
|
||
{{-- Prozentanzeige im Zentrum – leicht kleiner & feiner --}}
|
||
<div class="absolute inset-0 flex flex-col items-center justify-center">
|
||
<div class="text-2xl md:text-3xl font-semibold leading-none tracking-tight">
|
||
{{ $diskCenterText['percent'] }}
|
||
</div>
|
||
<div class="text-[10px] md:text-[11px] text-white/60 mt-1 uppercase tracking-wide">
|
||
{{ $diskCenterText['label'] }}
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Segment-Ring – größerer Abstand zum Kreis --}}
|
||
@foreach($diskSegments as $seg)
|
||
<span class="absolute top-1/2 left-1/2 block"
|
||
style="
|
||
transform: rotate({{ $seg['angle'] }}deg) translateX({{ $diskSegOuterRadius + 14 }}px);
|
||
width: 12px; height: 6px; margin:-3px 0 0 -6px;">
|
||
<span class="block w-full h-full rounded-full {{ $seg['class'] }}"></span>
|
||
</span>
|
||
@endforeach
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Zahlen rechts (kompakter Satz) --}}
|
||
<div class="md:pl-2">
|
||
<dl class="space-y-2">
|
||
<div class="flex items-center justify-between">
|
||
<dt class="text-white/60 text-sm">Gesamt</dt>
|
||
<dd class="font-medium tabular-nums text-base">
|
||
{{ is_numeric($diskTotalGb) ? $diskTotalGb.' GB' : '–' }}
|
||
</dd>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<dt class="text-white/60 text-sm">Genutzt</dt>
|
||
<dd class="font-medium tabular-nums text-base">
|
||
{{ is_numeric($diskUsedGb) ? $diskUsedGb.' GB' : '–' }}
|
||
</dd>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<dt class="text-white/60 text-sm">Frei</dt>
|
||
<dd class="font-medium tabular-nums text-base">
|
||
{{ is_numeric($diskFreeGb) ? $diskFreeGb.' GB' : '–' }}
|
||
</dd>
|
||
</div>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div class="glass-card p-4">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div
|
||
class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-gear-six text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] tracking-wide uppercase text-white/70">Dienste</span>
|
||
</div>
|
||
<span
|
||
class="inline-flex items-center gap-1 rounded-full bg-white/5 border border-white/10 px-2 py-0.5 text-[10px] text-white/60">
|
||
systemctl / TCP
|
||
</span>
|
||
</div>
|
||
<ul class="overflow-auto divide-y divide-white/5">
|
||
@forelse($servicesCompact as $s)
|
||
<li class="grid grid-cols-[auto,1fr,auto] items-center gap-3 py-2">
|
||
<div class="flex items-center justify-between">
|
||
<div>
|
||
<div class="flex items-center gap-2">
|
||
<span class="h-2 w-2 rounded-full {{ $s['dotClass'] }}"></span>
|
||
<div class="min-w-0">
|
||
<div class="text-white/90 truncate">{{ $s['label'] }}</div>
|
||
</div>
|
||
</div>
|
||
@if($s['hint'])
|
||
<div class="text-[11px] text-white/45 truncate">{{ $s['hint'] }}</div>
|
||
@endif
|
||
</div>
|
||
<span
|
||
class="justify-self-end inline-flex items-center px-2.5 py-0.5 rounded-full text-xs border {{ $s['pillClass'] }}">
|
||
{{ $s['pillText'] }}
|
||
</span>
|
||
</div>
|
||
</li>
|
||
@empty
|
||
<li class="py-2 text-white/50 text-sm">Keine Daten.</li>
|
||
@endforelse
|
||
</ul>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|