{title}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx
index 8ba9bb63..3f3bf2da 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx
@@ -3,9 +3,10 @@
import { Link } from 'react-router-dom'
import { useGetItemTags } from '#components/Map/hooks/useTags'
-import { Item } from '#src/types'
import { getValue } from '#utils/GetValue'
+import type { Item } from '#types/Item'
+
export const PopupButton = ({
url,
parameterField,
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx
index 64c3eb61..42a1d6ca 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx
@@ -1,4 +1,4 @@
-import { Item } from '#src/types'
+import type { Item } from '#types/Item'
export const PopupCheckboxInput = ({
dataField,
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx
index f46ce126..819182d6 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/prefer-optional-chain */
import { TextInput } from '#components/Input'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
interface StartEndInputProps {
item?: Item
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx
index 6f8fabf2..c07b6b26 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx
@@ -1,5 +1,6 @@
import { TextAreaInput } from '#components/Input'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const PopupTextAreaInput = ({
dataField,
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx
index df72cbed..4030769f 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx
@@ -1,5 +1,6 @@
import { TextInput } from '#components/Input'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const PopupTextInput = ({
dataField,
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
index 4496535f..c41d86f4 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/prefer-optional-chain */
-import { Item } from '#src/types'
+import type { Item } from '#types/Item'
export const StartEndView = ({ item }: { item?: Item }) => {
return (
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx
index 8ba7f09b..59115151 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx
@@ -1,7 +1,5 @@
+/* eslint-disable no-console */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
-/* eslint-disable @typescript-eslint/restrict-template-expressions */
-/* eslint-disable @typescript-eslint/no-unsafe-argument */
-/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/no-unsafe-return */
@@ -13,12 +11,14 @@ import remarkBreaks from 'remark-breaks'
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
import { useTags } from '#components/Map/hooks/useTags'
-import { Item } from '#src/types'
import { decodeTag } from '#utils/FormatTags'
import { getValue } from '#utils/GetValue'
import { hashTagRegex } from '#utils/HashTagRegex'
import { fixUrls, mailRegex } from '#utils/ReplaceURLs'
+import type { Item } from '#types/Item'
+import type { Tag } from '#types/Tag'
+
export const TextView = ({
item,
truncate = false,
@@ -76,47 +76,54 @@ export const TextView = ({
})
}
- // eslint-disable-next-line react/prop-types
const CustomH1 = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomH2 = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomH3 = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomH4 = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomH5 = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomH6 = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomParagraph = ({ children }) =>
{children}
- // eslint-disable-next-line react/prop-types
+
const CustomUnorderdList = ({ children }) => (
)
- // eslint-disable-next-line react/prop-types
+
const CustomOrderdList = ({ children }) => (
{children}
)
- // eslint-disable-next-line react/prop-types
+
const CustomHorizontalRow = ({ children }) =>
{children}
// eslint-disable-next-line react/prop-types
const CustomImage = ({ alt, src, title }) => (

)
- // eslint-disable-next-line react/prop-types
+
const CustomExternalLink = ({ href, children }) => (
{' '}
{children}
)
- /* eslint-disable react/prop-types */
- const CustomHashTagLink = ({ children, tag, item }) => {
+
+ const CustomHashTagLink = ({
+ children,
+ tag,
+ item,
+ }: {
+ children: string
+ tag: Tag
+ item?: Item
+ }) => {
return (
{
e.stopPropagation()
addFilterTag(tag)
@@ -126,7 +133,6 @@ export const TextView = ({
)
}
- /* eslint-enable react/prop-types */
// eslint-disable-next-line react/display-name
const MemoizedVideoEmbed = memo(({ url }: { url: string }) => (
@@ -144,32 +150,34 @@ export const TextView = ({
remarkPlugins={[remarkBreaks]}
components={{
p: CustomParagraph,
- a: ({ href, children }) => {
- // eslint-disable-next-line react/prop-types
+ a: ({ href, children }: { href: string; children: string }) => {
const isYouTubeVideo = href?.startsWith('https://www.youtube.com/watch?v=')
- // eslint-disable-next-line react/prop-types
+
const isRumbleVideo = href?.startsWith('https://rumble.com/embed/')
if (isYouTubeVideo) {
- // eslint-disable-next-line react/prop-types
const videoId = href?.split('v=')[1].split('&')[0]
const youtubeEmbedUrl = `https://www.youtube-nocookie.com/embed/${videoId}`
return
}
if (isRumbleVideo) {
- return
+ return
}
- // eslint-disable-next-line react/prop-types
+
if (href?.startsWith('#')) {
+ console.log(href.slice(1).toLowerCase())
+ console.log(tags)
const tag = tags.find(
(t) => t.name.toLowerCase() === decodeURI(href).slice(1).toLowerCase(),
)
- return (
-
- {children}
-
- )
+ if (tag)
+ return (
+
+ {children}
+
+ )
+ else return children
} else {
return
{children}
}
diff --git a/src/Components/Map/Subcomponents/ItemViewPopup.tsx b/src/Components/Map/Subcomponents/ItemViewPopup.tsx
index f7aedff4..633634e0 100644
--- a/src/Components/Map/Subcomponents/ItemViewPopup.tsx
+++ b/src/Components/Map/Subcomponents/ItemViewPopup.tsx
@@ -15,12 +15,14 @@ import { toast } from 'react-toastify'
import { useRemoveItem, useUpdateItem } from '#components/Map/hooks/useItems'
import { useSetSelectPosition } from '#components/Map/hooks/useSelectPosition'
-import { Item, ItemFormPopupProps } from '#src/types'
import { timeAgo } from '#utils/TimeAgo'
import { HeaderView } from './ItemPopupComponents/HeaderView'
import { TextView } from './ItemPopupComponents/TextView'
+import type { Item } from '#types/Item'
+import type { ItemFormPopupProps } from '#types/ItemFormPopupProps'
+
export interface ItemViewPopupProps {
item: Item
children?: React.ReactNode
@@ -63,6 +65,7 @@ export const ItemViewPopup = forwardRef((props: ItemViewPopupProps, ref: any) =>
props.item.layer?.onlyOnePerOwner &&
(await props.item.layer.api?.updateItem!({ id: props.item.id, position: null }))
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
diff --git a/src/Components/Map/Tags.tsx b/src/Components/Map/Tags.tsx
index c9a9f538..ff77a3ff 100644
--- a/src/Components/Map/Tags.tsx
+++ b/src/Components/Map/Tags.tsx
@@ -1,11 +1,12 @@
import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'
-import { ItemsApi, Tag } from '#src/types'
-
import { useAddFilterTag, useFilterTags, useResetFilterTags } from './hooks/useFilter'
import { useSetTagData, useSetTagApi, useTags } from './hooks/useTags'
+import type { ItemsApi } from '#types/ItemsApi'
+import type { Tag } from '#types/Tag'
+
export function Tags({ data, api }: { data?: Tag[]; api?: ItemsApi
}) {
const setTagData = useSetTagData()
const setTagApi = useSetTagApi()
diff --git a/src/Components/Map/UtopiaMap.tsx b/src/Components/Map/UtopiaMap.tsx
index 0a577e9a..5240d681 100644
--- a/src/Components/Map/UtopiaMap.tsx
+++ b/src/Components/Map/UtopiaMap.tsx
@@ -1,7 +1,9 @@
import { ContextWrapper } from '#components/AppShell/ContextWrapper'
-import { UtopiaMapProps } from '#src/types'
import { UtopiaMapInner } from './UtopiaMapInner'
+
+import type { UtopiaMapProps } from '#types/UtopiaMapProps'
+
// eslint-disable-next-line import/no-unassigned-import
import 'react-toastify/dist/ReactToastify.css'
diff --git a/src/Components/Map/UtopiaMapInner.tsx b/src/Components/Map/UtopiaMapInner.tsx
index deb3fa59..3a8df9ce 100644
--- a/src/Components/Map/UtopiaMapInner.tsx
+++ b/src/Components/Map/UtopiaMapInner.tsx
@@ -23,8 +23,6 @@ import MarkerClusterGroup from 'react-leaflet-cluster'
import { Outlet } from 'react-router-dom'
import { toast } from 'react-toastify'
-import { ItemFormPopupProps, UtopiaMapProps } from '#src/types'
-
// eslint-disable-next-line import/no-unassigned-import
import './UtopiaMap.css'
@@ -46,6 +44,8 @@ import { TagsControl } from './Subcomponents/Controls/TagsControl'
import { TextView } from './Subcomponents/ItemPopupComponents/TextView'
import { SelectPosition } from './Subcomponents/SelectPosition'
+import type { ItemFormPopupProps } from '#types/ItemFormPopupProps'
+import type { UtopiaMapProps } from '#types/UtopiaMapProps'
import type { Feature, Geometry as GeoJSONGeometry } from 'geojson'
const mapDivRef = createRef()
diff --git a/src/Components/Map/hooks/useFilter.tsx b/src/Components/Map/hooks/useFilter.tsx
index 8b21caf1..febc6bfd 100644
--- a/src/Components/Map/hooks/useFilter.tsx
+++ b/src/Components/Map/hooks/useFilter.tsx
@@ -7,11 +7,12 @@
import { useCallback, useReducer, createContext, useContext, useState } from 'react'
import { useNavigate } from 'react-router-dom'
-import { LayerProps, Tag } from '#src/types'
-
import { useLayers } from './useLayers'
import useWindowDimensions from './useWindowDimension'
+import type { LayerProps } from '#types/LayerProps'
+import type { Tag } from '#types/Tag'
+
type ActionType =
| { type: 'ADD_TAG'; tag: Tag }
| { type: 'REMOVE_TAG'; name: string }
diff --git a/src/Components/Map/hooks/useItems.tsx b/src/Components/Map/hooks/useItems.tsx
index 3e67c2c9..db174e77 100644
--- a/src/Components/Map/hooks/useItems.tsx
+++ b/src/Components/Map/hooks/useItems.tsx
@@ -3,17 +3,16 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
-/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-misused-promises */
import { useCallback, useReducer, createContext, useContext, useState } from 'react'
import { toast } from 'react-toastify'
-import { Item, LayerProps } from '#src/types'
-
import { useAddLayer } from './useLayers'
+import type { Item } from '#types/Item'
+import type { LayerProps } from '#types/LayerProps'
+
type ActionType =
| { type: 'ADD'; item: Item }
| { type: 'UPDATE'; item: Item }
@@ -82,13 +81,11 @@ function useItemsManager(initialItems: Item[]): {
},
},
})
- if (result) {
- result.map((item) => {
- dispatch({ type: 'ADD', item: { ...item, layer } })
- return null
- })
- setallItemsLoaded(true)
- }
+ result.map((item) => {
+ dispatch({ type: 'ADD', item: { ...item, layer } })
+ return null
+ })
+ setallItemsLoaded(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
diff --git a/src/Components/Map/hooks/useLayers.tsx b/src/Components/Map/hooks/useLayers.tsx
index 392d535a..477ffc64 100644
--- a/src/Components/Map/hooks/useLayers.tsx
+++ b/src/Components/Map/hooks/useLayers.tsx
@@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import { useCallback, useReducer, createContext, useContext } from 'react'
-import { LayerProps } from '#src/types'
+import type { LayerProps } from '#types/LayerProps'
interface ActionType {
type: 'ADD LAYER'
diff --git a/src/Components/Map/hooks/useLeafletRefs.tsx b/src/Components/Map/hooks/useLeafletRefs.tsx
index 3a728b4e..a092d98e 100644
--- a/src/Components/Map/hooks/useLeafletRefs.tsx
+++ b/src/Components/Map/hooks/useLeafletRefs.tsx
@@ -1,10 +1,10 @@
/* eslint-disable react/prop-types */
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-empty-function */
-import { Marker, Popup } from 'leaflet'
import { useCallback, useReducer, createContext, useContext } from 'react'
-import { Item } from '#src/types'
+import type { Item } from '#types/Item'
+import type { Marker, Popup } from 'leaflet'
interface LeafletRef {
item: Item
diff --git a/src/Components/Map/hooks/usePermissions.tsx b/src/Components/Map/hooks/usePermissions.tsx
index d74021b7..5d149eb3 100644
--- a/src/Components/Map/hooks/usePermissions.tsx
+++ b/src/Components/Map/hooks/usePermissions.tsx
@@ -1,6 +1,5 @@
/* eslint-disable react/prop-types */
/* eslint-disable @typescript-eslint/no-misused-promises */
-/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/prefer-optional-chain */
/* eslint-disable @typescript-eslint/no-unsafe-call */
@@ -10,7 +9,12 @@
import { useCallback, useReducer, createContext, useContext, useState } from 'react'
import { useAuth } from '#components/Auth/useAuth'
-import { Item, ItemsApi, LayerProps, Permission, PermissionAction } from '#src/types'
+
+import type { Item } from '#types/Item'
+import type { ItemsApi } from '#types/ItemsApi'
+import type { LayerProps } from '#types/LayerProps'
+import type { Permission } from '#types/Permission'
+import type { PermissionAction } from '#types/PermissionAction'
type ActionType = { type: 'ADD'; permission: Permission } | { type: 'REMOVE'; id: string }
@@ -57,12 +61,10 @@ function usePermissionsManager(initialPermissions: Permission[]): {
const setPermissionApi = useCallback(async (api: ItemsApi) => {
const result = await api.getItems()
- if (result) {
- result.map((permission) => {
- dispatch({ type: 'ADD', permission })
- return null
- })
- }
+ result.map((permission) => {
+ dispatch({ type: 'ADD', permission })
+ return null
+ })
}, [])
const setPermissionData = useCallback((data: Permission[]) => {
diff --git a/src/Components/Map/hooks/useSelectPosition.tsx b/src/Components/Map/hooks/useSelectPosition.tsx
index 310ce7ad..541e05a4 100644
--- a/src/Components/Map/hooks/useSelectPosition.tsx
+++ b/src/Components/Map/hooks/useSelectPosition.tsx
@@ -8,15 +8,18 @@
/* 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'
+import type { Item } from '#types/Item'
+import type { ItemFormPopupProps } from '#types/ItemFormPopupProps'
+import type { LayerProps } from '#types/LayerProps'
+import type { Point } from 'geojson'
+import type { LatLng } from 'leaflet'
+
interface PolygonClickedProps {
position: LatLng
setItemFormPopup: React.Dispatch>
@@ -67,7 +70,11 @@ function useSelectPositionManager(): {
}
if ('text' in selectPosition) {
const position =
- mapClicked?.position.lng && new Geometry(mapClicked.position.lng, mapClicked.position.lat)
+ mapClicked?.position.lng &&
+ ({
+ type: 'Point',
+ coordinates: [mapClicked.position.lng, mapClicked.position.lat],
+ } as Point)
position && itemUpdatePosition({ ...selectPosition, position })
setSelectPosition(null)
}
@@ -89,6 +96,7 @@ function useSelectPositionManager(): {
position: null,
})
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
@@ -113,6 +121,7 @@ function useSelectPositionManager(): {
position: updatedItem.position,
})
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
@@ -134,6 +143,7 @@ function useSelectPositionManager(): {
try {
await markerClicked.layer?.api?.updateItem!(updatedItem)
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
diff --git a/src/Components/Map/hooks/useTags.tsx b/src/Components/Map/hooks/useTags.tsx
index 83e3a373..f80e96ad 100644
--- a/src/Components/Map/hooks/useTags.tsx
+++ b/src/Components/Map/hooks/useTags.tsx
@@ -1,6 +1,5 @@
/* eslint-disable react/prop-types */
/* eslint-disable @typescript-eslint/no-misused-promises */
-/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/prefer-optional-chain */
@@ -11,10 +10,13 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { useCallback, useReducer, createContext, useContext, useState } from 'react'
-import { Item, ItemsApi, Tag } from '#src/types'
import { getValue } from '#utils/GetValue'
import { hashTagRegex } from '#utils/HashTagRegex'
+import type { Item } from '#types/Item'
+import type { ItemsApi } from '#types/ItemsApi'
+import type { Tag } from '#types/Tag'
+
type ActionType = { type: 'ADD'; tag: Tag } | { type: 'REMOVE'; id: string }
type UseTagManagerResult = ReturnType
diff --git a/src/Components/Profile/ProfileForm.tsx b/src/Components/Profile/ProfileForm.tsx
index d57c8f0c..c5339657 100644
--- a/src/Components/Profile/ProfileForm.tsx
+++ b/src/Components/Profile/ProfileForm.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/no-misused-promises */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
@@ -15,7 +14,6 @@ import { useLayers } from '#components/Map/hooks/useLayers'
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
import { useAddTag, useGetItemTags, useTags } from '#components/Map/hooks/useTags'
import { MapOverlayPage } from '#components/Templates'
-import { Item, Tag } from '#src/types'
import { getValue } from '#utils/GetValue'
import { linkItem, onUpdateItem, unlinkItem } from './itemFunctions'
@@ -25,6 +23,9 @@ import { OnepagerForm } from './Templates/OnepagerForm'
import { SimpleForm } from './Templates/SimpleForm'
import { TabsForm } from './Templates/TabsForm'
+import type { Item } from '#types/Item'
+import type { Tag } from '#types/Tag'
+
export function ProfileForm() {
const [state, setState] = useState({
color: '',
@@ -78,7 +79,7 @@ export function ProfileForm() {
const layer = layers.find((l) => l.itemType.name === appState.userType)
setItem({
id: crypto.randomUUID(),
- name: user ? user.first_name : '',
+ name: user?.first_name ?? '',
text: '',
layer,
new: true,
@@ -148,58 +149,64 @@ export function ProfileForm() {
backdrop
className='tw-mx-4 tw-mt-4 tw-mb-4 tw-overflow-x-hidden tw-w-[calc(100%-32px)] md:tw-w-[calc(50%-32px)] tw-max-w-3xl !tw-left-auto tw-top-0 tw-bottom-0'
>
-
-
+
>
)
diff --git a/src/Components/Profile/ProfileView.tsx b/src/Components/Profile/ProfileView.tsx
index 2414075c..76c42aec 100644
--- a/src/Components/Profile/ProfileView.tsx
+++ b/src/Components/Profile/ProfileView.tsx
@@ -21,7 +21,6 @@ import { useSelectPosition, useSetSelectPosition } from '#components/Map/hooks/u
import { useTags } from '#components/Map/hooks/useTags'
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
import { MapOverlayPage } from '#components/Templates'
-import { Item, ItemsApi, Tag } from '#src/types'
import { getValue } from '#utils/GetValue'
import { handleDelete, linkItem, unlinkItem } from './itemFunctions'
@@ -30,6 +29,10 @@ 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'
+
export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi
}) {
const [item, setItem] = useState- ()
const [updatePermission, setUpdatePermission] = useState(false)
@@ -64,7 +67,9 @@ export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi
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)
diff --git a/src/Components/Profile/Subcomponents/ActionsButton.tsx b/src/Components/Profile/Subcomponents/ActionsButton.tsx
index 4b62d2d3..7eea5e44 100644
--- a/src/Components/Profile/Subcomponents/ActionsButton.tsx
+++ b/src/Components/Profile/Subcomponents/ActionsButton.tsx
@@ -10,9 +10,10 @@ import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
import { useGetItemTags } from '#components/Map/hooks/useTags'
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
import DialogModal from '#components/Templates/DialogModal'
-import { Item } from '#src/types'
import { getValue } from '#utils/GetValue'
+import type { Item } from '#types/Item'
+
export function ActionButton({
item,
triggerAddButton,
diff --git a/src/Components/Profile/Subcomponents/AvatarWidget.tsx b/src/Components/Profile/Subcomponents/AvatarWidget.tsx
index 237c1256..ab4be26d 100644
--- a/src/Components/Profile/Subcomponents/AvatarWidget.tsx
+++ b/src/Components/Profile/Subcomponents/AvatarWidget.tsx
@@ -1,8 +1,6 @@
/* eslint-disable react/prop-types */
/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/prefer-optional-chain */
import { useState, useCallback, useRef } from 'react'
import { ReactCrop, centerCrop, makeAspectCrop } from 'react-image-crop'
diff --git a/src/Components/Profile/Subcomponents/ContactInfoForm.tsx b/src/Components/Profile/Subcomponents/ContactInfoForm.tsx
index 9a87fc6a..7f129d01 100644
--- a/src/Components/Profile/Subcomponents/ContactInfoForm.tsx
+++ b/src/Components/Profile/Subcomponents/ContactInfoForm.tsx
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { TextInput } from '#components/Input'
-import { FormState } from '#src/types'
+
+import type { FormState } from '#types/FormState'
export const ContactInfoForm = ({
state,
@@ -22,6 +23,7 @@ export const ContactInfoForm = ({
setState((prevState) => ({
@@ -41,6 +43,9 @@ export const ContactInfoForm = ({
setState((prevState) => ({
diff --git a/src/Components/Profile/Subcomponents/ContactInfoView.tsx b/src/Components/Profile/Subcomponents/ContactInfoView.tsx
index 80bc5f93..a8368d24 100644
--- a/src/Components/Profile/Subcomponents/ContactInfoView.tsx
+++ b/src/Components/Profile/Subcomponents/ContactInfoView.tsx
@@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/restrict-plus-operands */
import { useEffect, useState } from 'react'
@@ -8,7 +7,8 @@ import { Link } from 'react-router-dom'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import { useItems } from '#components/Map/hooks/useItems'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const ContactInfoView = ({ item, heading }: { item: Item; heading: string }) => {
const appState = useAppState()
diff --git a/src/Components/Profile/Subcomponents/FormHeader.tsx b/src/Components/Profile/Subcomponents/FormHeader.tsx
index a20a778f..357ad7a4 100644
--- a/src/Components/Profile/Subcomponents/FormHeader.tsx
+++ b/src/Components/Profile/Subcomponents/FormHeader.tsx
@@ -44,6 +44,7 @@ export const FormHeader = ({ item, state, setState }) => {
/>
setState((prevState) => ({
diff --git a/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx b/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx
index 98196e27..7718b075 100644
--- a/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx
+++ b/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx
@@ -1,7 +1,7 @@
-import { Item } from '#src/types'
-
import SocialShareBar from './SocialShareBar'
+import type { Item } from '#types/Item'
+
export const GroupSubHeaderView = ({
item,
shareBaseUrl,
diff --git a/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx b/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx
index cd4084dd..55b8c58f 100644
--- a/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx
+++ b/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx
@@ -4,7 +4,9 @@
import { useEffect } from 'react'
import ComboBoxInput from '#components/Input/ComboBoxInput'
-import { Item, FormState } from '#src/types'
+
+import type { FormState } from '#types/FormState'
+import type { Item } from '#types/Item'
interface groupType {
groupTypes_id: {
@@ -30,13 +32,16 @@ export const GroupSubheaderForm = ({
useEffect(() => {
if (groupTypes && groupStates) {
const groupType = groupTypes.find((gt) => gt.groupTypes_id.name === state.group_type)
- // eslint-disable-next-line no-console
- console.log(state.group_type)
+ const customImage = !groupTypes.some(
+ (gt) => gt.groupTypes_id.image === state.image || !state.image,
+ )
setState((prevState) => ({
...prevState,
color: groupType?.groupTypes_id.color || groupTypes[0].groupTypes_id.color,
marker_icon: groupType?.groupTypes_id.markerIcon || groupTypes[0].groupTypes_id.markerIcon,
- image: groupType?.groupTypes_id.image || groupTypes[0].groupTypes_id.image,
+ image: customImage
+ ? state.image
+ : groupType?.groupTypes_id.image || groupTypes[0].groupTypes_id.image,
status: state.status || groupStates[0],
group_type: state.group_type || groupTypes[0].groupTypes_id.name,
}))
diff --git a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
index 48d1d72a..57dd0ce9 100644
--- a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
+++ b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
@@ -8,9 +8,10 @@
import { useEffect } from 'react'
import { useAppState } from '#components/AppShell/hooks/useAppState'
-import { Item } from '#src/types'
import { getValue } from '#utils/GetValue'
+import type { Item } from '#types/Item'
+
export function LinkedItemsHeaderView({
item,
unlinkCallback,
diff --git a/src/Components/Profile/Subcomponents/MarkdownHint.tsx b/src/Components/Profile/Subcomponents/MarkdownHint.tsx
new file mode 100644
index 00000000..1b79bbc3
--- /dev/null
+++ b/src/Components/Profile/Subcomponents/MarkdownHint.tsx
@@ -0,0 +1,34 @@
+import { useState } from 'react'
+
+export const MarkdownHint = () => {
+ const [expended, setExpended] = useState(false)
+ return (
+
setExpended(true)}
+ title='Markdown is supported'
+ className='flex tw-flex-row tw-text-gray-400 tw-cursor-pointer tw-items-center'
+ >
+
+ {expended && (
+
+ Markdown is support{' '}
+
+ )}
+
+ )
+}
diff --git a/src/Components/Profile/Subcomponents/PlusButton.tsx b/src/Components/Profile/Subcomponents/PlusButton.tsx
index 9faba0db..c8122d95 100644
--- a/src/Components/Profile/Subcomponents/PlusButton.tsx
+++ b/src/Components/Profile/Subcomponents/PlusButton.tsx
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
-import { LayerProps } from '#src/types'
+
+import type { LayerProps } from '#types/LayerProps'
export function PlusButton({
layer,
diff --git a/src/Components/Profile/Subcomponents/ProfileStartEndForm.tsx b/src/Components/Profile/Subcomponents/ProfileStartEndForm.tsx
index 5657ac6c..e5f67ffe 100644
--- a/src/Components/Profile/Subcomponents/ProfileStartEndForm.tsx
+++ b/src/Components/Profile/Subcomponents/ProfileStartEndForm.tsx
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { PopupStartEndInput } from '#components/Map'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const ProfileStartEndForm = ({
item,
diff --git a/src/Components/Profile/Subcomponents/ProfileStartEndView.tsx b/src/Components/Profile/Subcomponents/ProfileStartEndView.tsx
index f166523d..8d64e55d 100644
--- a/src/Components/Profile/Subcomponents/ProfileStartEndView.tsx
+++ b/src/Components/Profile/Subcomponents/ProfileStartEndView.tsx
@@ -1,5 +1,6 @@
import { StartEndView } from '#components/Map'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const ProfileStartEndView = ({ item }: { item: Item }) => {
return (
diff --git a/src/Components/Profile/Subcomponents/ProfileTextForm.tsx b/src/Components/Profile/Subcomponents/ProfileTextForm.tsx
index ccac9c44..1d72a3b3 100644
--- a/src/Components/Profile/Subcomponents/ProfileTextForm.tsx
+++ b/src/Components/Profile/Subcomponents/ProfileTextForm.tsx
@@ -5,9 +5,12 @@
import { useEffect, useState } from 'react'
import { TextAreaInput } from '#components/Input'
-import { FormState } from '#src/types'
import { getValue } from '#utils/GetValue'
+import { MarkdownHint } from './MarkdownHint'
+
+import type { FormState } from '#types/FormState'
+
export const ProfileTextForm = ({
state,
setState,
@@ -15,6 +18,7 @@ export const ProfileTextForm = ({
heading,
size,
hideInputLabel,
+ required,
}: {
state: FormState
setState: React.Dispatch>
@@ -22,6 +26,7 @@ export const ProfileTextForm = ({
heading: string
size: string
hideInputLabel: boolean
+ required?: boolean
}) => {
const [field, setField] = useState(dataField || 'text')
@@ -33,12 +38,15 @@ export const ProfileTextForm = ({
return (
-
+
+
+
+
)
diff --git a/src/Components/Profile/Subcomponents/ProfileTextView.tsx b/src/Components/Profile/Subcomponents/ProfileTextView.tsx
index e36f04db..8a2725ce 100644
--- a/src/Components/Profile/Subcomponents/ProfileTextView.tsx
+++ b/src/Components/Profile/Subcomponents/ProfileTextView.tsx
@@ -1,8 +1,9 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { TextView } from '#components/Map'
-import { Item } from '#src/types'
import { getValue } from '#utils/GetValue'
+import type { Item } from '#types/Item'
+
export const ProfileTextView = ({
item,
dataField,
diff --git a/src/Components/Profile/Subcomponents/SocialShareBar.tsx b/src/Components/Profile/Subcomponents/SocialShareBar.tsx
index 13b94910..150fde40 100644
--- a/src/Components/Profile/Subcomponents/SocialShareBar.tsx
+++ b/src/Components/Profile/Subcomponents/SocialShareBar.tsx
@@ -16,7 +16,9 @@ const SocialShareBar = ({
.writeText(url)
.then(() => {
toast.success('link copied to clipboard')
+ return null
})
+ // eslint-disable-next-line promise/prefer-await-to-callbacks
.catch((error: never) => {
toast.error('Fehler beim Kopieren des Links: ', error)
})
diff --git a/src/Components/Profile/Subcomponents/SocialShareButton.tsx b/src/Components/Profile/Subcomponents/SocialShareButton.tsx
index 04809fcf..64f0858a 100644
--- a/src/Components/Profile/Subcomponents/SocialShareButton.tsx
+++ b/src/Components/Profile/Subcomponents/SocialShareButton.tsx
@@ -84,6 +84,7 @@ const SocialShareButton = ({
url: string
title: string
}) => {
+ // eslint-disable-next-line security/detect-object-injection
const config = platformConfigs[platform]
if (!config) {
diff --git a/src/Components/Profile/Subcomponents/TagsWidget.tsx b/src/Components/Profile/Subcomponents/TagsWidget.tsx
index 3a5709ab..b1a03ad1 100644
--- a/src/Components/Profile/Subcomponents/TagsWidget.tsx
+++ b/src/Components/Profile/Subcomponents/TagsWidget.tsx
@@ -8,10 +8,11 @@ import { useEffect, useState } from 'react'
import { Autocomplete } from '#components/Input/Autocomplete'
import { useTags } from '#components/Map/hooks/useTags'
-import { Tag } from '#src/types'
import { decodeTag, encodeTag } from '#utils/FormatTags'
import { randomColor } from '#utils/RandomColor'
+import type { Tag } from '#types/Tag'
+
// eslint-disable-next-line react/prop-types
export const TagsWidget = ({ placeholder, containerStyle, defaultTags, onUpdate }) => {
const [input, setInput] = useState('')
diff --git a/src/Components/Profile/Templates/FlexForm.tsx b/src/Components/Profile/Templates/FlexForm.tsx
index c7a8d5f4..56f14eac 100644
--- a/src/Components/Profile/Templates/FlexForm.tsx
+++ b/src/Components/Profile/Templates/FlexForm.tsx
@@ -7,7 +7,9 @@ import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoFo
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
import { ProfileStartEndForm } from '#components/Profile/Subcomponents/ProfileStartEndForm'
import { ProfileTextForm } from '#components/Profile/Subcomponents/ProfileTextForm'
-import { Item, FormState } from '#src/types'
+
+import type { FormState } from '#types/FormState'
+import type { Item } from '#types/Item'
const componentMap = {
groupSubheaders: GroupSubheaderForm,
diff --git a/src/Components/Profile/Templates/FlexView.tsx b/src/Components/Profile/Templates/FlexView.tsx
index 0fb741e9..1dea72d6 100644
--- a/src/Components/Profile/Templates/FlexView.tsx
+++ b/src/Components/Profile/Templates/FlexView.tsx
@@ -6,7 +6,8 @@ import { ContactInfoView } from '#components/Profile/Subcomponents/ContactInfoVi
import { GroupSubHeaderView } from '#components/Profile/Subcomponents/GroupSubHeaderView'
import { ProfileStartEndView } from '#components/Profile/Subcomponents/ProfileStartEndView'
import { ProfileTextView } from '#components/Profile/Subcomponents/ProfileTextView'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
const componentMap = {
groupSubheaders: GroupSubHeaderView,
diff --git a/src/Components/Profile/Templates/OnepagerForm.tsx b/src/Components/Profile/Templates/OnepagerForm.tsx
index db7d4f3f..163cae4e 100644
--- a/src/Components/Profile/Templates/OnepagerForm.tsx
+++ b/src/Components/Profile/Templates/OnepagerForm.tsx
@@ -3,7 +3,9 @@
import { TextAreaInput } from '#components/Input'
import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoForm'
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
-import { FormState, Item } from '#src/types'
+
+import type { FormState } from '#types/FormState'
+import type { Item } from '#types/Item'
export const OnepagerForm = ({
item,
diff --git a/src/Components/Profile/Templates/OnepagerView.tsx b/src/Components/Profile/Templates/OnepagerView.tsx
index b5e93280..32a786ee 100644
--- a/src/Components/Profile/Templates/OnepagerView.tsx
+++ b/src/Components/Profile/Templates/OnepagerView.tsx
@@ -1,10 +1,10 @@
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { TextView } from '#components/Map'
import { ContactInfoView } from '#components/Profile/Subcomponents/ContactInfoView'
import { GroupSubHeaderView } from '#components/Profile/Subcomponents/GroupSubHeaderView'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const OnepagerView = ({ item }: { item: Item }) => {
return (
@@ -13,7 +13,7 @@ export const OnepagerView = ({ item }: { item: Item }) => {
item={item}
shareBaseUrl={`https://www.wuerdekompass.org/aktivitaeten/gruppensuche/#/gruppe/${item.slug}`}
/>
- {item.user_created.first_name && }
+ {item.user_created?.first_name && }
{/* Description Section */}
diff --git a/src/Components/Profile/Templates/SimpleView.tsx b/src/Components/Profile/Templates/SimpleView.tsx
index 027ed7c4..dca6d079 100644
--- a/src/Components/Profile/Templates/SimpleView.tsx
+++ b/src/Components/Profile/Templates/SimpleView.tsx
@@ -1,5 +1,6 @@
import { TextView } from '#components/Map'
-import { Item } from '#src/types'
+
+import type { Item } from '#types/Item'
export const SimpleView = ({ item }: { item: Item }) => {
return (
diff --git a/src/Components/Profile/Templates/TabsView.tsx b/src/Components/Profile/Templates/TabsView.tsx
index 2b046f7b..d23d0c7b 100644
--- a/src/Components/Profile/Templates/TabsView.tsx
+++ b/src/Components/Profile/Templates/TabsView.tsx
@@ -16,9 +16,11 @@ import { useItems } from '#components/Map/hooks/useItems'
import { ActionButton } from '#components/Profile/Subcomponents/ActionsButton'
import { LinkedItemsHeaderView } from '#components/Profile/Subcomponents/LinkedItemsHeaderView'
import { TagView } from '#components/Templates/TagView'
-import { Item, Tag } from '#src/types'
import { timeAgo } from '#utils/TimeAgo'
+import type { Item } from '#types/Item'
+import type { Tag } from '#types/Tag'
+
export const TabsView = ({
attestations,
item,
@@ -50,7 +52,7 @@ export const TabsView = ({
const appState = useAppState()
const getUserProfile = (id: string) => {
return items.find(
- (i) => i.user_created.id === id && i.layer?.itemType.name === appState.userType,
+ (i) => i.user_created?.id === id && i.layer?.itemType.name === appState.userType,
)
}
@@ -130,7 +132,7 @@ export const TabsView = ({
{attestations
- .filter((a) => a.to.some((t) => t.directus_users_id === item.user_created.id))
+ .filter((a) => a.to.some((t) => t.directus_users_id === item.user_created?.id))
.sort(
(a, b) =>
new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),
diff --git a/src/Components/Profile/UserSettings.tsx b/src/Components/Profile/UserSettings.tsx
index 88d644e7..9f602f63 100644
--- a/src/Components/Profile/UserSettings.tsx
+++ b/src/Components/Profile/UserSettings.tsx
@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
-/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
@@ -8,7 +7,8 @@ import { toast } from 'react-toastify'
import { useAuth } from '#components/Auth'
import { TextInput } from '#components/Input'
import { MapOverlayPage } from '#components/Templates'
-import { UserItem } from '#src/types'
+
+import type { UserItem } from '#types/UserItem'
export function UserSettings() {
const { user, updateUser, loading /* token */ } = useAuth()
@@ -43,6 +43,9 @@ export function UserSettings() {
},
})
.then(() => navigate('/'))
+ .catch((e) => {
+ throw e
+ })
}
return (
diff --git a/src/Components/Profile/itemFunctions.ts b/src/Components/Profile/itemFunctions.ts
index 3ad3d1d5..ad11c536 100644
--- a/src/Components/Profile/itemFunctions.ts
+++ b/src/Components/Profile/itemFunctions.ts
@@ -11,11 +11,13 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { toast } from 'react-toastify'
-import { Item } from '#src/types'
import { encodeTag } from '#utils/FormatTags'
import { hashTagRegex } from '#utils/HashTagRegex'
import { randomColor } from '#utils/RandomColor'
+import type { Item } from '#types/Item'
+
+// eslint-disable-next-line promise/avoid-new
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
export const submitNewItem = async (
@@ -62,6 +64,7 @@ export const submitNewItem = async (
await layer?.api?.createItem!({ ...formItem, id: uuid, type, parent: item.id })
await linkItem(uuid)
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
@@ -83,6 +86,7 @@ export const linkItem = async (id: string, item, updateItem) => {
try {
await item?.layer?.api?.updateItem!(updatedItem)
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
@@ -100,6 +104,7 @@ export const unlinkItem = async (id: string, item, updateItem) => {
try {
await item?.layer?.api?.updateItem!(updatedItem)
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
@@ -123,6 +128,7 @@ export const handleDelete = async (
try {
await item.layer?.api?.deleteItem!(item.id)
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
@@ -243,6 +249,7 @@ export const onUpdateItem = async (
.then(() => {
setLoading(false)
navigate(`/item/${item.id}${params && '?' + params}`)
+ return null
})
} else {
item.new = false
@@ -272,6 +279,7 @@ export const onUpdateItem = async (
.then(() => {
setLoading(false)
navigate(`/${params && '?' + params}`)
+ return null
})
}
}
diff --git a/src/Components/Templates/AttestationForm.tsx b/src/Components/Templates/AttestationForm.tsx
index c7c30e5c..a9b84086 100644
--- a/src/Components/Templates/AttestationForm.tsx
+++ b/src/Components/Templates/AttestationForm.tsx
@@ -1,15 +1,16 @@
-/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { useRef, useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import { useItems } from '#components/Map/hooks/useItems'
-import { Item, ItemsApi } from '#src/types'
import { EmojiPicker } from './EmojiPicker'
import { MapOverlayPage } from './MapOverlayPage'
+import type { Item } from '#types/Item'
+import type { ItemsApi } from '#types/ItemsApi'
+
export const AttestationForm = ({ api }: { api?: ItemsApi }) => {
const items = useItems()
const appState = useAppState()
@@ -39,7 +40,7 @@ export const AttestationForm = ({ api }: { api?: ItemsApi }) => {
const sendAttestation = async () => {
const to: any[] = []
- users?.map((u) => to.push({ directus_users_id: u.user_created.id }))
+ users?.map((u) => to.push({ directus_users_id: u.user_created?.id }))
api?.createItem &&
toast
@@ -66,7 +67,7 @@ export const AttestationForm = ({ api }: { api?: ItemsApi }) => {
'/item/' +
items.find(
(i) =>
- i.user_created.id === to[0].directus_users_id &&
+ i.user_created?.id === to[0].directus_users_id &&
i.layer?.itemType.name === 'player',
)?.id +
'?tab=2',
diff --git a/src/Components/Templates/CircleLayout.tsx b/src/Components/Templates/CircleLayout.tsx
index f36b8681..67e64ff1 100644
--- a/src/Components/Templates/CircleLayout.tsx
+++ b/src/Components/Templates/CircleLayout.tsx
@@ -25,6 +25,7 @@ export const CircleLayout = ({
const angle = startAngle + (i / itemCount) * (2 * Math.PI)
const x = radius * Math.cos(angle)
const y = radius * Math.sin(angle)
+ // eslint-disable-next-line security/detect-object-injection
const child = container.children[i] as HTMLElement
child.style.transform = `translate(${x}px, ${y}px)`
}
diff --git a/src/Components/Templates/DateUserInfo.tsx b/src/Components/Templates/DateUserInfo.tsx
index a25e623e..4243a9c0 100644
--- a/src/Components/Templates/DateUserInfo.tsx
+++ b/src/Components/Templates/DateUserInfo.tsx
@@ -1,13 +1,12 @@
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
-/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/prefer-optional-chain */
import { useState } from 'react'
-import { Item } from '#src/types'
import { timeAgo } from '#utils/TimeAgo'
+import type { Item } from '#types/Item'
+
export const DateUserInfo = ({ item }: { item: Item }) => {
const [infoExpanded, setInfoExpanded] = useState(false)
return (
diff --git a/src/Components/Templates/DialogModal.tsx b/src/Components/Templates/DialogModal.tsx
index 3fa4da0e..f207be3e 100644
--- a/src/Components/Templates/DialogModal.tsx
+++ b/src/Components/Templates/DialogModal.tsx
@@ -1,4 +1,6 @@
-import { MouseEvent, useEffect, useRef } from 'react'
+import { useEffect, useRef } from 'react'
+
+import type { MouseEvent } from 'react'
const isClickInsideRectangle = (e: MouseEvent, element: HTMLElement) => {
const r = element.getBoundingClientRect()
diff --git a/src/Components/Templates/ItemCard.tsx b/src/Components/Templates/ItemCard.tsx
index 2c2d9251..585d18ae 100644
--- a/src/Components/Templates/ItemCard.tsx
+++ b/src/Components/Templates/ItemCard.tsx
@@ -9,11 +9,12 @@ import { useNavigate } from 'react-router-dom'
import { StartEndView, TextView } from '#components/Map'
import useWindowDimensions from '#components/Map/hooks/useWindowDimension'
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
-import { Item } from '#src/types'
import { getValue } from '#utils/GetValue'
import { DateUserInfo } from './DateUserInfo'
+import type { Item } from '#types/Item'
+
export const ItemCard = ({
i,
loading,
diff --git a/src/Components/Templates/MarketView.tsx b/src/Components/Templates/MarketView.tsx
index 6009e683..18822755 100644
--- a/src/Components/Templates/MarketView.tsx
+++ b/src/Components/Templates/MarketView.tsx
@@ -8,12 +8,13 @@ import { useNavigate } from 'react-router-dom'
import { useItems } from '#components/Map/hooks/useItems'
import { useTags } from '#components/Map/hooks/useTags'
-import { Tag } from '#src/types'
import { getValue } from '#utils/GetValue'
import { MapOverlayPage } from './MapOverlayPage'
import { TagView } from './TagView'
+import type { Tag } from '#types/Tag'
+
function groupAndCount(arr) {
const grouped = arr.reduce((acc, obj) => {
const found = acc.find((item) => JSON.stringify(item.object) === JSON.stringify(obj))
diff --git a/src/Components/Templates/OverlayItemsIndexPage.tsx b/src/Components/Templates/OverlayItemsIndexPage.tsx
index 291abbd4..3388cddc 100644
--- a/src/Components/Templates/OverlayItemsIndexPage.tsx
+++ b/src/Components/Templates/OverlayItemsIndexPage.tsx
@@ -19,13 +19,14 @@ import { Control } from '#components/Map/Subcomponents/Controls/Control'
import { SearchControl } from '#components/Map/Subcomponents/Controls/SearchControl'
import { TagsControl } from '#components/Map/Subcomponents/Controls/TagsControl'
import { PlusButton } from '#components/Profile/Subcomponents/PlusButton'
-import { Item } from '#src/types'
import { hashTagRegex } from '#utils/HashTagRegex'
import { randomColor } from '#utils/RandomColor'
import { ItemCard } from './ItemCard'
import { MapOverlayPage } from './MapOverlayPage'
+import type { Item } from '#types/Item'
+
export const OverlayItemsIndexPage = ({
url,
layerName,
@@ -91,13 +92,14 @@ export const OverlayItemsIndexPage = ({
try {
await layer?.api?.createItem!({ ...formItem, id: uuid })
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
if (success) {
toast.success('New item created')
}
- addItem({ ...formItem, user_created: user, id: uuid, layer, public_edit: !user })
+ addItem({ ...formItem, user_created: user ?? undefined, id: uuid, layer, public_edit: !user })
setLoading(false)
setAddItemPopupType('')
}
@@ -108,6 +110,7 @@ export const OverlayItemsIndexPage = ({
try {
await layer?.api?.deleteItem!(item.id)
success = true
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
toast.error(error.toString())
}
diff --git a/src/Components/Templates/TagView.tsx b/src/Components/Templates/TagView.tsx
index 13c184a5..f19c5adc 100644
--- a/src/Components/Templates/TagView.tsx
+++ b/src/Components/Templates/TagView.tsx
@@ -1,8 +1,9 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */
-import { Tag } from '#src/types'
import { decodeTag } from '#utils/FormatTags'
+import type { Tag } from '#types/Tag'
+
export const TagView = ({
tag,
heighlight,
diff --git a/src/Utils/GetValue.ts b/src/Utils/GetValue.ts
index c2d73ed3..ff159599 100644
--- a/src/Utils/GetValue.ts
+++ b/src/Utils/GetValue.ts
@@ -7,6 +7,7 @@ export function getValue(obj, path) {
const pathArray = path.split('.') // Use a different variable for the split path
for (let i = 0, len = pathArray.length; i < len; i++) {
if (!obj) return undefined // Check if obj is falsy at each step
+ // eslint-disable-next-line security/detect-object-injection
obj = obj[pathArray[i]] // Dive one level deeper
}
return obj // Return the final value
diff --git a/src/Utils/MarkerIconFactory.ts b/src/Utils/MarkerIconFactory.ts
index eb3614eb..6de46870 100644
--- a/src/Utils/MarkerIconFactory.ts
+++ b/src/Utils/MarkerIconFactory.ts
@@ -25,6 +25,7 @@ const createSvg = (shape: string, markerColor: string, borderColor: string) => {
markerColor +
'" />',
}
+ // eslint-disable-next-line security/detect-object-injection
return svgMap[shape]
}
diff --git a/src/Utils/ReplaceURLs.ts b/src/Utils/ReplaceURLs.ts
index 8c45acd1..25981922 100644
--- a/src/Utils/ReplaceURLs.ts
+++ b/src/Utils/ReplaceURLs.ts
@@ -1,5 +1,5 @@
export const urlRegex =
- // eslint-disable-next-line no-useless-escape
+ // eslint-disable-next-line no-useless-escape, security/detect-unsafe-regex
/(^| )(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,10}(:[0-9]{1,10})?(\/.*)?$/gm
export const mailRegex = /(?
// Formatiere die Adresse
const formattedAddress = `${street} ${houseNumber}, ${city}`.trim()
return formattedAddress || ''
+ // eslint-disable-next-line no-catch-all/no-catch-all
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error:', error)
diff --git a/src/index.tsx b/src/index.tsx
index 6008084d..8592a9ee 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -41,7 +41,8 @@ export { TextInput, TextAreaInput, SelectBox } from './Components/Input'
declare global {
interface Window {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- my_modal_3: any
+ my_modal_3: {
+ showModal(): void
+ }
}
}
diff --git a/src/types.ts b/src/types.ts
deleted file mode 100644
index 4b964237..00000000
--- a/src/types.ts
+++ /dev/null
@@ -1,207 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import { LatLng } from 'leaflet'
-
-export interface Tag {
- color: string
- id: string
- name: string
- offer_or_need?: boolean
-}
-
-export interface UtopiaMapProps {
- height?: string
- width?: string
- center?: [number, number]
- zoom?: number
- tags?: Tag[]
- children?: React.ReactNode
- geo?: any
- showFilterControl?: boolean
- showLayerControl?: boolean
- showGratitudeControl?: boolean
- infoText?: string
-}
-
-export interface ItemType {
- name: string
- [key: string]: any
-}
-
-export interface ItemsApi {
- getItems(): Promise
- getItem?(id: string): Promise
- createItem?(item: T): Promise
- updateItem?(item: T): Promise
- deleteItem?(id: string): Promise
- collectionName?: string
-}
-
-export interface LayerProps {
- id?: string
- // eslint-disable-next-line no-use-before-define
- data?: Item[]
- children?: React.ReactNode
- name: string
- menuIcon: any
- menuColor: string
- menuText: string
- markerIcon: string
- markerShape: string
- markerDefaultColor: string
- markerDefaultColor2?: string
- api?: ItemsApi
- itemType: ItemType
- itemNameField?: string
- itemSubnameField?: string
- itemTextField?: string
- itemAvatarField?: string
- itemColorField?: string
- itemOwnerField?: string
- itemTagsField?: string
- itemLatitudeField?: any
- itemLongitudeField?: any
- itemOffersField?: string
- itemNeedsField?: string
- onlyOnePerOwner?: boolean
- customEditLink?: string
- customEditParameter?: string
- public_edit_items?: boolean
- listed?: boolean
- item_presets?: Record
- // eslint-disable-next-line no-use-before-define
- setItemFormPopup?: React.Dispatch>
- // eslint-disable-next-line no-use-before-define
- itemFormPopup?: ItemFormPopupProps | null
- clusterRef?: any
-}
-
-export class Geometry {
- type: string
- coordinates: number[]
- constructor(lng: number, lat: number) {
- this.coordinates = [lng, lat]
- this.type = 'Point'
- }
-}
-
-export interface Relation {
- related_items_id: string
- [key: string]: any
-}
-
-export class Item {
- id: string
- name: string
- text: string
- position?: Geometry
- date_created?: string
- date_updated?: string | null
- start?: string
- end?: string
- api?: ItemsApi
- tags?: string[]
- layer?: LayerProps
- relations?: Relation[]
- parent?: string
- subname?: string
- public_edit?: boolean
- slug?: string;
- [key: string]: any
- constructor(
- id: string,
- name: string,
- text: string,
- position: Geometry,
- layer?: LayerProps,
- api?: ItemsApi,
- ) {
- this.id = id
- this.name = name
- this.text = text
- this.position = position
- this.layer = layer
- this.api = api
- }
-}
-
-export interface AssetsApi {
- upload(file: Blob, title: string): any
- url: string
-}
-
-export interface Profile {
- id?: string
- avatar?: string
- color?: string
- name: string
- text: string
- geoposition?: Geometry
-}
-
-export interface UserItem {
- id?: string
- role?: any
- email?: string
- password?: string
- profile?: Profile
- [key: string]: any
-}
-
-export interface UserApi {
- register(email: string, password: string, userName: string): Promise
- login(email: string, password: string): Promise
- logout(): Promise
- getUser(): Promise
- getToken(): Promise
- updateUser(user: UserItem): Promise
- requestPasswordReset(email: string, reset_url?: string)
- passwordReset(token: string, new_password: string)
-}
-
-export interface PermissionCondition {
- user_created?: {
- _eq: string // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID
- }
- public_edit?: {
- _eq: boolean // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID
- }
-}
-
-export type PermissionAction = 'create' | 'read' | 'update' | 'delete'
-
-export interface Permission {
- id?: string
- policy: any
- collection: string
- action: PermissionAction
- permissions?: {
- // Optional, für spezifische Bedingungen wie `user_created`
- _and: PermissionCondition[]
- }
-}
-
-export interface ItemFormPopupProps {
- position: LatLng
- layer: LayerProps
- item?: Item
- children?: React.ReactNode
- setItemFormPopup?: React.Dispatch>
-}
-
-export interface FormState {
- color: string
- id: string
- group_type: string
- status: string
- name: string
- subname: string
- text: string
- contact: string
- telephone: string
- next_appointment: string
- image: string
- marker_icon: string
- offers: Tag[]
- needs: Tag[]
- relations: Item[]
-}
diff --git a/tsconfig.json b/tsconfig.json
index 1fcb7ebb..efc1cda9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,6 +20,7 @@
"#components/*": ["./src/Components/*"],
"#utils/*": ["./src/Utils/*"],
"#src/*": ["./src/*"],
+ "#types/*": ["./types/*"],
"#root/*": ["./*"]
}
},
diff --git a/types/AssetsApi.d.ts b/types/AssetsApi.d.ts
new file mode 100644
index 00000000..f2005016
--- /dev/null
+++ b/types/AssetsApi.d.ts
@@ -0,0 +1,4 @@
+export interface AssetsApi {
+ upload(file: Blob, title: string): Promise<{ id: string }>
+ url: string
+}
diff --git a/types/FormState.d.ts b/types/FormState.d.ts
new file mode 100644
index 00000000..20589afd
--- /dev/null
+++ b/types/FormState.d.ts
@@ -0,0 +1,20 @@
+import type { Item } from './Item'
+import type { Tag } from './Tag'
+
+export interface FormState {
+ color: string
+ id: string
+ group_type: string
+ status: string
+ name: string
+ subname: string
+ text: string
+ contact: string
+ telephone: string
+ next_appointment: string
+ image: string
+ marker_icon: string
+ offers: Tag[]
+ needs: Tag[]
+ relations: Item[]
+}
diff --git a/types/Item.d.ts b/types/Item.d.ts
new file mode 100644
index 00000000..47560e66
--- /dev/null
+++ b/types/Item.d.ts
@@ -0,0 +1,44 @@
+import type { ItemsApi } from './ItemsApi'
+import type { LayerProps } from './LayerProps'
+import type { Relation } from './Relation'
+import type { UserItem } from './UserItem'
+import type { Point } from 'geojson'
+
+export interface Item {
+ id: string
+ name: string
+ text: string
+ position?: Point
+ date_created?: string
+ date_updated?: string | null
+ start?: string
+ end?: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api?: ItemsApi
+ tags?: string[]
+ layer?: LayerProps
+ relations?: Relation[]
+ parent?: string
+ subname?: string
+ public_edit?: boolean
+ slug?: string
+ user_created?: UserItem
+ image?: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ [key: string]: any
+ /* constructor(
+ id: string,
+ name: string,
+ text: string,
+ position: Geometry,
+ layer?: LayerProps,
+ api?: ItemsApi,
+ ) {
+ this.id = id
+ this.name = name
+ this.text = text
+ this.position = position
+ this.layer = layer
+ this.api = api
+ } */
+}
diff --git a/types/ItemFormPopupProps.d.ts b/types/ItemFormPopupProps.d.ts
new file mode 100644
index 00000000..64e880bb
--- /dev/null
+++ b/types/ItemFormPopupProps.d.ts
@@ -0,0 +1,11 @@
+import type { Item } from './Item'
+import type { LayerProps } from './LayerProps'
+import type { LatLng } from 'leaflet'
+
+export interface ItemFormPopupProps {
+ position: LatLng
+ layer: LayerProps
+ item?: Item
+ children?: React.ReactNode
+ setItemFormPopup?: React.Dispatch>
+}
diff --git a/types/ItemType.d.ts b/types/ItemType.d.ts
new file mode 100644
index 00000000..1f125cc7
--- /dev/null
+++ b/types/ItemType.d.ts
@@ -0,0 +1,5 @@
+export interface ItemType {
+ name: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ [key: string]: any
+}
diff --git a/types/ItemsApi.d.ts b/types/ItemsApi.d.ts
new file mode 100644
index 00000000..147fa462
--- /dev/null
+++ b/types/ItemsApi.d.ts
@@ -0,0 +1,8 @@
+export interface ItemsApi {
+ getItems(): Promise
+ getItem?(id: string): Promise
+ createItem?(item: T): Promise
+ updateItem?(item: T): Promise
+ deleteItem?(id: string): Promise
+ collectionName?: string
+}
diff --git a/types/LayerProps.d.ts b/types/LayerProps.d.ts
new file mode 100644
index 00000000..7d742d5e
--- /dev/null
+++ b/types/LayerProps.d.ts
@@ -0,0 +1,42 @@
+import type { Item } from './Item'
+import type { ItemFormPopupProps } from './ItemFormPopupProps'
+import type { ItemsApi } from './ItemsApi'
+import type { ItemType } from './ItemType'
+
+export interface LayerProps {
+ id?: string
+ data?: Item[]
+ children?: React.ReactNode
+ name: string
+ menuIcon: string
+ menuColor: string
+ menuText: string
+ markerIcon: string
+ markerShape: string
+ markerDefaultColor: string
+ markerDefaultColor2?: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api?: ItemsApi
+ itemType: ItemType
+ itemNameField?: string
+ itemSubnameField?: string
+ itemTextField?: string
+ itemAvatarField?: string
+ itemColorField?: string
+ itemOwnerField?: string
+ itemTagsField?: string
+ itemLatitudeField?: string
+ itemLongitudeField?: string
+ itemOffersField?: string
+ itemNeedsField?: string
+ onlyOnePerOwner?: boolean
+ customEditLink?: string
+ customEditParameter?: string
+ public_edit_items?: boolean
+ listed?: boolean
+ item_presets?: Record
+ setItemFormPopup?: React.Dispatch>
+ itemFormPopup?: ItemFormPopupProps | null
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ clusterRef?: any
+}
diff --git a/types/Permission.d.ts b/types/Permission.d.ts
new file mode 100644
index 00000000..57067fee
--- /dev/null
+++ b/types/Permission.d.ts
@@ -0,0 +1,13 @@
+import type { PermissionAction } from './PermissionAction'
+import type { PermissionCondition } from './PermissionCondition'
+
+export interface Permission {
+ id?: string
+ policy?: { name: string }
+ collection: string
+ action: PermissionAction
+ permissions?: {
+ // Optional, für spezifische Bedingungen wie `user_created`
+ _and: PermissionCondition[]
+ }
+}
diff --git a/types/PermissionAction.d.ts b/types/PermissionAction.d.ts
new file mode 100644
index 00000000..7278a069
--- /dev/null
+++ b/types/PermissionAction.d.ts
@@ -0,0 +1 @@
+export type PermissionAction = 'create' | 'read' | 'update' | 'delete'
diff --git a/types/PermissionCondition.d.ts b/types/PermissionCondition.d.ts
new file mode 100644
index 00000000..e946bdb1
--- /dev/null
+++ b/types/PermissionCondition.d.ts
@@ -0,0 +1,8 @@
+export interface PermissionCondition {
+ user_created?: {
+ _eq: string // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID
+ }
+ public_edit?: {
+ _eq: boolean // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID
+ }
+}
diff --git a/types/Profile.d.ts b/types/Profile.d.ts
new file mode 100644
index 00000000..4bfb8980
--- /dev/null
+++ b/types/Profile.d.ts
@@ -0,0 +1,10 @@
+import type { Geometry } from 'geojson'
+
+export interface Profile {
+ id?: string
+ avatar?: string
+ color?: string
+ name: string
+ text: string
+ geoposition?: Geometry
+}
diff --git a/types/Relation.d.ts b/types/Relation.d.ts
new file mode 100644
index 00000000..0b038022
--- /dev/null
+++ b/types/Relation.d.ts
@@ -0,0 +1,5 @@
+export interface Relation {
+ related_items_id: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ [key: string]: any
+}
diff --git a/types/Tag.d.ts b/types/Tag.d.ts
new file mode 100644
index 00000000..1dc7c5a9
--- /dev/null
+++ b/types/Tag.d.ts
@@ -0,0 +1,6 @@
+export interface Tag {
+ color: string
+ id: string
+ name: string
+ offer_or_need?: boolean
+}
diff --git a/types/UserApi.d.ts b/types/UserApi.d.ts
new file mode 100644
index 00000000..6c36cd4e
--- /dev/null
+++ b/types/UserApi.d.ts
@@ -0,0 +1,12 @@
+import type { UserItem } from './UserItem'
+
+export interface UserApi {
+ register(email: string, password: string, userName: string): Promise
+ login(email: string, password: string): Promise
+ logout(): Promise
+ getUser(): Promise
+ getToken(): Promise
+ updateUser(user: UserItem): Promise
+ requestPasswordReset(email: string, reset_url?: string)
+ passwordReset(token: string, new_password: string)
+}
diff --git a/types/UserItem.d.ts b/types/UserItem.d.ts
new file mode 100644
index 00000000..1d28817e
--- /dev/null
+++ b/types/UserItem.d.ts
@@ -0,0 +1,13 @@
+import type { Profile } from './Profile'
+
+export interface UserItem {
+ id?: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ role?: any
+ email?: string
+ password?: string
+ profile?: Profile
+ first_name?: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ [key: string]: any
+}
diff --git a/types/UtopiaMapProps.d.ts b/types/UtopiaMapProps.d.ts
new file mode 100644
index 00000000..99389e81
--- /dev/null
+++ b/types/UtopiaMapProps.d.ts
@@ -0,0 +1,16 @@
+import type { Tag } from './Tag'
+import type { GeoJsonObject } from 'geojson'
+
+export interface UtopiaMapProps {
+ height?: string
+ width?: string
+ center?: [number, number]
+ zoom?: number
+ tags?: Tag[]
+ children?: React.ReactNode
+ geo?: GeoJsonObject
+ showFilterControl?: boolean
+ showLayerControl?: boolean
+ showGratitudeControl?: boolean
+ infoText?: string
+}