-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
frontend - add clear filter button #5275 #5413
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
When I click clear filters, it also clears my selected location. IMO it shouldn't clear location but everything else. But deferring to @jesseallhands what do you think? |
/** | ||
* Checks if filters are applied | ||
*/ | ||
useEffect(() => { | ||
const filtersActive = | ||
queryName !== "" || | ||
lastActiveFilter !== 0 || | ||
hostingStatusFilter.length !== 0 || | ||
numberOfGuestFilter !== undefined || | ||
completeProfileFilter !== false || | ||
(locationResult?.location.lng !== 0 && | ||
locationResult?.location.lat !== 0); | ||
|
||
setAreFiltersApplied(filtersActive); | ||
}, [ | ||
queryName, | ||
lastActiveFilter, | ||
hostingStatusFilter, | ||
numberOfGuestFilter, | ||
completeProfileFilter, | ||
locationResult, | ||
]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay first of all, this was a great first attempt, and it pretty much works! Well done taking this on as one of your first tickets as honestly the map is confusing even for me!
A few notes on things I'd change due to the approach:
First a caveat - this isn't how I'd ideally do this in i.e. a day job, normally I'd just send an api call to the backend to clear everything and that would return an updated response, which would update the UI.
BUT we cache the result and filter it on the frontend, which is why that doesn't work here.
Given we will refactor the map soon anyway, this is how I'd go about it as a stop gap:
We already have a very similar useEffect to the one you created for wasSearchPerformed
in the parent component SearchPage so IMO we want to avoid another one.
Also I'd generally try to keep this functionality in the same place the values are set in useState, which is in SearchPage.
Since you are correctly clearing the values there, we just need a variable to pass down to say "hey the filters changed refilter the user pin results in this component. Your function is already updating the state, which is re-running the api call and regenerating "result", which gets passed down to MapWrapper
.
So IMO we just need to tell MapWrapper the search was cleared as the actual functionality is already there.
I'd simplify it a bit like so:
- In SearchPage create a useState variable
areFiltersCleared, setAreFiltersCleared
and set it to true as a default value - When you run the handleClearFilters function in SearchPage, set this to true
- In SearchPage, in the useEffect that checks if
if (!wasSearchPerformed)
create an else to the inner if clause that checks if everything is 0 or undefined, andsetAreFiltersCleared
false there - In MapWrapper, in the useEffect that re-renders users list on map, change
wasSearchedPerformed
to{wasSearchPerformed || areFilltersCleared)
I thiiiiink that should do it but let me know if not!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thank you so much for the detailed feedback and explanation Nicole! Really appreciate it!
I've made the changes you outlined, however I just want to call out that updating the useEffect that checks if if (!wasSearchPerformed)
in SearchPage differed a bit from what you proposed... this was to ensure that the areFiltersCleared state was properly updated all the time, not just upon the first search. LMK if this makes more sense now.
* Clicks on 'clear filters' button | ||
*/ | ||
const handleClearFiltersOnClick = () => { | ||
handleClearFilters(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a standard practice, I'd change the prop name from handleClearFilters to
onClearFiltersClick`.
Generally the handle functions update the state in that same component. If passing down to a child component, name it the action it does instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated! That makes sense thanks for the info.
The thing is, this is not "clear filters" (AFAIK) this is show all the users, and to do that we need to delete everything (including the location) because we can't apply filters/search a location when we display all the users on the map... |
It should clear location as well, but not reset the map position. If we don't clear location we still have the problem that users cannot see all of the pins on the map which is one of the main problems we are trying to resolve with this button. |
@nabramow hmmm that's weird the border radius is rounded for you. On my vercel preview and on my localhost mine looks like this (with the filter buttons intentionally squashed together but no border radius where they're touching) UPDATE: I re-ran all of my environments locally and now mine is showing like your screenshot... vercel preview still shows as intended though (weird). I will defer to initial design of equal border radius and margin since it is the most simple fix, unless you say otherwise. |
@nabramow @jesseallhands @bakeiro |
… the map position
const onClearFiltersClick = () => { | ||
const currentBbox = map.current?.getBounds().toArray(); | ||
if (currentBbox) { | ||
const bbox: [number, number, number, number] = [ | ||
currentBbox[0][0], | ||
currentBbox[0][1], | ||
currentBbox[1][0], | ||
currentBbox[1][1], | ||
]; | ||
handleClearFilters(bbox); | ||
} else { | ||
handleClearFilters(); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry it's the other way. Name the original function "handleClearFiltersClick", but when you pass it as a prop, name it 'onClickFiltersClick'.
That's because the function is "handling" it, but when you pass it you want to see the action it's doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aha! Okay just updated all of that. Thank you :)
Yes, sounds correct! I tested it on mobile but it doesn't appear to be working. See video below where you can see the "clear filters" button never is clickable despite a location filter (Berlin) being applied. Also, when I click "search here" the button also is not clickable despite the "search here" filter parameter being applied: Screen_Recording_20250103_110626_Firefox.mp4 |
@@ -105,7 +107,9 @@ export default function SearchPage({ | |||
>(); | |||
|
|||
const [isFiltersOpen, setIsFiltersOpen] = useState(false); | |||
const [areFiltersCleared, setAreFiltersCleared] = useState(true); | |||
const [areFiltersCleared, setAreFiltersCleared] = useState( | |||
locationResult.name === "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if locationResult is not finished loading? It's risky to make one state variable dependent on another in the same component. Curious why not just set it to true by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is set to true by default then the clear filters button will be disabled on initial render, even if the map is initially rendered with a location filter (ie: someone searched Berlin from the homepage) which is an issue. I see what you mean about the risk of making one state variable dependent on another though... I am thinking to change it to make it dependent on the locationName prop instead. Does that seem like a good fix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like locationName and bbox are passed in the props from the parent component to SearchPage
. I assume that's coming from the dashboard (please check). If so you could use that instead, something like locationName.length > 0
as the default value.
@@ -160,9 +162,9 @@ export default function SearchPage({ | |||
numberOfGuestFilter !== undefined || | |||
completeProfileFilter !== false || | |||
queryName !== "" || | |||
(locationResult.location.lng !== 0 && locationResult.location.lat !== 0); | |||
locationResult.name != "" || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want locationResult.name !== ""
here (two equal signs)
setQueryName(""); | ||
setLocationResult({ | ||
bbox: bbox || [0, 0, 0, 0], | ||
bbox: [390, 82, -173, -66], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these hardcoded numbers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are the hardcoded numbers that set the original map position on initial render, so upon clearing filters I set them back to the same numbers to remain consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhh gotcha okay!
Yeah these are both outstanding issues! David is working on 1 in #5294 and 2 I've come across before. Definitely things we should fix, but they existed before this PR so you don't need to address here. |
@@ -81,7 +81,9 @@ export default function SearchPage({ | |||
const isMobile = useMediaQuery(theme.breakpoints.down("md")); | |||
|
|||
// State | |||
const [wasSearchPerformed, setWasSearchPerformed] = useState(false); | |||
const [wasSearchPerformed, setWasSearchPerformed] = useState( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[David here] maybe a boolean it's better than empty string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like setting the wasSearchPerformed
to false can show all the users on the map?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry if I review this late, I've been busy lately 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nexagoai locationName !== ""
does return a boolean.
@@ -105,6 +107,9 @@ export default function SearchPage({ | |||
>(); | |||
|
|||
const [isFiltersOpen, setIsFiltersOpen] = useState(false); | |||
const [areFiltersCleared, setAreFiltersCleared] = useState( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey David @nexagoai! If it is set to true by default then the clear filters button will be disabled on initial render, even if the map is initially rendered with a location filter (ie: someone searched Berlin from the homepage) which is an issue. That's why it's currently set to a conditional that checks whether it should be true or false
}: mapWrapperProps) { | ||
const { t } = useTranslation([SEARCH]); | ||
const [areClustersLoaded, setAreClustersLoaded] = useState(false); | ||
const [isMapStyleLoaded, setIsMapStyleLoaded] = useState(false); | ||
const [isMapSourceLoaded, setIsMapSourceLoaded] = useState(false); | ||
const previousResult = usePrevious(selectedResult); | ||
const classes = useStyles(); | ||
const theme = useTheme(); | ||
const isMobile = useMediaQuery(theme.breakpoints.down("sm")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const isMobile = useMediaQuery(theme.breakpoints.down("sm")); | |
const isMobile = useMediaQuery(theme.breakpoints.down("md")); |
Medium here to represent mobile as it doesn't include the size defined. So this would mean "below medium" rather than "medium and below".
@@ -1,5 +1,6 @@ | |||
import ReplayIcon from "@mui/icons-material/Replay"; | |||
import TuneIcon from "@mui/icons-material/Tune"; | |||
import { useMediaQuery, useTheme } from "@mui/material"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than useTheme
you can just import our customized theme:
import { theme } from "theme";
Okay functionality-wise this is working great for me on both mobile and web. Happy to approve just those two small changes! |
@nabramow Awesome, thanks! I've made the final 2 updates so should be ready for approval. Note- the vercel deployment failed (for what seemed like no reason just a weird hiccup) so the last 2 commits were just to fix it and have it regenerate the vercel preview (I just moved an import 1 line down and then back again because of linting). All good now though and all checks pass :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! Thanks for your persistence on this one! 🚀
closes #5275
part of #5341
Web frontend checklist
yarn format
yarn lint --fix