loadDomains(); $this->activeTab = $this->normalizeTab($this->activeTab); if (! empty($this->domains) && ! $this->selectedDomain) { $this->selectedDomain = $this->domains[0]['domain'] ?? null; } if ($this->selectedDomain) { $this->loadLogs(); } } public function updatedActiveTab(): void { $this->activeTab = $this->normalizeTab($this->activeTab); if ($this->activeTab === 'logs' && $this->selectedDomain) { $this->loadLogs(); } } public function setTab(string $tab): void { $this->activeTab = $this->normalizeTab($tab); } protected function getForms(): array { return ['tabsForm']; } public function tabsForm(Schema $schema): Schema { return $schema->schema([ Tabs::make(__('Log Sections')) ->contained() ->livewireProperty('activeTab') ->tabs([ 'logs' => Tab::make(__('Logs')) ->icon('heroicon-o-document-text') ->schema([ View::make('filament.jabali.pages.logs-tab-logs'), ]), 'stats' => Tab::make(__('Statistics')) ->icon('heroicon-o-chart-bar') ->schema([ View::make('filament.jabali.pages.logs-tab-stats'), ]), 'activity' => Tab::make(__('Activity Log')) ->icon('heroicon-o-clipboard-document-list') ->schema([ EmbeddedTable::make(ActivityLogTable::class), ]), ]), ]); } protected function normalizeTab(?string $tab): string { return match ($tab) { 'logs', 'activity', 'stats' => (string) $tab, default => 'logs', }; } protected function getAgent(): AgentClient { if ($this->agent === null) { $this->agent = new AgentClient; } return $this->agent; } protected function getUsername(): string { return Auth::user()->username ?? Auth::user()->name ?? 'unknown'; } protected function loadDomains(): void { try { $result = $this->getAgent()->send('domain.list', [ 'username' => $this->getUsername(), ]); $this->domains = ($result['success'] ?? false) ? ($result['domains'] ?? []) : []; } catch (\Throwable $exception) { $this->domains = []; } } public function getDomainOptions(): array { $options = []; foreach ($this->domains as $domain) { $d = $domain['domain'] ?? $domain; $options[$d] = $d; } return $options; } public function updatedSelectedDomain(): void { $this->statsGenerated = false; $this->statsUrl = ''; $this->loadLogs(); } public function setLogType(string $type): void { $this->logType = $type; $this->loadLogs(); } public function loadLogs(): void { if (! $this->selectedDomain) { $this->logContent = ''; $this->logInfo = []; return; } try { $result = $this->getAgent()->send('logs.tail', [ 'username' => $this->getUsername(), 'domain' => $this->selectedDomain, 'type' => $this->logType, 'lines' => $this->logLines, ]); if ($result['success'] ?? false) { $this->logContent = $result['content'] ?? ''; $this->logInfo = [ 'file_size' => $this->formatBytes($result['file_size'] ?? 0), 'last_modified' => $result['last_modified'] ?? '', 'lines' => $result['lines'] ?? 0, ]; } else { $this->logContent = ''; $this->logInfo = []; } } catch (\Exception $e) { $this->logContent = ''; $this->logInfo = []; } } public function refreshLogs(): void { $this->loadLogs(); Notification::make() ->title(__('Logs refreshed')) ->success() ->send(); } public function generateStats(): void { if (! $this->selectedDomain) { Notification::make() ->title(__('No domain selected')) ->danger() ->send(); return; } try { $result = $this->getAgent()->send('logs.goaccess', [ 'username' => $this->getUsername(), 'domain' => $this->selectedDomain, 'period' => 'all', ]); if ($result['success'] ?? false) { $this->statsGenerated = true; $this->statsUrl = 'https://'.$this->selectedDomain.($result['report_url'] ?? '/stats/report.html'); Notification::make() ->title(__('Statistics generated')) ->body(__('Report generated with :lines log entries', ['lines' => number_format($result['log_lines'] ?? 0)])) ->success() ->send(); } else { Notification::make() ->title(__('Error generating statistics')) ->body($result['error'] ?? 'Unknown error') ->danger() ->send(); } } catch (\Exception $e) { Notification::make() ->title(__('Error')) ->body($e->getMessage()) ->danger() ->send(); } } protected function getHeaderActions(): array { return [ Action::make('generateStats') ->label(__('Generate Statistics')) ->icon('heroicon-o-chart-bar') ->color('primary') ->visible(fn () => $this->selectedDomain !== null && $this->activeTab === 'stats') ->action(fn () => $this->generateStats()), Action::make('refreshLogs') ->label(__('Refresh')) ->icon('heroicon-o-arrow-path') ->color('gray') ->visible(fn () => $this->selectedDomain !== null && $this->activeTab === 'logs') ->action(fn () => $this->refreshLogs()), ]; } protected function formatBytes(int $bytes, int $precision = 2): string { $units = ['B', 'KB', 'MB', 'GB', 'TB']; $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= pow(1024, $pow); return round($bytes, $precision).' '.$units[$pow]; } }