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
+24 -13
View File
@@ -39,24 +39,35 @@ export function TeamMemberInfo({ members, activeIndex, onSelect, onOpenBio }: Te
<button
onClick={onOpenBio}
aria-label={`Подробнее о ${member.name}`}
className="mt-3 text-sm font-medium text-gold hover:text-gold-light transition-colors cursor-pointer"
>
Подробнее
</button>
{/* Progress dots */}
<div className="mt-6 flex items-center justify-center gap-1.5">
{members.map((_, i) => (
<button
key={i}
onClick={() => onSelect(i)}
className={`h-1.5 rounded-full transition-all duration-500 cursor-pointer ${
i === activeIndex
? "w-6 bg-gold"
: "w-1.5 bg-white/15 hover:bg-white/30"
}`}
/>
))}
{/* Progress dots — mobile only (desktop has carousel arrows) */}
<div className="mt-6 flex items-center justify-center gap-2 sm:hidden">
{members.map((m, i) => {
const isActive = i === activeIndex;
return (
<button
key={i}
onClick={() => onSelect(i)}
aria-label={`Перейти к ${m.name}`}
className="relative flex items-center justify-center w-8 h-8 cursor-pointer group"
>
{/* Glow ring on active */}
{isActive && (
<span className="absolute inset-0 rounded-full bg-gold/15 scale-100 animate-pulse" />
)}
<span className={`relative block rounded-full transition-all duration-500 ${
isActive
? "w-3 h-3 bg-gold shadow-[0_0_8px_rgba(201,169,110,0.5)]"
: "w-2 h-2 bg-white/20 group-hover:bg-white/40 group-hover:scale-125"
}`} />
</button>
);
})}
</div>
</div>
);