feat: mobile UX, admin polish, rate limiting, and media assets

- Mobile responsiveness improvements across admin and public sections
- Admin: bookings modal, open-day page, team page, layout polish
- Added rate limiting, CSRF hardening, auth-edge improvements
- Scroll reveal, floating contact, back-to-top, Yandex map fixes
- Schedule filters refactor, team profile/info component updates
- New useTrainerPhotos hook
- Added class, team, master-class, and news images
This commit is contained in:
2026-04-10 18:42:54 +03:00
parent bbe485d8fc
commit a587736dd3
74 changed files with 724 additions and 298 deletions
+7 -5
View File
@@ -56,17 +56,19 @@ export default function AdminLayout({
const [unreadTotal, setUnreadTotal] = useState(0);
const isLoginPage = pathname === "/admin/login";
// Fetch unread counts — poll every 10s
// Fetch unread counts — poll every 10s, stop after 3 consecutive failures
useEffect(() => {
if (isLoginPage) return;
let failures = 0;
let interval: ReturnType<typeof setInterval>;
function fetchCounts() {
adminFetch("/api/admin/unread-counts")
.then((r) => r.json())
.then((data: { total: number }) => setUnreadTotal(data.total))
.catch(() => {});
.then((r) => { if (!r.ok) throw new Error(); return r.json(); })
.then((data: { total: number }) => { setUnreadTotal(data.total); failures = 0; })
.catch(() => { failures++; if (failures >= 3 && interval) clearInterval(interval); });
}
fetchCounts();
const interval = setInterval(fetchCounts, 10000);
interval = setInterval(fetchCounts, 10000);
return () => clearInterval(interval);
}, [isLoginPage]);