feat: add PWA manifest and Apple icon, and enhance map with fly-to selected shop functionality.

This commit is contained in:
2025-12-05 02:03:56 -05:00
parent 97bcf5e61c
commit b31d488e25
5 changed files with 88 additions and 3 deletions

34
src/app/apple-icon.tsx Normal file
View File

@@ -0,0 +1,34 @@
import { ImageResponse } from 'next/og';
export const runtime = 'edge';
export const size = {
width: 32,
height: 32,
};
export const contentType = 'image/png';
export default function Icon() {
return new ImageResponse(
(
<div
style={{
fontSize: 24,
background: '#8B4513',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
borderRadius: '20%',
}}
>
</div>
),
{
...size,
}
);
}

View File

@@ -1,6 +1,6 @@
import "~/styles/globals.css";
import { type Metadata } from "next";
import { type Metadata, type Viewport } from "next";
import { PT_Serif } from "next/font/google";
import { ThemeProvider } from "~/components/ThemeProvider";
@@ -11,6 +11,14 @@ export const metadata: Metadata = {
icons: [{ rel: "icon", url: "/favicon.ico" }],
};
export const viewport: Viewport = {
themeColor: "#8B4513",
width: "device-width",
initialScale: 1,
maximumScale: 1,
userScalable: false,
};
const ptSerif = PT_Serif({
subsets: ["latin"],
weight: ["400", "700"],

25
src/app/manifest.ts Normal file
View File

@@ -0,0 +1,25 @@
import { type MetadataRoute } from 'next';
export default function manifest(): MetadataRoute.Manifest {
return {
name: 'Lewisburg Coffee Map',
short_name: 'Coffee Map',
description: 'Find the best coffee in Lewisburg, PA',
start_url: '/',
display: 'standalone',
background_color: '#ffffff',
theme_color: '#8B4513',
icons: [
{
src: '/favicon.ico',
sizes: 'any',
type: 'image/x-icon',
},
{
src: '/icon.svg',
sizes: 'any',
type: 'image/svg+xml',
}
],
};
}

View File

@@ -17,6 +17,7 @@ export default function HomePage() {
<MapLoader
shops={COFFEE_SHOPS}
onShopSelect={(shop: typeof COFFEE_SHOPS[0]) => setSelectedShop(shop)}
selectedShop={selectedShop}
/>
</div>

View File

@@ -1,6 +1,6 @@
"use client";
import { MapContainer, TileLayer, Marker } from 'react-leaflet';
import { MapContainer, TileLayer, Marker, useMap } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
import { useState, useEffect } from 'react';
@@ -24,9 +24,25 @@ interface CoffeeShop {
interface MapProps {
shops: CoffeeShop[];
onShopSelect: (shop: CoffeeShop) => void;
selectedShop: CoffeeShop | null;
}
const Map = ({ shops, onShopSelect }: MapProps) => {
const MapController = ({ selectedShop }: { selectedShop: CoffeeShop | null }) => {
const map = useMap();
useEffect(() => {
if (selectedShop) {
map.flyTo([selectedShop.lat, selectedShop.lng], 16, {
duration: 1.5,
easeLinearity: 0.25,
});
}
}, [selectedShop, map]);
return null;
};
const Map = ({ shops, onShopSelect, selectedShop }: MapProps) => {
useEffect(() => {
// Fix for Leaflet default icon not found
// @ts-expect-error Fix for Leaflet default icon not found
@@ -107,6 +123,7 @@ const Map = ({ shops, onShopSelect }: MapProps) => {
attributionControl={false}
>
<Navbar />
<MapController selectedShop={selectedShop} />
<div className="absolute bottom-8 right-4 z-[1000] flex flex-col gap-2 items-end">
<ZoomControls />
<MapStyleControl currentStyle={mapStyle} onStyleChange={handleStyleChange} />