{embedded &&
}
+
setValue(e.target.value)}
@@ -105,9 +106,10 @@ export const SearchControl = () => {
if (windowDimensions.width < 500) map.closePopup();
}}
onBlur={() => hide()} />
+ {value.length > 0 && }
+
}
{hideSuggestions || Array.from(geoResults).length == 0 && itemsResults.length == 0 && tagsResults.length == 0 && !isGeoCoordinate(value) || value.length == 0 ? "" :
{tagsResults.length > 0 &&
@@ -115,8 +117,6 @@ export const SearchControl = () => {
{tagsResults.slice(0, 3).map(tag => (
{
addFilterTag(tag)
- let params = new URLSearchParams(window.location.search);
- window.history.pushState({}, "", "/" + `${params ? `?${params}` : ""}`);
}}>
#{decodeTag(tag.name)}
diff --git a/src/Components/Map/Tags.tsx b/src/Components/Map/Tags.tsx
index 01277f34..2ef90b3e 100644
--- a/src/Components/Map/Tags.tsx
+++ b/src/Components/Map/Tags.tsx
@@ -3,7 +3,7 @@ import { useEffect } from 'react';
import { ItemsApi, Tag } from '../../types';
import { useSetTagData, useSetTagApi, useTags } from './hooks/useTags'
import { useLocation } from 'react-router-dom';
-import { useAddFilterTag, useResetFilterTags } from './hooks/useFilter';
+import { useAddFilterTag, useFilterTags, useResetFilterTags } from './hooks/useFilter';
export function Tags({data, api} : {data?: Tag[], api?: ItemsApi
}) {
const setTagData = useSetTagData();
@@ -19,16 +19,18 @@ const location = useLocation();
const addFilterTag = useAddFilterTag();
const resetFilterTags = useResetFilterTags();
const tags = useTags();
+const filterTags = useFilterTags()
useEffect(() => {
let params = new URLSearchParams(location.search);
- let urlTags = params.get("tags");
- resetFilterTags()
- urlTags?.split(",").map(urlTag => {
+ let urlTags = params.get("tags")?.split(",");
+ if(urlTags?.some(ut => !filterTags.find(ft => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase()))||filterTags?.some(ft => !urlTags?.find(ut => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase())))
+ {resetFilterTags()
+ urlTags?.map(urlTag => {
const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
tag && addFilterTag(tag)
- });
+ });}
}, [location, tags]);
diff --git a/src/Components/Map/UtopiaMap.tsx b/src/Components/Map/UtopiaMap.tsx
index e8780036..09fb6e1e 100644
--- a/src/Components/Map/UtopiaMap.tsx
+++ b/src/Components/Map/UtopiaMap.tsx
@@ -78,11 +78,11 @@ function UtopiaMap({
-
+
-
+
diff --git a/src/Components/Map/hooks/useFilter.tsx b/src/Components/Map/hooks/useFilter.tsx
index ac73bd86..3b8d5042 100644
--- a/src/Components/Map/hooks/useFilter.tsx
+++ b/src/Components/Map/hooks/useFilter.tsx
@@ -2,7 +2,7 @@ import { useCallback, useReducer, createContext, useContext } from "react";
import * as React from "react";
import { LayerProps, Tag } from "../../../types";
import { useLayers } from "./useLayers";
-import { useLocation } from "react-router-dom";
+import { useLocation, useNavigate } from "react-router-dom";
type ActionType =
| { type: "ADD_TAG"; tag: Tag }
@@ -63,6 +63,7 @@ function useFilterManager(initialTags: Tag[]): {
}, initialTags);
const initialLayers = useLayers()
+ const navigate = useNavigate()
const [visibleLayers, dispatchLayers] = useReducer((state: LayerProps[], action: ActionType) => {
switch (action.type) {
@@ -95,7 +96,8 @@ function useFilterManager(initialTags: Tag[]): {
let urlTags = params.get("tags");
if(!urlTags?.includes(tag.name))
params.set("tags", `${urlTags ? urlTags : ""}${urlTags? ',' : ''}${tag.name}`)
- window.history.pushState('','', "?" +params.toString());
+ navigate(location.pathname + `${params ? `?${params}` : ""}`);
+
dispatchTags({
type: "ADD_TAG",
@@ -117,11 +119,11 @@ function useFilterManager(initialTags: Tag[]): {
});
if(newUrlTags !== "") {
params.set("tags", `${newUrlTags}`)
- window.history.pushState('','', "?" +params.toString());
+ navigate(location.pathname + `${params ? `?${params}` : ""}`);
}
else {
-
- window.history.pushState('','', window.location.pathname);
+ params.delete("tags");
+ navigate(location.pathname + `${params ? `?${params}` : ""}`);
}
dispatchTags({
diff --git a/src/Components/Templates/ItemCard.tsx b/src/Components/Templates/ItemCard.tsx
index dfa62685..14dd7fc5 100644
--- a/src/Components/Templates/ItemCard.tsx
+++ b/src/Components/Templates/ItemCard.tsx
@@ -9,7 +9,10 @@ export const ItemCard = ({i,loading, url, parameterField, deleteCallback}:{i:Ite
const navigate = useNavigate();
return (
- navigate(url + getValue(i, parameterField))}>
+
{
+ let params = new URLSearchParams(window.location.search);
+ navigate(url + getValue(i, parameterField) + `${params ? `?${params}` : ""}`)
+ }}>
navigate("/edit-item/" + i.id)} deleteCallback={() => deleteCallback(i)}>
{i.layer?.itemType.show_start_end &&
diff --git a/src/Components/Templates/OverlayItemsIndexPage.tsx b/src/Components/Templates/OverlayItemsIndexPage.tsx
index 2045e5be..78b7b031 100644
--- a/src/Components/Templates/OverlayItemsIndexPage.tsx
+++ b/src/Components/Templates/OverlayItemsIndexPage.tsx
@@ -5,7 +5,7 @@ import { getValue } from '../../Utils/GetValue';
import { PopupStartEndInput, StartEndView, TextView } from '../Map';
import { PlusButton } from '../Profile/PlusButton';
import { TextInput, TextAreaInput } from '../Input';
-import { useAddTag, useTags } from '../Map/hooks/useTags';
+import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags';
import { toast } from 'react-toastify';
import { hashTagRegex } from '../../Utils/HashTagRegex';
import { randomColor } from '../../Utils/RandomColor';
@@ -16,6 +16,10 @@ import { MapOverlayPage } from './MapOverlayPage';
import { useAddItem, useItems, useRemoveItem } from '../Map/hooks/useItems';
import { DateUserInfo } from './DateUserInfo';
import { ItemCard } from './ItemCard';
+import { Control } from '../Map/Subcomponents/Controls/Control';
+import { SearchControl } from '../Map/Subcomponents/Controls/SearchControl';
+import { TagsControl } from '../Map/Subcomponents/Controls/TagsControl';
+import { useFilterTags } from '../Map/hooks/useFilter';
type breadcrumb = {
@@ -24,7 +28,7 @@ type breadcrumb = {
}
-export const OverlayItemsIndexPage = ({ url, layerName, parameterField, breadcrumbs, plusButton = true, children }: { layerName: string, url: string, parameterField: string, breadcrumbs: Array
, plusButton?: boolean, children?: ReactNode }) => {
+export const OverlayItemsIndexPage = ({ url, layerName, parameterField, plusButton = true }: { layerName: string, url: string, parameterField: string, plusButton?: boolean }) => {
@@ -41,8 +45,6 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, breadcru
scroll();
}, [addItemPopupType])
- const navigate = useNavigate();
-
const tags = useTags();
const addTag = useAddTag();
const { user } = useAuth();
@@ -51,15 +53,11 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, breadcru
const removeItem = useRemoveItem();
const layers = useLayers();
- useEffect(() => {
- console.log(items);
-
-
- }, [items])
+ const filterTags = useFilterTags();
+ const getItemTags = useGetItemTags();
const layer = layers.find(l => l.name == layerName);
-
const submitNewItem = async (evt: any) => {
evt.preventDefault();
const formItem: Item = {} as Item;
@@ -107,58 +105,59 @@ export const OverlayItemsIndexPage = ({ url, layerName, parameterField, breadcru
}
+
return (
<>
-
-
- {breadcrumbs &&
-
-
- {breadcrumbs.map((b, i) => - {b.name}
)}
-
-
}
-
-
- {
- items?.filter(i => i.layer?.name === layerName)
- .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;
- const dateB = b.date_updated ? new Date(b.date_updated).getTime() : b.date_created ? new Date(b.date_created).getTime() : 0;
- return dateB - dateA; // Subtracts milliseconds which are numbers
- })
- .map((i, k) => {
- return (
-
deleteItem(i)} >
- )
- })
- }
- {addItemPopupType == "place" ?
+
+
+
+
+
+
+
+
+
+ {
+ items?.filter(i => i.layer?.name === layerName).
+ filter(item =>
+ filterTags.length == 0 ? item : filterTags.every(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;
+ const dateB = b.date_updated ? new Date(b.date_updated).getTime() : b.date_created ? new Date(b.date_created).getTime() : 0;
+ return dateB - dateA; // Subtracts milliseconds which are numbers
+ })?.
+ map((i, k) => {
+ return (
+
deleteItem(i)} >
+ )
+ })
+ }
+ {addItemPopupType == "place" ?
-
- {children}
-
diff --git a/src/index.css b/src/index.css
index a5583f95..c46cd342 100644
--- a/src/index.css
+++ b/src/index.css
@@ -74,4 +74,28 @@ input[type="file"] {
.tw-tab-content .container {
height: 100%;
+}
+
+.masonry {
+ column-count: 1;
+ column-gap: 1.5rem;
+}
+.masonry-item {
+ break-inside: avoid;
+ margin-bottom: 1.5rem;
+}
+@media (min-width: 640px) {
+ .masonry {
+ column-count: 2;
+ }
+}
+@media (min-width: 1024px) {
+ .masonry {
+ column-count: 3;
+ }
+}
+@media (min-width: 1536px) {
+ .masonry {
+ column-count: 4;
+ }
}
\ No newline at end of file