126 lines
7.2 KiB
PHP
126 lines
7.2 KiB
PHP
<x-app-layout>
|
||
<x-slot name="header">
|
||
<div class="flex items-center space-x-2">
|
||
<a href="{{ route('network.segments.index') }}" class="text-gray-500 hover:text-gray-700">Segmente</a>
|
||
<span class="text-gray-400">/</span>
|
||
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200">{{ $segment->name }} bearbeiten</h2>
|
||
</div>
|
||
</x-slot>
|
||
|
||
<div class="py-8">
|
||
<div class="max-w-xl mx-auto sm:px-6 lg:px-8">
|
||
<div class="bg-white dark:bg-gray-800 shadow-sm rounded-lg p-6">
|
||
<form method="POST" action="{{ route('network.segments.update', $segment) }}" class="space-y-5">
|
||
@csrf @method('PUT')
|
||
|
||
<div>
|
||
<x-input-label for="name" value="Name *" />
|
||
<x-text-input id="name" name="name" type="text" class="mt-1 block w-full"
|
||
value="{{ old('name', $segment->name) }}" required />
|
||
<x-input-error :messages="$errors->get('name')" class="mt-1" />
|
||
</div>
|
||
|
||
<div>
|
||
<x-input-label for="subnet" value="Subnetz *" />
|
||
<div class="flex gap-2 mt-1">
|
||
<x-text-input id="subnet" name="subnet" type="text" class="block w-full font-mono"
|
||
value="{{ old('subnet', $segment->subnet) }}" required />
|
||
<button type="button" id="detect-subnet-btn"
|
||
class="shrink-0 px-3 py-2 text-sm font-medium rounded-md border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition">
|
||
🔍 Erkennen
|
||
</button>
|
||
</div>
|
||
<x-input-error :messages="$errors->get('subnet')" class="mt-1" />
|
||
<div id="subnet-suggestions" class="mt-1 hidden"></div>
|
||
</div>
|
||
|
||
<div>
|
||
<x-input-label for="vlan_id" value="VLAN-ID (optional)" />
|
||
<x-text-input id="vlan_id" name="vlan_id" type="number" class="mt-1 block w-full"
|
||
value="{{ old('vlan_id', $segment->vlan_id) }}" min="1" max="4094" />
|
||
<x-input-error :messages="$errors->get('vlan_id')" class="mt-1" />
|
||
</div>
|
||
|
||
<div>
|
||
<x-input-label for="description" value="Beschreibung (optional)" />
|
||
<textarea id="description" name="description" rows="2"
|
||
class="mt-1 block w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm text-sm focus:ring-indigo-500 focus:border-indigo-500">{{ old('description', $segment->description) }}</textarea>
|
||
</div>
|
||
|
||
<div>
|
||
<x-input-label for="scan_interval_minutes" value="Scan-Zyklus (automatisch)" />
|
||
<select id="scan_interval_minutes" name="scan_interval_minutes"
|
||
class="mt-1 block w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-md shadow-sm text-sm focus:ring-indigo-500 focus:border-indigo-500">
|
||
<option value="">Manuell (kein Auto-Scan)</option>
|
||
@foreach([5 => 'Alle 5 Minuten', 15 => 'Alle 15 Minuten', 30 => 'Alle 30 Minuten', 60 => 'Stündlich', 360 => 'Alle 6 Stunden', 720 => 'Alle 12 Stunden', 1440 => 'Täglich'] as $val => $label)
|
||
<option value="{{ $val }}" {{ old('scan_interval_minutes', $segment->scan_interval_minutes) == $val ? 'selected' : '' }}>
|
||
{{ $label }}
|
||
</option>
|
||
@endforeach
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<x-input-label for="nmap_options" value="nmap-Parameter" />
|
||
<x-text-input id="nmap_options" name="nmap_options" type="text" class="mt-1 block w-full font-mono"
|
||
value="{{ old('nmap_options', $segment->nmap_options) }}" placeholder="-sn" />
|
||
<p class="mt-1 text-xs text-gray-500">-sn = Ping-Scan · -sn -p 22,80,443 = mit Ports</p>
|
||
</div>
|
||
|
||
<div class="flex items-center gap-2">
|
||
<input type="checkbox" id="active" name="active" value="1"
|
||
{{ old('active', $segment->active) ? 'checked' : '' }}
|
||
class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
|
||
<label for="active" class="text-sm text-gray-700 dark:text-gray-300">Aktiv</label>
|
||
</div>
|
||
|
||
<div class="flex justify-end gap-3">
|
||
<a href="{{ route('network.segments.index') }}"
|
||
class="px-4 py-2 text-sm font-medium rounded-md border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 transition">
|
||
Abbrechen
|
||
</a>
|
||
<button type="submit" style="background-color: var(--color-primary)"
|
||
class="px-5 py-2 text-white text-sm font-medium rounded-md hover:opacity-90 transition">
|
||
Speichern
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script>
|
||
document.getElementById('detect-subnet-btn').addEventListener('click', function() {
|
||
const btn = this;
|
||
const suggestions = document.getElementById('subnet-suggestions');
|
||
btn.textContent = '⏳ Suche...';
|
||
btn.disabled = true;
|
||
|
||
fetch('{{ route('network.detect-subnets') }}', {
|
||
headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' }
|
||
})
|
||
.then(r => r.json())
|
||
.then(function(subnets) {
|
||
btn.textContent = '🔍 Erkennen';
|
||
btn.disabled = false;
|
||
if (!subnets.length) {
|
||
suggestions.innerHTML = '<p class="text-xs text-gray-400">Keine Daten in der Datenbank gefunden.</p>';
|
||
suggestions.classList.remove('hidden');
|
||
return;
|
||
}
|
||
suggestions.innerHTML = '<p class="text-xs text-gray-500 mb-1">Erkannte Subnetze – klicken zum Übernehmen:</p>' +
|
||
subnets.map(function(s) {
|
||
return '<button type="button" onclick="document.getElementById(\'subnet\').value=\'' + s + '\'" ' +
|
||
'class="mr-1 mb-1 px-2 py-1 text-xs font-mono rounded border border-indigo-300 text-indigo-700 hover:bg-indigo-50 transition">' + s + '</button>';
|
||
}).join('');
|
||
suggestions.classList.remove('hidden');
|
||
})
|
||
.catch(function() {
|
||
btn.textContent = '🔍 Erkennen';
|
||
btn.disabled = false;
|
||
suggestions.innerHTML = '<p class="text-xs text-red-500">Fehler bei der Erkennung.</p>';
|
||
suggestions.classList.remove('hidden');
|
||
});
|
||
});
|
||
</script>
|
||
</x-app-layout>
|