61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from 'react';
|
|
import Map, { Source, Layer, MapRef, ViewState, NavigationControl, ScaleControl, FullscreenControl } from 'react-map-gl/mapbox';
|
|
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
import { useRef } from 'react';
|
|
import { MAPBOX_STYLES, MapboxStyle } from '@/app/_utils/const/map';
|
|
|
|
interface MapViewProps {
|
|
initialViewState?: Partial<ViewState>;
|
|
mapStyle?: MapboxStyle
|
|
onMapLoad?: (map: MapRef) => void
|
|
className?: string
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
const MapView: React.FC<MapViewProps> = ({
|
|
initialViewState = {
|
|
longitude: 113.6922, // Center of Jember Regency (approximately)
|
|
latitude: -8.1843,
|
|
zoom: 9
|
|
},
|
|
mapStyle = MAPBOX_STYLES.Standard,
|
|
children,
|
|
onMapLoad,
|
|
className = "h-[600px] w-full rounded-md",
|
|
}) => {
|
|
|
|
const [viewState, setViewState] = useState<Partial<ViewState>>(initialViewState);
|
|
|
|
const mapRef = useRef<MapRef | null>(null);
|
|
|
|
const handleMapLoad = () => {
|
|
if (mapRef.current && onMapLoad) {
|
|
onMapLoad(mapRef.current)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="w-full h-96">
|
|
<Map
|
|
{...viewState}
|
|
mapboxAccessToken={process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN}
|
|
onLoad={handleMapLoad}
|
|
onMove={evt => setViewState(evt.viewState)}
|
|
mapStyle={mapStyle}
|
|
ref={mapRef}
|
|
attributionControl={false}
|
|
reuseMaps
|
|
>
|
|
{/* Default Controls */}
|
|
<FullscreenControl position="top-right" />
|
|
<NavigationControl position="top-left" />
|
|
|
|
{children}
|
|
</Map>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MapView; |