feat: full dashboard-ticketing scaffold with data model, controllers, Vue pages
This commit is contained in:
144
src/Http/Controllers/TicketingSettingsController.php
Normal file
144
src/Http/Controllers/TicketingSettingsController.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Dashboard\Ticketing\Http\Controllers;
|
||||
|
||||
use Dashboard\Ticketing\Models\PriorityLevel;
|
||||
use Dashboard\Ticketing\Models\TicketingAgentAccess;
|
||||
use Dashboard\Ticketing\Models\TicketingGroup;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class TicketingSettingsController extends Controller
|
||||
{
|
||||
private function requireAgentAccess(): void
|
||||
{
|
||||
$hasAccess = TicketingAgentAccess::where('user_id', Auth::id())->exists();
|
||||
if (!$hasAccess) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
|
||||
private function requireManagerAccess(int $groupId): void
|
||||
{
|
||||
$isManager = TicketingAgentAccess::where('user_id', Auth::id())
|
||||
->where('group_id', $groupId)
|
||||
->where('role', 'manager')
|
||||
->exists();
|
||||
if (!$isManager) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
|
||||
public function index(): Response
|
||||
{
|
||||
$this->requireAgentAccess();
|
||||
|
||||
$userId = Auth::id();
|
||||
$myGroupIds = TicketingAgentAccess::where('user_id', $userId)->pluck('group_id');
|
||||
|
||||
$groups = TicketingGroup::whereIn('id', $myGroupIds)->get();
|
||||
|
||||
$agents = TicketingAgentAccess::whereIn('group_id', $myGroupIds)->get();
|
||||
$agentUserIds = $agents->pluck('user_id')->unique();
|
||||
$agentUsers = \DB::table('users')->whereIn('id', $agentUserIds)->get(['id', 'name', 'email'])->keyBy('id');
|
||||
$agents->each(fn($a) => $a->user = $agentUsers[$a->user_id] ?? null);
|
||||
|
||||
$priorities = PriorityLevel::where(fn($q) => $q->whereNull('group_id')->orWhereIn('group_id', $myGroupIds))
|
||||
->orderBy('sort_order')->get();
|
||||
|
||||
return Inertia::render('Ticketing/Settings', [
|
||||
'groups' => $groups,
|
||||
'agents' => $agents,
|
||||
'priorities' => $priorities,
|
||||
'myGroupIds' => $myGroupIds,
|
||||
]);
|
||||
}
|
||||
|
||||
public function storeGroup(Request $request)
|
||||
{
|
||||
$this->requireAgentAccess();
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:100',
|
||||
'email_address' => 'nullable|email',
|
||||
'color' => 'required|string|regex:/^#[0-9a-fA-F]{6}$/',
|
||||
'prefix' => 'required|string|max:10|alpha_num|unique:ticketing_groups,prefix',
|
||||
]);
|
||||
|
||||
$group = TicketingGroup::create($validated);
|
||||
|
||||
// Auto-add creator as manager
|
||||
TicketingAgentAccess::create([
|
||||
'user_id' => Auth::id(),
|
||||
'group_id' => $group->id,
|
||||
'role' => 'manager',
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Group created.');
|
||||
}
|
||||
|
||||
public function updateGroup(Request $request, TicketingGroup $group)
|
||||
{
|
||||
$this->requireManagerAccess($group->id);
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:100',
|
||||
'email_address' => 'nullable|email',
|
||||
'color' => 'required|string|regex:/^#[0-9a-fA-F]{6}$/',
|
||||
'prefix' => 'required|string|max:10|alpha_num|unique:ticketing_groups,prefix,' . $group->id,
|
||||
]);
|
||||
|
||||
$group->update($validated);
|
||||
|
||||
return back()->with('success', 'Group updated.');
|
||||
}
|
||||
|
||||
public function storeAgent(Request $request)
|
||||
{
|
||||
$this->requireAgentAccess();
|
||||
|
||||
$validated = $request->validate([
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'group_id' => 'required|exists:ticketing_groups,id',
|
||||
'role' => 'required|in:agent,manager',
|
||||
]);
|
||||
|
||||
$this->requireManagerAccess($validated['group_id']);
|
||||
|
||||
TicketingAgentAccess::updateOrCreate(
|
||||
['user_id' => $validated['user_id'], 'group_id' => $validated['group_id']],
|
||||
['role' => $validated['role']]
|
||||
);
|
||||
|
||||
return back()->with('success', 'Agent added.');
|
||||
}
|
||||
|
||||
public function destroyAgent(TicketingAgentAccess $access)
|
||||
{
|
||||
$this->requireManagerAccess($access->group_id);
|
||||
|
||||
$access->delete();
|
||||
|
||||
return back()->with('success', 'Agent removed.');
|
||||
}
|
||||
|
||||
public function storePriority(Request $request)
|
||||
{
|
||||
$this->requireAgentAccess();
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:100',
|
||||
'color' => 'required|string|regex:/^#[0-9a-fA-F]{6}$/',
|
||||
'description' => 'nullable|string',
|
||||
'sort_order' => 'integer|min:0',
|
||||
'group_id' => 'nullable|exists:ticketing_groups,id',
|
||||
]);
|
||||
|
||||
PriorityLevel::create($validated);
|
||||
|
||||
return back()->with('success', 'Priority level created.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user