diff --git a/src/Components/Map/Layer.tsx b/src/Components/Map/Layer.tsx index f369c481..4ba80c06 100644 --- a/src/Components/Map/Layer.tsx +++ b/src/Components/Map/Layer.tsx @@ -1,27 +1,17 @@ import * as React from 'react' import { Marker } from 'react-leaflet' -import { Item, Tag } from '../../types' +import { Item, Tag, Layer as LayerProps } from '../../types' import MarkerIconFactory from '../../Utils/MarkerIconFactory' -import { Popup } from './Popup' -import { useLayers, useAddLayer } from './useLayers' - - -export interface LayerProps { - data?: Item[], - children?: React.ReactNode - name: string, - menuIcon: string, - menuColor: string, - menuText: string, - markerIcon: string, - markerShape: string, - markerDefaultColor: string, - tags?: Tag[] -} +import { Popup } from './Subcomponents/Popup' +import { useLayers, useAddLayer } from './hooks/useLayers' +import { useTags } from './hooks/useTags' export const Layer = (props: LayerProps) => { + + const tags = useTags(); + // create a JS-Map with all Tags - let tagMap = new Map(props.tags?.map(key => [key.id, key])); + let tagMap = new Map(tags?.map(key => [key.id, key])); // returns all tags for passed item const getTags = (item: Item) => { @@ -32,14 +22,10 @@ export const Layer = (props: LayerProps) => { return tags; }; - const addLayer = useAddLayer(); addLayer(props); const layers = useLayers(); - console.log(layers); - - return ( <> {layers.get(props.name)?.data?.map((place: Item) => { diff --git a/src/Components/Map/AddButton.tsx b/src/Components/Map/Subcomponents/AddButton.tsx similarity index 84% rename from src/Components/Map/AddButton.tsx rename to src/Components/Map/Subcomponents/AddButton.tsx index 8c4c9010..ff211d0a 100644 --- a/src/Components/Map/AddButton.tsx +++ b/src/Components/Map/Subcomponents/AddButton.tsx @@ -1,15 +1,12 @@ import * as React from 'react' -import DynamicHeroIcon from '../../Utils/DynamicHeroIcon' -import { useLayers } from './useLayers' +import DynamicHeroIcon from '../../../Utils/DynamicHeroIcon' +import { useLayers } from '../hooks/useLayers' -export interface AddButtonProps { - setSelectMode: React.Dispatch> -} - -export default function AddButton(props: AddButtonProps) { +export default function AddButton({setSelectMode} : {setSelectMode: React.Dispatch>}) { const layers = useLayers(); + return (
diff --git a/src/Components/Map/NewItemPopup.tsx b/src/Components/Map/Subcomponents/NewItemPopup.tsx similarity index 93% rename from src/Components/Map/NewItemPopup.tsx rename to src/Components/Map/Subcomponents/NewItemPopup.tsx index 6c1a26d8..81753fdd 100644 --- a/src/Components/Map/NewItemPopup.tsx +++ b/src/Components/Map/Subcomponents/NewItemPopup.tsx @@ -2,9 +2,8 @@ import * as React from 'react' import { LatLng } from 'leaflet' import { Popup as LeafletPopup, useMap } from 'react-leaflet' import { useState } from 'react' -import { useAddItem } from './useLayers' -import { Item } from './UtopiaMap' -import { Geometry, Layer} from '../../types' +import { useAddItem } from '../hooks/useLayers' +import { Geometry, Layer, Item} from '../../../types' export interface NewItemPopupProps { position: LatLng, diff --git a/src/Components/Map/Popup.tsx b/src/Components/Map/Subcomponents/Popup.tsx similarity index 95% rename from src/Components/Map/Popup.tsx rename to src/Components/Map/Subcomponents/Popup.tsx index 4b6f0cc8..b225fc61 100644 --- a/src/Components/Map/Popup.tsx +++ b/src/Components/Map/Subcomponents/Popup.tsx @@ -1,7 +1,7 @@ import * as React from 'react' import { Popup as LeafletPopup} from 'react-leaflet' -import { Item, Tag } from '../../types' -import { replaceURLs } from '../../Utils/ReplaceURLs' +import { Item, Tag } from '../../../types' +import { replaceURLs } from '../../../Utils/ReplaceURLs' export interface UtopiaPopupProps { item: Item, diff --git a/src/Components/Map/Tags.tsx b/src/Components/Map/Tags.tsx new file mode 100644 index 00000000..081f0b71 --- /dev/null +++ b/src/Components/Map/Tags.tsx @@ -0,0 +1,20 @@ +import * as React from 'react' +import { useEffect } from 'react'; +import { Tag } from '../../types'; +import { useAddTag } from './hooks/useTags' + +export function Tags({data} : {data: Tag[]}) { +const addTag = useAddTag(); + + +useEffect(() => { + data.map(tag => { + console.log("Tag added: " + tag.name); + addTag(tag) + }) +}, []) + + return ( + <> + ) +} diff --git a/src/Components/Map/UtopiaMap.tsx b/src/Components/Map/UtopiaMap.tsx index 53c5b380..7d1de0f1 100644 --- a/src/Components/Map/UtopiaMap.tsx +++ b/src/Components/Map/UtopiaMap.tsx @@ -1,26 +1,17 @@ import { TileLayer, MapContainer, useMapEvents } from "react-leaflet"; import "leaflet/dist/leaflet.css"; import * as React from "react"; -import { Item, Tag, API, Layer } from "../../types" +import { Item, Tag, API, Layer, UtopiaMap as UtopiaMapProps } from "../../types" import "../../index.css" import { LatLng } from "leaflet"; import MarkerClusterGroup from 'react-leaflet-cluster' -import AddButton from "./AddButton"; -import { useState } from "react"; -import NewItemPopup, { NewItemPopupProps } from "./NewItemPopup"; -import { LayersProvider } from "./useLayers"; +import AddButton from "./Subcomponents/AddButton"; +import { useState } from "react"; +import NewItemPopup, { NewItemPopupProps } from "./Subcomponents/NewItemPopup"; +import { LayersProvider } from "./hooks/useLayers"; +import { TagsProvider } from "./hooks/useTags"; -export interface UtopiaMapProps { - height?: string, - width?: string, - center?: LatLng, - zoom?: number, - tags?: Tag[], - children?: React.ReactNode, - api?: API -} - export interface MapEventListenerProps { selectMode: Layer | null, @@ -54,39 +45,37 @@ function UtopiaMap({ const [selectMode, setSelectMode] = useState(null); const [newItemPopup, setNewItemPopup] = useState(null); - - - return ( - -
- - - - {children} - - - {newItemPopup && - - } - - - {selectMode != null && -
-
-
- Select {selectMode.name} position! + + +
+ + + + {children} + + + {newItemPopup && + + } + + + {selectMode != null && +
+
+
+ Select {selectMode.name} position! +
-
- } + } -
- +
+ + ); } -export { UtopiaMap, Item, Tag, API }; - +export { UtopiaMap, Item, Tag, API }; \ No newline at end of file diff --git a/src/Components/Map/data.ts b/src/Components/Map/data.ts index 75147ce8..c44f1b21 100644 --- a/src/Components/Map/data.ts +++ b/src/Components/Map/data.ts @@ -1,4 +1,4 @@ -import {Item, Tag} from "utopia-ui" +import {Item, Tag} from "../../types" export const tags : Tag[] = [ { diff --git a/src/Components/Map/useLayers.tsx b/src/Components/Map/hooks/useLayers.tsx similarity index 98% rename from src/Components/Map/useLayers.tsx rename to src/Components/Map/hooks/useLayers.tsx index c47a9a78..d14eb6ac 100644 --- a/src/Components/Map/useLayers.tsx +++ b/src/Components/Map/hooks/useLayers.tsx @@ -1,6 +1,6 @@ import { useCallback, useReducer, createContext, useContext } from "react"; import * as React from "react"; -import { Item, Layer } from "../../types"; +import { Item, Layer } from "../../../types"; type ActionType = | { type: "ADD LAYER"; layer: Layer } diff --git a/src/Components/Map/hooks/useTags.tsx b/src/Components/Map/hooks/useTags.tsx new file mode 100644 index 00000000..1f0361f8 --- /dev/null +++ b/src/Components/Map/hooks/useTags.tsx @@ -0,0 +1,73 @@ +import { useCallback, useReducer, createContext, useContext } from "react"; +import * as React from "react"; +import { Tag } from "../../../types"; + +type ActionType = +| { type: "ADD"; tag: Tag } +| { type: "REMOVE"; id: number }; + +type UseTagManagerResult = ReturnType; + +const TagContext = createContext({ + tags: [], + addTag: () => {}, + removeTag: () => {} +}); + +function useTagsManager (initialTags: Tag[]): { + tags: Tag[]; + addTag: (tag: Tag) => void; + removeTag: (id: number) => void; +} { + const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => { + switch (action.type) { + case "ADD": + return [ + ...state, + action.tag, + ]; + case "REMOVE": + return state.filter(({ id }) => id !== action.id); + default: + throw new Error(); + } + }, initialTags); + + const addTag = useCallback((tag: Tag) => { + dispatch({ + type: "ADD", + tag, + }); + }, []); + + const removeTag = useCallback((id: number) => { + dispatch({ + type: "REMOVE", + id, + }); + }, []); + return { tags, addTag, removeTag }; +} + +export const TagsProvider: React.FunctionComponent<{ + initialTags: Tag[], children?: React.ReactNode +}> = ({ initialTags, children }) => ( + + {children} + +); + +export const useTags = (): Tag[] => { + const { tags } = useContext(TagContext); + return tags; +}; + +export const useAddTag = (): UseTagManagerResult["addTag"] => { + const { addTag } = useContext(TagContext); + return addTag; +}; + +export const useRemoveTag = (): UseTagManagerResult["removeTag"] => { + const { removeTag } = useContext(TagContext); + return removeTag; +}; \ No newline at end of file diff --git a/src/Components/Map/index.tsx b/src/Components/Map/index.tsx index b4bdfddb..fe7474ca 100644 --- a/src/Components/Map/index.tsx +++ b/src/Components/Map/index.tsx @@ -1 +1,3 @@ export { UtopiaMap, Item, Tag, API } from './UtopiaMap' +export { Layer } from './Layer'; +export { Tags } from "./Tags"; \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index da105f6d..fb7fd4ad 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,2 +1 @@ -export { UtopiaMap, Item, Tag, API } from './Components/Map/index' -export { Layer } from './Components/Map/Layer'; \ No newline at end of file +export { UtopiaMap, Layer, Tags, Item, Tag, API } from './Components/Map/index' diff --git a/src/types.ts b/src/types.ts index c95d4ea0..1258da65 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,28 @@ +import { LatLng } from "leaflet"; + +export interface UtopiaMap { + height?: string, + width?: string, + center?: LatLng, + zoom?: number, + tags?: Tag[], + children?: React.ReactNode, + api?: API +} + +export interface Layer { + data?: Item[], + children?: React.ReactNode + name: string, + menuIcon: string, + menuColor: string, + menuText: string, + markerIcon: string, + markerShape: string, + markerDefaultColor: string, + tags?: Tag[] +} + export class Item { id: number; date_created?: string; @@ -32,20 +57,6 @@ export interface Tag { name: string; } - -export interface Layer { - data?: Item[], - children?: React.ReactNode - name: string, - menuIcon: string, - menuColor: string, - menuText: string, - markerIcon: string, - markerShape: string, - markerDefaultColor: string, - tags?: Tag[] -} - export interface API { getAll(): Promise, add(item : Item): Promise,