mirror of
https://github.com/soconnor0919/lewisburg-coffee.git
synced 2026-02-04 15:46:32 -05:00
feat: Refine glassmorphism styling for light and dark themes and synchronize app theme with map style selection.
This commit is contained in:
@@ -21,7 +21,7 @@ export default function HomePage() {
|
||||
}, []);
|
||||
|
||||
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-background text-foreground font-serif">
|
||||
{/* Navbar - always visible */}
|
||||
<Navbar isDiscoveryOpen={isDiscoveryOpen} onToggleDiscovery={() => setIsDiscoveryOpen(!isDiscoveryOpen)} />
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export function AboutModal({ isOpen, onClose }: AboutModalProps) {
|
||||
<div className="flex justify-center">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="gap-2 border-glass-border bg-glass-border/20 hover:bg-glass-border text-glass-text-primary hover:text-white"
|
||||
className="gap-2 border-glass-border bg-glass-border/20 hover:bg-glass-border text-glass-text-primary"
|
||||
asChild
|
||||
>
|
||||
<a href="https://github.com/soconnor0919/lewisburg-coffee" target="_blank" rel="noopener noreferrer">
|
||||
|
||||
@@ -86,15 +86,15 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(e) => toggleFavorite(activeShop.id, e)}
|
||||
className="bg-black/40 hover:bg-black/60 text-white rounded-full h-8 w-8 backdrop-blur-md border border-glass-border"
|
||||
className="bg-glass-background hover:bg-glass-border text-glass-text-primary rounded-full h-8 w-8 backdrop-blur-md border border-glass-border"
|
||||
>
|
||||
<Heart className={`w-4 h-4 ${favorites.has(activeShop.id) ? 'fill-red-500 text-red-500' : 'text-white'}`} />
|
||||
<Heart className={`w-4 h-4 ${favorites.has(activeShop.id) ? 'fill-red-500 text-red-500' : 'text-glass-text-primary'}`} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={onClose}
|
||||
className="bg-black/40 hover:bg-black/60 text-white rounded-full h-8 w-8 backdrop-blur-md border border-glass-border"
|
||||
className="bg-glass-background hover:bg-glass-border text-glass-text-primary rounded-full h-8 w-8 backdrop-blur-md border border-glass-border"
|
||||
>
|
||||
<ChevronLeft className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -105,7 +105,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
onClose();
|
||||
if (onToggleOpen) onToggleOpen();
|
||||
}}
|
||||
className="bg-black/40 hover:bg-black/60 text-white rounded-full h-8 w-8 backdrop-blur-md border border-glass-border"
|
||||
className="bg-glass-background hover:bg-glass-border text-glass-text-primary rounded-full h-8 w-8 backdrop-blur-md border border-glass-border"
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
</Button>
|
||||
@@ -119,8 +119,8 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
className="absolute inset-0 z-10 flex items-center justify-center"
|
||||
style={FADE_BOTTOM_STYLE}
|
||||
>
|
||||
<Skeleton className="h-full w-full absolute inset-0 bg-white/5" />
|
||||
<Coffee className="h-12 w-12 text-white/20 animate-pulse relative z-20" />
|
||||
<Skeleton className="h-full w-full absolute inset-0 bg-glass-border" />
|
||||
<Coffee className="h-12 w-12 text-glass-text-secondary/20 animate-pulse relative z-20" />
|
||||
</div>
|
||||
)}
|
||||
<div className="absolute inset-0 z-0">
|
||||
@@ -150,7 +150,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<Button className="w-full bg-white text-black hover:bg-white/90 gap-2 font-medium" asChild>
|
||||
<Button className="w-full bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90 gap-2 font-medium" asChild>
|
||||
<a
|
||||
href={`https://www.google.com/maps/dir/?api=1&destination=${activeShop.lat},${activeShop.lng}`}
|
||||
target="_blank"
|
||||
@@ -162,7 +162,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
</Button>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{activeShop.website && (
|
||||
<Button variant="outline" className="w-full border-glass-border text-glass-text-primary hover:bg-glass-border hover:text-white gap-2 text-xs" asChild>
|
||||
<Button variant="outline" className="w-full border-glass-border text-glass-text-primary hover:bg-glass-border hover:text-glass-text-primary gap-2 text-xs" asChild>
|
||||
<a href={activeShop.website} target="_blank" rel="noopener noreferrer">
|
||||
<Globe className="w-3.5 h-3.5" />
|
||||
Website
|
||||
@@ -170,7 +170,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
</Button>
|
||||
)}
|
||||
{activeShop.phone && (
|
||||
<Button variant="outline" className="w-full border-glass-border text-glass-text-primary hover:bg-glass-border hover:text-white gap-2 text-xs" asChild>
|
||||
<Button variant="outline" className="w-full border-glass-border text-glass-text-primary hover:bg-glass-border hover:text-glass-text-primary gap-2 text-xs" asChild>
|
||||
<a href={`tel:${activeShop.phone}`}>
|
||||
<Phone className="w-3.5 h-3.5" />
|
||||
Call
|
||||
@@ -207,7 +207,7 @@ export default function Drawer({ shop, shops, onSelect, onClose, isOpen, onToggl
|
||||
<ScrollArea className="flex-1 min-h-0">
|
||||
<div className="p-4 space-y-6">
|
||||
{filteredShops.length === 0 ? (
|
||||
<div className="text-center py-8 text-white/40">
|
||||
<div className="text-center py-8 text-glass-text-secondary/60">
|
||||
<Coffee className="h-12 w-12 mx-auto mb-3 opacity-20" />
|
||||
<p>No shops found matching "{searchQuery}"</p>
|
||||
</div>
|
||||
@@ -272,13 +272,13 @@ function ShopListItem({ shop, onSelect, isFavorite, onToggleFavorite }: { shop:
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-6 w-6 -mr-1 -mt-1 hover:bg-white/10 text-glass-text-secondary hover:text-red-500"
|
||||
className="h-6 w-6 -mr-1 -mt-1 hover:bg-glass-border text-glass-text-secondary hover:text-red-500"
|
||||
onClick={(e) => onToggleFavorite(shop.id, e)}
|
||||
>
|
||||
<Heart className={`w-4 h-4 ${isFavorite ? 'fill-red-500 text-red-500' : ''}`} />
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-sm text-glass-text-secondary leading-snug group-hover:text-white/80 transition-colors line-clamp-2">{shop.address}</p>
|
||||
<p className="text-sm text-glass-text-secondary leading-snug group-hover:text-glass-text-primary transition-colors line-clamp-2">{shop.address}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -72,7 +72,7 @@ export function LocateControl() {
|
||||
size="icon"
|
||||
onClick={handleLocate}
|
||||
disabled={loading}
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border hover:text-white"
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border"
|
||||
>
|
||||
<Locate className={`h-5 w-5 ${loading ? 'animate-pulse' : ''}`} />
|
||||
<span className="sr-only">Locate me</span>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import * as React from "react";
|
||||
import { Layers, Moon, Sun, Globe } from "lucide-react";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { useTheme } from "next-themes";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -16,24 +17,33 @@ interface MapStyleControlProps {
|
||||
}
|
||||
|
||||
export function MapStyleControl({ currentStyle, onStyleChange }: MapStyleControlProps) {
|
||||
const { setTheme } = useTheme();
|
||||
|
||||
const handleStyleChange = (style: string) => {
|
||||
onStyleChange(style);
|
||||
if (style === "dark") setTheme("dark");
|
||||
if (style === "light") setTheme("light");
|
||||
if (style === "satellite") setTheme("dark"); // Satellite looks better with dark UI
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="icon" className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border hover:text-white">
|
||||
<Button variant="outline" size="icon" className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border">
|
||||
<Layers className="h-5 w-5" />
|
||||
<span className="sr-only">Change map style</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-40 bg-background/90 backdrop-blur-xl">
|
||||
<DropdownMenuItem onClick={() => onStyleChange("dark")} className={currentStyle === "dark" ? "bg-accent" : ""}>
|
||||
<DropdownMenuContent align="end" className="w-40 bg-glass-background backdrop-blur-xl border-glass-border">
|
||||
<DropdownMenuItem onClick={() => handleStyleChange("dark")} className={`text-glass-text-primary focus:bg-glass-border focus:text-glass-text-primary cursor-pointer ${currentStyle === "dark" ? "bg-glass-border" : ""}`}>
|
||||
<Moon className="mr-2 h-4 w-4" />
|
||||
Dark
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => onStyleChange("light")} className={currentStyle === "light" ? "bg-accent" : ""}>
|
||||
<DropdownMenuItem onClick={() => handleStyleChange("light")} className={`text-glass-text-primary focus:bg-glass-border focus:text-glass-text-primary cursor-pointer ${currentStyle === "light" ? "bg-glass-border" : ""}`}>
|
||||
<Sun className="mr-2 h-4 w-4" />
|
||||
Light
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => onStyleChange("satellite")} className={currentStyle === "satellite" ? "bg-accent" : ""}>
|
||||
<DropdownMenuItem onClick={() => handleStyleChange("satellite")} className={`text-glass-text-primary focus:bg-glass-border focus:text-glass-text-primary cursor-pointer ${currentStyle === "satellite" ? "bg-glass-border" : ""}`}>
|
||||
<Globe className="mr-2 h-4 w-4" />
|
||||
Satellite
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Coffee, Search, X } from "lucide-react";
|
||||
import { Coffee, PanelLeft, X } from "lucide-react";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "~/components/ui/tooltip";
|
||||
import { useState, useEffect } from "react";
|
||||
@@ -59,9 +59,9 @@ export default function Navbar({ isDiscoveryOpen, onToggleDiscovery }: NavbarPro
|
||||
setIsOnboarding(false);
|
||||
localStorage.setItem('discovery-panel-hint-seen', 'true');
|
||||
}}
|
||||
className={`h-10 w-10 rounded-lg transition-colors ${isDiscoveryOpen ? 'bg-glass-border text-amber-500' : 'text-glass-text-primary hover:bg-glass-border hover:text-white'}`}
|
||||
className={`h-10 w-10 rounded-lg transition-colors ${isDiscoveryOpen ? 'bg-glass-border text-amber-500' : 'text-glass-text-primary hover:bg-glass-border'}`}
|
||||
>
|
||||
<Search className="h-5 w-5" />
|
||||
<PanelLeft className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle Panel</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
@@ -97,7 +97,7 @@ export default function Navbar({ isDiscoveryOpen, onToggleDiscovery }: NavbarPro
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setShowAbout(false)}
|
||||
className="absolute top-4 right-4 text-glass-text-secondary hover:text-white hover:bg-glass-border"
|
||||
className="absolute top-4 right-4 text-glass-text-secondary hover:text-glass-text-primary hover:bg-glass-border"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</Button>
|
||||
@@ -107,15 +107,15 @@ export default function Navbar({ isDiscoveryOpen, onToggleDiscovery }: NavbarPro
|
||||
<Coffee className="w-8 h-8 text-amber-500" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold font-serif">Lewisburg Coffee Map</h2>
|
||||
<p className="text-white/60 font-serif leading-relaxed">
|
||||
<p className="text-glass-text-secondary font-serif leading-relaxed">
|
||||
Discover the best coffee spots in Lewisburg, PA. Click on any marker to learn more about each location,
|
||||
or use the discovery panel to browse and search all available shops.
|
||||
</p>
|
||||
|
||||
<div className="w-full h-px bg-white/10 my-4" />
|
||||
<div className="w-full h-px bg-glass-border my-4" />
|
||||
|
||||
<div className="text-xs text-white/60 space-y-2 font-sans w-full text-left">
|
||||
<p><strong className="text-white/80">Features:</strong></p>
|
||||
<div className="text-xs text-glass-text-secondary space-y-2 font-sans w-full text-left">
|
||||
<p><strong className="text-glass-text-primary">Features:</strong></p>
|
||||
<ul className="list-disc list-inside space-y-1 ml-2">
|
||||
<li>Interactive map with coffee shop locations</li>
|
||||
<li>Search and filter coffee shops</li>
|
||||
@@ -123,9 +123,9 @@ export default function Navbar({ isDiscoveryOpen, onToggleDiscovery }: NavbarPro
|
||||
<li>Get directions to any shop</li>
|
||||
<li>Light/Dark theme support</li>
|
||||
</ul>
|
||||
<div className="pt-4 border-t border-white/10 mt-4">
|
||||
<p>Map Data © <a href="https://www.openstreetmap.org/copyright" className="underline hover:text-white transition-colors">OpenStreetMap</a> contributors</p>
|
||||
<p>Tiles © <a href="https://carto.com/attributions" className="underline hover:text-white transition-colors">CARTO</a></p>
|
||||
<div className="pt-4 border-t border-glass-border mt-4">
|
||||
<p>Map Data © <a href="https://www.openstreetmap.org/copyright" className="underline hover:text-glass-text-primary transition-colors">OpenStreetMap</a> contributors</p>
|
||||
<p>Tiles © <a href="https://carto.com/attributions" className="underline hover:text-glass-text-primary transition-colors">CARTO</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +88,7 @@ export function WelcomeModal() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<Button onClick={handleClose} className="w-full sm:w-auto min-w-[120px] bg-white text-black hover:bg-white/90">
|
||||
<Button onClick={handleClose} className="w-full sm:w-auto min-w-[120px] bg-black text-white hover:bg-black/90 dark:bg-white dark:text-black dark:hover:bg-white/90">
|
||||
Start Exploring
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ export function ZoomControls() {
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => map.zoomIn()}
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border hover:text-white"
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border"
|
||||
>
|
||||
<Plus className="h-5 w-5" />
|
||||
<span className="sr-only">Zoom in</span>
|
||||
@@ -22,7 +22,7 @@ export function ZoomControls() {
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => map.zoomOut()}
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border hover:text-white"
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border"
|
||||
>
|
||||
<Minus className="h-5 w-5" />
|
||||
<span className="sr-only">Zoom out</span>
|
||||
@@ -31,7 +31,7 @@ export function ZoomControls() {
|
||||
variant="outline"
|
||||
size="icon"
|
||||
onClick={() => map.setView([40.9645, -76.8845], 15)}
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border hover:text-white"
|
||||
className="rounded-xl border border-glass-border bg-glass-background text-glass-text-primary shadow-lg backdrop-blur-md transition-all hover:bg-glass-border"
|
||||
>
|
||||
<Home className="h-5 w-5" />
|
||||
<span className="sr-only">Reset view</span>
|
||||
|
||||
@@ -53,11 +53,11 @@
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
/* ... existing vars ... */
|
||||
--glass-background: rgba(0, 0, 0, 0.7);
|
||||
--glass-border: rgba(255, 255, 255, 0.15);
|
||||
--glass-text-primary: rgba(255, 255, 255, 0.95);
|
||||
--glass-text-secondary: rgba(255, 255, 255, 0.70);
|
||||
|
||||
--glass-background: rgba(255, 255, 255, 0.75);
|
||||
--glass-border: rgba(0, 0, 0, 0.1);
|
||||
--glass-text-primary: rgba(0, 0, 0, 0.9);
|
||||
--glass-text-secondary: rgba(0, 0, 0, 0.6);
|
||||
|
||||
--background: oklch(1 0 0);
|
||||
/* ... */
|
||||
--foreground: oklch(0.145 0 0);
|
||||
@@ -93,6 +93,11 @@
|
||||
}
|
||||
|
||||
.dark {
|
||||
--glass-background: rgba(0, 0, 0, 0.6);
|
||||
--glass-border: rgba(255, 255, 255, 0.15);
|
||||
--glass-text-primary: rgba(255, 255, 255, 0.95);
|
||||
--glass-text-secondary: rgba(255, 255, 255, 0.70);
|
||||
|
||||
--background: oklch(0.145 0 0);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.205 0 0);
|
||||
@@ -130,7 +135,8 @@
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user