mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-15 03:53:51 +00:00
Extract shlink-web-component outside of src folder
This commit is contained in:
56
shlink-web-component/visits/helpers/MapModal.tsx
Normal file
56
shlink-web-component/visits/helpers/MapModal.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { prop } from 'ramda';
|
||||
import type { FC } from 'react';
|
||||
import type { MapContainerProps } from 'react-leaflet';
|
||||
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet';
|
||||
import { Modal, ModalBody } from 'reactstrap';
|
||||
import type { CityStats } from '../types';
|
||||
import './MapModal.scss';
|
||||
|
||||
interface MapModalProps {
|
||||
toggle: () => void;
|
||||
isOpen: boolean;
|
||||
title: string;
|
||||
locations?: CityStats[];
|
||||
}
|
||||
|
||||
const OpenStreetMapTile: FC = () => (
|
||||
<TileLayer
|
||||
attribution='&copy <a href="https://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
/>
|
||||
);
|
||||
|
||||
const calculateMapProps = (locations: CityStats[]): MapContainerProps => {
|
||||
if (locations.length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (locations.length > 1) {
|
||||
return { bounds: locations.map(prop('latLong')) };
|
||||
}
|
||||
|
||||
// When there's only one location, an error is thrown if trying to calculate the bounds.
|
||||
// When that happens, we use "zoom" and "center" as a workaround
|
||||
const [{ latLong: center }] = locations;
|
||||
|
||||
return { zoom: 10, center };
|
||||
};
|
||||
|
||||
export const MapModal = ({ toggle, isOpen, title, locations = [] }: MapModalProps) => (
|
||||
<Modal toggle={toggle} isOpen={isOpen} className="map-modal__modal" contentClassName="map-modal__modal-content">
|
||||
<ModalBody className="map-modal__modal-body">
|
||||
<h3 className="map-modal__modal-title">
|
||||
{title}
|
||||
<button type="button" className="btn-close float-end" aria-label="Close" onClick={toggle} />
|
||||
</h3>
|
||||
<MapContainer {...calculateMapProps(locations)}>
|
||||
<OpenStreetMapTile />
|
||||
{locations.map(({ cityName, latLong, count }, index) => (
|
||||
<Marker key={index} position={latLong}>
|
||||
<Popup><b>{count}</b> visit{count > 1 ? 's' : ''} from <b>{cityName}</b></Popup>
|
||||
</Marker>
|
||||
))}
|
||||
</MapContainer>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
);
|
||||
Reference in New Issue
Block a user