feat: Refactor drawer for improved animations and update shadow styles across components

This commit is contained in:
2025-12-05 13:52:15 -05:00
parent bdee155760
commit 17cc85d177
10 changed files with 279 additions and 182 deletions

View File

@@ -31,11 +31,14 @@ export default function RootLayout({
return ( return (
<html lang="en" className={`${ptSerif.variable}`} suppressHydrationWarning> <html lang="en" className={`${ptSerif.variable}`} suppressHydrationWarning>
<head> <head>
{/* only load analytics on production */}
{process.env.NODE_ENV === "production" && (
<script <script
defer defer
src="https://umami-iccw808w4wk088o0w4o8c8kg.coolify.soconnor.dev/script.js" src="https://umami-iccw808w4wk088o0w4o8c8kg.coolify.soconnor.dev/script.js"
data-website-id="415c64e5-98c5-4975-bf49-2c900fe6b1b5" data-website-id="415c64e5-98c5-4975-bf49-2c900fe6b1b5"
/> />
)}
</head> </head>
<body> <body>
<ThemeProvider <ThemeProvider

View File

@@ -22,8 +22,6 @@ export default function HomePage() {
return ( return (
<main className="relative h-dvh w-screen overflow-hidden bg-black text-white font-serif"> <main className="relative h-dvh w-screen overflow-hidden bg-black text-white font-serif">
{/* Unified shadow container for navbar + drawer */}
<div className="absolute top-0 left-0 right-0 bottom-0 pointer-events-none z-[1000]" style={{ boxShadow: 'inset 0 0 40px 10px rgb(0 0 0 / 0.3)' }}>
{/* Navbar - always visible */} {/* Navbar - always visible */}
<Navbar isDiscoveryOpen={isDiscoveryOpen} onToggleDiscovery={() => setIsDiscoveryOpen(!isDiscoveryOpen)} /> <Navbar isDiscoveryOpen={isDiscoveryOpen} onToggleDiscovery={() => setIsDiscoveryOpen(!isDiscoveryOpen)} />
@@ -38,7 +36,6 @@ export default function HomePage() {
onToggleOpen={() => setIsDiscoveryOpen(false)} onToggleOpen={() => setIsDiscoveryOpen(false)}
/> />
)} )}
</div>
{/* Map Background */} {/* Map Background */}
<div className="absolute inset-0 z-0"> <div className="absolute inset-0 z-0">
@@ -48,6 +45,7 @@ export default function HomePage() {
setSelectedShop(shop); setSelectedShop(shop);
}} }}
selectedShop={selectedShop} selectedShop={selectedShop}
isDiscoveryOpen={isDiscoveryOpen}
/> />
</div> </div>

View File

@@ -1,4 +1,4 @@
import { X, MapPin, Globe, Phone, Coffee, ExternalLink, Search, ChevronRight } from "lucide-react"; import { X, MapPin, Globe, Phone, Coffee, ExternalLink, Search, ChevronRight, ChevronLeft } from "lucide-react";
import { Card } from "~/components/ui/card"; import { Card } from "~/components/ui/card";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { ScrollArea } from "~/components/ui/scroll-area"; import { ScrollArea } from "~/components/ui/scroll-area";
@@ -31,10 +31,13 @@ interface DrawerProps {
export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggleOpen }: DrawerProps) { export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggleOpen }: DrawerProps) {
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
const [imageLoading, setImageLoading] = useState(true); const [imageLoading, setImageLoading] = useState(true);
const [activeShop, setActiveShop] = useState<CoffeeShop | null>(shop);
// Reset loading state when shop changes // Update activeShop when shop changes, but only if it's not null
// This allows us to keep displaying the shop details while animating out
useEffect(() => { useEffect(() => {
if (shop) { if (shop) {
setActiveShop(shop);
setImageLoading(true); setImageLoading(true);
} }
}, [shop]); }, [shop]);
@@ -46,21 +49,36 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
return ( return (
<div <div
className={`absolute top-20 left-0 h-[calc(100dvh-6rem)] w-full sm:w-[400px] z-30 p-4 pointer-events-none transition-transform duration-300 ease-in-out ${isOpen || shop ? 'translate-x-0' : '-translate-x-full'}`} className={`absolute top-20 left-0 h-[calc(100dvh-6rem)] w-full sm:w-[400px] z-30 px-4 pt-3 pointer-events-none transition-transform duration-300 ease-in-out ${isOpen || shop ? 'translate-x-0' : '-translate-x-full'}`}
> >
<Card className="h-full w-full bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 overflow-hidden flex flex-col gap-0 pointer-events-auto rounded-r-xl p-0 border-0 transition-all duration-300"> <Card className="h-full w-full bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 overflow-hidden relative shadow-xl rounded-r-xl border-0">
{shop ? ( {/* Details View */}
// Details View <div
// Details View className={`absolute inset-0 z-20 transition-transform duration-300 ease-in-out bg-background/80 backdrop-blur-3xl ${shop ? 'translate-x-0' : 'translate-x-full'}`}
>
{activeShop && (
<div className="h-full flex flex-col relative"> <div className="h-full flex flex-col relative">
<div className="absolute top-4 right-4 z-50 flex gap-2">
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon"
onClick={onClose} onClick={onClose}
className="absolute top-4 right-4 z-50 bg-background/20 hover:bg-background/40 text-foreground rounded-full h-8 w-8 backdrop-blur-md border border-border/50" className="bg-background/20 hover:bg-background/40 text-foreground rounded-full h-8 w-8 backdrop-blur-md border border-border/50"
>
<ChevronLeft className="w-4 h-4" />
</Button>
<Button
variant="ghost"
size="icon"
onClick={() => {
onClose();
if (onToggleOpen) onToggleOpen();
}}
className="bg-background/20 hover:bg-background/40 text-foreground rounded-full h-8 w-8 backdrop-blur-md border border-border/50"
> >
<X className="w-4 h-4" /> <X className="w-4 h-4" />
</Button> </Button>
</div>
<ScrollArea className="flex-1 min-h-0"> <ScrollArea className="flex-1 min-h-0">
{/* Header Image - Now part of scroll area */} {/* Header Image - Now part of scroll area */}
@@ -79,8 +97,8 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
)} )}
<div className="absolute inset-0 z-0"> <div className="absolute inset-0 z-0">
<img <img
src={shop.image} src={activeShop.image}
alt={shop.name} alt={activeShop.name}
className={`w-full h-full object-cover transition-opacity duration-500 ${imageLoading ? 'opacity-0' : 'opacity-100'}`} className={`w-full h-full object-cover transition-opacity duration-500 ${imageLoading ? 'opacity-0' : 'opacity-100'}`}
onLoad={() => setImageLoading(false)} onLoad={() => setImageLoading(false)}
style={{ style={{
@@ -93,23 +111,23 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
{/* Content - Overlaps image slightly or just follows */} {/* Content - Overlaps image slightly or just follows */}
<div className="p-8 -mt-12 relative z-10"> <div className="p-8 -mt-12 relative z-10">
<h2 className="text-3xl font-bold font-serif mb-4 text-primary leading-tight drop-shadow-md">{shop.name}</h2> <h2 className="text-3xl font-bold font-serif mb-4 text-primary leading-tight drop-shadow-md">{activeShop.name}</h2>
<div className="space-y-4 mb-8"> <div className="space-y-4 mb-8">
<div className="flex items-start gap-3 text-muted-foreground font-serif text-sm"> <div className="flex items-start gap-3 text-muted-foreground font-serif text-sm">
<MapPin className="w-5 h-5 text-primary flex-shrink-0 mt-0.5" /> <MapPin className="w-5 h-5 text-primary flex-shrink-0 mt-0.5" />
<span>{shop.address}</span> <span>{activeShop.address}</span>
</div> </div>
{shop.phone && ( {activeShop.phone && (
<div className="flex items-center gap-3 text-muted-foreground font-serif text-sm"> <div className="flex items-center gap-3 text-muted-foreground font-serif text-sm">
<Phone className="w-5 h-5 text-primary flex-shrink-0" /> <Phone className="w-5 h-5 text-primary flex-shrink-0" />
<a href={`tel:${shop.phone}`} className="hover:text-foreground transition-colors">{shop.phone}</a> <a href={`tel:${activeShop.phone}`} className="hover:text-foreground transition-colors">{activeShop.phone}</a>
</div> </div>
)} )}
{shop.website && ( {activeShop.website && (
<div className="flex items-center gap-3 text-muted-foreground font-serif text-sm"> <div className="flex items-center gap-3 text-muted-foreground font-serif text-sm">
<Globe className="w-5 h-5 text-primary flex-shrink-0" /> <Globe className="w-5 h-5 text-primary flex-shrink-0" />
<a href={shop.website} target="_blank" rel="noopener noreferrer" className="hover:text-foreground transition-colors flex items-center gap-1"> <a href={activeShop.website} target="_blank" rel="noopener noreferrer" className="hover:text-foreground transition-colors flex items-center gap-1">
Visit Website <ExternalLink className="w-3 h-3" /> Visit Website <ExternalLink className="w-3 h-3" />
</a> </a>
</div> </div>
@@ -122,7 +140,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
<div> <div>
<h3 className="text-lg font-semibold mb-2 text-foreground font-serif">About</h3> <h3 className="text-lg font-semibold mb-2 text-foreground font-serif">About</h3>
<p className="text-muted-foreground leading-relaxed font-serif text-lg"> <p className="text-muted-foreground leading-relaxed font-serif text-lg">
{shop.description} {activeShop.description}
</p> </p>
</div> </div>
@@ -132,7 +150,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
className="w-auto px-6 bg-primary/20 hover:bg-primary/40 text-foreground font-semibold rounded-lg shadow-lg transition-all hover:scale-[1.02] border border-primary/50 backdrop-blur-md" className="w-auto px-6 bg-primary/20 hover:bg-primary/40 text-foreground font-semibold rounded-lg shadow-lg transition-all hover:scale-[1.02] border border-primary/50 backdrop-blur-md"
> >
<a <a
href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(`${shop.name}, ${shop.address}`)}`} href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(`${activeShop.name}, ${activeShop.address}`)}`}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
@@ -143,10 +161,14 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
</div> </div>
</ScrollArea> </ScrollArea>
</div> </div>
) : ( )}
// List View </div>
<div className="flex flex-col h-full">
<div className="p-4 border-b border-border/50 bg-background/40 backdrop-blur-md relative"> {/* List View */}
<div
className={`absolute inset-0 z-10 transition-all duration-300 ease-in-out flex flex-col h-full bg-background/0 ${shop ? '-translate-x-1/4 opacity-0 pointer-events-none' : 'translate-x-0 opacity-100 pointer-events-auto'}`}
>
<div className="p-4 border-b border-border/50 relative">
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon"
@@ -160,7 +182,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
<Search className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" /> <Search className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
<Input <Input
placeholder="Search shops..." placeholder="Search shops..."
className="pl-9 bg-background/50 border-border/50 focus:bg-background transition-colors" className="pl-9 bg-background/20 border-border/50 focus:bg-background/40 transition-colors"
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
/> />
@@ -193,7 +215,6 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
</div> </div>
</ScrollArea> </ScrollArea>
</div> </div>
)}
</Card> </Card>
</div> </div>
); );

View File

@@ -72,7 +72,7 @@ export function LocateControl() {
size="icon" size="icon"
onClick={handleLocate} onClick={handleLocate}
disabled={loading} disabled={loading}
className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-2xl text-foreground" className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-xl text-foreground"
> >
<Locate className={`h-5 w-5 ${loading ? 'animate-pulse' : ''}`} /> <Locate className={`h-5 w-5 ${loading ? 'animate-pulse' : ''}`} />
<span className="sr-only">Locate me</span> <span className="sr-only">Locate me</span>

View File

@@ -3,7 +3,7 @@
import { MapContainer, TileLayer, Marker, Tooltip, useMap } from 'react-leaflet'; import { MapContainer, TileLayer, Marker, Tooltip, useMap } from 'react-leaflet';
import 'leaflet/dist/leaflet.css'; import 'leaflet/dist/leaflet.css';
import L from 'leaflet'; import L from 'leaflet';
import { useState, useEffect } from 'react'; import { useState, useEffect, useRef } from 'react';
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import { MapStyleControl } from "./MapStyleControl"; import { MapStyleControl } from "./MapStyleControl";
import { LocateControl } from './LocateControl'; import { LocateControl } from './LocateControl';
@@ -25,24 +25,91 @@ interface MapProps {
shops: CoffeeShop[]; shops: CoffeeShop[];
onShopSelect: (shop: CoffeeShop) => void; onShopSelect: (shop: CoffeeShop) => void;
selectedShop: CoffeeShop | null; selectedShop: CoffeeShop | null;
isDiscoveryOpen: boolean;
} }
const MapController = ({ selectedShop }: { selectedShop: CoffeeShop | null }) => { const MapController = ({ selectedShop, isDiscoveryOpen }: { selectedShop: CoffeeShop | null, isDiscoveryOpen: boolean }) => {
const map = useMap(); const map = useMap();
const prevOpenRef = useRef(isDiscoveryOpen);
useEffect(() => {
// Handle general panning when drawer toggles (and no shop is selected)
const isDesktop = window.innerWidth >= 640;
if (prevOpenRef.current !== isDiscoveryOpen) {
if (!selectedShop && isDesktop) {
// If opening, we want to shift the view to the right (so panning map left? wait)
// If drawer opens on LEFT, the center of the remaining view is to the RIGHT.
// We want the content to move into that new center.
// So we pan the map in the POSITIVE X direction?
// Test: map.panBy([200, 0]) moves the map image 200px to the RIGHT relative to the viewport.
// This means a point at x=0 moves to x=200.
// This puts it into the open area. Correct.
// Inverting based on user feedback that it shifted wrong way.
// Opening -> Shift Map Image Left (View Right?) -> offset [-200, 0]
// Closing -> Shift Map Image Right (View Left?) -> offset [200, 0]
const offset = isDiscoveryOpen ? [-200, 0] : [200, 0];
map.panBy(offset as [number, number], {
animate: true,
duration: 0.5
});
}
prevOpenRef.current = isDiscoveryOpen;
}
}, [isDiscoveryOpen, selectedShop, map]);
useEffect(() => { useEffect(() => {
if (selectedShop) { if (selectedShop) {
map.flyTo([selectedShop.lat, selectedShop.lng], 16, { const targetLat = selectedShop.lat;
const targetLng = selectedShop.lng;
// Calculate offset if discovery panel is open and we're on desktop
let flyToOption = {
duration: 1.5, duration: 1.5,
easeLinearity: 0.25, easeLinearity: 0.25,
}); };
const isDesktop = window.innerWidth >= 640;
if (isDiscoveryOpen && isDesktop) {
// We need to offset the center so the point appears to the right of the drawer
// The drawer is 400px wide. We want to shift the center left by 200px (half drawer width)
// so that the target point appears 200px to the right of current center
// Get current zoom
const zoom = 16;
// Project the lat/lng to point
const point = map.project([targetLat, targetLng], zoom);
// Subtract offset (shift 'center' to the left, which moves 'view' to the right? Wait.)
// If we want the point to be at x + 200 (screen coords relative to center),
// we need the map center to be at x - 200 relative to point.
// Actually simpler: We want the point (targetLat, targetLng) to be at screen coordinates (width/2 + 200, height/2).
// Or simply: shift the target point by -200px in x before passing to flyTo? No, flyTo takes strict LatLng.
// Correct approach:
// Find the LatLng that, when centered, puts our target LatLng at the desired pixels.
// Center + Offset = Target -> Center = Target - Offset
const targetPoint = map.project([targetLat, targetLng], zoom);
// We want the target to appear 200px (half drawer width) to the right of the map center.
// So the new center should be 200px LEFT of the target.
const newCenterPoint = targetPoint.subtract([200, 0]);
const newCenter = map.unproject(newCenterPoint, zoom);
map.flyTo(newCenter, zoom, flyToOption);
} else {
map.flyTo([targetLat, targetLng], 16, flyToOption);
} }
}, [selectedShop, map]); }
}, [selectedShop, map, isDiscoveryOpen]);
return null; return null;
}; };
const Map = ({ shops, onShopSelect, selectedShop }: MapProps) => { const Map = ({ shops, onShopSelect, selectedShop, isDiscoveryOpen }: MapProps) => {
useEffect(() => { useEffect(() => {
// Fix for Leaflet default icon not found // Fix for Leaflet default icon not found
// @ts-expect-error Fix for Leaflet default icon not found // @ts-expect-error Fix for Leaflet default icon not found
@@ -122,7 +189,7 @@ const Map = ({ shops, onShopSelect, selectedShop }: MapProps) => {
zoomControl={false} zoomControl={false}
attributionControl={false} attributionControl={false}
> >
<MapController selectedShop={selectedShop} /> <MapController selectedShop={selectedShop} isDiscoveryOpen={isDiscoveryOpen} />
<div className="absolute bottom-8 right-4 z-[1000] flex flex-col gap-2 items-end"> <div className="absolute bottom-8 right-4 z-[1000] flex flex-col gap-2 items-end">
<LocateControl /> <LocateControl />
<ZoomControls /> <ZoomControls />
@@ -141,7 +208,14 @@ const Map = ({ shops, onShopSelect, selectedShop }: MapProps) => {
click: () => onShopSelect(shop), click: () => onShopSelect(shop),
}} }}
> >
<Tooltip direction="top" offset={[0, -20]} opacity={0.9}> <Tooltip
key={`${shop.id}-${selectedShop?.id === shop.id}`}
direction="top"
offset={[0, -20]}
opacity={0.9}
permanent={selectedShop?.id === shop.id}
className={selectedShop?.id === shop.id ? 'force-show' : ''}
>
<div className="font-serif font-semibold text-sm"> <div className="font-serif font-semibold text-sm">
{shop.name} {shop.name}
</div> </div>

View File

@@ -20,6 +20,7 @@ interface MapLoaderProps {
shops: CoffeeShop[]; shops: CoffeeShop[];
onShopSelect: (shop: CoffeeShop) => void; onShopSelect: (shop: CoffeeShop) => void;
selectedShop: CoffeeShop | null; selectedShop: CoffeeShop | null;
isDiscoveryOpen: boolean;
} }
// Move dynamic import outside component to prevent re-imports // Move dynamic import outside component to prevent re-imports
@@ -36,6 +37,6 @@ const Map = dynamic(() => import("./Map"), {
), ),
}); });
export default function MapLoader({ shops, onShopSelect, selectedShop }: MapLoaderProps) { export default function MapLoader({ shops, onShopSelect, selectedShop, isDiscoveryOpen }: MapLoaderProps) {
return <Map shops={shops} onShopSelect={onShopSelect} selectedShop={selectedShop} />; return <Map shops={shops} onShopSelect={onShopSelect} selectedShop={selectedShop} isDiscoveryOpen={isDiscoveryOpen} />;
} }

View File

@@ -19,7 +19,7 @@ export function MapStyleControl({ currentStyle, onStyleChange }: MapStyleControl
return ( return (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-2xl text-foreground"> <Button variant="outline" size="icon" className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-xl text-foreground">
<Layers className="h-5 w-5" /> <Layers className="h-5 w-5" />
<span className="sr-only">Change map style</span> <span className="sr-only">Change map style</span>
</Button> </Button>

View File

@@ -1,4 +1,4 @@
import { Coffee, PanelLeft, X } from "lucide-react"; import { Coffee, Search, X } from "lucide-react";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "~/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "~/components/ui/tooltip";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
@@ -41,7 +41,7 @@ export default function Navbar({ isDiscoveryOpen, onToggleDiscovery }: NavbarPro
return ( return (
<> <>
<div className="absolute top-4 left-4 right-4 z-[1000] flex justify-center pointer-events-none"> <div className="absolute top-4 left-4 right-4 z-[1000] flex justify-center pointer-events-none">
<div className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border border-border/50 rounded-xl p-2 flex items-center justify-between w-full pointer-events-auto"> <div className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border border-border/50 rounded-xl p-2 flex items-center justify-between w-full pointer-events-auto shadow-xl">
<div className="flex items-center gap-2 relative"> <div className="flex items-center gap-2 relative">
{/* Pulsing indicator ring - only during onboarding */} {/* Pulsing indicator ring - only during onboarding */}
{isOnboarding && showTooltip && ( {isOnboarding && showTooltip && (
@@ -61,11 +61,11 @@ export default function Navbar({ isDiscoveryOpen, onToggleDiscovery }: NavbarPro
}} }}
className={`h-10 w-10 rounded-lg hover:bg-background/40 transition-colors ${isDiscoveryOpen ? 'bg-background/40 text-primary' : 'text-muted-foreground'}`} className={`h-10 w-10 rounded-lg hover:bg-background/40 transition-colors ${isDiscoveryOpen ? 'bg-background/40 text-primary' : 'text-muted-foreground'}`}
> >
<PanelLeft className="h-5 w-5" /> <Search className="h-5 w-5" />
<span className="sr-only">Toggle Panel</span> <span className="sr-only">Toggle Panel</span>
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent side="bottom" className="bg-background/80 backdrop-blur-xl border-border/50 text-foreground font-semibold shadow-2xl"> <TooltipContent side="right" className="bg-background/80 backdrop-blur-xl border-border/50 text-foreground font-semibold font-serif shadow-2xl">
<p>Discover Coffee Shops</p> <p>Discover Coffee Shops</p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>

View File

@@ -46,7 +46,7 @@ export function WelcomeModal() {
return ( return (
<Dialog open={open} onOpenChange={handleOpenChange}> <Dialog open={open} onOpenChange={handleOpenChange}>
<DialogContent className="sm:max-w-md bg-background/80 backdrop-blur-xl border-border/50"> <DialogContent className="sm:max-w-md bg-background/80 backdrop-blur-xl border-border/50 font-serif">
<DialogHeader> <DialogHeader>
<div className="mx-auto bg-primary/10 p-3 rounded-full mb-4 w-fit"> <div className="mx-auto bg-primary/10 p-3 rounded-full mb-4 w-fit">
<Coffee className="h-8 w-8 text-primary" /> <Coffee className="h-8 w-8 text-primary" />

View File

@@ -13,7 +13,7 @@ export function ZoomControls() {
variant="outline" variant="outline"
size="icon" size="icon"
onClick={() => map.zoomIn()} onClick={() => map.zoomIn()}
className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-2xl text-foreground hover:bg-background/70 dark:hover:bg-background/75" className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-xl text-foreground hover:bg-background/70 dark:hover:bg-background/75"
> >
<Plus className="h-5 w-5" /> <Plus className="h-5 w-5" />
<span className="sr-only">Zoom in</span> <span className="sr-only">Zoom in</span>
@@ -22,7 +22,7 @@ export function ZoomControls() {
variant="outline" variant="outline"
size="icon" size="icon"
onClick={() => map.zoomOut()} onClick={() => map.zoomOut()}
className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-2xl text-foreground hover:bg-background/70 dark:hover:bg-background/75" className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-xl text-foreground hover:bg-background/70 dark:hover:bg-background/75"
> >
<Minus className="h-5 w-5" /> <Minus className="h-5 w-5" />
<span className="sr-only">Zoom out</span> <span className="sr-only">Zoom out</span>
@@ -31,7 +31,7 @@ export function ZoomControls() {
variant="outline" variant="outline"
size="icon" size="icon"
onClick={() => map.setView([40.9645, -76.8845], 15)} onClick={() => map.setView([40.9645, -76.8845], 15)}
className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-2xl text-foreground hover:bg-background/70 dark:hover:bg-background/75" className="bg-background/60 dark:bg-background/65 backdrop-blur-2xl border-border/50 dark:border-border/50 h-10 w-10 rounded-lg shadow-xl text-foreground hover:bg-background/70 dark:hover:bg-background/75"
> >
<Home className="h-5 w-5" /> <Home className="h-5 w-5" />
<span className="sr-only">Reset view</span> <span className="sr-only">Reset view</span>