with('user'); if ($request->filled('q')) { $q = $request->q; $query->where(function ($qry) use ($q) { $qry->where('subject', 'like', "%{$q}%") ->orWhereHas('user', fn ($u) => $u->where('mobile', 'like', "%{$q}%") ->orWhere('name', 'like', "%{$q}%")); }); } // Optional: Filter by status (open, answered, user_reply, closed) if ($request->filled('status')) { $query->where('status', $request->status); } $perPage = min(max((int) $request->input('per_page', 15), 10), 100); // Order by updated_at so tickets with new replies jump to the top $tickets = $query->latest('updated_at')->paginate($perPage)->withQueryString(); return view('admin.tickets.index', compact('tickets')); } public function show(Ticket $ticket) { // Load messages and the user belonging to the ticket $ticket->load(['messages.user', 'user']); return view('admin.tickets.show', compact('ticket')); } public function reply(Request $request, Ticket $ticket) { $request->validate([ 'message' => 'required|string', 'attachment' => 'nullable|file|mimes:jpg,jpeg,png,pdf|max:5120', ]); $attachmentPath = null; if ($request->hasFile('attachment')) { $attachmentPath = $request->file('attachment')->store('tickets', 'public'); } TicketMessage::create([ 'ticket_id' => $ticket->id, 'user_id' => auth()->id(), // This will be the Admin's ID 'message' => $request->message, 'attachment_path' => $attachmentPath, ]); $ticket->update(['status' => 'answered']); return redirect()->route('tickets.show', $ticket->id) ->with('success', 'پاسخ شما با موفقیت ارسال شد.'); } public function close(Ticket $ticket) { $ticket->update(['status' => 'closed']); return redirect()->route('tickets.index') ->with('success', 'تیکت با موفقیت بسته شد.'); } }