diff --git a/src/components/SasquatchGuide.tsx b/src/components/SasquatchGuide.tsx index 7725b41..45ba9f8 100644 --- a/src/components/SasquatchGuide.tsx +++ b/src/components/SasquatchGuide.tsx @@ -621,7 +621,7 @@ Instructions: ref={dragRef} className={cn( 'z-50 touch-none select-none', - dragPos ? '' : 'fixed bottom-[9.5rem] right-4 md:bottom-6 md:right-auto md:left-4', + dragPos ? '' : 'fixed bottom-[9.5rem] left-4 md:bottom-6 md:left-4', )} style={bubbleStyle} onPointerDown={onPointerDown} diff --git a/src/pages/MapPage.tsx b/src/pages/MapPage.tsx index 358ebf7..f9c6b43 100644 --- a/src/pages/MapPage.tsx +++ b/src/pages/MapPage.tsx @@ -18,6 +18,7 @@ import { Skeleton } from '@/components/ui/skeleton'; import { Progress } from '@/components/ui/progress'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { LoginArea } from '@/components/auth/LoginArea'; import { useSkateSpots } from '@/hooks/useSkateSpots'; @@ -70,6 +71,7 @@ import { LocateOff, Store, Info, + Layers, } from 'lucide-react'; import { CameraCapture } from '@/components/CameraCapture'; import { useUploadFile } from '@/hooks/useUploadFile'; @@ -585,6 +587,11 @@ export default function MapPage() { return () => window.removeEventListener('sasquatch:panelchange', handler); }, []); + // Mobile "Add" speed-dial (fans out Add Spot / Shop / Tour / Quick Snap) + const [addDialOpen, setAddDialOpen] = useState(false); + // Mobile layers popover + const [layersOpen, setLayersOpen] = useState(false); + // Quick camera capture const [showQuickCamera, setShowQuickCamera] = useState(false); const { mutateAsync: uploadFile, isPending: isUploadingQuickPhoto } = useUploadFile(); @@ -890,6 +897,8 @@ export default function MapPage() { // Count active layer filters for mobile badge const activeLayerCount = [showSpots, showShops, showGear, showTours, showBtcMap].filter(Boolean).length; + // Count of the 4 primary layers active — shown as a badge on the mobile Layers button + const mobileLayerCount = [showSpots, showShops, showGear, showTours].filter(Boolean).length; const activeCategoryCount = selectedCategories.length; const totalActiveFilters = activeCategoryCount + (trustFilter !== 'all' ? 1 : 0) + (sortBy !== 'recent' ? 1 : 0); @@ -1486,20 +1495,23 @@ export default function MapPage() { )} - {/* Right-side control strip — layer toggles + Near Me + Snap (mobile only) */} + {/* ── Mobile map controls (redesigned) ────────────────────────── + Right edge holds just TWO small controls: Near Me + Layers. + Primary "Add" action is a speed-dial FAB (bottom-right). This + replaces the old 12-item vertical strip. */}
{/* Near Me */} - {/* Divider */} -
- - {/* Layer toggles — slim pill style */} - {[ - { key: 'spots', emoji: '🛹', active: showSpots, toggle: () => setShowSpots(v => !v) }, - { key: 'shops', emoji: '🏪', active: showShops, toggle: () => setShowShops(v => !v) }, - { key: 'gear', emoji: '🛒', active: showGear, toggle: () => setShowGear(v => !v) }, - { key: 'tours', emoji: '🗺️', active: showTours, toggle: () => setShowTours(v => !v) }, - ].map(({ key, emoji, active, toggle }) => ( - - ))} - - {/* Divider + Add actions + Quick Snap */} - {user && ( - <> -
- {/* Add Spot */} - - - - {/* Add Shop */} - - - -
- {/* Quick Snap */} + {/* Layers popover — labelled toggles with color dots */} + + - - )} + + +

Show on Map

+
+ {[ + { key: 'spots', label: 'Spots', dot: '#ff0040', active: showSpots, toggle: () => setShowSpots(v => !v) }, + { key: 'shops', label: 'Shops', dot: '#a855f7', active: showShops, toggle: () => setShowShops(v => !v) }, + { key: 'gear', label: 'Gear', dot: '#f97316', active: showGear, toggle: () => setShowGear(v => !v) }, + { key: 'tours', label: 'Tours', dot: '#06b6d4', active: showTours, toggle: () => setShowTours(v => !v) }, + ].map(({ key, label, dot, active, toggle }) => ( + + ))} +
+
+
+ + {/* ── Add speed-dial FAB (mobile, logged in) ──────────────────── */} + {user && ( +
+ {/* Fan-out actions */} + {addDialOpen && ( + <> + {[ + { label: 'Add Spot', to: '/create-spot', bg: 'bg-[#ff0040]', icon: }, + { label: 'Add Shop', to: '/create-shop', bg: 'bg-[#a855f7]', icon: }, + { label: 'Offer Tour', to: '/create-tour', bg: 'bg-[#06b6d4]', icon: }, + ].map((a, i) => ( + setAddDialOpen(false)} + className="flex items-center gap-2.5 animate-in fade-in slide-in-from-bottom-2 duration-200" + style={{ animationDelay: `${i * 40}ms` }} + > + + {a.label} + + + {a.icon} + + + ))} + {/* Quick Snap */} + + + )} + + {/* Main FAB */} + +
+ )} + + {/* Tap-catcher to close the speed-dial */} + {addDialOpen && ( +
setAddDialOpen(false)} + /> + )} ) : (