admin: share one drinks list between Drinks and Bars instead of two independent copies

Drinks and Bars each fetched + held their own copy of the drinks list. Adding
(or editing/archiving) a drink only updated Drinks's own copy — Bars's
BarDrinkEditor kept rendering the stale pre-change snapshot until a full page
reload re-mounted everything, so a newly added drink didn't show up in the
'add to bar' list without a manual refresh.

Lifted the drinks list + its reload fn into Dashboard, passed down as props to
both Drinks and Bars.
This commit is contained in:
iris 2026-07-29 21:20:36 +02:00
commit 7fc4c1912c

View file

@ -76,6 +76,18 @@ function Login({ onAuthed }: { onAuthed: () => void }) {
}
function Dashboard({ onLogout }: { onLogout: () => void }) {
// Drinks lives here, not inside <Drinks>, so <Bars> (specifically
// BarDrinkEditor's "available to add" list) sees a newly added/edited
// drink immediately. Each component used to fetch its own independent
// copy of the drinks list, so adding a drink updated only <Drinks>'s
// copy — <Bars> kept rendering its stale pre-add snapshot until a full
// page reload re-mounted everything.
const [drinks, setDrinks] = useState<Drink[]>([]);
function reloadDrinks() {
fetch('/admin/api/drinks').then(j).then(setDrinks).catch(e => alert(`Fehler beim Laden: ${e}`));
}
useEffect(reloadDrinks, []);
return (
<div class="admin">
<div class="row" style="justify-content: space-between">
@ -86,8 +98,8 @@ function Dashboard({ onLogout }: { onLogout: () => void }) {
</div>
<Stats />
<Exports />
<Drinks />
<Bars />
<Drinks drinks={drinks} reload={reloadDrinks} />
<Bars drinks={drinks} />
</div>
);
}
@ -175,17 +187,11 @@ function Exports() {
);
}
function Drinks() {
const [list, setList] = useState<Drink[]>([]);
function Drinks({ drinks: list, reload }: { drinks: Drink[]; reload: () => void }) {
const [name, setName] = useState('');
const [price, setPrice] = useState('');
const [adding, setAdding] = useState(false);
function reload() {
fetch('/admin/api/drinks').then(j).then(setList).catch(e => alert(`Fehler beim Laden: ${e}`));
}
useEffect(reload, []);
async function add() {
const cents = Math.round(parseFloat(price) * 100);
if (!name || !Number.isFinite(cents) || adding) return;
@ -360,15 +366,13 @@ function BarDrinkEditor({
);
}
function Bars() {
function Bars({ drinks }: { drinks: Drink[] }) {
const [bars, setBars] = useState<BarRow[]>([]);
const [drinks, setDrinks] = useState<Drink[]>([]);
const [newName, setNewName] = useState('');
const [addingBar, setAddingBar] = useState(false);
function reload() {
fetch('/admin/api/bars').then(j).then(setBars).catch(e => alert(`Fehler beim Laden: ${e}`));
fetch('/admin/api/drinks').then(j).then(setDrinks).catch(e => alert(`Fehler beim Laden: ${e}`));
}
useEffect(reload, []);