fix: auto-refresh bookings silently instead of showing update banner

Polling detects new bookings and silently re-fetches tab data + dashboard
counts. No more "press to update" banner — data appears automatically.
This commit is contained in:
2026-03-24 17:41:08 +03:00
parent 18c11d0611
commit 42be063c7f

View File

@@ -699,29 +699,24 @@ function BookingsPageInner() {
const [addOpen, setAddOpen] = useState(false);
const [searchResults, setSearchResults] = useState<SearchResult[] | null>(null);
const [statusFilter, setStatusFilter] = useState<BookingFilter>("all");
const [newBookingsBanner, setNewBookingsBanner] = useState(false);
const [refreshKey, setRefreshKey] = useState(0);
const lastTotalRef = useRef<number | null>(null);
const { showError } = useToast();
// #10: Pause polling when browser tab not visible
// Poll for new bookings, auto-refresh silently
useEffect(() => {
let id: ReturnType<typeof setInterval>;
function startPolling() {
id = setInterval(() => {
const id = setInterval(() => {
if (document.hidden) return;
adminFetch("/api/admin/unread-counts")
.then((r) => r.json())
.then((data: { total: number }) => {
if (lastTotalRef.current !== null && data.total !== lastTotalRef.current) {
// #6: Show banner instead of remounting with key
setNewBookingsBanner(true);
setRefreshKey((k) => k + 1);
}
lastTotalRef.current = data.total;
})
.catch(() => {});
}, 10000);
}
startPolling();
return () => clearInterval(id);
}, []);
@@ -772,16 +767,6 @@ function BookingsPageInner() {
</button>
</div>
{/* #6: New bookings banner instead of full remount */}
{newBookingsBanner && (
<button
onClick={() => { setNewBookingsBanner(false); window.location.reload(); }}
className="mt-3 w-full rounded-lg border border-gold/30 bg-gold/10 px-4 py-2 text-sm text-gold hover:bg-gold/20 transition-all text-center"
>
Появились новые записи нажмите для обновления
</button>
)}
{/* Search */}
<div className="mt-3">
<SearchBar
@@ -829,7 +814,7 @@ function BookingsPageInner() {
) : (
<>
{/* Dashboard — what needs attention */}
<DashboardSummary onNavigate={setTab} />
<DashboardSummary key={refreshKey} onNavigate={setTab} />
{/* Tabs */}
<div className="mt-5 flex border-b border-white/10">
@@ -851,8 +836,8 @@ function BookingsPageInner() {
))}
</div>
{/* Tab content — no key={refreshKey}, banner handles new data */}
<div className="mt-4">
{/* Tab content — auto-refreshes when new bookings detected */}
<div className="mt-4" key={refreshKey}>
{tab === "reminders" && <RemindersTab />}
{tab === "classes" && <GroupBookingsTab filter={statusFilter} />}
{tab === "master-classes" && <McRegistrationsTab filter={statusFilter} />}
@@ -864,7 +849,7 @@ function BookingsPageInner() {
<AddBookingModal
open={addOpen}
onClose={() => setAddOpen(false)}
onAdded={() => setNewBookingsBanner(true)}
onAdded={() => setRefreshKey((k) => k + 1)}
/>
</div>
);