first(); $totalDevices = NetworkDevice::count(); $onlineDevices = NetworkDevice::where('status', 'online')->count(); $recentEvents = NetworkDeviceEvent::with('device') ->where('documented', false) ->latest() ->take(10) ->get(); $scans = NetworkScan::latest()->take(10)->get(); return view('network.index', compact( 'latestScan', 'totalDevices', 'onlineDevices', 'recentEvents', 'scans' )); } // --- Alle Geräte --- public function devices(Request $request): View { $query = NetworkDevice::with('events') ->orderBy('current_ip'); if ($request->filled('status')) { $query->where('status', $request->status); } if ($request->filled('search')) { $s = $request->search; $query->where(function ($q) use ($s) { $q->where('current_ip', 'like', "%{$s}%") ->orWhere('mac_address', 'like', "%{$s}%") ->orWhere('hostname', 'like', "%{$s}%") ->orWhere('label', 'like', "%{$s}%") ->orWhere('mac_vendor', 'like', "%{$s}%"); }); } $devices = $query->paginate(50)->withQueryString(); return view('network.devices', compact('devices')); } // --- Geräte-Detail --- public function device(NetworkDevice $device): View { $device->load(['events.documentedBy', 'hosts.scan']); $ipHistory = $device->hosts() ->select('ip_address', 'status', 'ping_ms', 'created_at') ->join('network_scans', 'network_scans.id', '=', 'network_hosts.scan_id') ->orderByDesc('network_hosts.created_at') ->take(50) ->get(); return view('network.device', compact('device', 'ipHistory')); } // --- Gerät: Label/Notiz speichern --- public function updateDevice(Request $request, NetworkDevice $device): RedirectResponse { $validated = $request->validate([ 'label' => ['nullable', 'string', 'max:100'], 'notes' => ['nullable', 'string', 'max:1000'], ]); $oldLabel = $device->label; $device->update($validated); if ($oldLabel !== $validated['label']) { NetworkDeviceEvent::create([ 'device_id' => $device->id, 'event_type' => 'label_changed', 'old_value' => $oldLabel, 'new_value' => $validated['label'], 'description'=> 'Bezeichnung manuell geändert', 'documented' => true, 'documented_by' => auth()->id(), 'documented_at' => now(), ]); } return redirect()->route('network.device', $device) ->with('success', 'Gerät aktualisiert.'); } // --- Ereignis dokumentieren --- public function documentEvent(Request $request, NetworkDeviceEvent $event): RedirectResponse { $request->validate([ 'description' => ['nullable', 'string', 'max:500'], ]); $event->update([ 'documented' => true, 'documented_by' => auth()->id(), 'documented_at' => now(), 'description' => $request->description ?? $event->description, ]); return back()->with('success', 'Ereignis dokumentiert.'); } // --- Manuelle Notiz hinzufügen --- public function addNote(Request $request, NetworkDevice $device): RedirectResponse { $request->validate([ 'description' => ['required', 'string', 'max:500'], ]); NetworkDeviceEvent::create([ 'device_id' => $device->id, 'event_type' => 'manual_note', 'description' => $request->description, 'documented' => true, 'documented_by' => auth()->id(), 'documented_at' => now(), ]); return back()->with('success', 'Notiz hinzugefügt.'); } // --- Import --- public function showImport(): View { return view('network.import'); } public function import(Request $request, NetworkScanImporter $importer): RedirectResponse { $request->validate([ 'scan_file' => ['required', 'file', 'mimes:txt,csv', 'max:5120'], ]); $path = $request->file('scan_file')->store('imports', 'local'); $fullPath = storage_path('app/' . $path); $scan = $importer->importAngryIpScannerFile($fullPath, auth()->id()); return redirect()->route('network.scan', $scan) ->with('success', "Import abgeschlossen: {$scan->online_hosts} online, {$scan->new_devices} neue Geräte."); } // --- Scan-Detail --- public function scan(NetworkScan $scan): View { $hosts = $scan->hosts() ->orderByRaw("INET_ATON(ip_address)") ->get(); return view('network.scan', compact('scan', 'hosts')); } }