import { MapOverlayPage } from '../Templates' import { useAddItem, useItems, useRemoveItem, useUpdateItem } from '../Map/hooks/useItems' import { useLocation, useNavigate } from 'react-router-dom' import { useEffect, useRef, useState } from 'react'; import { Item } from '../../types'; import { useMap } from 'react-leaflet'; import { LatLng } from 'leaflet'; import { PopupStartEndInput, StartEndView, TextView } from '../Map'; import useWindowDimensions from '../Map/hooks/useWindowDimension'; import { useAddTag, useTags } from '../Map/hooks/useTags'; import { useFilterTags, useResetFilterTags } from '../Map/hooks/useFilter'; import { useHasUserPermission } from '../Map/hooks/usePermissions'; import { TextAreaInput, TextInput } from '../Input'; import { hashTagRegex } from '../../Utils/HashTagRegex'; import { randomColor } from '../../Utils/RandomColor'; import { toast } from 'react-toastify'; import { useAuth } from '../Auth'; import { useLayers } from '../Map/hooks/useLayers'; import { ActionButton } from './ActionsButton'; import { LinkedItemsHeaderView } from './LinkedItemsHeaderView'; import { HeaderView } from '../Map/Subcomponents/ItemPopupComponents/HeaderView'; import { useSelectPosition, useSetSelectPosition } from '../Map/hooks/useSelectPosition'; import { useClusterRef } from '../Map/hooks/useClusterRef'; import { useLeafletRefs } from '../Map/hooks/useLeafletRefs'; export function OverlayItemProfile() { const [updatePermission, setUpdatePermission] = useState(false); const [relations, setRelations] = useState>([]); const [activeTab, setActiveTab] = useState(1); const [addItemPopupType, setAddItemPopupType] = useState(""); const [loading, setLoading] = useState(false); const location = useLocation(); const items = useItems(); const updateItem = useUpdateItem(); const [item, setItem] = useState({} as Item) const map = useMap(); const layers = useLayers(); const selectPosition = useSelectPosition(); const removeItem = useRemoveItem(); const tags = useTags(); const navigate = useNavigate(); const addTag = useAddTag(); const resetFilterTags = useResetFilterTags(); const filterTags = useFilterTags(); const addItem = useAddItem(); const { user } = useAuth(); const hasUserPermission = useHasUserPermission(); const setSelectPosition = useSetSelectPosition(); const clusterRef = useClusterRef(); const leafletRefs = useLeafletRefs(); const tabRef = useRef(null); function scroll() { tabRef.current?.scrollIntoView(); } useEffect(() => { scroll(); }, [addItemPopupType]) const updateActiveTab = (id: number) => { setActiveTab(id); let params = new URLSearchParams(window.location.search); let urlTab = params.get("tab"); if (!urlTab?.includes(id.toString())) params.set("tab", `${id ? id : ""}`) window.history.pushState('', '', "?" + params.toString()); } useEffect(() => { const itemId = location.pathname.split("/")[2]; const item = items.find(i => i.id === itemId); item && setItem(item); }, [items,location]) useEffect(() => { if (item) { if(item.position) { const marker = Object.entries(leafletRefs).find(r => r[1].item == item)?.[1].marker; marker && clusterRef?.zoomToShowLayer(marker, () => { const bounds = map.getBounds(); const x = bounds.getEast() - bounds.getWest() map.setView(new LatLng(item?.position?.coordinates[1]!, item?.position?.coordinates[0]! + x / 4), undefined, {duration: 1})} ); } else { const parent = items.find(i => i.id == item.parent); const marker = Object.entries(leafletRefs).find(r => r[1].item == parent)?.[1].marker; marker && clusterRef?.zoomToShowLayer(marker, () => { const bounds = map.getBounds(); const x = bounds.getEast() - bounds.getWest() map.setView(new LatLng(parent?.position?.coordinates[1]!, parent?.position?.coordinates[0]! + x / 4), undefined, {duration: 1})} ); } } }, [item]) useEffect(() => { let params = new URLSearchParams(location.search); let urlTab = params.get("tab"); urlTab ? setActiveTab(Number(urlTab)) : setActiveTab(1); }, [location]) useEffect(() => { setRelations([]); item.relations?.map(r => { const item = items.find(i => i.id == r.related_items_id) item && setRelations(current => [...current, item]) }) }, [item]) useEffect(() => { item && item.user_created && hasUserPermission("items", "update", item) && setUpdatePermission(true); }, [item]) useEffect(() => { selectPosition && map.closePopup(); }, [selectPosition]) const submitNewItem = async (evt: any, type: string) => { evt.preventDefault(); const formItem: Item = {} as Item; Array.from(evt.target).forEach((input: HTMLInputElement) => { if (input.name) { formItem[input.name] = input.value; } }); setLoading(true); formItem.text && formItem.text.toLocaleLowerCase().match(hashTagRegex)?.map(tag => { if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) { addTag({ id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() }) } }); const uuid = crypto.randomUUID(); console.log(layers); const layer = layers.find(l => l.name.toLocaleLowerCase().replace("s", "") == addItemPopupType.toLocaleLowerCase()) console.log(layer); let success = false; try { await layer?.api?.createItem!({ ...formItem, id: uuid, type: type }); await linkItem(uuid); success = true; } catch (error) { toast.error(error.toString()); } if (success) { addItem({ ...formItem, id: uuid, type: type, layer: layer, user_created: user }); toast.success("New item created"); resetFilterTags(); } setLoading(false); setAddItemPopupType(""); } const linkItem = async (id: string) => { let new_relations = item.relations || []; new_relations?.push({ items_id: item.id, related_items_id: id }) const updatedItem = { id: item.id, relations: new_relations } let success = false; try { await item?.layer?.api?.updateItem!(updatedItem) success = true; } catch (error) { toast.error(error.toString()); } if (success) { updateItem({ ...item, relations: new_relations }) toast.success("Item linked"); } } const unlinkItem = async (id: string) => { console.log(id); let new_relations = item.relations?.filter(r => r.related_items_id !== id) console.log(new_relations); const updatedItem = { id: item.id, relations: new_relations } let success = false; try { await item?.layer?.api?.updateItem!(updatedItem) success = true; } catch (error) { toast.error(error.toString()); } if (success) { updateItem({ ...item, relations: new_relations }) toast.success("Item unlinked"); } } const handleDelete = async (event: React.MouseEvent) => { event.stopPropagation(); setLoading(true); let success = false; try { await item.layer?.api?.deleteItem!(item.id) success = true; } catch (error) { toast.error(error.toString()); } if (success) { removeItem(item); toast.success("Item deleted"); } setLoading(false); map.closePopup(); let params = new URLSearchParams(window.location.search); window.history.pushState({}, "", "/" + `${params ? `?${params}` : ""}`); navigate("/"); } return ( <> {item && <> navigate("/edit-item/" + item.id)} setPositionCallback={()=>{map.closePopup();setSelectPosition(item); navigate("/")}} big />
updateActiveTab(1)} />
updateActiveTab(2)} />
{relations && relations.map(i => { if (i.type == 'project') return (
navigate('/item/' + i.id)}>
) else return null })} {addItemPopupType == "project" ?
submitNewItem(e, addItemPopupType)} >
: <> } {updatePermission && { setAddItemPopupType("project"); scroll() }} color={item.color}>}
updateActiveTab(3)} />
{relations && relations.map(i => { if (i.type == 'event') return (
navigate('/item/' + i.id)}>
) else return null })} {addItemPopupType == "event" ?
submitNewItem(e, addItemPopupType)} >
: <> } {updatePermission && { setAddItemPopupType("event"); scroll() }} color={item.color}>}
updateActiveTab(4)} />
} ) }