Files
Helpddesk/resources/themes/backend/views/modules/helpdesk/livewire/kanban-board.blade.php
T
2026-08-25 17:12:22 +01:00

173 lines
8.4 KiB
PHP

<div class="hd-helpdesk-surface space-y-6" wire:key="helpdesk-kanban-{{ $refreshNonce }}">
<div class="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
<div>
<flux:heading size="xl">{{ __('Helpdesk Kanban') }}</flux:heading>
<flux:text class="mt-1">
{{ __('Move tickets through the workflow for the selected board.') }}
</flux:text>
</div>
<div class="flex flex-wrap items-end gap-3">
@if ($boards->isNotEmpty())
<div class="min-w-64">
<flux:select
wire:model.live="board_id"
:label="__('Board')"
>
@foreach ($boards as $boardOption)
<option value="{{ $boardOption->id }}">
{{ $boardOption->name }}
@if ($boardOption->is_default)
— {{ __('Default') }}
@endif
</option>
@endforeach
</flux:select>
</div>
@endif
<flux:button
:href="route('helpdesk.tickets.index')"
wire:navigate
>
{{ __('Ticket list') }}
</flux:button>
<flux:button
variant="primary"
:href="route('helpdesk.tickets.create')"
wire:navigate
>
{{ __('New ticket') }}
</flux:button>
</div>
</div>
@if (session('success'))
<div class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-3 text-sm font-medium text-emerald-800 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-200">
{{ session('success') }}
</div>
@endif
@if ($board === null)
<div class="rounded-2xl border border-dashed border-zinc-300 bg-white p-10 text-center dark:border-zinc-700 dark:bg-zinc-900">
<flux:heading size="lg">{{ __('No Kanban board configured') }}</flux:heading>
<flux:text class="mt-2">
{{ __('Create a board in Helpdesk settings before using Kanban.') }}
</flux:text>
<flux:button
class="mt-5"
variant="primary"
:href="route('helpdesk.settings')"
wire:navigate
>
{{ __('Open settings') }}
</flux:button>
</div>
@else
<div class="flex gap-4 overflow-x-auto pb-4">
@foreach ($statuses as $status)
@php
$statusTickets = collect($ticketsByStatus[$status->id] ?? []);
@endphp
<section
class="w-[22rem] min-w-[22rem] rounded-2xl border border-zinc-200 bg-zinc-100/70 p-3 dark:border-zinc-700 dark:bg-zinc-900"
wire:key="kanban-status-{{ $status->id }}-{{ $refreshNonce }}"
>
<header class="mb-3 flex items-center justify-between gap-3 px-1">
<div class="min-w-0">
<flux:heading size="sm" class="truncate">
{{ $status->name }}
</flux:heading>
</div>
<span class="inline-flex min-w-7 items-center justify-center rounded-full bg-white px-2 py-1 text-xs font-semibold text-zinc-600 shadow-sm dark:bg-zinc-800 dark:text-zinc-300">
{{ $statusTickets->count() }}
</span>
</header>
<div class="space-y-3">
@forelse ($statusTickets as $ticket)
<article
class="rounded-xl border border-zinc-200 bg-white p-4 shadow-sm transition hover:shadow-md dark:border-zinc-700 dark:bg-zinc-800"
wire:key="kanban-ticket-{{ $ticket->id }}-{{ $ticket->status_id }}"
>
<div class="flex items-start justify-between gap-3">
<div class="min-w-0">
<a
href="{{ route('helpdesk.tickets.show', $ticket) }}"
wire:navigate
class="text-xs font-semibold text-blue-600 hover:underline dark:text-blue-400"
>
{{ $ticket->reference }}
</a>
<a
href="{{ route('helpdesk.tickets.show', $ticket) }}"
wire:navigate
class="mt-1 block font-semibold leading-snug text-zinc-900 hover:underline dark:text-zinc-100"
>
{{ $ticket->subject }}
</a>
</div>
@if ($ticket->priority)
<span class="shrink-0 rounded-full bg-zinc-100 px-2 py-1 text-[11px] font-semibold text-zinc-600 dark:bg-zinc-700 dark:text-zinc-200">
{{ $ticket->priority->name }}
</span>
@endif
</div>
<div class="mt-3 space-y-1 text-xs text-zinc-500 dark:text-zinc-400">
@if ($ticket->agent)
<div>{{ __('Agent') }}: {{ $ticket->agent->name }}</div>
@endif
@if ($ticket->category)
<div>{{ __('Category') }}: {{ $ticket->category->name }}</div>
@endif
@if ($ticket->project)
<div>{{ __('Project') }}: {{ $ticket->project->name ?? $ticket->project->title ?? '—' }}</div>
@endif
</div>
@can('update', $ticket)
<div class="mt-4">
<label class="mb-1 block text-xs font-semibold text-zinc-500 dark:text-zinc-400">
{{ __('Move to') }}
</label>
<select
class="hd-select !min-h-0 !rounded-lg !px-3 !py-2 text-sm"
wire:change="moveTicket({{ $ticket->id }}, $event.target.value)"
wire:loading.attr="disabled"
wire:target="moveTicket"
>
<option value="{{ $status->id }}">{{ $status->name }}</option>
@foreach ($statuses as $targetStatus)
@if ($targetStatus->id !== $status->id)
<option value="{{ $targetStatus->id }}">
{{ $targetStatus->name }}
</option>
@endif
@endforeach
</select>
</div>
@endcan
</article>
@empty
<div class="rounded-xl border border-dashed border-zinc-300 bg-white/70 px-4 py-8 text-center text-sm text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800/40 dark:text-zinc-400">
{{ __('No tickets') }}
</div>
@endforelse
</div>
</section>
@endforeach
</div>
@endif
</div>