You've already forked Atomcms-edit
refactor: integrate diagnostics into Commandocentrum and split EmulatorUpdateService
- Add DiagnosticRunner integration to Commandocentrum for system health display - Refactor EmulatorUpdateService from 2524 lines to 395 lines (facade pattern) - Extract EmulatorStatusService, EmulatorJarService, EmulatorSourceService - Extract EmulatorBuildService, EmulatorSqlService, EmulatorBackupService - Add shared EmulatorConfiguration trait for dependency injection - Preserve backward compatibility on all public methods
This commit is contained in:
@@ -9,6 +9,7 @@ use App\Models\Miscellaneous\WebsitePermission;
|
||||
use App\Models\StaffActivity;
|
||||
use App\Services\AutoDetectService;
|
||||
use App\Services\CatalogService;
|
||||
use App\Services\Diagnostics\DiagnosticRunner;
|
||||
use App\Services\EmulatorUpdateService;
|
||||
use App\Services\RconService;
|
||||
use App\Services\SettingsService;
|
||||
@@ -61,9 +62,13 @@ final class Commandocentrum extends Page implements HasForms
|
||||
|
||||
public string $catalogSyncUrl = '';
|
||||
|
||||
/** @var array<\App\Services\Diagnostics\DiagnosticResult> */
|
||||
public array $diagnostics = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->fillForm();
|
||||
$this->runDiagnostics();
|
||||
}
|
||||
|
||||
protected function fillForm(): void
|
||||
@@ -147,6 +152,22 @@ final class Commandocentrum extends Page implements HasForms
|
||||
->content(fn (): HtmlString => $this->renderServerInfo()),
|
||||
]),
|
||||
|
||||
Section::make('🩺 Systeem Gezondheid')
|
||||
->description('Automatische systeem diagnostiek')
|
||||
->icon('heroicon-o-heart')
|
||||
->afterHeader([
|
||||
Action::make('refresh_diagnostics')
|
||||
->label('Vernieuwen')
|
||||
->icon('heroicon-o-arrow-path')
|
||||
->color('info')
|
||||
->action('refreshDiagnostics'),
|
||||
])
|
||||
->schema([
|
||||
Placeholder::make('diagnostics')
|
||||
->label('')
|
||||
->content(fn (): HtmlString => $this->renderDiagnostics()),
|
||||
]),
|
||||
|
||||
Section::make('🏨 Hotel Status')
|
||||
->description('Emulator en Nitro status')
|
||||
->icon('heroicon-o-building-office')
|
||||
@@ -1941,4 +1962,111 @@ final class Commandocentrum extends Page implements HasForms
|
||||
->color($color)
|
||||
->send();
|
||||
}
|
||||
|
||||
public function refreshDiagnostics(): void
|
||||
{
|
||||
$this->runDiagnostics();
|
||||
$this->notify('Success', 'Diagnostiek vernieuwd', 'success');
|
||||
}
|
||||
|
||||
private function runDiagnostics(): void
|
||||
{
|
||||
$runner = app(DiagnosticRunner::class);
|
||||
$this->diagnostics = $runner->runAll();
|
||||
}
|
||||
|
||||
private function renderDiagnostics(): HtmlString
|
||||
{
|
||||
if ($this->diagnostics === []) {
|
||||
$this->runDiagnostics();
|
||||
}
|
||||
|
||||
$errors = array_filter($this->diagnostics, fn ($r) => $r->status === 'error');
|
||||
$warnings = array_filter($this->diagnostics, fn ($r) => $r->status === 'warning');
|
||||
$ok = array_filter($this->diagnostics, fn ($r) => $r->status === 'ok');
|
||||
|
||||
$errorCount = count($errors);
|
||||
$warningCount = count($warnings);
|
||||
$okCount = count($ok);
|
||||
|
||||
$overallStatus = $errorCount > 0 ? 'error' : ($warningCount > 0 ? 'warning' : 'ok');
|
||||
$overallColor = match ($overallStatus) {
|
||||
'error' => '#ef4444',
|
||||
'warning' => '#f59e0b',
|
||||
default => '#22c55e',
|
||||
};
|
||||
$overallLabel = match ($overallStatus) {
|
||||
'error' => 'Kritieke Problemen',
|
||||
'warning' => 'Waarschuwingen',
|
||||
default => 'Gezond',
|
||||
};
|
||||
|
||||
$html = '<div style="display:flex;flex-direction:column;gap:16px;">';
|
||||
|
||||
// Summary cards
|
||||
$html .= '<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:12px;">';
|
||||
$html .= $this->getSummaryCardHtml('Gezond', $okCount, '#22c55e', 'heroicon-o-check-circle');
|
||||
$html .= $this->getSummaryCardHtml('Waarschuwingen', $warningCount, '#f59e0b', 'heroicon-o-exclamation-triangle');
|
||||
$html .= $this->getSummaryCardHtml('Fouten', $errorCount, '#ef4444', 'heroicon-o-x-circle');
|
||||
$html .= '</div>';
|
||||
|
||||
// Overall status banner
|
||||
$html .= '<div style="background:{$overallColor}15;border:1px solid {$overallColor}30;border-radius:12px;padding:16px;display:flex;align-items:center;gap:12px;">';
|
||||
$html .= '<div style="width:12px;height:12px;border-radius:50%;background:{$overallColor};"></div>';
|
||||
$html .= '<span style="font-weight:700;color:{$overallColor};font-size:16px;">Systeem Status: {$overallLabel}</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Detailed results
|
||||
if ($errorCount > 0 || $warningCount > 0) {
|
||||
$html .= '<div style="display:flex;flex-direction:column;gap:8px;">';
|
||||
foreach ($this->diagnostics as $result) {
|
||||
if ($result->status === 'ok') {
|
||||
continue;
|
||||
}
|
||||
$color = $result->status === 'error' ? '#ef4444' : '#f59e0b';
|
||||
$icon = $result->status === 'error'
|
||||
? '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="' . $color . '" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>'
|
||||
: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="' . $color . '" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>';
|
||||
|
||||
$html .= '<div style="background:#fff;border:1px solid ' . $color . '30;border-radius:10px;padding:14px 16px;display:flex;align-items:flex-start;gap:12px;">';
|
||||
$html .= '<div style="flex-shrink:0;margin-top:2px;">' . $icon . '</div>';
|
||||
$html .= '<div style="flex:1;">';
|
||||
$html .= '<div style="font-weight:600;color:#1e293b;font-size:14px;">' . e($result->name) . '</div>';
|
||||
$html .= '<div style="color:#64748b;font-size:13px;margin-top:2px;">' . e($result->message) . '</div>';
|
||||
if ($result->fix) {
|
||||
$html .= '<div style="background:#f8fafc;border-radius:6px;padding:8px 12px;margin-top:8px;font-size:12px;color:#475569;font-family:monospace;">💡 ' . e($result->fix) . '</div>';
|
||||
}
|
||||
$html .= '</div></div>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
return new HtmlString($html);
|
||||
}
|
||||
|
||||
private function getSummaryCardHtml(string $label, int $count, string $color, string $icon): string
|
||||
{
|
||||
$iconSvg = match ($icon) {
|
||||
'heroicon-o-check-circle' => '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />',
|
||||
'heroicon-o-exclamation-triangle' => '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />',
|
||||
'heroicon-o-x-circle' => '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" />',
|
||||
default => '',
|
||||
};
|
||||
|
||||
return <<<HTML
|
||||
<div style="background:#fff;border-radius:12px;padding:16px;border:1px solid #e2e8f0;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px;">
|
||||
<div style="background:{$color}15;padding:8px;border-radius:10px;">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="{$color}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
{$iconSvg}
|
||||
</svg>
|
||||
</div>
|
||||
<span style="font-size:12px;font-weight:600;color:#64748b;">{$label}</span>
|
||||
</div>
|
||||
<div style="font-size:28px;font-weight:800;color:{$color};line-height:1;">{$count}</div>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user