hotel-ai-widget
Version:
A customizable hotel chat widget for React and vanilla HTML
83 lines (82 loc) • 3.46 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef } from "react";
import { GoogleMap, OverlayView } from "@react-google-maps/api";
import { Pin } from "lucide-react";
const MapSection = ({ markers, hoveredMarker }) => {
const mapRef = useRef(null);
const onLoad = (mapInstance) => {
mapRef.current = mapInstance;
mapInstance.setZoom(5);
mapInstance.setCenter(center);
};
useEffect(() => {
if (mapRef.current && markers.length > 0) {
const lastMarker = markers[markers.length - 1];
if (Number(lastMarker.lat) === 0 || Number(lastMarker.lng) === 0)
return;
flyTo(mapRef.current, { lat: lastMarker.lat, lng: lastMarker.lng }, { duration: 2000, zoom: 13 });
}
}, [markers]);
useEffect(() => {
if (mapRef.current && hoveredMarker) {
flyTo(mapRef.current, { lat: hoveredMarker.lat, lng: hoveredMarker.lng }, {
duration: 1000,
zoom: 13,
});
}
}, [hoveredMarker]);
return (_jsx("div", { className: "flex-1 p-2 h-[92vh]", children: _jsx(GoogleMap, { mapContainerStyle: containerStyle, center: center, zoom: 5, onLoad: onLoad, children: markers?.length &&
markers.map(({ label, lat, lng }, index) => {
const isHovered = hoveredMarker &&
hoveredMarker.lat === lat &&
hoveredMarker.lng === lng;
return (_jsx(OverlayView, { position: { lat, lng }, mapPaneName: OverlayView.OVERLAY_MOUSE_TARGET, children: _jsxs("div", { className: `flex items-center transition-transform duration-200 ease-in-out ${isHovered ? "scale-125 z-[999]" : "scale-100 z-[10]"}`, style: {
position: "relative",
top: isHovered ? "-6px" : "0px", // thoda sa upar ho jaye
}, children: [_jsx(Pin, { className: "w-10 h-10 text-red-500" }), _jsx("div", { className: "bg-white px-2 py-1 rounded shadow text-xs border ml-1 text-nowrap", children: label })] }) }, index));
}) }) }));
};
export default MapSection;
const containerStyle = {
width: "100%",
height: "100%",
//border:'4px solid #ff0000',
borderRadius: "16px",
};
const center = {
lat: 28.6139, // Delhi
lng: 77.209,
};
function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
function flyTo(map, target, options = {}) {
const { steps = 100, zoom = 13 } = options;
const center = map.getCenter();
if (!center)
return;
const startLat = center.lat();
const startLng = center.lng();
const targetLat = target.lat;
const targetLng = target.lng;
const startZoom = map.getZoom() ?? 5;
const zoomDiff = zoom - startZoom;
let step = 0;
function animate() {
step++;
const progress = easeInOutCubic(step / steps);
const lat = startLat + (targetLat - startLat) * progress;
const lng = startLng + (targetLng - startLng) * progress;
const currZoom = startZoom + zoomDiff * progress;
map.setCenter({ lat, lng });
map.setZoom(currZoom);
if (step < steps) {
requestAnimationFrame(animate);
}
else {
map.setCenter(target);
map.setZoom(zoom);
}
}
animate();
}