77 lines
2.4 KiB
PHP
77 lines
2.4 KiB
PHP
<?php
|
||
|
||
namespace App\Livewire\Ui\System;
|
||
|
||
use Livewire\Component;
|
||
use Illuminate\Support\Facades\Artisan;
|
||
use App\Models\Setting;
|
||
|
||
class StorageCard extends Component
|
||
{
|
||
public string $target = '/';
|
||
|
||
public ?int $diskTotalGb = null;
|
||
public ?int $diskUsedGb = null; // inkl. Reserve (passt zum Donut)
|
||
public ?int $diskFreeGb = null; // wird unten auf free_plus_reserve_gb gesetzt
|
||
|
||
public array $diskSegments = [];
|
||
public int $diskSegOuterRadius = 92;
|
||
public int $diskInnerSize = 160;
|
||
public array $diskCenterText = ['percent' => '–', 'label' => 'SPEICHER BELEGT'];
|
||
public ?string $measuredAt = null;
|
||
|
||
protected int $segCount = 48;
|
||
|
||
public function mount(string $target = '/'): void
|
||
{
|
||
$this->target = $target ?: '/';
|
||
$this->loadFromSettings();
|
||
}
|
||
|
||
public function render() { return view('livewire.ui.system.storage-card'); }
|
||
|
||
public function refresh(): void
|
||
{
|
||
Artisan::call('health:probe-disk', ['target' => $this->target]);
|
||
$this->loadFromSettings();
|
||
}
|
||
|
||
protected function loadFromSettings(): void
|
||
{
|
||
$disk = Setting::get('health.disk', []);
|
||
if (!is_array($disk) || empty($disk)) return;
|
||
|
||
$this->diskTotalGb = $disk['total_gb'] ?? null;
|
||
$this->diskUsedGb = $disk['used_gb'] ?? null;
|
||
$this->diskFreeGb = $disk['free_gb'] ?? ($disk['free_plus_reserve_gb'] ?? null);
|
||
|
||
$percent = $disk['percent_used_total'] ?? null;
|
||
$this->diskCenterText = [
|
||
'percent' => is_numeric($percent) ? $percent.'%' : '–',
|
||
'label' => 'SPEICHER BELEGT',
|
||
];
|
||
$this->diskSegments = $this->buildSegments($percent);
|
||
|
||
$this->measuredAt = Setting::get('health.disk_updated_at', null);
|
||
}
|
||
|
||
protected function buildSegments(?int $percent): array
|
||
{
|
||
$segments = [];
|
||
$active = is_int($percent) ? (int) round($this->segCount * $percent / 100) : 0;
|
||
|
||
$activeClass = match (true) {
|
||
!is_int($percent) => 'bg-white/15',
|
||
$percent >= 90 => 'bg-rose-400',
|
||
$percent >= 70 => 'bg-amber-300',
|
||
default => 'bg-emerald-400',
|
||
};
|
||
|
||
for ($i = 0; $i < $this->segCount; $i++) {
|
||
$angle = (360 / $this->segCount) * $i - 90;
|
||
$segments[] = ['angle' => $angle, 'class' => $i < $active ? $activeClass : 'bg-white/15'];
|
||
}
|
||
return $segments;
|
||
}
|
||
}
|