68 lines
3.1 KiB
PHP
Executable File
68 lines
3.1 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Helpdesk\Livewire;
|
|
|
|
use App\Models\User;
|
|
use Carbon\CarbonPeriod;
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Livewire\Component;
|
|
use Modules\Helpdesk\Models\Ticket;
|
|
|
|
final class HelpdeskDashboardWidget extends Component
|
|
{
|
|
public int $days = 7;
|
|
|
|
public function updatedDays(): void
|
|
{
|
|
if (! in_array($this->days, [7, 14, 30], true)) $this->days = 7;
|
|
}
|
|
|
|
public function render(): View
|
|
{
|
|
$user = Auth::user();
|
|
$base = Ticket::query()->without('user')->visibleTo($user);
|
|
$totalCount = (clone $base)->count();
|
|
$openCount = (clone $base)->whereNull('completed_at')->count();
|
|
$closedCount = (clone $base)->whereNotNull('completed_at')->count();
|
|
$inProgressCount = (clone $base)->whereNull('completed_at')->whereHas('status', static fn ($q) => $q->whereIn('slug', ['assigned', 'in-progress', 'in_progress', 'progress']))->count();
|
|
|
|
$period = CarbonPeriod::create(now()->subDays($this->days - 1)->startOfDay(), now()->startOfDay());
|
|
$trendRows = (clone $base)->where('created_at', '>=', now()->subDays($this->days - 1)->startOfDay())->get(['created_at', 'completed_at']);
|
|
$trend = collect($period)->map(function ($date) use ($trendRows): array {
|
|
$day = $date->toDateString();
|
|
return [
|
|
'label' => $date->format('M j'),
|
|
'created' => $trendRows->filter(fn ($ticket) => optional($ticket->created_at)->toDateString() === $day)->count(),
|
|
'resolved' => $trendRows->filter(fn ($ticket) => optional($ticket->completed_at)->toDateString() === $day)->count(),
|
|
];
|
|
})->values();
|
|
|
|
$priorityRows = (clone $base)->with('priority')->get();
|
|
$priorityBreakdown = $priorityRows->groupBy(fn ($ticket) => strtolower((string) ($ticket->priority?->name ?? 'Unspecified')))
|
|
->map(fn ($rows, $name) => ['name' => ucfirst($name), 'count' => $rows->count()])
|
|
->sortByDesc('count')->take(4)->values();
|
|
|
|
$requesterCounts = (clone $base)->selectRaw('user_id, COUNT(*) as ticket_count')->whereNotNull('user_id')->groupBy('user_id')->orderByDesc('ticket_count')->limit(5)->get();
|
|
$requesters = User::query()->whereIn('id', $requesterCounts->pluck('user_id'))->get()->keyBy('id');
|
|
$topRequesters = $requesterCounts->map(fn ($row) => ['user' => $requesters->get($row->user_id), 'count' => (int) $row->ticket_count])->filter(fn ($row) => $row['user'] !== null)->values();
|
|
|
|
return view('modules.helpdesk.livewire.dashboard-widget', [
|
|
'totalCount' => $totalCount,
|
|
'openCount' => $openCount,
|
|
'closedCount' => $closedCount,
|
|
'inProgressCount' => $inProgressCount,
|
|
'trend' => $trend,
|
|
'priorityBreakdown' => $priorityBreakdown,
|
|
'topRequesters' => $topRequesters,
|
|
'recentTickets' => (clone $base)
|
|
->with(['user:id,name,email', 'status', 'priority'])
|
|
->latest('last_activity_at')
|
|
->limit(5)
|
|
->get(),
|
|
]);
|
|
}
|
|
}
|