Przegląd Widget'a Mapy
Główne zalety:
- Plug & Play: Łatwa integracja w 4 prostych krokach
- Responsywność: Automatyczne dostosowanie do różnych ekranów
- Customizacja: Różne motywy kolorystyczne i opcje konfiguracji
- Performance: Optymalizowane ładowanie danych i cache'owanie
- Accessibility: Zgodność z WCAG 2.1 oraz obsługa czytników ekranu
Funkcjonalności Widget'a
Interaktywna Mapa
Pełna interakcja - zoom, drag, klikanie markerów. Bazuje na bibliotece Leaflet.js z optymalizacjami dla urządzeń mobilnych.
Popup'y Informacyjne
Szczegółowe informacje o sklepach w eleganckich popup'ach - nazwa, adres, telefon, godziny otwarcia, zakresy NFZ.
Mobile-First Design
Responsywny design z touch-friendly kontrolkami. Automatyczne wykrywanie orientacji i rozmiaru ekranu.
Zaawansowane Filtrowanie
Filtrowanie według zakresu świadczeń NFZ (AS, PO, SP, SO), odległości oraz dostępności konkretnych wyrobów.
Nawigacja GPS
Bezpośrednie przekierowanie do aplikacji nawigacyjnych (Google Maps, Apple Maps) z obliczoną trasą.
Motywy Kolorystyczne
4 gotowe motywy (Default, Medical, Light, Dark) oraz możliwość pełnej customizacji CSS.
Demonstracja na Żywo
Przetestuj widget w akcji. System automatycznie spróbuje pobrać Twoją lokalizację lub użyje przykładowego miasta polskiego.
Przewodnik Integracji
Załaduj Wymagane Biblioteki
Widget wymaga biblioteki Leaflet.js do obsługi map. Dodaj poniższe znaczniki do sekcji <head> i przed zamknięciem </body>:
<!-- W sekcji <head> -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin="" />
<!-- Przed zamknięciem </body> -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
Załaduj eZWM Widget Loader
Dodaj nasz specjalny skrypt widget'a, który obsługuje automatyczne wykrywanie środowiska:
<script src="https://ecommerce.ezwm.pl/widgets/ezwm-map-loader.js"></script>
Przygotuj Kontener HTML
Utwórz element HTML, w którym zostanie wyrenderowana mapa:
<div id="medical-shops-map" style="width: 100%; height: 400px; border-radius: 8px;">
<!-- Loader będzie tutaj wyświetlony podczas ładowania -->
<div class="map-loading" style="display: flex; align-items: center; justify-content: center; height: 100%; background: #f8f9fa;">
<i class="fas fa-spinner fa-spin fa-2x text-primary"></i>
<span class="ms-2">Ładowanie mapy...</span>
</div>
</div>
Inicjalizuj Widget
Wywołaj metodę inicjalizacji z odpowiednimi parametrami konfiguracyjnymi:
<script>
// Podstawowa inicjalizacja dla określonej lokalizacji
EZWMMapLoader.loadMap('medical-shops-map', {
latitude: 50.0647, // Kraków - współrzędne GPS
longitude: 19.9449,
theme: 'default',
promieniWyszukiwania: 25, // km
limitSklepow: 15,
zakresSwiadczenia: null // wszystkie zakresy NFZ
});
// Zaawansowana inicjalizacja z geolokalizacją użytkownika
document.addEventListener('DOMContentLoaded', function() {
if (navigator.geolocation && window.location.protocol === 'https:') {
// Geolokalizacja działa tylko przez HTTPS
navigator.geolocation.getCurrentPosition(
function(position) {
// Sukces - użyj lokalizacji użytkownika
EZWMMapLoader.loadMap('medical-shops-map', {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
theme: 'medical',
promieniWyszukiwania: 20,
limitSklepow: 10,
zakresSwiadczenia: 'PO' // tylko produkty ortopedyczne
});
},
function(error) {
// Błąd geolokalizacji - użyj domyślnej lokalizacji
console.warn('Geolocation error:', error);
EZWMMapLoader.loadMap('medical-shops-map', {
latitude: 52.2297, // Warszawa jako fallback
longitude: 21.0122,
theme: 'light',
promieniWyszukiwania: 30,
limitSklepow: 12
});
},
{
timeout: 10000, // max 10 sekund na geolokalizację
enableHighAccuracy: true, // wysoka precyzja
maximumAge: 300000 // cache przez 5 minut
}
);
} else {
// Fallback dla przeglądarek bez geolokalizacji lub HTTP
EZWMMapLoader.loadMap('medical-shops-map', {
latitude: 50.0647,
longitude: 19.9449,
theme: 'default'
});
}
});
</script>
Opcje Konfiguracji
| Parametr | Typ | Domyślnie | Opis | Przykład |
|---|---|---|---|---|
latitude |
number | wymagane | Szerokość geograficzna centrum mapy (-90 do 90) | 50.0647 |
longitude |
number | wymagane | Długość geograficzna centrum mapy (-180 do 180) | 19.9449 |
theme |
string | 'default' |
Motyw kolorystyczny: 'default', 'medical', 'light', 'dark' | 'medical' |
promieniWyszukiwania |
number | 20 |
Promień wyszukiwania w kilometrach (1-100) | 25 |
limitSklepow |
number | 10 |
Maksymalna liczba sklepów do wyświetlenia (1-50) | 15 |
zakresSwiadczenia |
string|null | null |
Filtr zakresu NFZ: 'AS', 'PO', 'SP', 'SO' lub null (wszystkie) | 'PO' |
zoomLevel |
number | 12 |
Początkowy poziom powiększenia mapy (1-18) | 14 |
showUserLocation |
boolean | true |
Czy pokazać marker lokalizacji użytkownika | false |
enableClustering |
boolean | true |
Włącz grupowanie markerów dla lepszej wydajności | false |
Przykłady Zaawansowanej Integracji
Przykład 1: Widget z filtrowaniem w czasie rzeczywistym
<select id="nfz-filter" class="form-select">
<option value="">Wszystkie zakresy NFZ</option>
<option value="AS">Aparaty słuchowe</option>
<option value="PO">Produkty ortopedyczne</option>
<option value="SP">Środki pomocnicze</option>
<option value="SO">Szkła okularowe</option>
</select>
<div id="filtered-map" style="height: 500px;"></div>
<script>
let mapInstance = null;
const baseConfig = {
latitude: 50.0647,
longitude: 19.9449,
theme: 'medical',
promieniWyszukiwania: 30
};
// Inicjalizacja
EZWMMapLoader.loadMap('filtered-map', baseConfig).then(instance => {
mapInstance = instance;
});
// Obsługa zmiany filtra
document.getElementById('nfz-filter').addEventListener('change', function(e) {
const newConfig = {
...baseConfig,
zakresSwiadczenia: e.target.value || null
};
// Przeładuj mapę z nowym filtrem
EZWMMapLoader.loadMap('filtered-map', newConfig);
});
</script>
Przykład 2: Integracja z formularzem wyszukiwania
<form id="search-form">
<input type="text" id="address-input" placeholder="Wpisz adres..." class="form-control">
<button type="submit">Znajdź sklepy</button>
</form>
<div id="search-results-map" style="height: 400px;"></div>
<script>
document.getElementById('search-form').addEventListener('submit', async function(e) {
e.preventDefault();
const address = document.getElementById('address-input').value;
try {
// Geokodowanie adresu (można użyć zewnętrznego serwisu)
const coords = await geocodeAddress(address);
// Załaduj mapę dla nowej lokalizacji
await EZWMMapLoader.loadMap('search-results-map', {
latitude: coords.lat,
longitude: coords.lng,
theme: 'light',
promieniWyszukiwania: 15,
limitSklepow: 20,
zoomLevel: 13
});
} catch (error) {
console.error('Błąd geokodowania:', error);
alert('Nie można znaleźć podanego adresu');
}
});
async function geocodeAddress(address) {
// Przykład z użyciem Nominatim OpenStreetMap (bezpłatne)
const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}&countrycodes=pl&limit=1`);
const data = await response.json();
if (data.length === 0) {
throw new Error('Address not found');
}
return {
lat: parseFloat(data[0].lat),
lng: parseFloat(data[0].lon)
};
}
</script>
Rozwiązywanie Problemów
Możliwe przyczyny i rozwiązania:
- Brak biblioteki Leaflet: Upewnij się, że załadowałeś CSS i JS Leaflet.js przed skryptem widget'a
- Błędne współrzędne: Sprawdź czy latitude (-90 do 90) i longitude (-180 do 180) są poprawne
- Problemy z CORS: Widget musi być załadowany z domeny HTTPS lub localhost
- Brak wysokości kontenera: Element musi mieć określoną wysokość w CSS
Optymalizacja dla mobile:
- Viewport: Dodaj
<meta name="viewport" content="width=device-width, initial-scale=1.0"> - Touch handling: Widget automatycznie obsługuje gesty touch
- Minimalna wysokość: Ustaw wysokość minimum 300px dla lepszego UX
- Geolokalizacja: Działa tylko przez HTTPS na mobilnych
Optymalizacja wydajności:
- Limit sklepów: Zmniejsz
limitSklepowdo maksymalnie 20 dla lepszej wydajności - Clustering: Włącz
enableClustering: truedla dużej liczby markerów - Promień wyszukiwania: Ogranicz
promieniWyszukiwaniado rozsądnych wartości (20-50km) - Lazy loading: Ładuj widget dopiero gdy jest widoczny na ekranie