'use client'; import { ChangeEvent, Dispatch, SetStateAction, useCallback, useEffect, useState, } from 'react'; import Modal from '@/components/ui/Modal'; import { PlusIcon } from '@heroicons/react/24/outline'; import TagMultiCombobox, { TagOption } from '@/components/ui/TagMultiCombobox'; import Button from '@/components/ui/Button'; import type { DeviceDetail } from './page'; type DeviceCreateModalProps = { open: boolean; onClose: () => void; onCreated: (device: DeviceDetail) => void; allTags: TagOption[]; setAllTags: Dispatch>; }; type NewDevice = { inventoryNumber: string; name: string; manufacturer: string; model: string; serialNumber: string | null; productNumber: string | null; comment: string | null; group: string | null; location: string | null; ipv4Address: string | null; ipv6Address: string | null; macAddress: string | null; username: string | null; passwordHash: string | null; tags: string[]; }; const emptyDevice: NewDevice = { inventoryNumber: '', name: '', manufacturer: '', model: '', serialNumber: null, productNumber: null, comment: null, group: null, location: null, ipv4Address: null, ipv6Address: null, macAddress: null, username: null, passwordHash: null, tags: [], }; export default function DeviceCreateModal({ open, onClose, onCreated, allTags, setAllTags, }: DeviceCreateModalProps) { const [form, setForm] = useState(emptyDevice); const [saveLoading, setSaveLoading] = useState(false); const [error, setError] = useState(null); // Formular resetten, wenn Modal neu geöffnet wird useEffect(() => { if (open) { setForm(emptyDevice); setError(null); setSaveLoading(false); } }, [open]); const handleFieldChange = ( field: keyof NewDevice, e: ChangeEvent, ) => { const value = e.target.value; setForm((prev) => ({ ...prev, [field]: value === '' && prev[field] === null ? null : value, })); }; const handleSave = useCallback(async () => { if (!form.inventoryNumber.trim() || !form.name.trim()) { setError('Bitte mindestens Inventar-Nr. und Bezeichnung ausfüllen.'); return; } setSaveLoading(true); setError(null); try { const res = await fetch('/api/devices', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ inventoryNumber: form.inventoryNumber.trim(), name: form.name.trim(), manufacturer: form.manufacturer || '', model: form.model || '', serialNumber: form.serialNumber || null, productNumber: form.productNumber || null, comment: form.comment || null, group: form.group || null, location: form.location || null, ipv4Address: form.ipv4Address || null, ipv6Address: form.ipv6Address || null, macAddress: form.macAddress || null, username: form.username || null, passwordHash: form.passwordHash || null, tags: form.tags ?? [], }), }); if (!res.ok) { if (res.status === 409) { throw new Error( 'Es existiert bereits ein Gerät mit dieser Inventar-Nr.', ); } throw new Error('Anlegen des Geräts ist fehlgeschlagen.'); } const created = (await res.json()) as DeviceDetail; onCreated(created); onClose(); } catch (err: any) { console.error('Error creating device', err); setError( err instanceof Error ? err.message : 'Netzwerkfehler beim Anlegen des Geräts.', ); } finally { setSaveLoading(false); } }, [form, onCreated, onClose]); const handleClose = () => { if (saveLoading) return; onClose(); }; return ( } tone="info" variant="centered" size="sm" footer={
} > {error && (

{error}

)} {/* Body wie bei DeviceDetailModal: einfach Inhalt, Scroll kommt vom Modal */}
{/* Inventarnummer */}

Inventar-Nr. *

handleFieldChange('inventoryNumber', e)} />
{/* Bezeichnung */}

Bezeichnung *

handleFieldChange('name', e)} />
{/* Hersteller / Modell */}

Hersteller

handleFieldChange('manufacturer', e)} />

Modell

handleFieldChange('model', e)} />
{/* Seriennummer / Produktnummer */}

Seriennummer

handleFieldChange('serialNumber', e)} />

Produktnummer

handleFieldChange('productNumber', e)} />
{/* Standort / Gruppe */}

Standort / Raum

handleFieldChange('location', e)} />

Gruppe

handleFieldChange('group', e)} />
{/* Tags */}
({ name }))} onChange={(next) => { const names = next.map((t) => t.name); setForm((prev) => ({ ...prev, tags: names, })); setAllTags((prev) => { const map = new Map(prev.map((t) => [t.name.toLowerCase(), t])); for (const t of next) { const key = t.name.toLowerCase(); if (!map.has(key)) { map.set(key, t); } } return Array.from(map.values()); }); }} placeholder="z.B. Drucker, Serverraum, kritisch" />
{/* Netzwerkdaten */}

IPv4-Adresse

handleFieldChange('ipv4Address', e)} />

IPv6-Adresse

handleFieldChange('ipv6Address', e)} />

MAC-Adresse

handleFieldChange('macAddress', e)} />
{/* Zugangsdaten */}

Benutzername

handleFieldChange('username', e)} />

Passwort

handleFieldChange('passwordHash', e)} />
{/* Kommentar */}

Kommentar