mailwolt/resources/views/livewire/ui/dashboard/health-card.blade.php

279 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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 &amp; 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>
<div class="grid grid-cols-2 #items-center justify-between gap-3">
{{-- MailGuard Status Card --}}
<div
class="glass-card p-4 flex flex-row items-start justify-between gap-4 relative overflow-hidden mb-4">
{{-- Linke Seite: Icon + Titel --}}
<div class="flex #items-start gap-3 relative z-10">
<div class="shrink-0">
{{-- Modernes Shield-Icon --}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<defs>
<linearGradient id="shieldGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#4ade80"/>
<stop offset="1" stop-color="#15803d"/>
</linearGradient>
<radialGradient id="shine" cx="30%" cy="20%" r="70%">
<stop offset="0%" stop-color="rgba(255,255,255,0.4)"/>
<stop offset="100%" stop-color="rgba(255,255,255,0)"/>
</radialGradient>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="0" stdDeviation="3" flood-color="#22c55e"
flood-opacity="0.6"/>
</filter>
</defs>
<path d="M32 6l20 8v12c0 13.5-8.7 22.7-20 27-11.3-4.3-20-13.5-20-27V14l20-8z"
fill="url(#shieldGradient)" filter="url(#glow)"/>
<path d="M32 6l20 8v12c0 13.5-8.7 22.7-20 27-11.3-4.3-20-13.5-20-27V14l20-8z"
fill="url(#shine)"/>
<path d="M23 33l7 7 11-14" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round"
stroke-linejoin="round"/>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-white/90">WoltGuard</h3>
<p class="text-sm text-white/50">System-Wächter aktiv und fehlerfrei</p>
</div>
</div>
{{-- Rechte Seite: Status & Avatar --}}
<div class="flex items-start gap-3 relative z-10">
{{-- Status Badge --}}
@if($guardOk ?? false)
<span
class="inline-flex #items-center gap-1 px-3 py-1 rounded-full text-sm border border-emerald-400/30 text-emerald-300 bg-emerald-500/10">
<i class="ph ph-check-circle text-[14px]"></i>
<span class="text-[11px]">alle&nbsp;Dienste&nbsp;OK</span>
</span>
@else
<span
class="inline-flex #items-center gap-1 px-3 py-1 rounded-full text-sm border border-rose-400/30 text-rose-300 bg-rose-500/10">
<i class="ph ph-warning-circle text-[11px]"></i>
Störung erkannt
</span>
@endif
</div>
</div>
<livewire:ui.system.update-card/>
</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>