Maps Documentation
Welcome to the Maps documentation.
Komponen MapsLocation
Dokumentasi ini memberi contoh penggunaan Google Maps pada aplikasi web (misalnya menampilkan titik clock in/out pada modul Laporan Kehadiran (Role Cashier), Informasi Toko, Backoffice create Toko, dan Company profile > Food Bazaar). Anda dapat menyalin kode berikut dan menyesuaikan sesuai kebutuhan.
Untuk Kode lengkapnya silahkan lihat disini
MapsLocation adalah komponen React (TypeScript) untuk menampilkan peta Google Maps dengan satu marker, pencarian Places Autocomplete, tombol Geolocate, serta kemampuan memilih lokasi lewat klik pada peta. Komponen ini cocok dipakai pada form alamat/lokasi (mis. input lokasi presensi, alamat pengiriman, titik outlet).
⚠️ Catatan integrasi
- Komponen memuat script Google Maps secara dinamis lewat
getRenderMap()yang mengembalikan kode JavaScript dengan callback globalwindow.initMap.- Pastikan implementasi
getRenderMapAnda menyertakan Maps JavaScript API (+ Places Library) dan memanggilinitMap()saat selesai memuat.
Get response dari API :
export const getRenderMap = async () => {
const res = await ApiClient.get(
"/gateway/google-maps/js-api?libraries=marker,places&callback=initMap&v=weekly",
{ responseType: "text" }
);
return res.data;
};Pada modul Kasir :
Komponen berikut digunakan untuk memuat peta tanpa menggunakan library pihak ketiga:
Type & Props
// Titik koordinat bawaan Google Maps
type LatLngLiteral = google.maps.LatLngLiteral;
export SingleMarker {
position: LatLngLiteral;
title?: string;
icon?: string; // URL icon custom
draggable?: boolean; // marker dapat di-drag
}
interface MapsLocationProps {
center: LatLngLiteral;
zoom?: number;
height?: number | string;
marker?: SingleMarker | null;
selectable?: boolean;
onSelect?: (pos: LatLngLiteral) => void;
onLocationChange?: (pos: LatLngLiteral) => void;
onAddressChange?: (address: string) => void;
resolveAddress?: (lat: number, lng: number) => Promise<{ address: string } | string>;
showSearch?: boolean;
searchPlaceholder?: string;
showGeolocateButton?: boolean;
autocompleteRestrictions?: google.maps.places.ComponentRestrictions;
autocompleteTypes?: string[];
}MapsLocationProps
| Prop | Tipe | Default | Keterangan |
|---|---|---|---|
center | LatLngLiteral | – | Pusat peta saat inisialisasi. |
zoom | number | 15 | Level zoom peta. |
height | number | string | 500 | Tinggi elemen peta. |
marker | SingleMarker | null | null | Marker awal yang ditampilkan. Bisa draggable. |
selectable | boolean | false | Jika true, klik di peta akan memilih titik dan memindah/menambah marker. |
onSelect | (pos) => void | – | Dipanggil saat pemilihan titik (klik/drag/auto/geo). |
onLocationChange | (pos) => void | – | Alias event lokasi (dipanggil bersama onSelect). |
onAddressChange | (address) => void | – | Dipanggil setelah alamat berhasil di-resolve (autocomplete/geocoding). |
resolveAddress | (lat,lng) => Promise<{ address: string } | string> | – | Resolver alamat opsional (reverse-geocode). Dipanggil hanya jika formatted_address tidak tersedia. |
showSearch | boolean | true | Tampilkan input Autocomplete di atas peta. |
searchPlaceholder | string | "Cari lokasi" | Placeholder untuk input. |
showGeolocateButton | boolean | true | Tampilkan tombol Lokasi Saya (HTML Geolocation). |
autocompleteRestrictions | google.maps.places.ComponentRestrictions | – | Pembatasan negara/area Autocomplete, mis. { country: 'ID' }. |
autocompleteTypes | string[] | ["geocode"] | Jenis pencarian Places (mis. ['geocode','establishment']). |
Cara Kerja (Arsitektur Singkat)
- Load Peta — Saat mount, komponen memanggil
getRenderMap()→ membuatBlobdari teks JS → memasang<script src=blob://...>→ memanggilwindow.initMap()ketika Maps siap. - Inisialisasi — Membuat
google.maps.Map, menempatkan marker awal (jika ada), memasang listener klik bilaselectable=true, serta mengaktifkan Places Autocomplete jikashowSearch=true. - Pemilihan Titik — Klik peta / geser marker / pilih dari Autocomplete / Geolocate → mengubah posisi marker → memicu
onSelect/onLocationChangedan (bila tersedia)onAddressChange. - Cleanup — Pada unmount, komponen melepas semua listener, menghapus marker, mencabut script blob, dan menghapus
window.initMapuntuk mencegah kebocoran memori.
♻️ Debounce resolve alamat — Komponen menyimpan
lastResolvedKeyRef(membulatkan 5 desimal ≈ 1–3 m) agar reverse‑geocode tidak dipanggil berulang untuk titik yang sama.
Interaksi Utama
1) Klik Peta (mode selectable)
- Menaruh/memindahkan marker ke titik yang diklik.
- Memanggil
onSelect(pos)danonLocationChange(pos). - Jika
resolveAddressdisediakan → dipanggil untuk menurunkan alamat dan mengirimkanonAddressChange.
2) Drag Marker (marker.draggable = true)
- Setelah
dragend, memanggil event lokasi + resolve alamat seperti di atas.
3) Places Autocomplete (showSearch = true)
- Menyetel pusat & zoom (17) ke lokasi pilihan pengguna.
- Mengisi
onAddressChangedariplace.formatted_addressbila tersedia; jika tidak, memakairesolveAddress.
4) Geolocate (showGeolocateButton = true)
- Mengambil koordinat
navigator.geolocation, memusatkan peta (zoom 17), menaruh marker, dan memicu event lokasi + alamat.
Contoh Pemakaian
A. Paling Sederhana
<MapsLocation
center={{ lat: -6.2, lng: 106.8166 }}
onSelect={(pos) => console.log("Dipilih:", pos)}
/>B. Dengan Reverse Geocoding Kustom
async function reverseGeocode(lat: number, lng: number) {
const res = await fetch(`/api/geocode?lat=${lat}&lng=${lng}`);
const data = await res.json();
return data.address as string; // atau { address: string }
}
<MapsLocation
center={{ lat: -6.2, lng: 106.8166 }}
selectable
resolveAddress={reverseGeocode}
onAddressChange={(address) => setValue("alamat", address)}
/>;C. Marker Awal & Bisa Diseret
<MapsLocation
center={{ lat: -6.9, lng: 107.6 }}
marker={{
position: { lat: -6.9, lng: 107.6 },
title: "Gudang",
draggable: true,
}}
onLocationChange={(pos) => setValue("koordinat", pos)}
/>D. Membatasi Autocomplete untuk Indonesia & Tempat Bisnis
<MapsLocation
center={{ lat: -6.2, lng: 106.8166 }}
autocompleteRestrictions={{ country: "ID" }}
autocompleteTypes={["geocode", "establishment"]}
/>Styling & UI
- Input Autocomplete diposisikan absolut di atas peta:
top: 0; left/right: 0;denganshadowdanrounded. - Tombol Geolocate berada di kanan bawah peta, berbentuk bulat (
rounded-full) menggunakan ikonLocateFixeddarilucide-react. - Tinggi peta diatur via prop
height(angka atau string CSS, mis."60vh").
Siklus Hidup & Cleanup
Komponen membersihkan resource pada useEffect unmount:
- Melepas listener klik peta &
dragendmarker. - Menghapus marker dari peta.
- Me-null‑kan instance Autocomplete & Map.
- Menghapus
window.initMap. - Menghapus elemen
<script>(blob) danURL.revokeObjectURL.
Prasyarat getRenderMap()
Agar komponen dapat bekerja:
- Endpoint
getRenderMapmengembalikan teks JavaScript yang saat dieksekusi akan memuat Google Maps JavaScript API (termasuk Places Library) dengan API Key yang valid; - Di akhir pemuatan, harus memanggil
window.initMap().
Contoh minimal JS yang dikembalikan (ilustrasi):
const script = document.createElement("script"); script.src = "https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places&callback=initMap"; document.head.appendChild(script);
Error Handling & Batasan
- Jika
navigator.geolocationtidak tersedia → komponen akan menampilkanalertstandar bahasa browser. - Jika Places tidak dimuat → input Autocomplete tidak akan diaktifkan (komponen tetap menampilkan peta dasar).
- Reverse‑geocode tidak otomatis jika
resolveAddresstidak diberikan danplace.formatted_addresskosong.
Contoh Penggunaan Komponen MapsLocation
<MapsLocation
center={{ lat: props.lat, lng: props.lng }}
zoom={18}
height={500}
selectable
marker={{
position: { lat: props.lat, lng: props.lng },
title: "Lokasi",
draggable: true,
}}
onLocationChange={(pos) => props.setLocation(pos)}
resolveAddress={async (lat, lng) => {
const r = await GeoLocationServer({ lat, lng });
return r.address;
}}
onAddressChange={(address) => props.setAddress(address)}
/>
