/* eslint-disable react/prop-types */ /* eslint-disable @typescript-eslint/prefer-optional-chain */ /* eslint-disable @typescript-eslint/no-floating-promises */ /* eslint-disable @typescript-eslint/no-empty-function */ /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ /* eslint-disable @typescript-eslint/await-thenable */ /* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import { LatLng } from 'leaflet' import { createContext, useContext, useEffect, useState } from 'react' import { toast } from 'react-toastify' import { Geometry, Item, LayerProps, ItemFormPopupProps } from '#src/types' import { useUpdateItem } from './useItems' import { useHasUserPermission } from './usePermissions' interface PolygonClickedProps { position: LatLng setItemFormPopup: React.Dispatch> } type UseSelectPositionManagerResult = ReturnType const SelectPositionContext = createContext({ selectPosition: null, setSelectPosition: () => {}, setMarkerClicked: () => {}, setMapClicked: () => {}, }) function useSelectPositionManager(): { selectPosition: Item | LayerProps | null setSelectPosition: React.Dispatch> setMarkerClicked: React.Dispatch> setMapClicked: React.Dispatch> } { const [selectPosition, setSelectPosition] = useState(null) const [markerClicked, setMarkerClicked] = useState() const [mapClicked, setMapClicked] = useState() const updateItem = useUpdateItem() const hasUserPermission = useHasUserPermission() useEffect(() => { if ( selectPosition && markerClicked && 'text' in selectPosition && markerClicked.id !== selectPosition.id ) { itemUpdateParent({ ...selectPosition, parent: markerClicked.id }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [markerClicked]) useEffect(() => { if (selectPosition != null) { if ('menuIcon' in selectPosition) { mapClicked && mapClicked.setItemFormPopup({ layer: selectPosition as LayerProps, position: mapClicked.position, }) setSelectPosition(null) } if ('text' in selectPosition) { const position = mapClicked?.position.lng && new Geometry(mapClicked.position.lng, mapClicked.position.lat) position && itemUpdatePosition({ ...selectPosition, position }) setSelectPosition(null) } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [mapClicked]) const itemUpdateParent = async (updatedItem: Item) => { if ( markerClicked?.layer?.api?.collectionName && hasUserPermission(markerClicked.layer.api.collectionName, 'update', markerClicked) ) { let success = false try { await updatedItem.layer?.api?.updateItem!({ id: updatedItem.id, parent: updatedItem.parent, position: null, }) success = true } catch (error) { toast.error(error.toString()) } if (success) { await updateItem({ ...updatedItem, parent: updatedItem.parent, position: undefined }) await linkItem(updatedItem.id) toast.success('Item position updated') setSelectPosition(null) setMarkerClicked(null) } } else { setSelectPosition(null) toast.error("you don't have permission to add items to " + markerClicked?.name) } } const itemUpdatePosition = async (updatedItem: Item) => { let success = false try { await updatedItem.layer?.api?.updateItem!({ id: updatedItem.id, position: updatedItem.position, }) success = true } catch (error) { toast.error(error.toString()) } if (success) { updateItem(updatedItem) toast.success('Item position updated') } } const linkItem = async (id: string) => { if (markerClicked) { const newRelations = markerClicked.relations || [] if (!newRelations.some((r) => r.related_items_id === id)) { newRelations.push({ items_id: markerClicked.id, related_items_id: id }) const updatedItem = { id: markerClicked.id, relations: newRelations } let success = false try { await markerClicked.layer?.api?.updateItem!(updatedItem) success = true } catch (error) { toast.error(error.toString()) } if (success) { updateItem({ ...markerClicked, relations: newRelations }) toast.success('Item linked') } } } } return { selectPosition, setSelectPosition, setMarkerClicked, setMapClicked } } export const SelectPositionProvider: React.FunctionComponent<{ children?: React.ReactNode }> = ({ children }) => ( {children} ) export const useSelectPosition = (): Item | LayerProps | null => { const { selectPosition } = useContext(SelectPositionContext) return selectPosition } export const useSetSelectPosition = (): UseSelectPositionManagerResult['setSelectPosition'] => { const { setSelectPosition } = useContext(SelectPositionContext) return setSelectPosition } export const useSetMarkerClicked = (): UseSelectPositionManagerResult['setMarkerClicked'] => { const { setMarkerClicked } = useContext(SelectPositionContext) return setMarkerClicked } export const useSetMapClicked = (): UseSelectPositionManagerResult['setMapClicked'] => { const { setMapClicked } = useContext(SelectPositionContext) return setMapClicked }