diff --git a/client/src/admin/Admin.tsx b/client/src/admin/Admin.tsx index 40dc8b8..0710e6a 100644 --- a/client/src/admin/Admin.tsx +++ b/client/src/admin/Admin.tsx @@ -93,7 +93,9 @@ function fmtDay(day: string): string { function Stats() { const [data, setData] = useState<{ totals: Totals[]; per_drink: PerDrink[]; by_day: ByDay[] } | null>(null); - function reload() { fetch('/admin/api/stats').then(j).then(setData); } + function reload() { + fetch('/admin/api/stats').then(j).then(setData).catch(e => alert(`Fehler beim Laden: ${e}`)); + } useEffect(reload, []); async function reset() { @@ -171,27 +173,37 @@ function Drinks() { const [list, setList] = useState([]); const [name, setName] = useState(''); const [price, setPrice] = useState(''); + const [adding, setAdding] = useState(false); - function reload() { fetch('/admin/api/drinks').then(j).then(setList); } + 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)) return; - await fetch('/admin/api/drinks', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name, price_cents: cents }), - }); - setName(''); setPrice(''); reload(); + if (!name || !Number.isFinite(cents) || adding) return; + setAdding(true); + try { + const res = await fetch('/admin/api/drinks', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, price_cents: cents }), + }); + if (!res.ok) { alert(`Fehler: ${await errText(res)}`); return; } + setName(''); setPrice(''); reload(); + } finally { + setAdding(false); + } } async function patch(id: number, body: Partial) { - await fetch(`/admin/api/drinks/${id}`, { + const res = await fetch(`/admin/api/drinks/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); + if (!res.ok) { alert(`Fehler: ${await errText(res)}`); return; } reload(); } @@ -237,7 +249,7 @@ function Drinks() {
setName(e.currentTarget.value)} /> setPrice(e.currentTarget.value)} /> - +
); @@ -333,10 +345,11 @@ function Bars() { const [bars, setBars] = useState([]); const [drinks, setDrinks] = useState([]); const [newName, setNewName] = useState(''); + const [addingBar, setAddingBar] = useState(false); function reload() { - fetch('/admin/api/bars').then(j).then(setBars); - fetch('/admin/api/drinks').then(j).then(setDrinks); + 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, []); @@ -359,18 +372,23 @@ function Bars() { async function addBar() { const name = newName.trim(); - if (!name) return; - const res = await fetch('/admin/api/bars', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name, pfand_cents: 200 }), - }); - if (!res.ok) { - alert(`Fehler: ${await errText(res)}`); - return; + if (!name || addingBar) return; + setAddingBar(true); + try { + const res = await fetch('/admin/api/bars', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, pfand_cents: 200 }), + }); + if (!res.ok) { + alert(`Fehler: ${await errText(res)}`); + return; + } + setNewName(''); + reload(); + } finally { + setAddingBar(false); } - setNewName(''); - reload(); } return ( @@ -412,7 +430,7 @@ function Bars() { value={newName} onInput={(e: any) => setNewName(e.currentTarget.value)} /> - + );