diff --git a/client/src/admin/Admin.tsx b/client/src/admin/Admin.tsx index dd80d69..c418fae 100644 --- a/client/src/admin/Admin.tsx +++ b/client/src/admin/Admin.tsx @@ -211,7 +211,23 @@ function BarDrinkEditor({ onChange: (ids: number[]) => void; }) { const byId = new Map(allDrinks.map(d => [d.id, d])); - const selected = bar.drink_ids.filter(id => { + + // `onChange` fires a fire-and-forget PATCH (see Bars.patch) that only + // resolves into a fresh `bar` prop once its `reload()` completes. Deriving + // `selected` straight from `bar.drink_ids` meant a second click before that + // round-trip landed re-derived its reorder/add/remove from the same stale + // array the first click started from — whichever PATCH the server applied + // last won, silently discarding the rest. `pendingIds` tracks our own + // in-flight optimistic state so back-to-back clicks chain off each other + // instead of the lagging prop; it's cleared whenever the server sends back + // a fresh `bar.drink_ids` (our own round-trip landing, or an edit from + // elsewhere), deferring to that as the new source of truth. + const [pendingIds, setPendingIds] = useState(null); + useEffect(() => { + setPendingIds(null); + }, [bar.drink_ids]); + + const selected = (pendingIds ?? bar.drink_ids).filter(id => { const d = byId.get(id); return d && !d.archived; }); @@ -220,18 +236,22 @@ function BarDrinkEditor({ const dragFrom = useRef(null); const [dragOver, setDragOver] = useState(null); + function commit(next: number[]) { + setPendingIds(next); + onChange(next); + } function remove(idx: number) { - onChange(selected.filter((_, i) => i !== idx)); + commit(selected.filter((_, i) => i !== idx)); } function add(id: number) { - onChange([...selected, id]); + commit([...selected, id]); } function reorder(from: number, to: number) { if (from === to || from < 0 || to < 0 || from >= selected.length || to >= selected.length) return; const next = selected.slice(); const [moved] = next.splice(from, 1); next.splice(to, 0, moved!); - onChange(next); + commit(next); } return (