mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
* rollup - fail when typescript has warnings or errors Currently this is detected when building the docu. Since the developer rarely does that the problem is detected on github. This change allows the developer to discover the error early by failing the build. * 3.0.75 * removed tw-elements * removed tw-elements package * found userType artefacts and removed it * fixed linting * 3.0.76 * adjust sidebar size and transition --------- Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
221 lines
7.6 KiB
TypeScript
221 lines
7.6 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
|
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
|
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
import { LatLng } from 'leaflet'
|
|
import { useEffect, useState } from 'react'
|
|
import { useMap } from 'react-leaflet'
|
|
import { useLocation, useNavigate } from 'react-router-dom'
|
|
|
|
import { useClusterRef } from '#components/Map/hooks/useClusterRef'
|
|
import { useItems, useRemoveItem, useUpdateItem } from '#components/Map/hooks/useItems'
|
|
import { useLayers } from '#components/Map/hooks/useLayers'
|
|
import { useLeafletRefs } from '#components/Map/hooks/useLeafletRefs'
|
|
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
|
|
import { useSelectPosition, useSetSelectPosition } from '#components/Map/hooks/useSelectPosition'
|
|
import { useTags } from '#components/Map/hooks/useTags'
|
|
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
|
|
import { MapOverlayPage } from '#components/Templates'
|
|
|
|
import { handleDelete, linkItem, unlinkItem } from './itemFunctions'
|
|
import { FlexView } from './Templates/FlexView'
|
|
import { OnepagerView } from './Templates/OnepagerView'
|
|
import { SimpleView } from './Templates/SimpleView'
|
|
import { TabsView } from './Templates/TabsView'
|
|
|
|
import type { Item } from '#types/Item'
|
|
import type { ItemsApi } from '#types/ItemsApi'
|
|
import type { Tag } from '#types/Tag'
|
|
import type { Marker } from 'leaflet'
|
|
|
|
/**
|
|
* @category Profile
|
|
*/
|
|
export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any> }) {
|
|
const [item, setItem] = useState<Item>()
|
|
const [updatePermission, setUpdatePermission] = useState<boolean>(false)
|
|
const [relations, setRelations] = useState<Item[]>([])
|
|
const [offers, setOffers] = useState<Tag[]>([])
|
|
const [needs, setNeeds] = useState<Tag[]>([])
|
|
const [loading, setLoading] = useState<boolean>(false)
|
|
const [template, setTemplate] = useState<string>('')
|
|
|
|
const location = useLocation()
|
|
const items = useItems()
|
|
const updateItem = useUpdateItem()
|
|
const map = useMap()
|
|
const selectPosition = useSelectPosition()
|
|
const removeItem = useRemoveItem()
|
|
const tags = useTags()
|
|
const navigate = useNavigate()
|
|
const hasUserPermission = useHasUserPermission()
|
|
const setSelectPosition = useSetSelectPosition()
|
|
const clusterRef = useClusterRef()
|
|
const leafletRefs = useLeafletRefs()
|
|
const layers = useLayers()
|
|
|
|
const [attestations, setAttestations] = useState<any[]>([])
|
|
|
|
useEffect(() => {
|
|
if (attestationApi) {
|
|
attestationApi
|
|
.getItems()
|
|
.then((value) => {
|
|
// eslint-disable-next-line no-console
|
|
console.log(value)
|
|
|
|
setAttestations(value)
|
|
return null
|
|
})
|
|
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
.catch((error) => {
|
|
// eslint-disable-next-line no-console
|
|
console.error('Error fetching items:', error)
|
|
})
|
|
}
|
|
}, [attestationApi])
|
|
|
|
useEffect(() => {
|
|
const itemId = location.pathname.split('/')[2]
|
|
const item = items.find((i) => i.id === itemId)
|
|
item && setItem(item)
|
|
}, [items, location])
|
|
|
|
useEffect(() => {
|
|
setOffers([])
|
|
setNeeds([])
|
|
setRelations([])
|
|
|
|
item?.offers?.forEach((o) => {
|
|
const tag = tags.find((t) => t.id === o.tags_id)
|
|
tag && setOffers((current) => [...current, tag])
|
|
})
|
|
item?.needs?.forEach((n) => {
|
|
const tag = tags.find((t) => t.id === n.tags_id)
|
|
tag && setNeeds((current) => [...current, tag])
|
|
})
|
|
item?.relations?.forEach((r) => {
|
|
const item = items.find((i) => i.id === r.related_items_id)
|
|
item && setRelations((current) => [...current, item])
|
|
})
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [item, items])
|
|
|
|
useEffect(() => {
|
|
const setMap = (marker: Marker, x: number) => {
|
|
map.setView(
|
|
new LatLng(item?.position?.coordinates[1]!, item?.position?.coordinates[0]! + x / 4),
|
|
undefined,
|
|
)
|
|
setTimeout(() => {
|
|
marker.openPopup()
|
|
}, 500)
|
|
}
|
|
if (item) {
|
|
if (item.position) {
|
|
const marker = Object.entries(leafletRefs).find((r) => r[1].item === item)?.[1].marker
|
|
marker &&
|
|
clusterRef.hasLayer(marker) &&
|
|
clusterRef?.zoomToShowLayer(marker, () => {
|
|
const bounds = map.getBounds()
|
|
const x = bounds.getEast() - bounds.getWest()
|
|
setMap(marker, x)
|
|
})
|
|
} else {
|
|
const parent = getFirstAncestor(item)
|
|
const marker = Object.entries(leafletRefs).find((r) => r[1].item === parent)?.[1].marker
|
|
marker &&
|
|
clusterRef.hasLayer(marker) &&
|
|
clusterRef?.zoomToShowLayer(marker, () => {
|
|
const bounds = map.getBounds()
|
|
const x = bounds.getEast() - bounds.getWest()
|
|
setMap(marker, x)
|
|
})
|
|
}
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [item])
|
|
|
|
const getFirstAncestor = (item: Item): Item | undefined => {
|
|
const parent = items.find((i) => i.id === item.parent)
|
|
if (parent?.parent) {
|
|
return getFirstAncestor(parent)
|
|
} else {
|
|
return parent
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
item && hasUserPermission('items', 'update', item) && setUpdatePermission(true)
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [item])
|
|
|
|
useEffect(() => {
|
|
selectPosition && map.closePopup()
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [selectPosition])
|
|
|
|
useEffect(() => {
|
|
if (item?.layer?.itemType.template) setTemplate(item.layer.itemType.template)
|
|
else {
|
|
const userLayer = layers.find((l) => l.userProfileLayer === true)
|
|
if (userLayer) setTemplate(userLayer.itemType.template)
|
|
}
|
|
}, [item, layers])
|
|
|
|
return (
|
|
<>
|
|
{item && (
|
|
<MapOverlayPage
|
|
key={item.id}
|
|
className={`!tw-p-0 tw-mx-4 tw-mt-4 tw-mb-4 md:tw-w-[calc(50%-32px)] tw-w-[calc(100%-32px)] tw-min-w-80 tw-max-w-3xl !tw-left-0 sm:!tw-left-auto tw-top-0 tw-bottom-0 tw-transition-opacity tw-duration-500 ${!selectPosition ? 'tw-opacity-100 tw-pointer-events-auto' : 'tw-opacity-0 tw-pointer-events-none'}`}
|
|
>
|
|
<>
|
|
<div className={'tw-px-6 tw-pt-6'}>
|
|
<HeaderView
|
|
api={item.layer?.api}
|
|
item={item}
|
|
deleteCallback={(e) => handleDelete(e, item, setLoading, removeItem, map, navigate)}
|
|
editCallback={() => navigate('/edit-item/' + item.id)}
|
|
setPositionCallback={() => {
|
|
map.closePopup()
|
|
setSelectPosition(item)
|
|
navigate('/')
|
|
}}
|
|
big
|
|
truncateSubname={false}
|
|
/>
|
|
</div>
|
|
|
|
{template === 'onepager' && <OnepagerView item={item} />}
|
|
|
|
{template === 'simple' && <SimpleView item={item} />}
|
|
|
|
{template === 'flex' && <FlexView item={item} />}
|
|
|
|
{template === 'tabs' && (
|
|
<TabsView
|
|
attestations={attestations}
|
|
item={item}
|
|
loading={loading}
|
|
offers={offers}
|
|
needs={needs}
|
|
relations={relations}
|
|
updatePermission={updatePermission}
|
|
linkItem={(id) => linkItem(id, item, updateItem)}
|
|
unlinkItem={(id) => unlinkItem(id, item, updateItem)}
|
|
/>
|
|
)}
|
|
</>
|
|
</MapOverlayPage>
|
|
)}
|
|
</>
|
|
)
|
|
}
|