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:
@@ -28,21 +28,27 @@ export function YandexMap({ addresses, height = 380 }: YandexMapProps) {
|
||||
let cancelled = false;
|
||||
|
||||
async function build() {
|
||||
const points: { lat: number; lon: number }[] = [];
|
||||
|
||||
for (const addr of addresses) {
|
||||
try {
|
||||
// Geocode all addresses in parallel
|
||||
const results = await Promise.allSettled(
|
||||
addresses.map(async (addr) => {
|
||||
const cleaned = cleanAddress(addr);
|
||||
const query = cleaned.toLowerCase().includes("минск") ? cleaned : `Минск ${cleaned}`;
|
||||
const res = await fetch(
|
||||
`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=1&countrycodes=by`
|
||||
`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=1&countrycodes=by`,
|
||||
{ signal: AbortSignal.timeout(5000) }
|
||||
);
|
||||
const data = await res.json();
|
||||
if (data.length > 0) {
|
||||
points.push({ lat: parseFloat(data[0].lat), lon: parseFloat(data[0].lon) });
|
||||
return { lat: parseFloat(data[0].lat), lon: parseFloat(data[0].lon) };
|
||||
}
|
||||
} catch { /* skip */ }
|
||||
}
|
||||
return null;
|
||||
})
|
||||
);
|
||||
|
||||
const points = results
|
||||
.filter((r): r is PromiseFulfilledResult<{ lat: number; lon: number } | null> => r.status === "fulfilled")
|
||||
.map((r) => r.value)
|
||||
.filter((p): p is { lat: number; lon: number } => p !== null);
|
||||
|
||||
if (cancelled || points.length === 0) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user