workign comments strucuture
This commit is contained in:
@@ -231,10 +231,10 @@
|
||||
? 'border-color: '.$sectionPalette['border'].'; background-color: '.$sectionPalette['active'].'; color: #ffffff; box-shadow: 0 16px 36px rgba(0,0,0,.32);'
|
||||
: 'border-color: '.$sectionPalette['border'].'; background-color: '.$sectionPalette['bg'].'; color: #ffffff; box-shadow: 0 10px 24px rgba(0,0,0,.20);';
|
||||
@endphp
|
||||
<button type="button" dusk="helpdesk-settings-section-{{ $key }}" wire:click="$set('section', '{{ $key }}')" class="rounded-2xl border px-4 py-3 text-left shadow-sm transition hover:-translate-y-0.5" style="{{ $sectionStyle }}">
|
||||
<a href="{{ route('helpdesk.settings', ['section' => $key]) }}" dusk="helpdesk-settings-section-{{ $key }}" class="rounded-2xl border px-4 py-3 text-left shadow-sm transition hover:-translate-y-0.5" style="{{ $sectionStyle }}">
|
||||
<div class="text-xs font-semibold uppercase tracking-wide opacity-70">{{ $item['label'] }}</div>
|
||||
<div class="mt-1 text-2xl font-semibold">{{ $item['count'] }}</div>
|
||||
</button>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
|
||||
@@ -74,13 +74,13 @@
|
||||
<h2 class="text-lg font-semibold text-zinc-900 dark:text-white">Conversation</h2>
|
||||
|
||||
@if ($ticket->comments->isNotEmpty())
|
||||
@include('helpdesk::partials.comment-thread', ['comments' => $ticket->comments, 'level' => 0])
|
||||
@include('helpdesk::partials.comment-thread', ['comments' => $ticket->comments, 'level' => 0, 'ticket' => $ticket])
|
||||
@else
|
||||
<div class="rounded-2xl border border-dashed border-zinc-300 p-8 text-center text-zinc-500 dark:border-zinc-700">No responses yet.</div>
|
||||
@endif
|
||||
</section>
|
||||
|
||||
<form method="POST" action="{{ route('helpdesk.tickets.comments.store', $ticket) }}" enctype="multipart/form-data" class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<form method="POST" action="{{ route('helpdesk.tickets.comments.store', $ticket) }}" enctype="multipart/form-data" class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900" data-helpdesk-comment-form>
|
||||
@csrf
|
||||
<h2 class="mb-4 text-base font-semibold text-zinc-900 dark:text-white">Add reply</h2>
|
||||
@if (session('ticket-comment-added'))
|
||||
@@ -88,26 +88,42 @@
|
||||
{{ session('ticket-comment-added') }}
|
||||
</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div class="mb-4 rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm font-bold text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-100">
|
||||
{{ $errors->first() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($cannedResponses->isNotEmpty())
|
||||
<div class="mb-4 grid gap-3 md:grid-cols-[1fr_auto]">
|
||||
<flux:select wire:model="canned_response_id" label="Canned response">
|
||||
<option value="">Choose a saved response...</option>
|
||||
@foreach ($cannedResponses as $response)
|
||||
<option value="{{ $response->id }}">{{ $response->name }}</option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
<div>
|
||||
<label for="ticket-canned-response" class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-200">Canned response</label>
|
||||
<select id="ticket-canned-response" name="canned_response_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white p-2.5 text-sm font-semibold text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-canned-response-select>
|
||||
<option value="">Choose a saved response...</option>
|
||||
@foreach ($cannedResponses as $response)
|
||||
<option value="{{ $response->id }}" data-body="{{ e($response->body) }}">{{ $response->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex items-end">
|
||||
<flux:button type="button" wire:click="applyCannedResponse" variant="ghost" icon="document-duplicate" class="!bg-blue-600 !text-white hover:!bg-blue-700 focus:!ring-blue-400/60">Insert response</flux:button>
|
||||
<button type="button" dusk="insert-canned-response" class="inline-flex items-center justify-center rounded-xl bg-blue-600 px-4 py-2 text-sm font-bold text-white shadow-sm transition hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400/70" data-insert-canned-response>
|
||||
<i class="fa-solid fa-copy mr-2" aria-hidden="true"></i>
|
||||
Insert response
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<x-helpdesk::html-editor dusk="ticket-comment-editor" wire:model="commentBody" label="Comment" rows="5" placeholder="Write a professional response..." />
|
||||
<div>
|
||||
<label for="ticket-comment-body" class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-200">Comment</label>
|
||||
<textarea id="ticket-comment-body" dusk="ticket-comment-editor" name="commentBody" rows="5" placeholder="Write a professional response..." required class="block w-full rounded-xl border border-zinc-300 bg-white p-3 text-sm text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100">{{ old('commentBody') }}</textarea>
|
||||
</div>
|
||||
|
||||
@can('update', $ticket)
|
||||
<div class="mt-4">
|
||||
<flux:checkbox wire:model="internal" label="Internal note only" />
|
||||
</div>
|
||||
<label class="mt-4 flex items-center gap-2 text-sm font-semibold text-zinc-700 dark:text-zinc-200">
|
||||
<input type="checkbox" name="internal" value="1" @checked(old('internal')) class="rounded border-zinc-300">
|
||||
Internal note only
|
||||
</label>
|
||||
@endcan
|
||||
|
||||
<div class="mt-4">
|
||||
@@ -119,10 +135,52 @@
|
||||
<div class="mt-5 flex justify-end">
|
||||
<button dusk="post-comment" type="submit" class="inline-flex items-center justify-center rounded-xl bg-emerald-600 px-4 py-2 text-sm font-bold text-white shadow-sm transition hover:bg-emerald-700 focus:outline-none focus:ring-2 focus:ring-emerald-400/70">
|
||||
<i class="fa-solid fa-comments mr-2" aria-hidden="true"></i>
|
||||
<span>Post reply</span>
|
||||
Post reply
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.addEventListener('click', function (event) {
|
||||
const insertButton = event.target.closest('[data-insert-canned-response]');
|
||||
|
||||
if (insertButton) {
|
||||
const form = insertButton.closest('[data-helpdesk-comment-form]');
|
||||
const select = form?.querySelector('[data-canned-response-select]');
|
||||
const textarea = form?.querySelector('textarea[name="commentBody"]');
|
||||
const selected = select?.selectedOptions?.[0];
|
||||
const body = selected?.dataset?.body || '';
|
||||
|
||||
if (textarea && body.trim() !== '') {
|
||||
textarea.value = textarea.value.trim() === ''
|
||||
? body
|
||||
: textarea.value.replace(/\s+$/, '') + "\n\n" + body;
|
||||
textarea.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
textarea.focus();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const replyButton = event.target.closest('[data-helpdesk-reply-toggle]');
|
||||
|
||||
if (! replyButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = document.getElementById(replyButton.dataset.helpdeskReplyToggle || '');
|
||||
|
||||
if (! target) {
|
||||
return;
|
||||
}
|
||||
|
||||
target.classList.toggle('hidden');
|
||||
|
||||
if (! target.classList.contains('hidden')) {
|
||||
target.querySelector('textarea')?.focus();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<aside class="space-y-6">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@props(['comments', 'level' => 0])
|
||||
@props(['comments', 'level' => 0, 'ticket' => null])
|
||||
|
||||
<div class="space-y-3">
|
||||
@foreach ($comments as $comment)
|
||||
@@ -6,6 +6,8 @@
|
||||
$commentUser = $comment->relationLoaded('user') ? $comment->getRelation('user') : null;
|
||||
$commentAttachments = $comment->relationLoaded('attachments') ? $comment->getRelation('attachments') : collect();
|
||||
$commentReplies = $comment->relationLoaded('replies') ? $comment->getRelation('replies') : collect();
|
||||
$replyFormId = 'helpdesk-reply-form-'.$comment->id;
|
||||
$currentTicket = $ticket ?? $comment->ticket ?? null;
|
||||
@endphp
|
||||
|
||||
<div class="rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-700 dark:bg-zinc-900" style="margin-left: {{ min((int) $level, 4) * 1.25 }}rem">
|
||||
@@ -20,7 +22,7 @@
|
||||
</div>
|
||||
|
||||
@if ($comment->is_internal)
|
||||
<flux:badge color="amber">Internal</flux:badge>
|
||||
<span class="rounded-full bg-amber-100 px-2.5 py-1 text-xs font-bold text-amber-800 dark:bg-amber-950 dark:text-amber-100">Internal</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -31,24 +33,30 @@
|
||||
@if ($commentAttachments->isNotEmpty())
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
@foreach ($commentAttachments as $attachment)
|
||||
<a href="{{ $attachment->url() }}" target="_blank" class="rounded-lg border border-zinc-200 px-3 py-1 text-xs text-zinc-600 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800">
|
||||
{{ $attachment->original_name }}
|
||||
<a href="{{ route('helpdesk.attachments.download', $attachment->id) }}" target="_blank" class="rounded-lg border border-zinc-200 px-3 py-1 text-xs text-zinc-600 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800">
|
||||
{{ $attachment->original_name ?? $attachment->original_filename ?? $attachment->filename ?? $attachment->file_name ?? basename($attachment->path ?? $attachment->file_path ?? '') }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="mt-3 flex justify-end">
|
||||
<flux:button size="sm" variant="primary" wire:click="startReply({{ $comment->id }})" class="!bg-blue-600 !text-white hover:!bg-blue-700 focus:!ring-blue-400/60">Reply</flux:button>
|
||||
</div>
|
||||
@if ($currentTicket !== null)
|
||||
<div class="mt-3 flex justify-end">
|
||||
<button type="button" dusk="reply-to-comment-{{ $comment->id }}" data-helpdesk-reply-toggle="{{ $replyFormId }}" class="inline-flex items-center justify-center rounded-lg bg-blue-600 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400/70">
|
||||
<i class="fa-solid fa-reply mr-2" aria-hidden="true"></i>
|
||||
Reply
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@if (($reply_parent_id ?? null) === $comment->id)
|
||||
<form wire:submit="addReply" class="mt-4 rounded-xl border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/40">
|
||||
<x-helpdesk::html-editor wire:key="reply-editor-{{ $comment->id }}" wire:model="replyBody" label="Reply" rows="4" placeholder="Write a reply..." />
|
||||
<form id="{{ $replyFormId }}" method="POST" action="{{ route('helpdesk.tickets.comments.store', $currentTicket) }}" enctype="multipart/form-data" class="mt-4 hidden rounded-xl border border-blue-200 bg-blue-50 p-4 dark:border-blue-900 dark:bg-blue-950/40">
|
||||
@csrf
|
||||
<input type="hidden" name="parent_id" value="{{ $comment->id }}">
|
||||
<label for="reply-body-{{ $comment->id }}" class="mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-200">Reply</label>
|
||||
<textarea id="reply-body-{{ $comment->id }}" dusk="reply-body-{{ $comment->id }}" name="commentBody" rows="4" required class="block w-full rounded-xl border border-zinc-300 bg-white p-3 text-sm text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" placeholder="Write a reply..."></textarea>
|
||||
|
||||
<div class="mt-4 flex justify-end gap-2">
|
||||
<flux:button type="button" wire:click="cancelReply" variant="ghost" class="!bg-slate-600 !text-white hover:!bg-slate-700 focus:!ring-slate-400/60">Cancel</flux:button>
|
||||
<flux:button type="submit" variant="primary" class="!bg-emerald-600 !text-white hover:!bg-emerald-700 focus:!ring-emerald-400/60">Post reply</flux:button>
|
||||
<button type="button" data-helpdesk-reply-toggle="{{ $replyFormId }}" class="inline-flex items-center justify-center rounded-lg bg-slate-600 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-slate-400/70">Cancel</button>
|
||||
<button type="submit" dusk="post-reply-{{ $comment->id }}" class="inline-flex items-center justify-center rounded-lg bg-emerald-600 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-emerald-700 focus:outline-none focus:ring-2 focus:ring-emerald-400/70">Post reply</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
@@ -58,6 +66,7 @@
|
||||
@include('helpdesk::partials.comment-thread', [
|
||||
'comments' => $commentReplies,
|
||||
'level' => ((int) $level) + 1,
|
||||
'ticket' => $currentTicket,
|
||||
])
|
||||
</div>
|
||||
@endif
|
||||
|
||||
Reference in New Issue
Block a user