'use client'; import { useEffect, useRef, useState } from 'react'; import type { ObjektOption, SelectedObjekt } from '@/types/logbuch'; interface Props { selected: SelectedObjekt[]; onChange: (objekte: SelectedObjekt[]) => void; } export default function ObjektSelector({ selected, onChange }: Props) { const [all, setAll] = useState([]); const [search, setSearch] = useState(''); const [dropdownOpen, setDropdownOpen] = useState(false); const [newName, setNewName] = useState(''); const [showNewInput, setShowNewInput] = useState(false); const wrapperRef = useRef(null); useEffect(() => { fetch('/api/objekte') .then((r) => { if (!r.ok) throw new Error('Fehler'); return r.json(); }) .then(setAll) .catch(() => {}); }, []); useEffect(() => { function handleOutside(e: MouseEvent) { if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) { setDropdownOpen(false); } } if (dropdownOpen) document.addEventListener('mousedown', handleOutside); return () => document.removeEventListener('mousedown', handleOutside); }, [dropdownOpen]); const selectedNames = new Set(selected.map((o) => o.Name.toLowerCase())); const available = all.filter((o) => !selectedNames.has(o.Name.toLowerCase())); const filtered = search ? available.filter((o) => o.Name.toLowerCase().startsWith(search.toLowerCase())) : available; function add(obj: ObjektOption) { onChange([...selected, { ID: obj.ID, Name: obj.Name }]); setSearch(''); setDropdownOpen(false); } function addNew() { const name = newName.trim(); if (!name || selectedNames.has(name.toLowerCase())) return; const existing = all.find((o) => o.Name.toLowerCase() === name.toLowerCase()); if (existing) { onChange([...selected, { ID: existing.ID, Name: existing.Name }]); } else { onChange([...selected, { ID: null, Name: name }]); } setNewName(''); setShowNewInput(false); } function remove(name: string) { onChange(selected.filter((o) => o.Name !== name)); } return (
{selected.map((o) => ( {o.Name} ))}
{available.length > 0 && (
{ setSearch(e.target.value); setDropdownOpen(true); }} onFocus={() => setDropdownOpen(true)} placeholder="Objekt suchen..." className="w-full px-3 py-2 border-2 border-gray-400 rounded-lg bg-white text-sm text-gray-900 focus:border-blue-500 focus:outline-none" /> {dropdownOpen && filtered.length > 0 && (
{filtered.map((o) => ( ))}
)}
)}
{showNewInput && (
setNewName(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addNew(); } }} placeholder="Objektname eingeben" className="flex-1 px-3 py-2 border-2 border-gray-400 rounded-lg bg-white text-sm focus:border-blue-500 focus:outline-none" autoFocus />
)}
); }