// Dashboard — przegląd stanu bota + ostatnie rezerwacje + recent events
const { useState: uSD, useEffect: uED, useMemo: uMD } = React;
function StatCard({ label, value, sub, tone }) {
return (
{label}
{value}
{sub &&
{sub}
}
);
}
function DashboardView({ status, toast }) {
const [reservations, setReservations] = uSD([]);
const [events, setEvents] = uSD([]);
const [busy, setBusy] = uSD("");
uED(() => {
const load = () => {
window.ZlapApi.listReservations(10).then(setReservations).catch(()=>{});
window.ZlapApi.getEvents({ limit: 30 }).then(rs => setEvents(rs.map(window.ZlapApi.adapters.event))).catch(()=>{});
};
load();
const iv = setInterval(load, 5000);
return () => clearInterval(iv);
}, []);
const botCtl = async (action) => {
setBusy(action);
try {
const fn = { start: "botStart", pause: "botPause", resume: "botResume", restart: "botRestart" }[action];
const res = await window.ZlapApi[fn]();
toast(`Bot ${action}: ${res.ok ? "OK" : "błąd"}`, res.ok ? "ok" : "err");
} catch (e) {
toast(`${action}: ${e.message}`, "err");
} finally {
setBusy("");
}
};
const st = status || {};
return (
Dashboard
{st.last_error && (
Ostatni błąd
{st.last_error}
)}
Ostatnie rezerwacje
{reservations.length === 0 &&
Brak rezerwacji
}
{reservations.slice(0, 6).map(r => (
{r.status}
{" "}{r.slot_date} {r.slot_time} · {r.word_name}
{r.payment_url && (
Opłać
)}
))}
Ostatnie zdarzenia
{events.length === 0 &&
Brak zdarzeń
}
{events.slice(0, 30).map(e => (
{e.msg}
))}
);
}
window.DashboardView = DashboardView;