Improve frontend UI/UX: accessibility, discoverability, and cleanup

- Add prefers-reduced-motion support (global CSS + SwipeCard spring config)
- Add dismissible map click hint overlay with localStorage persistence
- Replace generic image alt text with descriptive property info across 4 components
- Rename filter buttons to clarify intent (Show Matching Listings / Scrape New from Rightmove)
- Fix mobile FAB overlap with bottom sheet via dynamic snap-aware positioning
- Add swipe review onboarding overlay with gesture explanations and button labels
- Delete unused components: AppSidebar, ActiveQuery, SavedView
This commit is contained in:
Viktor Barzin 2026-02-22 18:47:09 +00:00
parent 268f4fd272
commit 339e2cf2ab
No known key found for this signature in database
GPG key ID: 0EB088298288D958
13 changed files with 143 additions and 354 deletions

View file

@ -46,6 +46,9 @@ export function SwipeReviewMode({
const [currentIndex, setCurrentIndex] = useState(0);
const [history, setHistory] = useState<HistoryEntry[]>([]);
const [showOnboarding, setShowOnboarding] = useState(() => {
return localStorage.getItem('swipe-review-onboarded') !== 'true';
});
const handleSwipe = useCallback(
(direction: 'left' | 'right' | 'up') => {
@ -142,41 +145,85 @@ export function SwipeReviewMode({
{/* Action buttons */}
{!isFinished && (
<div className="flex items-center justify-center gap-6 py-6 px-4">
<Button
variant="outline"
size="lg"
className="rounded-full h-14 w-14 border-red-300 text-red-500 hover:bg-red-50"
onClick={() => handleSwipe('left')}
>
<X className="h-6 w-6" />
</Button>
<div className="flex flex-col items-center gap-1">
<Button
variant="outline"
size="lg"
className="rounded-full h-14 w-14 border-red-300 text-red-500 hover:bg-red-50"
onClick={() => handleSwipe('left')}
>
<X className="h-6 w-6" />
</Button>
<span className="text-xs text-muted-foreground">Dislike</span>
</div>
<Button
variant="outline"
size="sm"
className="rounded-full h-10 w-10"
onClick={handleUndo}
disabled={history.length === 0}
>
<Undo2 className="h-4 w-4" />
</Button>
<div className="flex flex-col items-center gap-1">
<Button
variant="outline"
size="sm"
className="rounded-full h-10 w-10"
onClick={handleUndo}
disabled={history.length === 0}
>
<Undo2 className="h-4 w-4" />
</Button>
<span className="text-xs text-muted-foreground">Undo</span>
</div>
<Button
variant="outline"
size="sm"
className="rounded-full h-10 w-10"
onClick={() => handleSwipe('up')}
>
<ArrowUp className="h-4 w-4" />
</Button>
<div className="flex flex-col items-center gap-1">
<Button
variant="outline"
size="sm"
className="rounded-full h-10 w-10"
onClick={() => handleSwipe('up')}
>
<ArrowUp className="h-4 w-4" />
</Button>
<span className="text-xs text-muted-foreground">Skip</span>
</div>
<div className="flex flex-col items-center gap-1">
<Button
variant="outline"
size="lg"
className="rounded-full h-14 w-14 border-green-300 text-green-500 hover:bg-green-50"
onClick={() => handleSwipe('right')}
>
<Heart className="h-6 w-6" />
</Button>
<span className="text-xs text-muted-foreground">Like</span>
</div>
</div>
)}
{/* Onboarding overlay */}
{showOnboarding && (
<div className="absolute inset-0 z-50 bg-black/60 flex flex-col items-center justify-center gap-8 p-8">
<div className="flex items-center gap-12 text-white">
<div className="flex flex-col items-center gap-2">
<X className="h-10 w-10 text-red-400" />
<span className="text-sm font-medium">Swipe left</span>
<span className="text-xs text-white/70">Dislike</span>
</div>
<div className="flex flex-col items-center gap-2">
<ArrowUp className="h-10 w-10 text-white/80" />
<span className="text-sm font-medium">Swipe up</span>
<span className="text-xs text-white/70">Skip</span>
</div>
<div className="flex flex-col items-center gap-2">
<Heart className="h-10 w-10 text-green-400" />
<span className="text-sm font-medium">Swipe right</span>
<span className="text-xs text-white/70">Like</span>
</div>
</div>
<Button
variant="outline"
size="lg"
className="rounded-full h-14 w-14 border-green-300 text-green-500 hover:bg-green-50"
onClick={() => handleSwipe('right')}
variant="secondary"
onClick={() => {
setShowOnboarding(false);
localStorage.setItem('swipe-review-onboarded', 'true');
}}
>
<Heart className="h-6 w-6" />
Got it
</Button>
</div>
)}