getActiveClients())->map(fn ($c) => [ 'mac' => $c['mac'], 'hostname' => $c['hostname'] ?? $c['name'] ?? '', 'ip' => $c['ip'] ?? '', 'oui' => $c['oui'] ?? '', 'os' => $c['os_name'] ?? null, 'dev_cat' => $c['dev_cat'] ?? null, 'dev_family' => $c['dev_family'] ?? null, 'dev_vendor' => $c['dev_vendor'] ?? null, 'is_wired' => $c['is_wired'] ?? false, 'is_guest' => $c['is_guest'] ?? false, 'ssid' => $c['essid'] ?? null, 'network' => $c['network'] ?? null, 'ap_mac' => $c['ap_mac'] ?? null, 'sw_mac' => $c['sw_mac'] ?? null, 'sw_port' => $c['sw_port'] ?? null, 'rssi' => $c['rssi'] ?? null, 'signal' => $c['signal'] ?? null, 'channel' => $c['channel'] ?? null, 'tx_bytes' => $c['tx_bytes'] ?? 0, 'rx_bytes' => $c['rx_bytes'] ?? 0, 'tx_rate' => $c['tx_rate'] ?? 0, 'rx_rate' => $c['rx_rate'] ?? 0, 'tx_rate_r' => $c['tx_bytes-r'] ?? 0, 'rx_rate_r' => $c['rx_bytes-r'] ?? 0, 'uptime' => $c['uptime'] ?? 0, 'satisfaction' => $c['satisfaction'] ?? null, 'vlan_id' => ($c['vlan_id'] ?? 0) ?: null, 'dot1x' => $c['1x_identity'] ?? $c['dot1x_identity'] ?? null, 'is_known' => KnownMac::where('mac_address', strtolower($c['mac']))->exists(), ])->values(); // APs and switches for the device filter dropdown $devices = collect($unifi->getDevices()) ->filter(fn ($d) => in_array($d['type'] ?? '', ['uap', 'usw'])) ->map(fn ($d) => [ 'mac' => $d['mac'], 'name' => $d['name'] ?? $d['model'] ?? $d['mac'], 'type' => $d['type'], ]) ->sortBy('name') ->values(); return Inertia::render('Unifi/Clients', [ 'clients' => $clients, 'vlanGroups' => VlanGroup::orderBy('sort_order')->get(), 'devices' => $devices, 'selectedDevice' => $request->query('device'), ]); } catch (\Throwable $e) { return Inertia::render('Unifi/Clients', ['clients' => [], 'error' => $e->getMessage()]); } } public function kick(Request $request, UnifiApiClient $unifi) { $request->validate(['mac' => 'required|string']); try { $unifi->kickClient($request->mac); // Deactivate portal session if there is one PortalSession::where('mac_address', strtolower($request->mac)) ->where('is_active', true) ->update(['is_active' => false]); return back()->with('success', 'Client disconnected.'); } catch (\Throwable $e) { return back()->withErrors(['error' => $e->getMessage()]); } } }