admin: reorder drinks per bar
This commit is contained in:
parent
02c7e9b5fd
commit
4904ff0032
1 changed files with 73 additions and 20 deletions
|
|
@ -191,6 +191,74 @@ function Drinks() {
|
|||
);
|
||||
}
|
||||
|
||||
function BarDrinkEditor({
|
||||
bar,
|
||||
allDrinks,
|
||||
onChange,
|
||||
}: {
|
||||
bar: BarRow;
|
||||
allDrinks: Drink[];
|
||||
onChange: (ids: number[]) => void;
|
||||
}) {
|
||||
const byId = new Map(allDrinks.map(d => [d.id, d]));
|
||||
const selected = bar.drink_ids.filter(id => {
|
||||
const d = byId.get(id);
|
||||
return d && !d.archived;
|
||||
});
|
||||
const available = allDrinks.filter(d => !d.archived && !selected.includes(d.id));
|
||||
|
||||
function move(idx: number, dir: -1 | 1) {
|
||||
const j = idx + dir;
|
||||
if (j < 0 || j >= selected.length) return;
|
||||
const next = selected.slice();
|
||||
[next[idx], next[j]] = [next[j]!, next[idx]!];
|
||||
onChange(next);
|
||||
}
|
||||
function remove(idx: number) {
|
||||
onChange(selected.filter((_, i) => i !== idx));
|
||||
}
|
||||
function add(id: number) {
|
||||
onChange([...selected, id]);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style="margin-top:8px; font-size:14px; opacity:0.7">Aktive Getränke (Reihenfolge)</div>
|
||||
<table style="margin-bottom:8px">
|
||||
<tbody>
|
||||
{selected.length === 0 && (
|
||||
<tr><td class="muted" colSpan={2}>Keine</td></tr>
|
||||
)}
|
||||
{selected.map((id, idx) => {
|
||||
const d = byId.get(id);
|
||||
if (!d) return null;
|
||||
return (
|
||||
<tr key={id}>
|
||||
<td style="width:60%">{idx + 1}. {d.name}</td>
|
||||
<td>
|
||||
<button onClick={() => move(idx, -1)} disabled={idx === 0}>↑</button>
|
||||
<button onClick={() => move(idx, 1)} disabled={idx === selected.length - 1}>↓</button>
|
||||
<button onClick={() => remove(idx)}>×</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
{available.length > 0 && (
|
||||
<>
|
||||
<div style="font-size:14px; opacity:0.7">Hinzufügen</div>
|
||||
<div class="row">
|
||||
{available.map(d => (
|
||||
<button key={d.id} onClick={() => add(d.id)}>+ {d.name}</button>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Bars() {
|
||||
const [bars, setBars] = useState<BarRow[]>([]);
|
||||
const [drinks, setDrinks] = useState<Drink[]>([]);
|
||||
|
|
@ -253,26 +321,11 @@ function Bars() {
|
|||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
{drinks.filter(d => !d.archived).map(d => {
|
||||
const checked = b.drink_ids.includes(d.id);
|
||||
return (
|
||||
<label key={d.id}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={() => {
|
||||
const next = checked
|
||||
? b.drink_ids.filter(x => x !== d.id)
|
||||
: [...b.drink_ids, d.id];
|
||||
patch(b.id, { drink_ids: next } as any);
|
||||
}}
|
||||
/>
|
||||
{d.name}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<BarDrinkEditor
|
||||
bar={b}
|
||||
allDrinks={drinks}
|
||||
onChange={(ids) => patch(b.id, { drink_ids: ids } as any)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
<div class="row">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue