improve
This commit is contained in:
parent
f03edb86c1
commit
e9e47fd811
10 changed files with 141 additions and 24 deletions
|
|
@ -7,7 +7,7 @@ import { useMapData } from '../../hooks/useMapData';
|
|||
import { usePOIData } from '../../hooks/usePOIData';
|
||||
import { useActualListings } from '../../hooks/useActualListings';
|
||||
import { buildTravelParam } from '../../lib/travel-params';
|
||||
import { useFilters } from '../../hooks/useFilters';
|
||||
import { useFilters, countEffectiveFilters } from '../../hooks/useFilters';
|
||||
import { useHexagonSelection } from '../../hooks/useHexagonSelection';
|
||||
import { usePaneResize } from '../../hooks/usePaneResize';
|
||||
import { useCollapsibleGroups } from '../../hooks/useCollapsibleGroups';
|
||||
|
|
@ -159,17 +159,49 @@ export default function MapPage({
|
|||
user?.isAdmin === true;
|
||||
const effectiveFilterCap = isLoggedIn ? REGISTERED_MAX_FILTERS : DEMO_MAX_FILTERS;
|
||||
const filterLimit = filtersUnlimited ? null : effectiveFilterCap;
|
||||
// On a shared link, non-paying users may view and adjust the shared filters but
|
||||
// not add new ones — so a richer shared search can't become a way around the cap.
|
||||
const lockFilterAdds = !filtersUnlimited && !!shareCode;
|
||||
// Which upsell the modal frames: a shared-link block, or a plain filter-cap hit.
|
||||
const upgradeReason: 'filters' | 'shared' = lockFilterAdds ? 'shared' : 'filters';
|
||||
// On a shared link, anonymous visitors may view and adjust the shared filters but
|
||||
// not add new ones. Keyed off login state (not paid status) so the "create a free
|
||||
// account to build your own" upsell isn't a dead-end — once registered, the user can
|
||||
// add filters up to their normal cap right there on the shared search. The
|
||||
// `!filtersUnlimited` term also excludes the non-interactive screenshot/OG render
|
||||
// (treated as unlimited above), which must show the shared filters in full.
|
||||
const lockFilterAdds = !isLoggedIn && !filtersUnlimited && !!shareCode;
|
||||
// A shared/bookmarked link can encode more filters than the viewer's tier allows.
|
||||
// The initial set is then trimmed to the cap (the server 400s the full request), so
|
||||
// the viewer would silently see a broader result than was shared. Count the effective
|
||||
// filters (folded + known to the backend, matching what the server counts) so stale
|
||||
// or unknown keys don't raise a false alarm; recomputed once features finish loading.
|
||||
const initialEffectiveFilterCount = useMemo(
|
||||
() =>
|
||||
countEffectiveFilters(initialFilters, features) + (initialTravelTime?.entries?.length ?? 0),
|
||||
[initialFilters, features, initialTravelTime]
|
||||
);
|
||||
// Gate on features being loaded: until then countEffectiveFilters can't drop unknown
|
||||
// keys and would over-count (firing the popup for a set that actually fits the cap).
|
||||
const sharedSearchTrimmed =
|
||||
features.length > 0 && !filtersUnlimited && initialEffectiveFilterCount > effectiveFilterCap;
|
||||
// Which upsell the modal frames: a shared-link context (lock, or a trimmed shared
|
||||
// search), or a plain filter-cap hit.
|
||||
const upgradeReason: 'filters' | 'shared' =
|
||||
lockFilterAdds || sharedSearchTrimmed ? 'shared' : 'filters';
|
||||
const [filterLimitHit, setFilterLimitHit] = useState(false);
|
||||
const handleFilterLimitReached = useCallback(() => {
|
||||
trackEvent('Upgrade Modal Shown');
|
||||
setFilterLimitHit(true);
|
||||
}, []);
|
||||
|
||||
// Pop the upgrade modal once when the shared/bookmarked search carried more filters
|
||||
// than the viewer's tier allows — so trimmed filters are surfaced, not silently
|
||||
// dropped. Fires when the signal first turns true (which may be after features finish
|
||||
// loading), and only once so dismissing it sticks.
|
||||
const overCapPopupShownRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (sharedSearchTrimmed && !overCapPopupShownRef.current) {
|
||||
overCapPopupShownRef.current = true;
|
||||
handleFilterLimitReached();
|
||||
}
|
||||
}, [sharedSearchTrimmed, handleFilterLimitReached]);
|
||||
|
||||
// Travel-time destinations count toward the same cap as feature filters (each one
|
||||
// restricts which properties match). Cap an over-budget initial travel set (from a
|
||||
// bookmarked/shared URL), preferring feature filters, so the first data request
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue