authorizeAbility($request, 'watchlist.view'); $organization = $this->organization($request); $entries = WatchlistEntry::owned($this->ownerRef($request)) ->where('organization_id', $organization->id) ->with('visitor') ->when($request->status, fn ($q, $status) => $q->where('status', $status)) ->when($request->q, function ($q, $search) { $q->where(function ($inner) use ($search) { $inner->where('full_name', 'like', "%{$search}%") ->orWhere('company', 'like', "%{$search}%"); }); }) ->latest() ->paginate(25) ->withQueryString(); $statsQuery = WatchlistEntry::owned($this->ownerRef($request)) ->where('organization_id', $organization->id); $heroStats = [ 'total' => (clone $statsQuery)->count(), 'requires_approval' => (clone $statsQuery)->where('status', Visitor::WATCHLIST_REQUIRES_APPROVAL)->count(), 'blacklisted' => (clone $statsQuery)->where('status', Visitor::WATCHLIST_BLACKLISTED)->count(), ]; return view('frontdesk.watchlist.index', [ 'entries' => $entries, 'organization' => $organization, 'statuses' => config('frontdesk.watchlist_statuses'), 'heroStats' => $heroStats, 'canManage' => app(\App\Services\Frontdesk\FrontdeskPermissions::class) ->can($this->member($request), 'watchlist.manage'), ]); } public function create(Request $request): View { $this->authorizeAbility($request, 'watchlist.manage'); $organization = $this->organization($request); $visitors = Visitor::owned($this->ownerRef($request)) ->where('organization_id', $organization->id) ->orderBy('full_name') ->limit(100) ->get(); return view('frontdesk.watchlist.create', [ 'organization' => $organization, 'visitors' => $visitors, 'statuses' => config('frontdesk.watchlist_statuses'), ]); } public function store(Request $request, WatchlistService $watchlist): RedirectResponse { $this->authorizeAbility($request, 'watchlist.manage'); $organization = $this->organization($request); $validated = $request->validate([ 'visitor_id' => ['nullable', 'integer'], 'full_name' => ['required_without:visitor_id', 'string', 'max:255'], 'company' => ['nullable', 'string', 'max:255'], 'status' => ['required', 'string', 'in:'.implode(',', array_keys(config('frontdesk.watchlist_statuses')))], 'reason' => ['nullable', 'string', 'max:2000'], ]); if ($validated['status'] === Visitor::WATCHLIST_ALLOWED) { return back()->withErrors(['status' => 'Choose requires approval or blacklisted for watchlist entries.']); } $visitor = null; if (! empty($validated['visitor_id'])) { $visitor = Visitor::owned($this->ownerRef($request))->findOrFail($validated['visitor_id']); $validated['full_name'] = $visitor->full_name; $validated['company'] = $visitor->company; } $entry = WatchlistEntry::create([ 'owner_ref' => $this->ownerRef($request), 'organization_id' => $organization->id, 'visitor_id' => $visitor?->id, 'full_name' => $validated['full_name'], 'company' => $validated['company'] ?? null, 'status' => $validated['status'], 'reason' => $validated['reason'] ?? null, 'created_by' => $this->ownerRef($request), ]); if ($visitor) { $visitor->update(['watchlist_status' => $validated['status'], 'notes' => $validated['reason'] ?? $visitor->notes]); } AuditLog::record( $this->ownerRef($request), 'watchlist.entry_created', $organization->id, $this->ownerRef($request), WatchlistEntry::class, $entry->id, ['full_name' => $entry->full_name, 'status' => $entry->status], ); return redirect() ->route('frontdesk.watchlist.index') ->with('success', 'Watchlist entry added.'); } public function destroy(Request $request, WatchlistEntry $entry, WatchlistService $watchlist): RedirectResponse { $this->authorizeAbility($request, 'watchlist.manage'); $this->authorizeOwner($request, $entry); $organization = $this->organization($request); if ($entry->visitor_id) { $visitor = Visitor::owned($this->ownerRef($request))->find($entry->visitor_id); $visitor?->update(['watchlist_status' => Visitor::WATCHLIST_ALLOWED]); } AuditLog::record( $this->ownerRef($request), 'watchlist.entry_removed', $organization->id, $this->ownerRef($request), WatchlistEntry::class, $entry->id, ['full_name' => $entry->full_name], ); $entry->delete(); return back()->with('success', 'Watchlist entry removed.'); } }