new item popups

This commit is contained in:
AT 2022-07-18 14:15:33 +02:00
parent 2b48eb84f8
commit 654d066587
4 changed files with 96 additions and 32 deletions

View File

@ -4,6 +4,7 @@ import DynamicHeroIcon from '../../Utils/DynamicHeroIcon'
export interface AddButtonProps {
layers: Layer[],
setSelectMode: React.Dispatch<React.SetStateAction<any>>
}
export default function AddButton(props: AddButtonProps) {
@ -23,8 +24,10 @@ export default function AddButton(props: AddButtonProps) {
<li key={layer.name} >
<a>
<div className="tooltip tooltip-left" data-tip={layer.menuText}>
<button tabIndex={0} className="z-500 border-0 p-0 mb-2 mt-2 w-10 h-10 cursor-pointer rounded-full mouse drop-shadow-md transition ease-in duration-200 focus:outline-none"
style={{ backgroundColor: layer.menuColor }}>
<button tabIndex={0}
className="z-500 border-0 p-0 mb-2 mt-2 w-10 h-10 cursor-pointer rounded-full mouse drop-shadow-md transition ease-in duration-200 focus:outline-none"
style={{ backgroundColor: layer.menuColor }}
onClick={() => { props.setSelectMode(layer.name ) }}>
<DynamicHeroIcon icon={layer.menuIcon} />
</button>
</div>

View File

@ -0,0 +1,22 @@
import * as React from 'react'
import { LatLng } from 'leaflet'
import { Popup as LeafletPopup } from 'react-leaflet'
export interface NewItemPopupProps {
position: LatLng,
itemType: string,
}
export default function NewItemPopup(props: NewItemPopupProps) {
console.log(props.itemType);
return (
<LeafletPopup maxHeight={300} minWidth={275} maxWidth={275} autoPanPadding={[20, 5]}
position={props.position}>
<div className='flex justify-center'><b className="text-xl font-bold">New {props.itemType}</b></div>
<input type="text" placeholder="Name" className="input input-bordered w-full max-w-xs mt-5" />
<textarea className="textarea textarea-bordered w-full mt-5" placeholder="Text"></textarea>
<div className='flex justify-center'><button className="btn mt-5 place-self-center">Save</button></div>
</LeafletPopup>
)
}

View File

@ -1,4 +1,4 @@
import { TileLayer, MapContainer } from "react-leaflet";
import { TileLayer, MapContainer, useMapEvents } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import * as React from "react";
import { Item, Tag } from "../../types"
@ -7,8 +7,10 @@ import { LatLng } from "leaflet";
import MarkerClusterGroup from 'react-leaflet-cluster'
import AddButton from "./AddButton";
import { Layer, LayerProps } from "./Layer";
import { useState } from "react";
import NewItemPopup, { NewItemPopupProps } from "./NewItemPopup";
export interface MapProps {
export interface UtopiaMapProps {
height?: string,
width?: string,
center?: LatLng,
@ -16,10 +18,34 @@ export interface MapProps {
places?: Item[],
events?: Item[],
tags?: Tag[],
children?: React.ReactNode
children?: React.ReactNode
}
function UtopiaMap(this: any, props: MapProps) {
export interface MapEventListenerProps {
selectMode: string | null,
setSelectMode: React.Dispatch<React.SetStateAction<any>>,
setNewItemPopup: React.Dispatch<React.SetStateAction<any>>
}
function MapEventListener(props: MapEventListenerProps) {
useMapEvents({
click: (e) => {
console.log(e.latlng.lat + ',' + e.latlng.lng);
console.log(props.selectMode);
if (props.selectMode != null) {
props.setNewItemPopup({ itemType: props.selectMode, position: e.latlng })
props.setSelectMode(null)
}
},
locationfound: (location) => {
console.log('location found:', location)
},
})
return null
}
function UtopiaMap(this: any, props: UtopiaMapProps) {
// init / set default values
let center: LatLng = new LatLng(50.6, 9.5);
if (props.center)
@ -34,44 +60,49 @@ function UtopiaMap(this: any, props: MapProps) {
if (props.width)
width = props.width;
const layers: LayerProps[] = [];
const [selectMode, setSelectMode] = useState<string | null>(null);
const [newItemPopup, setNewItemPopup] = useState<NewItemPopupProps | undefined>(undefined);
// all the layers
if(props.events) layers.push({ name: 'event', menuIcon: 'CalendarIcon', menuText: 'add new event', menuColor: '#f9a825', markerIcon: 'calendar-days-solid', markerShape: 'square', markerDefaultColor: '#777', data: props.events });
if(props.places) layers.push({ name: 'place', menuIcon: 'LocationMarkerIcon', menuText: 'add new place', menuColor: '#2E7D32', markerIcon: 'circle-solid', markerShape: 'circle', markerDefaultColor: '#777', data: props.places });
const layers: LayerProps[] = [];
// put places / events if provided as props
if (props.events) layers.push({ name: 'event', menuIcon: 'CalendarIcon', menuText: 'add new event', menuColor: '#f9a825', markerIcon: 'calendar-days-solid', markerShape: 'square', markerDefaultColor: '#777', data: props.events });
if (props.places) layers.push({ name: 'place', menuIcon: 'LocationMarkerIcon', menuText: 'add new place', menuColor: '#2E7D32', markerIcon: 'circle-solid', markerShape: 'circle', markerDefaultColor: '#777', data: props.places });
return (
<>
<div className={(selectMode != null ? "crosshair-cursor-enabled" : undefined)}>
<MapContainer style={{ height: height, width: width }} center={center} zoom={zoom}>
<>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
<MarkerClusterGroup showCoverageOnHover chunkedLoading maxClusterRadius={50}>
{layers &&
layers.map(layer => (
<Layer
key={layer.name}
name={layer.name}
menuIcon={layer.menuIcon}
menuText={layer.menuText}
menuColor={layer.menuColor}
markerIcon={layer.markerIcon}
markerShape={layer.markerShape}
markerDefaultColor={layer.markerDefaultColor}
data={layer.data}
tags={props.tags}/>
))
layers.map(layer => (
<Layer
key={layer.name}
name={layer.name}
menuIcon={layer.menuIcon}
menuText={layer.menuText}
menuColor={layer.menuColor}
markerIcon={layer.markerIcon}
markerShape={layer.markerShape}
markerDefaultColor={layer.markerDefaultColor}
data={layer.data}
tags={props.tags} />
))
}
{console.log(props.children)}
{console.log("children of UtopiaMap: " + props.children)}
</MarkerClusterGroup>
</>
<MapEventListener setSelectMode={setSelectMode} selectMode={selectMode} setNewItemPopup={setNewItemPopup} />
{newItemPopup &&
<NewItemPopup position={newItemPopup.position} itemType={newItemPopup.itemType}/>
}
</MapContainer>
<AddButton layers={layers}></AddButton>
</>
<AddButton layers={layers} setSelectMode={setSelectMode}></AddButton>
</div>
);
}

View File

@ -8,3 +8,11 @@
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAQCAYAAACcN8ZaAAAB3klEQVR42s3U4UdDURzG8czMXJnJ1Vwzc6VJZjaZJdlMlpQsKdmUFNOUspRSSqUolfQfr+fF98Vx5mwv9qbDx7LdznnO7/7Omej3+/+Ga0QMUYkhbvBgmhzCQxwxibIGrGEF8CQhU+LLtKQkQNqScUgjxRxTBIxbgfgD/BgnhM8kM5KTeclLQYqGkkMRBckzR8ic/mAgd5BAZplsUaqyIg2sDtHg2brUZJk5SmwopErJUWE8SpmTMhNvya60Zd/SNrR4bkeaskG4uiwRZk6yrJEYFibGAxn+scECHTmTnuVCzvmty3PHciB7bGKN6lQkzysPqIrHmpFhYbKUtckC1/Ioz4ZHuZdbuSLYiRxRpSZVWXZVxAzC0R4Ik5SQsu6w8yd5l2/5kg95I9SdXMoZQfYIUjeqEUrgOkXGPeN4TYRhxy8E+ZUf+eS7B7miIoeybVSjKDnm8u3+gH3pDTYwu1igATvs/pXqvBKiR4i2bNJfi1ZfUAnjgrOG8wY2quNzBKuU/ZS+uSFEl5O0xRGuUIlZCcw7xG5QPkeHYUSNV5WXGou2sC3rBC0LjenqCXGO0WEiTJa0Lr4KixdHBrDGuGGiRqCUpFk8pGIpQtCU7p4YPwxYxEMCk1aAMQZh8Ac8PfbIzYPJOwAAAABJRU5ErkJggg==') no-repeat;
background-position: 6px 32px;
}
.crosshair-cursor-enabled {
cursor: crosshair;
}
.leaflet-container {
cursor: inherit;
}