lint fixes

This commit is contained in:
Ulf Gebhardt 2024-10-29 18:24:11 +01:00
parent 9546b2e9f4
commit 36aeda5919
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
36 changed files with 185 additions and 153 deletions

View File

@ -34,7 +34,7 @@ export default function NavBar ({ appName, userType }: { appName: string, userTy
useEffect(() => {
const params = new URLSearchParams(location.search)
const embedded = params.get('embedded')
embedded != 'true' && setShowNav(true)
embedded !== 'true' && setShowNav(true)
}, [location])
const onLogout = () => {
@ -43,7 +43,7 @@ export default function NavBar ({ appName, userType }: { appName: string, userTy
{
success: {
render () {
return `Bye bye`
return 'Bye bye'
},
// other options
icon: '👋'

View File

@ -48,7 +48,7 @@ export function SideBar ({ routes, bottomRoutes }: { routes: route[], bottomRout
useEffect(() => {
const params = new URLSearchParams(location.search)
const embedded = params.get('embedded')
embedded != 'true' && setEmbedded(false)
embedded !== 'true' && setEmbedded(false)
}, [location])
const params = new URLSearchParams(window.location.search)

View File

@ -35,7 +35,7 @@ function SidebarSubmenu ({ submenu, name, icon } : { path: string;
<Link to={m.path} className='' >
{m.icon}<span className="" data-te-sidenav-slim="false">{m.name}</span>
{
location.pathname == m.path
location.pathname === m.path
? (<span className="absolute mt-1 mb-1 inset-y-0 left-0 w-1 rounded-tr-md rounded-br-md bg-primary "
aria-hidden="true"></span>)
: null

View File

@ -5,7 +5,7 @@ import { useAuth } from './useAuth'
import { MapOverlayPage } from '../Templates'
// eslint-disable-next-line react/prop-types
export function RequestPasswordPage ({ reset_url }) {
export function RequestPasswordPage ({ resetUrl }) {
const [email, setEmail] = useState<string>('')
const { requestPasswordReset, loading } = useAuth()
@ -14,7 +14,7 @@ export function RequestPasswordPage ({ reset_url }) {
const onReset = async () => {
await toast.promise(
requestPasswordReset(email, reset_url),
requestPasswordReset(email, resetUrl),
{
success: {
render () {

View File

@ -34,14 +34,14 @@ type AuthContextProps = {
const AuthContext = createContext<AuthContextProps>({
isAuthenticated: false,
user: null,
login: () => Promise.reject(),
register: () => Promise.reject(),
login: () => Promise.reject(Error('Unimplemented')),
register: () => Promise.reject(Error('Unimplemented')),
loading: false,
logout: () => Promise.reject(),
updateUser: () => Promise.reject(),
logout: () => Promise.reject(Error('Unimplemented')),
updateUser: () => Promise.reject(Error('Unimplemented')),
token: '',
requestPasswordReset: () => Promise.reject(),
passwordReset: () => Promise.reject()
requestPasswordReset: () => Promise.reject(Error('Unimplemented')),
passwordReset: () => Promise.reject(Error('Unimplemented'))
})
export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
@ -123,10 +123,10 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
}
}
const requestPasswordReset = async (email: string, reset_url?: string): Promise<any> => {
const requestPasswordReset = async (email: string, resetUrl?: string): Promise<any> => {
setLoading(true)
try {
await userApi.requestPasswordReset(email, reset_url)
await userApi.requestPasswordReset(email, resetUrl)
return setLoading(false)
} catch (error: any) {
setLoading(false)
@ -134,10 +134,10 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
}
}
const passwordReset = async (token: string, new_password:string): Promise<any> => {
const passwordReset = async (token: string, newPassword:string): Promise<any> => {
setLoading(true)
try {
await userApi.passwordReset(token, new_password)
await userApi.passwordReset(token, newPassword)
return setLoading(false)
} catch (error: any) {
setLoading(false)

View File

@ -19,7 +19,7 @@ export function Quests () {
const items = useItems()
useEffect(() => {
setProfie(items.find(i => i.user_created?.id === user?.id && i.layer?.itemType.name == 'user' && i.user_created?.id != null))
setProfie(items.find(i => i.user_created?.id === user?.id && i.layer?.itemType.name === 'user' && i.user_created?.id != null))
}, [items, user])
return (

View File

@ -57,7 +57,7 @@ export const Autocomplete = ({ inputProps, suggestions, onSelected, pushFiltered
onSelected(filteredSuggestions[heighlightedSuggestion])
setHeighlightedSuggestion(0)
}
filteredSuggestions.length == 0 && inputProps.onKeyDown(event)
filteredSuggestions.length === 0 && inputProps.onKeyDown(event)
break
default:
inputProps.onKeyDown(event)
@ -70,7 +70,7 @@ export const Autocomplete = ({ inputProps, suggestions, onSelected, pushFiltered
<input ref={inputRef} {...inputProps} type="text" onChange={(e) => handleChange(e)} tabIndex="-1" onKeyDown={handleKeyDown}/>
<ul className={`tw-absolute tw-z-[4000] ${filteredSuggestions.length > 0 && 'tw-bg-base-100 tw-rounded-xl tw-p-2'}`}>
{filteredSuggestions.map((suggestion, index) => (
<li key={index} onClick={() => handleSuggestionClick(suggestion)}><TagView heighlight={index == heighlightedSuggestion} tag={suggestion}></TagView></li>
<li key={index} onClick={() => handleSuggestionClick(suggestion)}><TagView heighlight={index === heighlightedSuggestion} tag={suggestion}></TagView></li>
))}
</ul>
</div>

View File

@ -26,7 +26,7 @@ const ComboBoxInput = ({ id, options, value, onValueChange }: ComboBoxProps) =>
onChange={handleChange}
>
{options.map((o) =>
<option value={o.value} key={o.value} selected={o.value == value}>{o.label}</option>
<option value={o.value} key={o.value} selected={o.value === value}>{o.label}</option>
)}
</select>
)

View File

@ -44,6 +44,7 @@ export const Layer = ({
onlyOnePerOwner = false,
customEditLink,
customEditParameter,
// eslint-disable-next-line camelcase
public_edit_items,
listed = true,
setItemFormPopup,
@ -82,15 +83,17 @@ export const Layer = ({
const visibleGroupTypes = useVisibleGroupType()
useEffect(() => {
// eslint-disable-next-line camelcase
data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, markerDefaultColor2, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, listed, setItemFormPopup, itemFormPopup, clusterRef })
// eslint-disable-next-line camelcase
api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, markerDefaultColor2, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, listed, setItemFormPopup, itemFormPopup, clusterRef })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [data, api])
useMapEvents({
popupopen: (e) => {
const item = Object.entries(leafletRefs).find(r => r[1].popup == e.popup)?.[1].item
if (item?.layer?.name == name && window.location.pathname.split('/')[1] != item.id) {
const item = Object.entries(leafletRefs).find(r => r[1].popup === e.popup)?.[1].item
if (item?.layer?.name === name && window.location.pathname.split('/')[1] !== item.id) {
const params = new URLSearchParams(window.location.search)
if (!location.pathname.includes('/item/')) {
window.history.pushState({}, '', `/${item.id}` + `${params.toString() !== '' ? `?${params}` : ''}`)
@ -138,6 +141,7 @@ export const Layer = ({
processedTags[newtag.name] = true
addTag(newtag)
}
return null
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -149,9 +153,9 @@ export const Layer = ({
items
.filter(item => item.layer?.name === name)
?.filter(item =>
filterTags.length == 0 ? item : filterTags.some(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))
filterTags.length === 0 ? item : filterTags.some(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))
?.filter(item => item.layer && isLayerVisible(item.layer))
.filter(item => item.group_type && isGroupTypeVisible(item.group_type) || visibleGroupTypes.length == 0)
.filter(item => item.group_type && isGroupTypeVisible(item.group_type) || visibleGroupTypes.length === 0)
.map((item: Item) => {
if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
if (getValue(item, itemTextField)) item[itemTextField] = getValue(item, itemTextField)
@ -171,6 +175,7 @@ export const Layer = ({
const newTag = { id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() }
setNewTagsToAdd(current => [...current, newTag])
}
return null
})
!tagsReady && setTagsReady(true)
}
@ -192,7 +197,7 @@ export const Layer = ({
}
return (
<Marker ref={(r) => {
if (!(item.id in leafletRefs && leafletRefs[item.id].marker == r)) { r && addMarker(item, r) }
if (!(item.id in leafletRefs && leafletRefs[item.id].marker === r)) { r && addMarker(item, r) }
}}
eventHandlers={{
click: () => {
@ -205,7 +210,7 @@ export const Layer = ({
? React.Children.toArray(children).map((child) =>
React.isValidElement(child) && child.props.__TYPE === 'ItemView'
? <ItemViewPopup ref={(r) => {
if (!(item.id in leafletRefs && leafletRefs[item.id].popup == r)) { r && addPopup(item, r as Popup) }
if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) { r && addPopup(item, r as Popup) }
}} key={item.id + item.name}
item={item}
setItemFormPopup={setItemFormPopup}>
@ -215,7 +220,7 @@ export const Layer = ({
)
: <>
<ItemViewPopup key={item.id + item.name} ref={(r) => {
if (!(item.id in leafletRefs && leafletRefs[item.id].popup == r)) { r && addPopup(item, r as Popup) }
if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) { r && addPopup(item, r as Popup) }
}}
item={item}
setItemFormPopup={setItemFormPopup} />
@ -229,7 +234,7 @@ export const Layer = ({
}
{// {children}}
}
{itemFormPopup && itemFormPopup.layer!.name == name &&
{itemFormPopup && itemFormPopup.layer!.name === name &&
(children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === 'ItemForm')
? React.Children.toArray(children).map((child) =>
React.isValidElement(child) && child.props.__TYPE === 'ItemForm'

View File

@ -10,6 +10,7 @@ export default function AddButton ({ triggerAction }: { triggerAction: React.Dis
let canAdd = false
layers.map(layer => {
if (layer.api?.createItem && hasUserPermission(layer.api.collectionName!, 'create', undefined, layer) && layer.listed) canAdd = true
return null
})
return canAdd
}

View File

@ -80,7 +80,7 @@ export const SearchControl = () => {
useEffect(() => {
const params = new URLSearchParams(location.search)
const embedded = params.get('embedded')
embedded != 'true' && setEmbedded(false)
embedded !== 'true' && setEmbedded(false)
}, [location])
return (<>
@ -101,7 +101,7 @@ export const SearchControl = () => {
</div>
<LocateControl />
</div>
{hideSuggestions || Array.from(geoResults).length == 0 && itemsResults.length == 0 && tagsResults.length == 0 && !isGeoCoordinate(value) || value.length == 0
{hideSuggestions || Array.from(geoResults).length === 0 && itemsResults.length === 0 && tagsResults.length === 0 && !isGeoCoordinate(value) || value.length === 0
? ''
: <div className='tw-card tw-card-body tw-bg-base-100 tw-p-4 tw-mt-2 tw-shadow-xl tw-overflow-y-auto tw-max-h-[calc(100dvh-152px)] tw-absolute tw-z-3000'>
{tagsResults.length > 0 &&
@ -119,7 +119,7 @@ export const SearchControl = () => {
{itemsResults.length > 0 && tagsResults.length > 0 && <hr className='tw-opacity-50'></hr>}
{itemsResults.slice(0, 5).map(item => (
<div key={item.id} className='tw-cursor-pointer hover:tw-font-bold' onClick={() => {
const marker = Object.entries(leafletRefs).find(r => r[1].item == item)?.[1].marker
const marker = Object.entries(leafletRefs).find(r => r[1].item === item)?.[1].marker
if (marker) {
navigate(`/${item.id}?${new URLSearchParams(window.location.search)}`)
} else {

View File

@ -59,6 +59,7 @@ export function ItemFormPopup (props: ItemFormPopupProps) {
if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
addTag({ id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() })
}
return null
})
if (props.item) {

View File

@ -80,7 +80,7 @@ export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: a
{
infoExpanded
? <p className={'tw-italic tw-min-h-[21px] !tw-my-0 tw-text-gray-500'} >{`${props.item.date_updated && props.item.date_updated != props.item.date_created ? 'updated' : 'posted'} ${props.item && props.item.user_created && props.item.user_created.first_name ? `by ${props.item.user_created.first_name}` : ''} ${props.item.date_updated ? timeAgo(props.item.date_updated) : timeAgo(props.item.date_created!)}`}</p>
? <p className={'tw-italic tw-min-h-[21px] !tw-my-0 tw-text-gray-500'} >{`${props.item.date_updated && props.item.date_updated !== props.item.date_created ? 'updated' : 'posted'} ${props.item && props.item.user_created && props.item.user_created.first_name ? `by ${props.item.user_created.first_name}` : ''} ${props.item.date_updated ? timeAgo(props.item.date_updated) : timeAgo(props.item.date_created!)}`}</p>
: <p className="!tw-my-0 tw-min-h-[21px] tw-font-bold tw-cursor-pointer tw-text-gray-500" onClick={() => setInfoExpanded(true)}></p>
}
<div className='tw-grow'></div>

View File

@ -31,6 +31,7 @@ export function Tags ({ data, api } : {data?: Tag[], api?: ItemsApi<Tag>}) {
decodedTagsArray?.map(urlTag => {
const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
tag && addFilterTag(tag)
return null
})
}

View File

@ -105,7 +105,7 @@ function useFilterManager (initialTags: Tag[]): {
case 'TOGGLE_LAYER':
const exist2 = state.some((layer) =>
layer.name === action.layer.name)
if (exist2) return state.filter(({ name }) => name != action.layer.name)
if (exist2) return state.filter(({ name }) => name !== action.layer.name)
else return [...state, action.layer]
case 'RESET_LAYERS':
return initialLayers
@ -129,7 +129,7 @@ function useFilterManager (initialTags: Tag[]): {
case 'TOGGLE_GROUP_TYPE':
const exist2 = state.some((groupType) =>
groupType === action.groupType)
if (exist2) return state.filter((groupType) => groupType != action.groupType)
if (exist2) return state.filter((groupType) => groupType !== action.groupType)
else return [...state, action.groupType]
case 'RESET_GROUP_TYPE':
return []
@ -162,9 +162,10 @@ function useFilterManager (initialTags: Tag[]): {
const urlTags = params.get('tags')
let newUrlTags = ''
const tags = urlTags?.split(';')
if (tags?.length == 0 && urlTags?.length && urlTags?.length > 0) tags[0] = urlTags
if (tags?.length === 0 && urlTags?.length && urlTags?.length > 0) tags[0] = urlTags
tags?.map(urlTag => {
if (!(urlTag.toLocaleLowerCase() === name.toLocaleLowerCase())) { newUrlTags = newUrlTags + `${newUrlTags === '' ? urlTag : `;${urlTag}`}` }
return null
})
if (newUrlTags !== '') {
params.set('tags', `${newUrlTags}`)

View File

@ -91,6 +91,7 @@ function useItemsManager (initialItems: Item[]): {
if (result) {
result.map(item => {
dispatch({ type: 'ADD', item: { ...item, layer } })
return null
})
setallItemsLoaded(true)
}
@ -101,6 +102,7 @@ function useItemsManager (initialItems: Item[]): {
addLayer(layer)
layer.data?.map(item => {
dispatch({ type: 'ADD', item: { ...item, layer } })
return null
})
setallItemsLoaded(true)
// eslint-disable-next-line react-hooks/exhaustive-deps

View File

@ -57,6 +57,7 @@ function usePermissionsManager (initialPermissions: Permission[]): {
if (result) {
result.map(permission => {
dispatch({ type: 'ADD', permission })
return null
})
}
}, [])
@ -64,6 +65,7 @@ function usePermissionsManager (initialPermissions: Permission[]): {
const setPermissionData = useCallback((data: Permission[]) => {
data.map(permission => {
dispatch({ type: 'ADD', permission })
return null
})
}, [])

View File

@ -94,11 +94,11 @@ function useSelectPositionManager (): {
const linkItem = async (id: string) => {
if (markerClicked) {
const new_relations = markerClicked.relations || []
const newRelations = markerClicked.relations || []
if (!new_relations.some(r => r.related_items_id == id)) {
new_relations?.push({ items_id: markerClicked.id, related_items_id: id })
const updatedItem = { id: markerClicked.id, relations: new_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 {
@ -108,7 +108,7 @@ function useSelectPositionManager (): {
toast.error(error.toString())
}
if (success) {
updateItem({ ...markerClicked, relations: new_relations })
updateItem({ ...markerClicked, relations: newRelations })
toast.success('Item linked')
}
}

View File

@ -43,7 +43,7 @@ function useTagsManager (initialTags: Tag[]): {
...state,
{ ...action.tag }
]
if (tagCount == newState.length) setallTagsLoaded(true)
if (tagCount === newState.length) setallTagsLoaded(true)
return newState
} else return state
default:
@ -57,11 +57,12 @@ function useTagsManager (initialTags: Tag[]): {
setApi(api)
const result = await api.getItems()
setTagCount(result.length)
if (tagCount == 0) setallTagsLoaded(true)
if (tagCount === 0) setallTagsLoaded(true)
if (result) {
result.map(tag => {
// tag.name = tag.name.toLocaleLowerCase();
dispatch({ type: 'ADD', tag })
return null
})
}
@ -72,6 +73,7 @@ function useTagsManager (initialTags: Tag[]): {
data.map(tag => {
// tag.name = tag.name.toLocaleLowerCase();
dispatch({ type: 'ADD', tag })
return null
})
}, [])
@ -93,14 +95,17 @@ function useTagsManager (initialTags: Tag[]): {
if (tags.find(t => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
itemTags.push(tags.find(t => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())!)
}
return null
})
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField)?.map(o => {
const offer = tags.find(t => t.id === o.tags_id)
offer && itemTags.push(offer)
return null
})
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField)?.map(n => {
const need = tags.find(t => t.id === n.tags_id)
need && itemTags.push(need)
return null
})
return itemTags

View File

@ -64,7 +64,7 @@ export function ProfileForm ({ userType }: { userType: string }) {
const item = items.find(i => i.id === itemId)
item && setItem(item)
const layer = layers.find(l => l.itemType.name == userType)
const layer = layers.find(l => l.itemType.name === userType)
!item && setItem({ id: crypto.randomUUID(), name: user ? user.first_name : '', text: '', layer, new: true })
@ -132,15 +132,15 @@ export function ProfileForm ({ userType }: { userType: string }) {
<FormHeader item={item} state={state} setState={setState} />
{template == 'onepager' && (
{template === 'onepager' && (
<OnepagerForm item={item} state={state} setState={setState}></OnepagerForm>
)}
{template == 'simple' &&
{template === 'simple' &&
<SimpleForm state={state} setState={setState}></SimpleForm>
}
{template == 'tabs' &&
{template === 'tabs' &&
<TabsForm loading={loading} item={item} state={state} setState={setState} updatePermission={updatePermission} linkItem={(id) => linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)} setUrlParams={setUrlParams}></TabsForm>
}

View File

@ -69,14 +69,17 @@ export function ProfileView ({ userType, attestationApi }: { userType: string, a
item?.layer?.itemOffersField && getValue(item, item.layer.itemOffersField)?.map(o => {
const tag = tags.find(t => t.id === o.tags_id)
tag && setOffers(current => [...current, tag])
return null
})
item?.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField)?.map(n => {
const tag = tags.find(t => t.id === n.tags_id)
tag && setNeeds(current => [...current, tag])
return null
})
item?.relations?.map(r => {
const item = items.find(i => i.id == r.related_items_id)
const item = items.find(i => i.id === r.related_items_id)
item && setRelations(current => [...current, item])
return null
})
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -91,7 +94,7 @@ export function ProfileView ({ userType, attestationApi }: { userType: string, a
}
if (item) {
if (item.position) {
const marker = Object.entries(leafletRefs).find(r => r[1].item == item)?.[1].marker
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()
@ -100,7 +103,7 @@ export function ProfileView ({ userType, attestationApi }: { userType: string, a
)
} else {
const parent = getFirstAncestor(item)
const marker = Object.entries(leafletRefs).find(r => r[1].item == parent)?.[1].marker
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()
@ -146,15 +149,15 @@ export function ProfileView ({ userType, attestationApi }: { userType: string, a
<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' &&
{template === 'onepager' &&
<OnepagerView item={item} userType={userType}/>
}
{template == 'simple' &&
{template === 'simple' &&
<SimpleView item={item}/>
}
{template == 'tabs' &&
{template === 'tabs' &&
<TabsView userType={userType} attestations={attestations} setUrlParams={setUrlParams} item={item} loading={loading} offers={offers} needs={needs} relations={relations} updatePermission={updatePermission} linkItem={(id) => linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)}/>
}
</>

View File

@ -25,7 +25,7 @@ export function ActionButton ({ item, triggerAddButton, triggerItemSelected, exi
const items = useItems()
const filterdItems = items.filter(i => !itemType || i.layer?.itemType.name == itemType).filter(i => !existingRelations.some(s => s.id == i.id)).filter(i => i.id != item.id)
const filterdItems = items.filter(i => !itemType || i.layer?.itemType.name === itemType).filter(i => !existingRelations.some(s => s.id === i.id)).filter(i => i.id !== item.id)
return (
<>{hasUserPermission(collection, 'update', item) &&

View File

@ -29,7 +29,7 @@ const SubHeader = ({ type, status, url, title }) => (
<div className='tw-float-left tw-mt-2 tw-mb-4 tw-flex tw-items-center'>
{status && <div className="tw-mt-1.5">
<span className="tw-text-sm tw-text-current tw-bg-base-300 tw-rounded tw-py-0.5 tw-px-2 tw-inline-flex tw-items-center tw-mr-2"><span className={`tw-w-2 tw-h-2 ${status == 'in_planning' && 'tw-bg-blue-700'} ${status == 'paused' && 'tw-bg-orange-400'} ${status == 'active' && 'tw-bg-green-500'} tw-rounded-full tw-mr-1.5`}></span>{statusMapping[status]}</span>
<span className="tw-text-sm tw-text-current tw-bg-base-300 tw-rounded tw-py-0.5 tw-px-2 tw-inline-flex tw-items-center tw-mr-2"><span className={`tw-w-2 tw-h-2 ${status === 'in_planning' && 'tw-bg-blue-700'} ${status === 'paused' && 'tw-bg-orange-400'} ${status === 'active' && 'tw-bg-green-500'} tw-rounded-full tw-mr-1.5`}></span>{statusMapping[status]}</span>
</div>}
{type && <div className="tw-mt-1.5">
<span className="tw-text-sm tw-text-current tw-bg-base-300 tw-rounded tw-py-1 tw-px-2">{type}</span>

View File

@ -6,7 +6,7 @@ import { useEffect, useState } from 'react'
import { useItems } from '../../Map/hooks/useItems'
export const OnepagerView = ({ item, userType }:{item: Item, userType: string}) => {
const [profile_owner, setProfileOwner] = useState<Item>()
const [profileOwner, setProfileOwner] = useState<Item>()
const items = useItems()
useEffect(() => {
@ -34,7 +34,7 @@ export const OnepagerView = ({ item, userType }:{item: Item, userType: string})
/>
</div>
{item.user_created.first_name && (
<ContactInfo link={`/item/${profile_owner?.id}`} name={profile_owner?.name ? profile_owner.name : item.user_created.first_name} avatar={profile_owner?.image ? profile_owner.image : item.user_created.avatar} email={item.contact} telephone={item.telephone} />
<ContactInfo link={`/item/${profileOwner?.id}`} name={profileOwner?.name ? profileOwner.name : item.user_created.first_name} avatar={profileOwner?.image ? profileOwner.image : item.user_created.avatar} email={item.contact} telephone={item.telephone} />
)}
{/* Description Section */}

View File

@ -35,7 +35,7 @@ export const TabsForm = ({ item, state, setState, updatePermission, linkItem, un
return (
<div role="tablist" className="tw-tabs tw-tabs-lifted tw-mt-3">
<input type="radio" name="my_tabs_2" role="tab" className={'tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]'} aria-label="Info" checked={activeTab == 1 && true} onChange={() => updateActiveTab(1)} />
<input type="radio" name="my_tabs_2" role="tab" className={'tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]'} aria-label="Info" checked={activeTab === 1 && true} onChange={() => updateActiveTab(1)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-border-[var(--fallback-bc,oklch(var(--bc)/0.2))] tw-rounded-box tw-h-[calc(100dvh-332px)] tw-min-h-56 tw-border-none">
<div className={`tw-flex tw-flex-col tw-h-full ${item.layer.itemType.show_start_end_input && 'tw-pt-4'}`}>
{item.layer.itemType.show_start_end_input &&
@ -76,7 +76,7 @@ export const TabsForm = ({ item, state, setState, updatePermission, linkItem, un
</div>
{item.layer?.itemType.offers_and_needs &&
<>
<input type="radio" name="my_tabs_2" role="tab" className={'tw-tab tw-min-w-[10em] [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]'} aria-label="Offers & Needs" checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />
<input type="radio" name="my_tabs_2" role="tab" className={'tw-tab tw-min-w-[10em] [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]'} aria-label="Offers & Needs" checked={activeTab === 3 && true} onChange={() => updateActiveTab(3)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-border-[var(--fallback-bc,oklch(var(--bc)/0.2))] tw-rounded-box tw-h-[calc(100dvh-332px)] tw-min-h-56 tw-border-none">
<div className='tw-h-full'>
<div className='tw-w-full tw-h-[calc(50%-0.75em)] tw-mb-4'>
@ -97,7 +97,7 @@ export const TabsForm = ({ item, state, setState, updatePermission, linkItem, un
}
{item.layer?.itemType.relations &&
<>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Relations" checked={activeTab == 7 && true} onChange={() => updateActiveTab(7)} />
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Relations" checked={activeTab === 7 && true} onChange={() => updateActiveTab(7)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-332px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mx-4 tw-overflow-x-hidden fade">
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-1 lg:tw-grid-cols-1 xl:tw-grid-cols-1 2xl:tw-grid-cols-2 tw-mb-4'>

View File

@ -56,7 +56,7 @@ export const TabsView = ({ attestations, userType, item, offers, needs, relation
<div role="tablist" className="tw-tabs tw-tabs-lifted tw-mt-2 tw-mb-2 tw-px-6">
<input type="radio" name="my_tabs_2" role="tab"
className={'tw-tab tw-font-bold !tw-ps-2 !tw-pe-2 [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]'}
aria-label={`${item.layer?.itemType.icon_as_labels && activeTab != 1 ? '📝' : '📝\u00A0Info'}`} checked={activeTab == 1 && true}
aria-label={`${item.layer?.itemType.icon_as_labels && activeTab !== 1 ? '📝' : '📝\u00A0Info'}`} checked={activeTab === 1 && true}
onChange={() => updateActiveTab(1)} />
<div role="tabpanel"
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
@ -71,14 +71,14 @@ export const TabsView = ({ attestations, userType, item, offers, needs, relation
<>
<input type="radio" name="my_tabs_2" role="tab"
className={'tw-tab tw-font-bold !tw-ps-2 !tw-pe-2 [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]'}
aria-label={`${item.layer?.itemType.icon_as_labels && activeTab != 2 ? '❤️' : '❤️\u00A0Credibility'}`} checked={activeTab == 2 && true}
aria-label={`${item.layer?.itemType.icon_as_labels && activeTab !== 2 ? '❤️' : '❤️\u00A0Credibility'}`} checked={activeTab === 2 && true}
onChange={() => updateActiveTab(2)} />
<div role="tabpanel"
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
<table className="sm:tw-table-sm md:tw-table-md">
<tbody>
{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())
.map((a, i) => (
<tr key={i}>
@ -120,7 +120,7 @@ export const TabsView = ({ attestations, userType, item, offers, needs, relation
<>
<input type="radio" name="my_tabs_2" role="tab" className={`tw-tab tw-font-bold !tw-ps-2 !tw-pe-2 ${!(item.layer?.itemType.icon_as_labels && activeTab != 3) && 'tw-min-w-[10.4em]'} [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`} aria-label={`${item.layer?.itemType.icon_as_labels && activeTab != 3 ? '♻️' : '♻️\u00A0Offers & Needs'}`} checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />
<input type="radio" name="my_tabs_2" role="tab" className={`tw-tab tw-font-bold !tw-ps-2 !tw-pe-2 ${!(item.layer?.itemType.icon_as_labels && activeTab !== 3) && 'tw-min-w-[10.4em]'} [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`} aria-label={`${item.layer?.itemType.icon_as_labels && activeTab !== 3 ? '♻️' : '♻️\u00A0Offers & Needs'}`} checked={activeTab === 3 && true} onChange={() => updateActiveTab(3)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-268px)] tw-overflow-y-auto fade tw-pt-4 tw-pb-1" >
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1'>
@ -159,7 +159,7 @@ export const TabsView = ({ attestations, userType, item, offers, needs, relation
{item.layer?.itemType.relations &&
<>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab tw-font-bold !tw-ps-2 !tw-pe-2 [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label={`${item.layer?.itemType.icon_as_labels && activeTab != 7 ? '🔗' : '🔗\u00A0Relations'}`} checked={activeTab == 7 && true} onChange={() => updateActiveTab(7)} />
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab tw-font-bold !tw-ps-2 !tw-pe-2 [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label={`${item.layer?.itemType.icon_as_labels && activeTab !== 7 ? '🔗' : '🔗\u00A0Relations'}`} checked={activeTab === 7 && true} onChange={() => updateActiveTab(7)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mr-4 -tw-mb-4 tw-overflow-x-hidden">
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-1 lg:tw-grid-cols-1 xl:tw-grid-cols-1 2xl:tw-grid-cols-2 tw-pb-4'>

View File

@ -20,10 +20,11 @@ export const submitNewItem = async (evt: any, type: string, item, user, setLoadi
if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
addTag({ id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() })
}
return null
})
const uuid = crypto.randomUUID()
const layer = layers.find(l => l.name.toLocaleLowerCase().replace('s', '') == addItemPopupType.toLocaleLowerCase())
const layer = layers.find(l => l.name.toLocaleLowerCase().replace('s', '') === addItemPopupType.toLocaleLowerCase())
let success = false
try {
@ -43,9 +44,9 @@ export const submitNewItem = async (evt: any, type: string, item, user, setLoadi
}
export const linkItem = async (id: string, item, updateItem) => {
const new_relations = item.relations || []
new_relations?.push({ items_id: item.id, related_items_id: id })
const updatedItem = { id: item.id, relations: new_relations }
const newRelations = item.relations || []
newRelations?.push({ items_id: item.id, related_items_id: id })
const updatedItem = { id: item.id, relations: newRelations }
let success = false
try {
@ -55,14 +56,14 @@ export const linkItem = async (id: string, item, updateItem) => {
toast.error(error.toString())
}
if (success) {
updateItem({ ...item, relations: new_relations })
updateItem({ ...item, relations: newRelations })
toast.success('Item linked')
}
}
export const unlinkItem = async (id: string, item, updateItem) => {
const new_relations = item.relations?.filter(r => r.related_items_id !== id)
const updatedItem = { id: item.id, relations: new_relations }
const newRelations = item.relations?.filter(r => r.related_items_id !== id)
const updatedItem = { id: item.id, relations: newRelations }
let success = false
try {
@ -72,7 +73,7 @@ export const unlinkItem = async (id: string, item, updateItem) => {
toast.error(error.toString())
}
if (success) {
updateItem({ ...item, relations: new_relations })
updateItem({ ...item, relations: newRelations })
toast.success('Item unlinked')
}
}
@ -101,22 +102,24 @@ export const handleDelete = async (event: React.MouseEvent<HTMLElement>, item, s
export const onUpdateItem = async (state, item, tags, addTag, setLoading, navigate, updateItem, addItem, user, params) => {
let changedItem = {} as Item
const offer_updates: Array<any> = []
const offerUpdates: Array<any> = []
// check for new offers
await state.offers?.map(o => {
const existingOffer = item?.offers?.find(t => t.tags_id === o.id)
existingOffer && offer_updates.push(existingOffer.id)
existingOffer && offerUpdates.push(existingOffer.id)
if (!existingOffer && !tags.some(t => t.id === o.id)) addTag({ ...o, offer_or_need: true })
!existingOffer && offer_updates.push({ items_id: item?.id, tags_id: o.id })
!existingOffer && offerUpdates.push({ items_id: item?.id, tags_id: o.id })
return null
})
const needs_updates: Array<any> = []
const needsUpdates: Array<any> = []
await state.needs?.map(n => {
const existingNeed = item?.needs?.find(t => t.tags_id === n.id)
existingNeed && needs_updates.push(existingNeed.id)
!existingNeed && needs_updates.push({ items_id: item?.id, tags_id: n.id })
existingNeed && needsUpdates.push(existingNeed.id)
!existingNeed && needsUpdates.push({ items_id: item?.id, tags_id: n.id })
!existingNeed && !tags.some(t => t.id === n.id) && addTag({ ...n, offer_or_need: true })
return null
})
// update profile item in current state
@ -136,22 +139,24 @@ export const onUpdateItem = async (state, item, tags, addTag, setLoading, naviga
...state.markerIcon && { markerIcon: state.markerIcon },
next_appointment: state.nextAppointment,
...state.image.length > 10 && { image: state.image },
...state.offers.length > 0 && { offers: offer_updates },
...state.needs.length > 0 && { needs: needs_updates }
...state.offers.length > 0 && { offers: offerUpdates },
...state.needs.length > 0 && { needs: needsUpdates }
}
const offers_state: Array<any> = []
const needs_state: Array<any> = []
const offersState: Array<any> = []
const needsState: Array<any> = []
state.offers.map(o => {
offers_state.push({ items_id: item?.id, tags_id: o.id })
offersState.push({ items_id: item?.id, tags_id: o.id })
return null
})
state.needs.map(n => {
needs_state.push({ items_id: item?.id, tags_id: n.id })
needsState.push({ items_id: item?.id, tags_id: n.id })
return null
})
changedItem = { ...changedItem, offers: offers_state, needs: needs_state }
changedItem = { ...changedItem, offers: offersState, needs: needsState }
setLoading(true)
@ -159,6 +164,7 @@ export const onUpdateItem = async (state, item, tags, addTag, setLoading, naviga
if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
addTag({ id: crypto.randomUUID(), name: encodeTag(tag.slice(1).toLocaleLowerCase()), color: randomColor() })
}
return null
})
// take care that addTag request comes before item request

View File

@ -16,8 +16,8 @@ export const AttestationForm = ({ api }:{api?:ItemsApi<any>}) => {
useEffect(() => {
const params = new URLSearchParams(location.search)
const to_user_ids = params.get('to')
setUsers(items.filter(i => to_user_ids?.includes(i.id)))
const toUserIds = params.get('to')
setUsers(items.filter(i => toUserIds?.includes(i.id)))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [items, location])

View File

@ -9,7 +9,7 @@ export const DateUserInfo = ({ item }: { item: Item }) => {
{
infoExpanded
? <p className={'tw-italic tw-min-h-[21px] !tw-my-0 tw-text-gray-500'} onClick={() => setInfoExpanded(false)} >{`${item.date_updated && item.date_updated != item.date_created ? 'updated' : 'posted'} ${item && item.user_created && item.user_created.first_name ? `by ${item.user_created.first_name}` : ''} ${item.date_updated ? timeAgo(item.date_updated) : timeAgo(item.date_created!)}`}</p>
? <p className={'tw-italic tw-min-h-[21px] !tw-my-0 tw-text-gray-500'} onClick={() => setInfoExpanded(false)} >{`${item.date_updated && item.date_updated !== item.date_created ? 'updated' : 'posted'} ${item && item.user_created && item.user_created.first_name ? `by ${item.user_created.first_name}` : ''} ${item.date_updated ? timeAgo(item.date_updated) : timeAgo(item.date_created!)}`}</p>
: <p className="!tw-my-0 tw-min-h-[21px] tw-font-bold tw-cursor-pointer tw-text-gray-500" onClick={() => setInfoExpanded(true)}></p>
}
<div className='tw-grow '></div>

View File

@ -39,7 +39,7 @@ export const EmojiPicker = ({ selectedEmoji, selectedColor, selectedShape, setSe
<>
<div
onClick={toggleDropdown}
className={`tw-cursor-pointer ${selectedEmoji == 'select badge' ? 'tw-text-sm !tw-p-9 tw-text-center ' : 'tw-text-6xl'} tw-mask tw-mask-${selectedShape} tw-p-6 tw-bg-[${selectedColor}]`}
className={`tw-cursor-pointer ${selectedEmoji === 'select badge' ? 'tw-text-sm !tw-p-9 tw-text-center ' : 'tw-text-6xl'} tw-mask tw-mask-${selectedShape} tw-p-6 tw-bg-[${selectedColor}]`}
>
{selectedEmoji}
</div>
@ -51,7 +51,7 @@ export const EmojiPicker = ({ selectedEmoji, selectedColor, selectedShape, setSe
<button
key={emoji}
onClick={() => selectEmoji(emoji)}
className={`tw-cursor-pointer tw-text-2xl tw-p-2 hover:tw-bg-base-200 tw-rounded-md ${emoji == selectedEmoji && 'tw-bg-base-300'}`}
className={`tw-cursor-pointer tw-text-2xl tw-p-2 hover:tw-bg-base-200 tw-rounded-md ${emoji === selectedEmoji && 'tw-bg-base-300'}`}
>
{emoji}
</button>
@ -62,7 +62,7 @@ export const EmojiPicker = ({ selectedEmoji, selectedColor, selectedShape, setSe
{shapes.map(shape => (
<div
key={shape}
className={`tw-cursor-pointer hover:tw-bg-base-200 tw-rounded-md tw-p-2 ${shape == selectedShape && 'tw-bg-base-300'}`}
className={`tw-cursor-pointer hover:tw-bg-base-200 tw-rounded-md tw-p-2 ${shape === selectedShape && 'tw-bg-base-300'}`}
onClick={() => selectShape(shape)}>
<div className={`tw-h-12 tw-mask tw-mask-${shape} tw-bg-neutral-content`}></div>
</div>
@ -73,7 +73,7 @@ export const EmojiPicker = ({ selectedEmoji, selectedColor, selectedShape, setSe
{colors.map(color => (
<div
key={color}
className={`tw-cursor-pointer hover:tw-bg-base-200 tw-rounded-md tw-p-2 tw-flex tw-justify-center tw-items-center ${color == selectedColor && 'tw-bg-base-300'}`}
className={`tw-cursor-pointer hover:tw-bg-base-200 tw-rounded-md tw-p-2 tw-flex tw-justify-center tw-items-center ${color === selectedColor && 'tw-bg-base-300'}`}
onClick={() => selectColor(color)}>
<div className={`tw-h-8 tw-w-8 tw-rounded-full tw-bg-[${color}]`}></div>
</div>

View File

@ -38,11 +38,14 @@ export const MarketView = () => {
i?.layer?.itemOffersField && getValue(i, i.layer.itemOffersField)?.map(o => {
const tag = tags.find(t => t.id === o.tags_id)
tag && setOffers(current => [...current, tag])
return null
})
i?.layer?.itemNeedsField && getValue(i, i.layer.itemNeedsField)?.map(n => {
const tag = tags.find(t => t.id === n.tags_id)
tag && setNeeds(current => [...current, tag])
return null
})
return null
})
console.log(offers)

View File

@ -46,7 +46,7 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, plusButt
const filterTags = useFilterTags()
const getItemTags = useGetItemTags()
const layer = layers.find(l => l.name == layerName)
const layer = layers.find(l => l.name === layerName)
const submitNewItem = async (evt: any) => {
evt.preventDefault()
@ -61,6 +61,7 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, plusButt
if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
addTag({ id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() })
}
return null
})
const uuid = crypto.randomUUID()
let success = false
@ -109,7 +110,7 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, plusButt
{
items?.filter(i => i.layer?.name === layerName)
.filter(item =>
filterTags.length == 0 ? item : filterTags.some(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))
filterTags.length === 0 ? item : filterTags.some(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))
?.sort((a, b) => {
// Convert date_created to milliseconds, handle undefined by converting to lowest possible date (0 milliseconds)
const dateA = a.date_updated ? new Date(a.date_updated).getTime() : a.date_created ? new Date(a.date_created).getTime() : 0
@ -122,7 +123,7 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, plusButt
</div>
))
}
{addItemPopupType == 'place' && (
{addItemPopupType === 'place' && (
<form ref={tabRef} autoComplete='off' onSubmit={e => submitNewItem(e)}>
<div className='tw-cursor-pointer tw-break-inside-avoid tw-card tw-border-[1px] tw-border-base-300 tw-card-body tw-shadow-xl tw-bg-base-100 tw-text-base-content tw-p-6 tw-mb-10'>
<label className="tw-btn tw-btn-sm tw-rounded-2xl tw-btn-circle tw-btn-ghost hover:tw-bg-transparent tw-absolute tw-right-0 tw-top-0 tw-text-gray-600" onClick={() => setAddItemPopupType('')}>

View File

@ -6,7 +6,7 @@ import { Link } from 'react-router-dom'
export const SelectUser = ({ userType }: { userType: string }) => {
const items = useItems()
const users = items.filter(i => i.layer?.itemType.name == userType)
const users = items.filter(i => i.layer?.itemType.name === userType)
const assetsApi = useAssetApi()
const [selectedUsers, setSelectedUsers] = useState<Array<string>>([])

View File

@ -1,6 +1,6 @@
export function decodeTag (string : string) {
let formatedTag = string.replace(/_/g, '\u00A0')
return formatedTag = formatedTag.charAt(0).toUpperCase() + formatedTag.slice(1)
const formatedTag = string.replace(/_/g, '\u00A0')
return formatedTag.charAt(0).toUpperCase() + formatedTag.slice(1)
}
export function encodeTag (string : string) {

View File

@ -1,8 +1,8 @@
export const randomColor = () => {
return hsvToHex((Math.random() + golden_ratio_conjugate) % 1, 0.8, 0.7)
}
const goldenRatioConjugate = 0.618033988749895
const golden_ratio_conjugate = 0.618033988749895
export const randomColor = () => {
return hsvToHex((Math.random() + goldenRatioConjugate) % 1, 0.8, 0.7)
}
function hsvToHex (h, s, v) {
let r, g, b

View File

@ -3,6 +3,13 @@
import * as React from 'react'
import { ItemFormPopupProps } from './Components/Map/Subcomponents/ItemFormPopup'
export interface Tag {
color: string;
id: string;
name: string;
offer_or_need?: boolean
}
export interface UtopiaMapProps {
height?: string,
width?: string,
@ -17,8 +24,24 @@ export interface UtopiaMapProps {
infoText? : string
}
export interface ItemType {
name: string;
[key: string]: any;
}
export interface ItemsApi<T> {
getItems(): Promise<any>,
getItem?(id: string): Promise<any>,
createItem?(item : T): Promise<any>,
updateItem?(item : T): Promise<any>,
deleteItem?(id : string): Promise<any>,
collectionName?: string
}
export interface LayerProps {
id?: string,
// eslint-disable-next-line no-use-before-define
data?: Item[],
children?: React.ReactNode,
name: string,
@ -53,10 +76,18 @@ export interface LayerProps {
clusterRef?: any
}
export interface ItemType {
name: string;
[key: string]: any;
export class Geometry {
type: string
coordinates: number[]
constructor (lng: number, lat: number) {
this.coordinates = [lng, lat]
this.type = 'Point'
}
}
export type Relation = {
related_items_id: string;
[key: string]: any;
}
export class Item {
@ -87,45 +118,18 @@ export class Item {
}
}
export class Geometry {
type: string
coordinates: number[]
constructor (lng: number, lat: number) {
this.coordinates = [lng, lat]
this.type = 'Point'
}
}
export interface Tag {
color: string;
id: string;
name: string;
offer_or_need?: boolean
}
export interface ItemsApi<T> {
getItems(): Promise<any>,
getItem?(id: string): Promise<any>,
createItem?(item : T): Promise<any>,
updateItem?(item : T): Promise<any>,
deleteItem?(id : string): Promise<any>,
collectionName?: string
}
export interface AssetsApi {
upload(file: Blob, title: string): any,
url: string
}
export interface UserApi {
register(email: string, password: string, userName: string): Promise<void>,
login(email: string, password: string): Promise<any>,
logout(): Promise<void>,
getUser(): Promise<UserItem>,
getToken(): Promise<any>,
updateUser(user: UserItem): Promise<void>,
requestPasswordReset(email:string, reset_url?:string),
passwordReset(token:string, new_password:string)
export type Profile = {
id?: string;
avatar?: string;
color?: string;
name: string;
text: string;
geoposition?: Geometry
}
export type UserItem = {
@ -138,13 +142,15 @@ export type UserItem = {
}
export type Profile = {
id?: string;
avatar?: string;
color?: string;
name: string;
text: string;
geoposition?: Geometry
export interface UserApi {
register(email: string, password: string, userName: string): Promise<void>,
login(email: string, password: string): Promise<any>,
logout(): Promise<void>,
getUser(): Promise<UserItem>,
getToken(): Promise<any>,
updateUser(user: UserItem): Promise<void>,
requestPasswordReset(email:string, reset_url?:string),
passwordReset(token:string, new_password:string)
}
export type PermissionCondition = {
@ -156,6 +162,8 @@ export type PermissionCondition = {
};
};
export type PermissionAction = 'create'|'read'|'update'|'delete';
export type Permission = {
id?: string;
role: string;
@ -165,10 +173,3 @@ export type Permission = {
_and: PermissionCondition[];
};
};
export type PermissionAction = 'create'|'read'|'update'|'delete';
export type Relation = {
related_items_id: string;
[key: string]: any;
}