Small fixes

This commit is contained in:
Andras Schmelczer 2026-03-28 09:29:56 +00:00
parent d93beb9201
commit 7591e5fc05
12 changed files with 198 additions and 14 deletions

View file

@ -11,6 +11,8 @@ import InfoPopup from '../ui/InfoPopup';
import { FeatureInfoPopup } from '../ui/FeatureInfoPopup';
import { FeatureActions } from '../ui/FeatureIcons';
import { FeatureLabel } from '../ui/FeatureLabel';
import { getFeatureIcon } from '../../lib/feature-icons';
import { getGroupIcon } from '../../lib/group-icons';
import AiFilterInput from './AiFilterInput';
import type { AiFilterErrorType } from '../../hooks/useAiFilters';
import FeatureBrowser from './FeatureBrowser';
@ -552,6 +554,12 @@ export default memo(function Filters({
clampMax ? feature.max! : displayValue[1],
];
const mobileIconClass = 'w-4 h-4 text-teal-600 dark:text-teal-400 shrink-0';
const mobileIcon = getFeatureIcon(feature.name, mobileIconClass) || (() => {
const G = feature.group ? getGroupIcon(feature.group) : null;
return G ? <G className={mobileIconClass} /> : null;
})();
return (
<div
key={feature.name}
@ -559,7 +567,7 @@ export default memo(function Filters({
className={`space-y-0.5 px-2 py-1.5 rounded ${isActive ? 'ring-2 ring-teal-400 bg-teal-50 dark:bg-teal-900/30' : isPinned ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
>
<div className="flex items-center justify-between gap-1">
<FeatureLabel feature={feature} size="sm" className="min-w-0 shrink" />
<FeatureLabel feature={feature} size="sm" className="min-w-0 shrink" hideIconOnMobile />
<FeatureActions
feature={feature}
isPinned={isPinned}
@ -568,7 +576,9 @@ export default memo(function Filters({
onRemove={onRemoveFilter}
/>
</div>
<div>
<div className="flex md:block items-start gap-1.5">
{mobileIcon && <div className="md:hidden shrink-0 pt-0.5">{mobileIcon}</div>}
<div className="min-w-0 flex-1">
<Slider
min={scale ? 0 : feature.min!}
max={scale ? 100 : feature.max!}
@ -606,6 +616,7 @@ export default memo(function Filters({
feature={feature}
onValueChange={(v) => onFilterChange(feature.name, v)}
/>
</div>
</div>
</div>
);

View file

@ -338,6 +338,18 @@ export default function MapPage({
return () => document.removeEventListener('wheel', handleWheel);
}, []);
// On mobile, push a guard history entry to absorb accidental back navigations
// (e.g. iOS Safari edge-swipe that CSS touch-action can't prevent)
useEffect(() => {
if (!isMobile) return;
window.history.pushState({ dashboardGuard: true }, '');
const handlePopState = () => {
window.history.pushState({ dashboardGuard: true }, '');
};
window.addEventListener('popstate', handlePopState);
return () => window.removeEventListener('popstate', handlePopState);
}, [isMobile]);
const { handleHexagonClick } = selection;
const handleMobileHexagonClick = useCallback(
(id: string, isPostcode?: boolean, geometry?: PostcodeGeometry) => {
@ -611,7 +623,7 @@ export default function MapPage({
if (isMobile) {
return (
<div className="flex-1 flex flex-col overflow-hidden relative">
<div className="flex-1 flex flex-col overflow-hidden relative touch-pan-y">
{initialLoading && (
<div className="absolute inset-0 z-50 flex items-center justify-center bg-warm-50/80 dark:bg-navy-950/80 backdrop-blur-sm">
<div className="flex flex-col items-center gap-4">

View file

@ -15,6 +15,7 @@ interface FeatureLabelProps {
className?: string;
size?: 'xs' | 'sm';
description?: string;
hideIconOnMobile?: boolean;
}
export function FeatureLabel({
@ -23,9 +24,11 @@ export function FeatureLabel({
className = '',
size = 'xs',
description,
hideIconOnMobile,
}: FeatureLabelProps) {
const textClass = size === 'sm' ? 'text-sm' : 'text-xs';
const iconClass = 'w-3.5 h-3.5 text-teal-600 dark:text-teal-400 shrink-0';
const mobileHide = hideIconOnMobile ? 'hidden md:block ' : '';
const iconClass = `${mobileHide}w-3.5 h-3.5 text-teal-600 dark:text-teal-400 shrink-0`;
const featureIcon = getFeatureIcon(feature.name, iconClass);
const GroupIcon = !featureIcon && feature.group ? getGroupIcon(feature.group) : null;
const modeTag =

View file

@ -57,7 +57,7 @@ export function useHexagonSelection({
const filterStr = buildFilterString(filters, features);
if (filterStr) params.append('filters', filterStr);
if (fields) {
params.set('fields', fields.join(','));
params.set('fields', fields.join(';;'));
}
if (journeyDest) {
params.set('journey_mode', journeyDest.mode);