132 lines
9.4 KiB
PHP
Executable File
132 lines
9.4 KiB
PHP
Executable File
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6" dusk="helpdesk-ticket-archive">
|
|
<section class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<div class="hd-page-hero bg-gradient-to-br from-slate-950 via-slate-900 to-amber-950 px-6 py-7 text-white">
|
|
<div class="flex flex-col gap-5 lg:flex-row lg:items-center lg:justify-between">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-200">Ticket archive</p>
|
|
<h1 class="mt-2 text-3xl font-semibold tracking-tight">Archived tickets</h1>
|
|
<p class="mt-2 max-w-3xl text-sm leading-6 text-amber-100/85">
|
|
Restore tickets to active work or permanently remove tickets that are no longer required.
|
|
</p>
|
|
</div>
|
|
<a href="{{ route('helpdesk.tickets.index') }}" wire:navigate class="hd-btn hd-btn-blue">
|
|
<i class="fa-solid fa-arrow-left" aria-hidden="true"></i><span>Active tickets</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="hd-filter-panel rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<div class="hd-ticket-search-wrap max-w-2xl">
|
|
<i class="fa-solid fa-magnifying-glass hd-ticket-search-icon" aria-hidden="true"></i>
|
|
<input type="search" class="hd-ticket-search" wire:model.live.debounce.350ms="search"
|
|
placeholder="Search archived reference, subject or body" aria-label="Search archived tickets">
|
|
</div>
|
|
</section>
|
|
|
|
<section class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-zinc-200 text-sm dark:divide-zinc-700">
|
|
<thead class="bg-zinc-50 text-left text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:bg-zinc-800 dark:text-zinc-300">
|
|
<tr>
|
|
<th class="px-4 py-3">Reference</th><th class="px-4 py-3">Subject</th>
|
|
<th class="px-4 py-3">Status</th><th class="px-4 py-3">Requester</th>
|
|
<th class="px-4 py-3">Archived</th><th class="px-4 py-3 text-center">Files</th>
|
|
<th class="px-4 py-3 text-right">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-zinc-100 dark:divide-zinc-800">
|
|
@forelse ($tickets as $ticket)
|
|
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-800/70">
|
|
<td class="whitespace-nowrap px-4 py-3 font-mono text-xs font-semibold text-blue-700 dark:text-blue-300">{{ $ticket->reference }}</td>
|
|
<td class="min-w-[260px] px-4 py-3">
|
|
<div class="font-semibold text-zinc-900 dark:text-zinc-100">{{ $ticket->subject }}</div>
|
|
<div class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
|
{{ $ticket->category?->name ?? 'No category' }}
|
|
@if ($ticket->project) · {{ $ticket->project->title }} @endif
|
|
@if ($ticket->team) · {{ $ticket->team->name }} @endif
|
|
</div>
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
<x-helpdesk.colour-badge :color="$ticket->status?->color ?? 'zinc'">
|
|
{{ $ticket->status?->name ?? 'No status' }}
|
|
</x-helpdesk.colour-badge>
|
|
</td>
|
|
<td class="px-4 py-3 text-zinc-600 dark:text-zinc-300">{{ $ticket->requester_name ?? 'Unknown' }}</td>
|
|
<td class="whitespace-nowrap px-4 py-3">
|
|
<div class="font-medium text-zinc-700 dark:text-zinc-200">{{ ($ticket->archived_at ?? $ticket->deleted_at)?->format('d M Y H:i') }}</div>
|
|
<div class="text-xs text-zinc-500">{{ ($ticket->archived_at ?? $ticket->deleted_at)?->diffForHumans() }}</div>
|
|
</td>
|
|
<td class="px-4 py-3 text-center">
|
|
<span class="inline-flex items-center gap-1 rounded-full border border-zinc-200 bg-zinc-50 px-2.5 py-1 text-xs font-bold text-zinc-600 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-300">
|
|
<i class="fa-solid fa-paperclip"></i>{{ $ticket->attachments_count ?? 0 }}
|
|
</span>
|
|
</td>
|
|
<td class="whitespace-nowrap px-4 py-3 text-right">
|
|
<div class="inline-flex flex-wrap justify-end gap-2">
|
|
<button type="button" wire:click="restoreTicket({{ $ticket->id }})"
|
|
wire:loading.attr="disabled" wire:target="restoreTicket({{ $ticket->id }})"
|
|
class="hd-btn hd-btn-sm hd-btn-green">
|
|
<i class="fa-solid fa-rotate-left"></i><span>Restore</span>
|
|
</button>
|
|
@can('delete', $ticket)
|
|
<button type="button" wire:click="askToDeletePermanently({{ $ticket->id }})"
|
|
class="hd-btn hd-btn-sm hd-btn-red">
|
|
<i class="fa-solid fa-trash"></i><span>Delete permanently</span>
|
|
</button>
|
|
@endcan
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="7" class="px-4 py-14 text-center">
|
|
<span class="mx-auto grid h-14 w-14 place-items-center rounded-2xl bg-amber-500/15 text-amber-500">
|
|
<i class="fa-solid fa-box-open text-xl"></i>
|
|
</span>
|
|
<h2 class="mt-4 text-lg font-bold text-zinc-900 dark:text-white">Archive is empty</h2>
|
|
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">Tickets that you archive will appear here and can be restored later.</p>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="flex flex-col gap-3 border-t border-zinc-200 bg-zinc-50/70 px-4 py-4 dark:border-zinc-700 dark:bg-zinc-950/35 sm:flex-row sm:items-center sm:justify-between">
|
|
<div class="text-sm font-medium text-zinc-500 dark:text-zinc-400">{{ $tickets->total() }} archived ticket{{ $tickets->total() === 1 ? '' : 's' }}</div>
|
|
<div>@if ($tickets->hasPages()) {{ $tickets->onEachSide(1)->links() }} @endif</div>
|
|
</div>
|
|
</section>
|
|
|
|
@if ($deleteModalOpen)
|
|
<div class="fixed inset-0 z-[9998] flex items-center justify-center bg-black/75 px-4 py-6 backdrop-blur-sm" role="dialog" aria-modal="true">
|
|
<div class="w-full max-w-lg overflow-hidden rounded-3xl border border-red-500/35 bg-zinc-950 text-zinc-100 shadow-2xl">
|
|
<div class="border-b border-red-500/25 bg-red-950/45 px-6 py-5">
|
|
<h2 class="text-xl font-black text-white">Delete permanently?</h2>
|
|
<p class="mt-1 text-sm leading-6 text-red-100/90">
|
|
<span class="font-mono font-bold">{{ $pendingDeleteTicketReference }}</span> will be permanently removed and cannot be restored.
|
|
</p>
|
|
</div>
|
|
<div class="space-y-3 px-6 py-5">
|
|
@if ($pendingDeleteTicketSubject)
|
|
<div class="rounded-2xl border border-zinc-800 bg-zinc-900 px-4 py-3">
|
|
<p class="text-xs font-bold uppercase tracking-[0.2em] text-zinc-500">Ticket</p>
|
|
<p class="mt-1 font-semibold text-zinc-100">{{ $pendingDeleteTicketSubject }}</p>
|
|
</div>
|
|
@endif
|
|
<p class="text-sm leading-6 text-zinc-300">Stored attachment files linked to this ticket are also deleted.</p>
|
|
</div>
|
|
<div class="flex flex-col-reverse gap-3 border-t border-zinc-800 bg-zinc-900/80 px-6 py-4 sm:flex-row sm:justify-end">
|
|
<button type="button" wire:click="cancelPermanentDelete" class="hd-btn hd-btn-sm hd-btn-blue"><i class="fa-solid fa-xmark"></i><span>Cancel</span></button>
|
|
<button type="button" wire:click="deletePermanently" wire:loading.attr="disabled" wire:target="deletePermanently"
|
|
class="hd-btn hd-btn-sm hd-btn-red">
|
|
<i class="fa-solid fa-trash"></i>
|
|
<span wire:loading.remove wire:target="deletePermanently">Delete permanently</span>
|
|
<span wire:loading wire:target="deletePermanently">Deleting...</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|