diff --git a/components/BeoSelector.tsx b/components/BeoSelector.tsx index b405c2e..2acdfbc 100644 --- a/components/BeoSelector.tsx +++ b/components/BeoSelector.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import type { BeoOption } from '@/types/logbuch'; +import CustomSelect from './CustomSelect'; interface Props { selected: BeoOption[]; @@ -21,9 +22,8 @@ export default function BeoSelector({ selected, onChange }: Props) { const selectedIds = new Set(selected.map((b) => b.ID)); const available = all.filter((b) => !selectedIds.has(b.ID)); - function add(id: string) { - if (!id) return; - const beo = all.find((b) => b.ID === parseInt(id)); + function add(value: string) { + const beo = all.find((b) => b.ID === parseInt(value)); if (beo) onChange([...selected, beo]); } @@ -32,18 +32,18 @@ export default function BeoSelector({ selected, onChange }: Props) { } return ( -
+
{selected.map((b) => ( {b.Kuerzel} — {b.Name}
+ {available.length > 0 && ( - + ({ value: String(b.ID), label: `${b.Kuerzel} — ${b.Name}` }))} + onChange={add} + /> )}
); diff --git a/components/CustomSelect.tsx b/components/CustomSelect.tsx new file mode 100644 index 0000000..d581a66 --- /dev/null +++ b/components/CustomSelect.tsx @@ -0,0 +1,69 @@ +'use client'; + +import { useEffect, useRef, useState } from 'react'; + +export interface SelectOption { + value: string; + label: string; + disabled?: boolean; +} + +interface Props { + options: SelectOption[]; + placeholder: string; + onChange: (value: string) => void; +} + +export default function CustomSelect({ options, placeholder, onChange }: Props) { + const [open, setOpen] = useState(false); + const ref = useRef(null); + + useEffect(() => { + function handleOutside(e: MouseEvent) { + if (ref.current && !ref.current.contains(e.target as Node)) { + setOpen(false); + } + } + if (open) document.addEventListener('mousedown', handleOutside); + return () => document.removeEventListener('mousedown', handleOutside); + }, [open]); + + function select(value: string) { + setOpen(false); + onChange(value); + } + + return ( +
+ + + {open && ( +
+ {options.map((opt) => ( + + ))} +
+ )} +
+ ); +} diff --git a/components/ObjektSelector.tsx b/components/ObjektSelector.tsx index 85cd236..6c1dfe0 100644 --- a/components/ObjektSelector.tsx +++ b/components/ObjektSelector.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import type { ObjektOption, SelectedObjekt } from '@/types/logbuch'; +import CustomSelect from './CustomSelect'; interface Props { selected: SelectedObjekt[]; @@ -46,19 +47,24 @@ export default function ObjektSelector({ selected, onChange }: Props) { onChange(selected.filter((o) => o.Name !== name)); } + const options = [ + { value: 'neu', label: '— Neues Objekt eingeben —' }, + ...available.map((o) => ({ value: String(o.ID), label: o.Name })), + ]; + return ( -
+
{selected.map((o) => ( {o.Name}
- + {showNewInput && (
@@ -89,19 +87,19 @@ export default function ObjektSelector({ selected, onChange }: Props) { onChange={(e) => setNewName(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addNew(); } }} placeholder="Objektname eingeben" - className="flex-1 px-3 py-1.5 border-2 border-gray-400 rounded-lg bg-white text-sm focus:border-blue-500 focus:outline-none" + className="flex-1 px-3 py-3 border-2 border-gray-400 rounded-lg bg-white text-base focus:border-blue-500 focus:outline-none" />