resetPage(); } /** * Open the archive confirmation modal for a visible ticket. */ public function askToArchiveTicket(int $ticketId): void { $ticket = Ticket::query() ->visibleTo(Auth::user()) ->findOrFail($ticketId); $this->pendingArchiveTicketId = $ticket->id; $this->pendingArchiveTicketReference = $ticket->reference; $this->pendingArchiveTicketSubject = $ticket->subject; $this->archiveModalOpen = true; } public function cancelTicketArchive(): void { $this->resetTicketArchiveState(); } /** * Archive the confirmed ticket using Laravel soft deletes. */ public function confirmTicketArchive(): void { if ($this->pendingArchiveTicketId === null) { $this->resetTicketArchiveState(); return; } $ticket = Ticket::query() ->visibleTo(Auth::user()) ->findOrFail($this->pendingArchiveTicketId); $this->authorize('delete', $ticket); $reference = $ticket->reference; $ticket->forceFill(['archived_at' => now()])->save(); $ticket->delete(); $this->resetTicketArchiveState(); $this->resetPage(); $this->dispatch( 'thredary:toast', type: 'success', title: 'Ticket archived', message: "Ticket {$reference} was moved to the archive.", ); } public function render(): View { return view('modules.helpdesk.livewire.ticket-index', [ 'tickets' => $this->tickets(), 'statuses' => Status::query()->orderBy('sort_order')->get(), 'priorities' => Priority::query()->orderBy('sort_order')->get(), ])->layout('layouts.app'); } private function resetTicketArchiveState(): void { $this->archiveModalOpen = false; $this->pendingArchiveTicketId = null; $this->pendingArchiveTicketReference = null; $this->pendingArchiveTicketSubject = null; } /** * @return LengthAwarePaginator */ private function tickets(): LengthAwarePaginator { $user = Auth::user(); $search = trim($this->search); return Ticket::query() ->without('user') ->select('helpdesk_tickets.*') ->addSelect([ 'agent_name' => User::query() ->select('name') ->whereColumn('users.id', 'helpdesk_tickets.agent_id') ->limit(1), ]) ->with(['status', 'priority', 'category', 'project', 'team']) ->withCount('attachments') ->visibleTo($user) ->when($this->scope === 'open', static fn (Builder $query): Builder => $query->whereNull('completed_at')) ->when($this->scope === 'closed', static fn (Builder $query): Builder => $query->whereNotNull('completed_at')) ->when($this->status !== '', fn (Builder $query): Builder => $query->where('status_id', (int) $this->status)) ->when($this->priority !== '', fn (Builder $query): Builder => $query->where('priority_id', (int) $this->priority)) ->when($search !== '', static function (Builder $query) use ($search): Builder { return $query->where(static function (Builder $subQuery) use ($search): void { $subQuery->where('reference', 'like', '%'.$search.'%') ->orWhere('subject', 'like', '%'.$search.'%') ->orWhere('body', 'like', '%'.$search.'%'); }); }) ->latest('last_activity_at') ->paginate(15); } }