user()->isAdmin() || auth()->user()->isManager(), 403); $this->refreshData(); } public function refreshData(): void { $this->openToday = ServiceRequest::query() ->open() ->whereDate('created_at', now()->toDateString()) ->count(); $this->overdue = ServiceRequest::query()->overdue()->count(); $this->avgResolutionHours = (float) (ServiceRequest::query() ->whereNotNull('completed_at') ->whereDate('completed_at', '>=', now()->subDays(30)) ->selectRaw('AVG(TIMESTAMPDIFF(HOUR, created_at, completed_at)) as avg_hours') ->value('avg_hours') ?? 0); $this->statusChart = Status::query() ->orderBy('sort_order') ->get() ->map(fn (Status $status) => [ 'label' => $status->name, 'value' => ServiceRequest::query()->where('status_id', $status->id)->count(), 'color' => $status->color_hex, ]) ->toArray(); $this->priorityChart = ServiceRequest::query() ->join('priorities', 'priorities.id', '=', 'requests.priority_id') ->selectRaw('priorities.name as label, priorities.color_hex as color, COUNT(requests.id) as value') ->groupBy('priorities.id', 'priorities.name', 'priorities.color_hex') ->orderByRaw('MIN(priorities.level)') ->get() ->map(fn ($row) => [ 'label' => $row->label, 'value' => (int) $row->value, 'color' => $row->color, ]) ->toArray(); $this->topTechnicians = User::query() ->where('role', 'technician') ->withCount([ 'assignedRequests as closed_requests_count' => fn (Builder $query) => $query->whereHas('status', fn (Builder $status) => $status->where('slug', 'closed')), ]) ->orderByDesc('closed_requests_count') ->limit(5) ->get() ->map(fn (User $user) => [ 'name' => $user->name, 'closed_requests_count' => (int) $user->closed_requests_count, ]) ->toArray(); $this->recentActivities = ActivityLog::query() ->with('user') ->latest('created_at') ->limit(10) ->get() ->map(fn (ActivityLog $log) => [ 'user' => $log->user?->name ?? 'Система', 'action' => $log->action, 'description' => $log->description, 'created_at' => $log->created_at?->format('d.m.Y H:i'), ]) ->toArray(); $this->upcomingTasks = ServiceRequest::query() ->with(['assignee', 'status']) ->whereNotNull('planned_at') ->whereBetween('planned_at', [now(), now()->addDays(7)]) ->orderBy('planned_at') ->limit(8) ->get() ->map(fn (ServiceRequest $request) => [ 'ticket' => $request->ticket_number, 'title' => $request->title, 'planned_at' => $request->planned_at?->format('d.m.Y H:i'), 'assignee' => $request->assignee?->name ?? 'Не назначен', ]) ->toArray(); $this->dispatch('dashboard-charts-updated', status: $this->statusChart, priority: $this->priorityChart); } public function render() { return view('livewire.dashboard.dashboard-page')->title('Дашборд'); } }