Files
zemailnator/app/Livewire/Dashboard/Support.php
2025-11-14 01:51:35 -08:00

160 lines
4.5 KiB
PHP

<?php
namespace App\Livewire\Dashboard;
use App\Models\Ticket;
use App\Models\TicketResponse;
use Exception;
use Livewire\Component;
use Request;
use Str;
class Support extends Component
{
public $tickets = [];
public $subject;
public $message;
public $response;
public $list = false;
public $open = 0;
public $closed = 0;
public function store()
{
$this->validate([
'subject' => 'required|string|max:255',
'message' => 'required|string',
]);
try {
$ticket = Ticket::create([
'user_id' => auth()->id(),
'ticket_id' => strtoupper(Str::random(6)),
'subject' => $this->subject,
'message' => $this->message,
'ip_address' => $this->getClientIp(),
'last_response_at' => now(),
]);
$this->dispatch('showAlert', ['type' => 'success', 'message' => 'Your ticket has been created successfully!']);
$this->dispatch('closeModal');
$this->reset(['subject', 'message']);
$this->tickets = Ticket::with('responses')
->where('user_id', auth()->id())
->get();
} catch (Exception $exception) {
$this->dispatch('showAlert', ['type' => 'error', 'message' => 'Something went wrong!']);
}
}
public function reply($ticket_id)
{
$this->validate([
'response' => 'required|string',
]);
try {
if (! is_numeric($ticket_id)) {
$this->dispatch('showAlert', ['type' => 'error', 'message' => 'Invalid ticket ID.']);
return;
}
$ticket = Ticket::find($ticket_id);
if (! $ticket) {
$this->dispatch('showAlert', ['type' => 'error', 'message' => 'Ticket not found.']);
return;
}
TicketResponse::create([
'ticket_id' => $ticket_id,
'user_id' => auth()->id(),
'response' => $this->response,
'ip_address' => $this->getClientIp(),
]);
$ticket->last_response_at = now();
$ticket->save();
$this->dispatch('showAlert', ['type' => 'success', 'message' => 'Reply sent successfully!']);
$this->reset(['response']);
$this->tickets = Ticket::with('responses')
->where('user_id', auth()->id())
->get();
} catch (Exception $exception) {
session()->flash('error', 'Something went wrong!');
}
}
public function close($ticket_id)
{
if (! is_numeric($ticket_id)) {
$this->dispatch('showAlert', ['type' => 'error', 'message' => 'Invalid ticket ID.']);
return;
}
$ticket = Ticket::find($ticket_id);
if (! $ticket) {
$this->dispatch('showAlert', ['type' => 'error', 'message' => 'Ticket not found.']);
return;
}
$ticket->status = 'closed';
$ticket->save();
$this->tickets = Ticket::with('responses')
->where('user_id', auth()->id())
->get();
$this->updateTicketCounts();
$this->dispatch('showAlert', ['type' => 'error', 'message' => 'This ticket has been closed!']);
}
public function mount()
{
$this->tickets = Ticket::with('responses')
->where('user_id', auth()->id())
->get();
$this->updateTicketCounts();
}
public function updateTicketCounts()
{
$this->open = $this->tickets->filter(function ($ticket) {
return in_array($ticket->status, ['open', 'pending']);
})->count();
$this->closed = $this->tickets->filter(function ($ticket) {
return $ticket->status === 'closed';
})->count();
}
protected function getClientIp()
{
// Cloudflare or other proxies may send the original client IP in X-Forwarded-For header
$ip = Request::header('X-Forwarded-For');
// X-Forwarded-For can contain a comma-separated list of IPs, so we need to get the first one
if ($ip) {
return explode(',', $ip)[0]; // Get the first IP in the list
}
// Fallback to the real IP if no X-Forwarded-For header
return Request::ip();
}
public function render()
{
return view('livewire.dashboard.support')->layout('components.layouts.dashboard');
}
}