120 lines
7.5 KiB
PHP
120 lines
7.5 KiB
PHP
<div class="space-y-6" dusk="helpdesk-ticket-show">
|
|
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
|
<div>
|
|
<div class="mb-2 flex flex-wrap items-center gap-2">
|
|
<span class="font-mono text-xs text-zinc-500">{{ $ticket->reference }}</span>
|
|
<flux:badge color="{{ $ticket->status->color }}">{{ $ticket->status->name }}</flux:badge>
|
|
<flux:badge color="{{ $ticket->priority->color }}">{{ $ticket->priority->name }}</flux:badge>
|
|
</div>
|
|
<h1 class="text-2xl font-semibold tracking-tight text-zinc-900 dark:text-white">{{ $ticket->subject }}</h1>
|
|
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
|
Raised by {{ $ticket->owner?->name ?? 'Unknown user' }} · Assigned to {{ $ticket->agent?->name ?? 'Unassigned' }}
|
|
</p>
|
|
</div>
|
|
<flux:button :href="route('helpdesk.tickets.index')" wire:navigate icon="arrow-left" variant="ghost">Back</flux:button>
|
|
</div>
|
|
|
|
<div class="grid gap-6 lg:grid-cols-3">
|
|
<div class="space-y-6 lg:col-span-2">
|
|
<article class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<div class="prose max-w-none dark:prose-invert">
|
|
{!! nl2br(e($ticket->body)) !!}
|
|
</div>
|
|
</article>
|
|
|
|
@if ($ticket->attachments->isNotEmpty())
|
|
<div class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<h2 class="mb-4 text-base font-semibold text-zinc-900 dark:text-white">Ticket attachments</h2>
|
|
<div class="grid gap-3 sm:grid-cols-2">
|
|
@foreach ($ticket->attachments as $attachment)
|
|
<a href="{{ $attachment->url() }}" target="_blank" class="rounded-xl border border-zinc-200 p-3 text-sm hover:bg-zinc-50 dark:border-zinc-700 dark:hover:bg-zinc-800">
|
|
<div class="font-medium text-zinc-900 dark:text-zinc-100">{{ $attachment->original_name }}</div>
|
|
<div class="text-xs text-zinc-500">{{ Number::fileSize($attachment->size) }}</div>
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<section class="space-y-4">
|
|
<h2 class="text-lg font-semibold text-zinc-900 dark:text-white">Conversation</h2>
|
|
|
|
@forelse ($ticket->comments as $comment)
|
|
<div class="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900 {{ $comment->is_internal ? 'ring-2 ring-amber-300' : '' }}">
|
|
<div class="mb-3 flex items-center justify-between gap-3">
|
|
<div>
|
|
<div class="font-medium text-zinc-900 dark:text-zinc-100">{{ $comment->user?->name ?? 'Unknown user' }}</div>
|
|
<div class="text-xs text-zinc-500">{{ $comment->created_at->diffForHumans() }}</div>
|
|
</div>
|
|
@if ($comment->is_internal)
|
|
<flux:badge color="amber">Internal note</flux:badge>
|
|
@endif
|
|
</div>
|
|
<div class="prose max-w-none text-sm dark:prose-invert">{!! nl2br(e($comment->body)) !!}</div>
|
|
|
|
@if ($comment->attachments->isNotEmpty())
|
|
<div class="mt-4 flex flex-wrap gap-2">
|
|
@foreach ($comment->attachments as $attachment)
|
|
<a href="{{ $attachment->url() }}" target="_blank" class="rounded-full bg-zinc-100 px-3 py-1 text-xs text-zinc-700 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-200">
|
|
{{ $attachment->original_name }}
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@empty
|
|
<div class="rounded-2xl border border-dashed border-zinc-300 p-8 text-center text-zinc-500 dark:border-zinc-700">No comments yet.</div>
|
|
@endforelse
|
|
</section>
|
|
|
|
<form wire:submit="addComment" class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<h2 class="mb-4 text-base font-semibold text-zinc-900 dark:text-white">Add reply</h2>
|
|
<flux:textarea wire:model="commentBody" label="Comment" rows="5" required />
|
|
|
|
@can('update', $ticket)
|
|
<div class="mt-4">
|
|
<flux:checkbox wire:model="internal" label="Internal note only" />
|
|
</div>
|
|
@endcan
|
|
|
|
<div class="mt-4">
|
|
<label class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-200">Attach files</label>
|
|
<input wire:model="attachments" type="file" multiple class="block w-full rounded-lg border border-zinc-300 bg-white p-2 text-sm dark:border-zinc-700 dark:bg-zinc-950" />
|
|
@error('attachments.*') <div class="mt-2 text-sm text-red-600">{{ $message }}</div> @enderror
|
|
</div>
|
|
|
|
<div class="mt-5 flex justify-end">
|
|
<flux:button type="submit" variant="primary" icon="chat-bubble-left-right" wire:loading.attr="disabled">
|
|
<span wire:loading.remove>Post reply</span>
|
|
<span wire:loading>Posting...</span>
|
|
</flux:button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<aside class="space-y-6">
|
|
<div class="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<h2 class="mb-4 text-base font-semibold text-zinc-900 dark:text-white">Ticket details</h2>
|
|
<dl class="space-y-3 text-sm">
|
|
<div class="flex justify-between gap-4"><dt class="text-zinc-500">Category</dt><dd>{{ $ticket->category?->name ?? 'None' }}</dd></div>
|
|
<div class="flex justify-between gap-4"><dt class="text-zinc-500">Project</dt><dd>{{ $ticket->project?->title ?? 'None' }}</dd></div>
|
|
<div class="flex justify-between gap-4"><dt class="text-zinc-500">Created</dt><dd>{{ $ticket->created_at->format('d M Y H:i') }}</dd></div>
|
|
<div class="flex justify-between gap-4"><dt class="text-zinc-500">Due</dt><dd>{{ $ticket->due_at?->format('d M Y') ?? 'No due date' }}</dd></div>
|
|
</dl>
|
|
</div>
|
|
|
|
@can('update', $ticket)
|
|
<div class="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
|
<h2 class="mb-4 text-base font-semibold text-zinc-900 dark:text-white">Agent actions</h2>
|
|
<flux:select wire:model="status_id" label="Status">
|
|
@foreach ($statuses as $status)
|
|
<option value="{{ $status->id }}">{{ $status->name }}</option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:button wire:click="updateStatus" class="mt-4 w-full" variant="primary" icon="check">Update status</flux:button>
|
|
</div>
|
|
@endcan
|
|
</aside>
|
|
</div>
|
|
</div>
|