CustomSelect gains keepOpen prop: dropdown stays open after each selection, closes via Fertig button or tap outside. ObjektSelector separates Neu into its own button to keep the dropdown flow clean. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
'use client';
|
||
|
||
import { useEffect, useState } from 'react';
|
||
import type { BeoOption } from '@/types/logbuch';
|
||
import CustomSelect from './CustomSelect';
|
||
|
||
interface Props {
|
||
selected: BeoOption[];
|
||
onChange: (beos: BeoOption[]) => void;
|
||
}
|
||
|
||
export default function BeoSelector({ selected, onChange }: Props) {
|
||
const [all, setAll] = useState<BeoOption[]>([]);
|
||
|
||
useEffect(() => {
|
||
fetch('/api/beos')
|
||
.then((r) => { if (!r.ok) throw new Error('Fehler'); return r.json(); })
|
||
.then(setAll)
|
||
.catch(() => {});
|
||
}, []);
|
||
|
||
const selectedIds = new Set(selected.map((b) => b.ID));
|
||
const available = all.filter((b) => !selectedIds.has(b.ID));
|
||
|
||
function add(value: string) {
|
||
const beo = all.find((b) => b.ID === parseInt(value));
|
||
if (beo) onChange([...selected, beo]);
|
||
}
|
||
|
||
function remove(id: number) {
|
||
onChange(selected.filter((b) => b.ID !== id));
|
||
}
|
||
|
||
return (
|
||
<div className="space-y-3">
|
||
<div className="flex flex-wrap gap-2">
|
||
{selected.map((b) => (
|
||
<span
|
||
key={b.ID}
|
||
className="inline-flex items-center gap-2 bg-blue-100 text-blue-800 text-base px-3 py-2 rounded-full"
|
||
>
|
||
{b.Kuerzel} — {b.Name}
|
||
<button
|
||
type="button"
|
||
onClick={() => remove(b.ID)}
|
||
className="flex items-center justify-center w-7 h-7 rounded-full text-blue-600 hover:bg-red-100 hover:text-red-600 font-bold text-xl leading-none"
|
||
aria-label={`${b.Kuerzel} entfernen`}
|
||
>
|
||
×
|
||
</button>
|
||
</span>
|
||
))}
|
||
</div>
|
||
|
||
{available.length > 0 && (
|
||
<CustomSelect
|
||
placeholder="+ BEOs hinzufügen"
|
||
options={available.map((b) => ({ value: String(b.ID), label: `${b.Kuerzel} — ${b.Name}` }))}
|
||
onChange={add}
|
||
keepOpen
|
||
/>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|