migrant-web/app/Http/Controllers/Employer/SupportTicketController.php
2026-06-15 11:59:05 +05:30

198 lines
6.9 KiB
PHP

<?php
namespace App\Http\Controllers\Employer;
use App\Http\Controllers\Controller;
use App\Models\SupportTicket;
use App\Models\SupportTicketReply;
use App\Models\User;
use App\Models\ReportReason;
use Illuminate\Http\Request;
use Inertia\Inertia;
class SupportTicketController extends Controller
{
private function resolveEmployer(Request $request)
{
$sess = session('user');
$sessId = is_array($sess) ? ($sess['id'] ?? null) : ($sess->id ?? null);
if (!$sessId) {
$user = User::where('role', 'employer')->first();
if ($user) {
session(['user' => (object)[
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'role' => 'employer',
'subscription_status' => $user->subscription_status ?? 'active',
]]);
}
return $user;
}
return User::find($sessId);
}
public function index(Request $request)
{
$user = $this->resolveEmployer($request);
if (!$user) {
return redirect()->route('employer.login');
}
$tickets = SupportTicket::where('user_id', $user->id)
->with('reason')
->orderBy('created_at', 'desc')
->get()
->map(function ($ticket) {
return [
'id' => $ticket->id,
'ticket_number' => $ticket->ticket_number,
'subject' => $ticket->subject,
'reason' => $ticket->reason ? $ticket->reason->reason : null,
'status' => $ticket->status,
'priority' => $ticket->priority,
'created_at' => $ticket->created_at->format('Y-m-d H:i'),
'updated_at' => $ticket->updated_at->diffForHumans(),
];
});
return Inertia::render('Employer/Support/Index', [
'tickets' => $tickets,
]);
}
public function create(Request $request)
{
$user = $this->resolveEmployer($request);
if (!$user) {
return redirect()->route('employer.login');
}
$reasons = ReportReason::where('status', 'Active')
->where('type', 'Support')
->orderBy('reason', 'asc')
->get(['id', 'reason', 'type']);
return Inertia::render('Employer/Support/Create', [
'reasons' => $reasons,
]);
}
public function store(Request $request)
{
$user = $this->resolveEmployer($request);
if (!$user) {
return redirect()->route('employer.login');
}
$request->validate([
'reason_id' => 'nullable|exists:report_reasons,id',
'subject' => 'required|string|max:255',
'description' => 'required|string',
'priority' => 'required|string|in:low,medium,high',
'voice_note' => 'nullable|file|mimes:mp3,wav,m4a,ogg,webm,aac,3gp,amr|max:10240', // 10MB limit
]);
$voiceNotePath = null;
if ($request->hasFile('voice_note')) {
$voiceNotePath = $request->file('voice_note')->store('support_voice_notes', 'public');
}
$ticket = SupportTicket::create([
'ticket_number' => 'TKT-' . rand(100000, 999999),
'user_id' => $user->id,
'reason_id' => $request->reason_id,
'subject' => $request->subject,
'description' => $request->description,
'voice_note_path' => $voiceNotePath,
'priority' => $request->priority,
'status' => 'open',
]);
return redirect()->route('employer.support.show', $ticket->id)
->with('success', 'Ticket created successfully.');
}
public function show(Request $request, $id)
{
$user = $this->resolveEmployer($request);
if (!$user) {
return redirect()->route('employer.login');
}
$ticket = SupportTicket::where('user_id', $user->id)->with('reason')->findOrFail($id);
$replies = SupportTicketReply::where('support_ticket_id', $ticket->id)
->with(['user', 'worker'])
->orderBy('created_at', 'asc')
->get()
->map(function ($reply) {
return [
'id' => $reply->id,
'message' => $reply->message,
'sender_name' => $reply->sender_name,
'is_admin' => $reply->user && $reply->user->role === 'admin',
'is_developer_response' => (bool)$reply->is_developer_response,
'voice_note_url' => $reply->voice_note_path ? asset('storage/' . $reply->voice_note_path) : null,
'created_at' => $reply->created_at->format('Y-m-d H:i'),
];
});
return Inertia::render('Employer/Support/Show', [
'ticket' => [
'id' => $ticket->id,
'ticket_number' => $ticket->ticket_number,
'subject' => $ticket->subject,
'reason' => $ticket->reason ? $ticket->reason->reason : null,
'description' => $ticket->description,
'voice_note_url' => $ticket->voice_note_path ? asset('storage/' . $ticket->voice_note_path) : null,
'status' => $ticket->status,
'priority' => $ticket->priority,
'created_at' => $ticket->created_at->format('Y-m-d H:i'),
],
'replies' => $replies,
]);
}
public function reply(Request $request, $id)
{
$user = $this->resolveEmployer($request);
if (!$user) {
return redirect()->route('employer.login');
}
$ticket = SupportTicket::where('user_id', $user->id)->findOrFail($id);
if ($ticket->status === 'closed') {
return redirect()->back()->with('error', 'Cannot reply to a closed ticket.');
}
$request->validate([
'message' => 'nullable|required_without:voice_note|string',
'voice_note' => 'nullable|file|mimes:mp3,wav,m4a,ogg,webm,aac,3gp,amr|max:10240', // 10MB limit
]);
$voiceNotePath = null;
if ($request->hasFile('voice_note')) {
$voiceNotePath = $request->file('voice_note')->store('support_voice_notes', 'public');
}
SupportTicketReply::create([
'support_ticket_id' => $ticket->id,
'user_id' => $user->id,
'message' => $request->message,
'voice_note_path' => $voiceNotePath,
]);
// Reopen ticket if resolved/closed was updated
if ($ticket->status === 'resolved') {
$ticket->update(['status' => 'open']);
}
return redirect()->route('employer.support.show', $ticket->id)
->with('success', 'Reply posted successfully.');
}
}