first&last
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Dashboard;
|
||||
|
||||
use App\Models\ActivityLog;
|
||||
use App\Models\ServiceRequest;
|
||||
use App\Models\Status;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('layouts.app')]
|
||||
class DashboardPage extends Component
|
||||
{
|
||||
public int $openToday = 0;
|
||||
|
||||
public int $overdue = 0;
|
||||
|
||||
public float $avgResolutionHours = 0;
|
||||
|
||||
public array $statusChart = [];
|
||||
|
||||
public array $priorityChart = [];
|
||||
|
||||
public array $topTechnicians = [];
|
||||
|
||||
public array $recentActivities = [];
|
||||
|
||||
public array $upcomingTasks = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
abort_unless(auth()->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('Дашборд');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user