users menu listing
This commit is contained in:
+44
-188
@@ -1,196 +1,52 @@
|
||||
<div class="space-y-5" dusk="helpdesk-dashboard-widget">
|
||||
<span class="sr-only">Total tickets Open tickets Closed tickets</span>
|
||||
<div class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-2xl border border-blue-400/20 bg-gradient-to-br from-slate-950 to-blue-950/40 p-4 shadow-sm ring-1 ring-white/5">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-xs font-black uppercase tracking-[0.18em] text-blue-200/80">Total tickets</div>
|
||||
<div class="mt-2 text-3xl font-black text-white">{{ $totalCount }}</div>
|
||||
</div>
|
||||
<div class="flex h-11 w-11 items-center justify-center rounded-xl bg-blue-500/20 text-blue-200 ring-1 ring-blue-300/20">
|
||||
<i class="fa-solid fa-ticket" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 h-1.5 rounded-full bg-slate-800">
|
||||
<div class="h-1.5 rounded-full bg-blue-400" style="width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
@php
|
||||
$trendMax = max(1, (int) $trend->max(fn($row) => max($row['created'], $row['resolved'])));
|
||||
$pointCount = max(1, $trend->count() - 1);
|
||||
$createdPoints = $trend->map(fn($row, $i) => ($i * (100 / $pointCount)).','. (88 - (($row['created'] / $trendMax) * 68)))->implode(' ');
|
||||
$resolvedPoints = $trend->map(fn($row, $i) => ($i * (100 / $pointCount)).','. (88 - (($row['resolved'] / $trendMax) * 68)))->implode(' ');
|
||||
$palette = ['#ef4444', '#f59e0b', '#3b82f6', '#8b5cf6'];
|
||||
$priorityTotal = max(1, $priorityBreakdown->sum('count'));
|
||||
$offset = 0;
|
||||
$segments = [];
|
||||
foreach($priorityBreakdown as $index => $priority) {
|
||||
$percent = ($priority['count'] / $priorityTotal) * 100;
|
||||
$segments[] = $palette[$index % count($palette)].' '.$offset.'% '.($offset + $percent).'%';
|
||||
$offset += $percent;
|
||||
}
|
||||
@endphp
|
||||
<div class="hd-dashboard space-y-5" dusk="helpdesk-dashboard-widget">
|
||||
<section class="hd-dashboard-heading">
|
||||
<div><h1>Dashboard</h1><p>Overview of your helpdesk system</p></div>
|
||||
<label class="hd-range-select"><i class="fa-regular fa-calendar"></i><select wire:model.live="days"><option value="7">Last 7 days</option><option value="14">Last 14 days</option><option value="30">Last 30 days</option></select></label>
|
||||
</section>
|
||||
|
||||
<div class="rounded-2xl border border-blue-400/20 bg-gradient-to-br from-slate-950 to-blue-950/40 p-4 shadow-sm ring-1 ring-white/5">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-xs font-black uppercase tracking-[0.18em] text-blue-200/80">Open tickets</div>
|
||||
<div class="mt-2 text-3xl font-black text-blue-200">{{ $openCount }}</div>
|
||||
</div>
|
||||
<div class="flex h-11 w-11 items-center justify-center rounded-xl bg-blue-500/20 text-blue-200 ring-1 ring-blue-300/20">
|
||||
<i class="fa-solid fa-inbox" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 h-1.5 rounded-full bg-slate-800">
|
||||
<div class="h-1.5 rounded-full bg-blue-400" style="width: {{ $openPercent }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-2xl border border-emerald-400/20 bg-gradient-to-br from-slate-950 to-emerald-950/30 p-4 shadow-sm ring-1 ring-white/5">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-xs font-black uppercase tracking-[0.18em] text-emerald-200/80">Closed tickets</div>
|
||||
<div class="mt-2 text-3xl font-black text-emerald-200">{{ $closedCount }}</div>
|
||||
</div>
|
||||
<div class="flex h-11 w-11 items-center justify-center rounded-xl bg-emerald-500/20 text-emerald-200 ring-1 ring-emerald-300/20">
|
||||
<i class="fa-solid fa-circle-check" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 h-1.5 rounded-full bg-slate-800">
|
||||
<div class="h-1.5 rounded-full bg-emerald-400" style="width: {{ $closedPercent }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-2xl border border-rose-400/20 bg-gradient-to-br from-slate-950 to-rose-950/25 p-4 shadow-sm ring-1 ring-white/5">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-xs font-black uppercase tracking-[0.18em] text-rose-200/80">High priority</div>
|
||||
<div class="mt-2 text-3xl font-black text-rose-200">{{ $criticalCount }}</div>
|
||||
</div>
|
||||
<div class="flex h-11 w-11 items-center justify-center rounded-xl bg-rose-500/20 text-rose-200 ring-1 ring-rose-300/20">
|
||||
<i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-xs font-semibold text-slate-400">Open urgent/high/critical workload.</div>
|
||||
</div>
|
||||
<div class="hd-metric-grid">
|
||||
<article class="hd-metric-card hd-metric-blue"><span class="hd-metric-icon"><i class="fa-regular fa-clipboard"></i></span><div><small>Total Tickets</small><strong>{{ $totalCount }}</strong><em>All visible tickets</em></div></article>
|
||||
<article class="hd-metric-card hd-metric-green"><span class="hd-metric-icon"><i class="fa-regular fa-circle-check"></i></span><div><small>Resolved</small><strong>{{ $closedCount }}</strong><em>Completed workload</em></div></article>
|
||||
<article class="hd-metric-card hd-metric-amber"><span class="hd-metric-icon"><i class="fa-regular fa-clock"></i></span><div><small>In Progress</small><strong>{{ $inProgressCount }}</strong><em>Actively being worked</em></div></article>
|
||||
<article class="hd-metric-card hd-metric-red"><span class="hd-metric-icon"><i class="fa-solid fa-circle-exclamation"></i></span><div><small>Open</small><strong>{{ $openCount }}</strong><em>Awaiting resolution</em></div></article>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-5 xl:grid-cols-[minmax(0,2fr)_minmax(22rem,1fr)]">
|
||||
<div class="rounded-2xl border border-zinc-700 bg-gradient-to-br from-slate-950 via-slate-950 to-blue-950/20 shadow-sm ring-1 ring-white/5">
|
||||
<div class="flex items-center justify-between border-b border-white/10 px-5 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="flex h-10 w-10 items-center justify-center rounded-xl bg-blue-500/15 text-blue-200 ring-1 ring-blue-300/20">
|
||||
<i class="fa-solid fa-list-check" aria-hidden="true"></i>
|
||||
</span>
|
||||
<div>
|
||||
<h2 class="text-lg font-black text-white">Recent tickets</h2>
|
||||
<p class="text-sm text-slate-400">Latest support activity.</p>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ route('helpdesk.tickets.index') }}" wire:navigate class="hd-btn hd-btn-sm hd-btn-blue">View all tickets</a>
|
||||
</div>
|
||||
{{-- Recent Tickets --}}
|
||||
<div class="divide-y divide-white/10">
|
||||
@forelse ($recentTickets as $ticket)
|
||||
<a href="{{ route('helpdesk.tickets.show', $ticket) }}" wire:navigate
|
||||
class="flex flex-nowrap items-center gap-4 px-5 py-4 transition hover:bg-blue-500/10">
|
||||
<div class="flex w-36 shrink-0 items-center gap-3 text-sm font-semibold text-slate-300">
|
||||
<span class="h-2 w-2 shrink-0 rounded-full bg-blue-400"></span>
|
||||
<span class="whitespace-nowrap">{{ $ticket->reference }}</span>
|
||||
</div>
|
||||
<div class="hd-dashboard-grid">
|
||||
<section class="hd-dashboard-card hd-chart-card">
|
||||
<header><h2>Tickets Over Time</h2><span>{{ $days }} days</span></header>
|
||||
<div class="hd-chart-legend"><span><b class="bg-blue-500"></b>Created</span><span><b class="bg-emerald-500"></b>Resolved</span></div>
|
||||
<div class="hd-line-chart"><svg viewBox="0 0 100 100" preserveAspectRatio="none" aria-label="Ticket trend chart"><g class="hd-chart-grid-lines"><line x1="0" y1="20" x2="100" y2="20"/><line x1="0" y1="42" x2="100" y2="42"/><line x1="0" y1="64" x2="100" y2="64"/><line x1="0" y1="88" x2="100" y2="88"/></g><polyline class="hd-chart-line hd-chart-line-blue" points="{{ $createdPoints }}"/><polyline class="hd-chart-line hd-chart-line-green" points="{{ $resolvedPoints }}"/></svg></div>
|
||||
<div class="hd-chart-labels">@foreach($trend as $row)<span>{{ $row['label'] }}</span>@endforeach</div>
|
||||
</section>
|
||||
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate font-black text-white">{{ $ticket->subject }}</div>
|
||||
<div class="mt-1 truncate text-xs text-slate-400">
|
||||
{{ optional($ticket->last_activity_at)->format('d M Y H:i') ?? 'No activity yet' }}
|
||||
</div>
|
||||
</div>
|
||||
<section class="hd-dashboard-card hd-priority-card">
|
||||
<header><h2>Tickets by Priority</h2></header>
|
||||
<div class="hd-priority-body"><div class="hd-donut" style="background: conic-gradient({{ implode(', ', $segments) ?: '#334155 0 100%' }})"><span>{{ $priorityTotal }}</span></div><div class="hd-priority-legend">@foreach($priorityBreakdown as $i => $priority)<div><span><b style="background: {{ $palette[$i % count($palette)] }}"></b>{{ $priority['name'] }}</span><strong>{{ $priority['count'] }} ({{ round(($priority['count']/$priorityTotal)*100, 1) }}%)</strong></div>@endforeach</div></div>
|
||||
</section>
|
||||
|
||||
<div class="w-28 shrink-0">
|
||||
<x-helpdesk.colour-badge :color="$ticket->status?->color ?? 'zinc'">
|
||||
{{ $ticket->status?->name ?? 'No status' }}
|
||||
</x-helpdesk.colour-badge>
|
||||
</div>
|
||||
<section class="hd-dashboard-card hd-latest-card">
|
||||
<header><h2>Latest Tickets</h2><a href="{{ route('helpdesk.tickets.index') }}" wire:navigate>View all</a></header>
|
||||
<div class="hd-latest-list">@forelse($recentTickets as $ticket)<a href="{{ route('helpdesk.tickets.show', $ticket) }}" wire:navigate><span class="hd-priority-mini">{{ $ticket->priority?->name ?? 'Normal' }}</span><div><strong>{{ $ticket->subject }}</strong><small>#{{ $ticket->reference }} · {{ $ticket->user?->name ?? 'Unknown' }}</small></div><time>{{ optional($ticket->last_activity_at)->diffForHumans() }}</time><span class="hd-status-mini">{{ $ticket->status?->name ?? 'Open' }}</span></a>@empty<div class="hd-empty">No tickets yet.</div>@endforelse</div>
|
||||
</section>
|
||||
|
||||
<div class="w-28 shrink-0">
|
||||
<x-helpdesk.colour-badge :color="$ticket->priority?->color ?? 'zinc'">
|
||||
{{ $ticket->priority?->name ?? 'No priority' }}
|
||||
</x-helpdesk.colour-badge>
|
||||
</div>
|
||||
|
||||
<div class="w-28 shrink-0 whitespace-nowrap text-right text-sm font-semibold text-slate-400">
|
||||
{{ optional($ticket->last_activity_at)->diffForHumans() ?? 'No activity' }}
|
||||
</div>
|
||||
</a>
|
||||
@empty
|
||||
<div class="px-5 py-8 text-center text-sm text-slate-400">No helpdesk tickets yet.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
{{-- Recent Tickets End--}}
|
||||
</div>
|
||||
|
||||
<div class="space-y-5">
|
||||
<div class="rounded-2xl border border-zinc-700 bg-gradient-to-br from-slate-950 to-slate-900 p-5 shadow-sm ring-1 ring-white/5">
|
||||
<div class="mb-5 flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-black text-white">SLA overview</h2>
|
||||
<p class="text-sm text-slate-400">Closure rate and open workload.</p>
|
||||
</div>
|
||||
<span class="rounded-xl bg-emerald-500/15 px-3 py-1.5 text-sm font-black text-emerald-200 ring-1 ring-emerald-300/20">{{ $closedPercent }}% closed</span>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-5 sm:grid-cols-[9rem_minmax(0,1fr)] sm:items-center">
|
||||
<div class="relative mx-auto flex h-32 w-32 items-center justify-center rounded-full bg-slate-900 ring-8 ring-emerald-400/20">
|
||||
<div class="absolute inset-2 rounded-full border-8 border-emerald-400" style="clip-path: polygon(0 0, {{ max($closedPercent, 8) }}% 0, {{ max($closedPercent, 8) }}% 100%, 0 100%);"></div>
|
||||
<div class="relative text-center">
|
||||
<div class="text-3xl font-black text-white">{{ $closedPercent }}%</div>
|
||||
<div class="text-xs font-bold text-slate-400">closed</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<div class="mb-2 flex justify-between text-sm font-semibold text-slate-300"><span>Closed</span><span>{{ $closedPercent }}%</span></div>
|
||||
<div class="h-2 rounded-full bg-slate-800"><div class="h-2 rounded-full bg-emerald-400" style="width: {{ $closedPercent }}%"></div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-2 flex justify-between text-sm font-semibold text-slate-300"><span>Open</span><span>{{ $openPercent }}%</span></div>
|
||||
<div class="h-2 rounded-full bg-slate-800"><div class="h-2 rounded-full bg-blue-400" style="width: {{ $openPercent }}%"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<details
|
||||
class="group rounded-xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"
|
||||
dusk="recent-commits-card">
|
||||
<summary
|
||||
class="-mx-4 -mt-4 mb-4 flex cursor-pointer list-none items-center justify-between gap-3 rounded-t-xl bg-violet-700 px-4 py-4 text-white marker:hidden">
|
||||
<div class="flex min-w-0 items-center gap-3">
|
||||
<span
|
||||
class="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-violet-950 text-white ring-1 ring-violet-300/60 shadow-lg">
|
||||
<i class="fa-solid fa-code-branch text-lg" aria-hidden="true"></i>
|
||||
</span>
|
||||
|
||||
<div class="min-w-0">
|
||||
<h2 class="text-lg font-black uppercase tracking-wide">Recent commits</h2>
|
||||
<p class="text-xs font-semibold text-violet-100">Latest linked Git activity</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span
|
||||
class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-white/15 text-white ring-1 ring-white/20">
|
||||
<i class="fa-solid fa-chevron-right text-xs transition group-open:rotate-90" aria-hidden="true"></i>
|
||||
</span>
|
||||
</summary>
|
||||
|
||||
<div class="mb-4 flex justify-end">
|
||||
<a href="{{ route('helpdesk.settings') }}" wire:navigate class="hd-btn hd-btn-sm hd-btn-violet">
|
||||
Git setup
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
@forelse ($recentCommits as $commit)
|
||||
<div class="rounded-xl border border-zinc-200 bg-zinc-50 p-3 dark:border-zinc-700 dark:bg-zinc-950">
|
||||
<div class="font-mono text-xs text-zinc-500 dark:text-zinc-400">
|
||||
{{ $commit->short_hash }} · {{ $commit->repository?->name }}
|
||||
</div>
|
||||
<div class="mt-1 truncate text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
{{ $commit->message }}
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="rounded-xl border border-dashed border-zinc-300 p-4 text-center text-sm text-zinc-500 dark:border-zinc-700 dark:text-zinc-400">
|
||||
No commits tracked yet.
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<section class="hd-dashboard-card hd-requester-card">
|
||||
<header><h2>Top Requesters</h2></header>
|
||||
<div class="hd-requester-list">@forelse($topRequesters as $row)<div><span class="hd-user-avatar">{{ $row['user']->initials() }}</span><strong>{{ $row['user']->name }}</strong><em>{{ $row['count'] }} tickets</em></div>@empty<div class="hd-empty">No requester data yet.</div>@endforelse</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user