diff --git a/package.json b/package.json index ffa2b53b..2a4850f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "utopia-ui", - "version": "1.0.7", + "version": "1.0.8", "description": "Reuseable React Components to build mapping apps for all kinds of communities ", "repository": "https://github.com/utopia-os/utopia-ui", "homepage:": "https://utopia.os/", diff --git a/src/Components/Map/Layer.tsx b/src/Components/Map/Layer.tsx index 435358f9..bbd98fea 100644 --- a/src/Components/Map/Layer.tsx +++ b/src/Components/Map/Layer.tsx @@ -33,8 +33,10 @@ export const Layer = (props: LayerProps) => { item.layer = props; addItem(item); }) + addLayer(props); + }, []) - addLayer(props); + return ( <> @@ -50,7 +52,7 @@ export const Layer = (props: LayerProps) => { } return ( - + ); }) diff --git a/src/Components/Map/Subcomponents/AddButton.tsx b/src/Components/Map/Subcomponents/AddButton.tsx index afbb7855..56e44b94 100644 --- a/src/Components/Map/Subcomponents/AddButton.tsx +++ b/src/Components/Map/Subcomponents/AddButton.tsx @@ -6,8 +6,7 @@ import { useLayers } from '../hooks/useLayers' export default function AddButton({setSelectMode} : {setSelectMode: React.Dispatch>}) { const layers = useLayers(); - console.log(layers); - console.log(useLayers()); + console.log("Layers: " +layers); return (
diff --git a/src/Components/Map/Subcomponents/NewItemPopup.tsx b/src/Components/Map/Subcomponents/NewItemPopup.tsx index 4c16e1b8..ada8b0a2 100644 --- a/src/Components/Map/Subcomponents/NewItemPopup.tsx +++ b/src/Components/Map/Subcomponents/NewItemPopup.tsx @@ -1,13 +1,14 @@ import * as React from 'react' import { LatLng } from 'leaflet' import { Popup as LeafletPopup, useMap } from 'react-leaflet' -import { useState } from 'react' -import { useAddItem } from '../hooks/useItems' +import { useEffect, useState } from 'react' +import { useAddItem, useUpdateItem } from '../hooks/useItems' import { Geometry, Layer, Item} from '../../../types' export interface NewItemPopupProps { position: LatLng, layer: Layer, + item?: Item, setNewItemPopup: React.Dispatch> } @@ -17,22 +18,42 @@ export default function NewItemPopup(props: NewItemPopupProps) { const map = useMap(); const addItem = useAddItem(); + const updateItem = useUpdateItem(); const handleSubmit = (evt: any) => { evt.preventDefault() console.log("New Item Popup is adding Item ..."); - - addItem(new Item(Math.floor(Math.random() * 1000) + 200, name, text, new Geometry(props.position.lng, props.position.lat), props.layer)) + if(props.item) { + updateItem(new Item(props.item.id, name, text, new Geometry(props.position.lng, props.position.lat), props.layer)) + } + else { + addItem(new Item(crypto.randomUUID(), name, text, new Geometry(props.position.lng, props.position.lat), props.layer))} map.closePopup(); props.setNewItemPopup(null); - + } + + const resetPopup = () => { + setName(''); + setText(''); } - console.log("popup opend"); - + const setItemValues = () => { + if(props.item) { + setName(props.item?.name); + setText(props.item?.text); + console.log('set name + txt'); + } + } + + useEffect(() => { + setItemValues(); + },[props.item]) return (
New {props.layer.name}
diff --git a/src/Components/Map/Subcomponents/Popup.tsx b/src/Components/Map/Subcomponents/Popup.tsx index 1dd1de89..fce65ff9 100644 --- a/src/Components/Map/Subcomponents/Popup.tsx +++ b/src/Components/Map/Subcomponents/Popup.tsx @@ -1,12 +1,15 @@ +import { LatLng } from 'leaflet' import * as React from 'react' import { Popup as LeafletPopup, useMap } from 'react-leaflet' import { Item, Tag } from '../../../types' import { replaceURLs } from '../../../Utils/ReplaceURLs' import { useRemoveItem } from '../hooks/useItems' +import { NewItemPopupProps } from './NewItemPopup' export interface UtopiaPopupProps { item: Item, tags: Tag[], + setNewItemPopup?: React.Dispatch> } @@ -17,11 +20,18 @@ const Popup = (props: UtopiaPopupProps) => { const map = useMap(); const removeItemFromMap = (event: React.MouseEvent) => { - removeItem(item) - event.stopPropagation() + removeItem(item); + event.stopPropagation(); map.closePopup(); } + const openEditPopup = (event: React.MouseEvent) => { + event.stopPropagation(); + map.closePopup(); + if(props.setNewItemPopup) + props.setNewItemPopup({position: new LatLng(item.position.coordinates[1],item.position.coordinates[0]), layer: item.layer, item: item, setNewItemPopup: props.setNewItemPopup}) + } + return (
@@ -37,7 +47,7 @@ const Popup = (props: UtopiaPopupProps) => {
} - - ); } diff --git a/src/Components/Map/hooks/useItems.tsx b/src/Components/Map/hooks/useItems.tsx index 98fa20d9..49ef70cc 100644 --- a/src/Components/Map/hooks/useItems.tsx +++ b/src/Components/Map/hooks/useItems.tsx @@ -4,6 +4,7 @@ import { Item } from "../../../types"; type ActionType = | { type: "ADD"; item: Item } +| { type: "UPDATE"; item: Item } | { type: "REMOVE"; item: Item }; type UseItemManagerResult = ReturnType; @@ -11,12 +12,14 @@ type UseItemManagerResult = ReturnType; const ItemContext = createContext({ items: [], addItem: () => {}, + updateItem: () => {}, removeItem: () => {} }); function useItemsManager (initialItems: Item[]): { items: Item[]; addItem: (item: Item) => void; + updateItem: (item: Item) => void; removeItem: (item: Item) => void; } { const [items, dispatch] = useReducer((state: Item[], action: ActionType) => { @@ -26,6 +29,13 @@ function useItemsManager (initialItems: Item[]): { ...state, action.item, ]; + case "UPDATE": + return state.map((item) => { + if (item.id === action.item.id) { + return action.item + } + return item + }); case "REMOVE": return state.filter(item => item !== action.item); default: @@ -40,13 +50,20 @@ function useItemsManager (initialItems: Item[]): { }); }, []); + const updateItem = useCallback((item: Item) => { + dispatch({ + type: "UPDATE", + item, + }); + }, []); + const removeItem = useCallback((item: Item) => { dispatch({ type: "REMOVE", item, }); }, []); - return { items, addItem, removeItem }; + return { items, updateItem, addItem, removeItem }; } export const ItemsProvider: React.FunctionComponent<{ @@ -67,6 +84,11 @@ export const useAddItem = (): UseItemManagerResult["addItem"] => { return addItem; }; +export const useUpdateItem = (): UseItemManagerResult["updateItem"] => { + const { updateItem } = useContext(ItemContext); + return updateItem; +}; + export const useRemoveItem = (): UseItemManagerResult["removeItem"] => { const { removeItem } = useContext(ItemContext); return removeItem; diff --git a/src/Components/Map/hooks/useLayers.tsx b/src/Components/Map/hooks/useLayers.tsx index 7a10c9ac..d3e6b500 100644 --- a/src/Components/Map/hooks/useLayers.tsx +++ b/src/Components/Map/hooks/useLayers.tsx @@ -20,17 +20,10 @@ function useLayerManager(initialLayers: Layer[]): { const [layers, dispatch] = useReducer((state: Layer[], action: ActionType) => { switch (action.type) { case "ADD LAYER": - { - if (!state.includes(action.layer)) - state.push(action.layer); - return state; - } - case "ADD ITEM": - { - if(!state.find(layer => layer.name === action.layer.name)?.data.find(item => item.id === action.item.id)) - state.find(layer => layer.name === action.layer.name)?.data.push(action.item) - return state; - } + return [ + ...state, + action.layer, + ]; default: throw new Error(); } diff --git a/src/types.ts b/src/types.ts index 07b85be0..6578ed8d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,5 @@ import { LatLng } from "leaflet"; +import { NewItemPopupProps } from "./Components/Map/Subcomponents/NewItemPopup"; export interface UtopiaMap { height?: string, @@ -21,20 +22,21 @@ export interface Layer { markerShape: string, markerDefaultColor: string, tags?: Tag[], + setNewItemPopup?: React.Dispatch> } export class Item { - id: number; + id: string | number; date_created?: string; date_updated?: string | null; name: string; text: string; position: Geometry; - layer?: Layer; + layer: Layer; start?: string; end?: string; tags?: number[]; - constructor(id:number,name:string,text:string,position:Geometry, layer: Layer){ + constructor(id:string|number,name:string,text:string,position:Geometry, layer: Layer){ this.id = id; this.name = name; this.text = text; @@ -54,7 +56,7 @@ export class Geometry { export interface Tag { color: string; - id: number; + id: string | number; name: string; }