From dbe99290b83fc48ffb029da5924867fe90e2216f Mon Sep 17 00:00:00 2001 From: Sean O'Connor Date: Thu, 4 Dec 2025 23:58:30 -0500 Subject: [PATCH] feat: Add Radix UI components and data utility, refactor map markers, and integrate Navbar. --- bun.lock | 68 +++++++++++++++ package.json | 4 + src/app/layout.tsx | 11 +-- src/app/page.tsx | 106 +---------------------- src/components/Drawer.tsx | 114 +++++++++++++----------- src/components/Map.tsx | 32 ++++--- src/components/Navbar.tsx | 106 +++++++++++++++++++---- src/components/ui/button.tsx | 60 +++++++++++++ src/components/ui/card.tsx | 92 ++++++++++++++++++++ src/components/ui/scroll-area.tsx | 58 +++++++++++++ src/components/ui/separator.tsx | 28 ++++++ src/components/ui/sheet.tsx | 139 ++++++++++++++++++++++++++++++ src/lib/data.ts | 112 ++++++++++++++++++++++++ 13 files changed, 743 insertions(+), 187 deletions(-) create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/card.tsx create mode 100644 src/components/ui/scroll-area.tsx create mode 100644 src/components/ui/separator.tsx create mode 100644 src/components/ui/sheet.tsx create mode 100644 src/lib/data.ts diff --git a/bun.lock b/bun.lock index 789fb46..4886893 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,10 @@ "": { "name": "lewisburg-coffee", "dependencies": { + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-separator": "^1.1.8", + "@radix-ui/react-slot": "^1.2.4", "@t3-oss/env-nextjs": "^0.12.0", "@tanstack/react-query": "^5.69.0", "@trpc/client": "^11.0.0", @@ -167,6 +171,48 @@ "@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="], + "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], + + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], + + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], + + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], + + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], + + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], + + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], + + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], + + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], + + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], + + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], + + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], + + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + + "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="], + + "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g=="], + + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], + + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], + + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], + + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], + + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], + + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], + "@react-leaflet/core": ["@react-leaflet/core@3.0.0", "", { "peerDependencies": { "leaflet": "^1.9.0", "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ=="], "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], @@ -305,6 +351,8 @@ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="], @@ -387,6 +435,8 @@ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], @@ -479,6 +529,8 @@ "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], @@ -719,6 +771,12 @@ "react-leaflet": ["react-leaflet@5.0.0", "", { "dependencies": { "@react-leaflet/core": "^3.0.0" }, "peerDependencies": { "leaflet": "^1.9.0", "react": "^19.0.0", "react-dom": "^19.0.0" } }, "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw=="], + "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], @@ -835,6 +893,10 @@ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="], @@ -853,6 +915,12 @@ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-separator/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], diff --git a/package.json b/package.json index fd1ce4f..74edd4d 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,10 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-separator": "^1.1.8", + "@radix-ui/react-slot": "^1.2.4", "@t3-oss/env-nextjs": "^0.12.0", "@tanstack/react-query": "^5.69.0", "@trpc/client": "^11.0.0", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a69fc64..4c9e216 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,26 +1,27 @@ import "~/styles/globals.css"; import { type Metadata } from "next"; -import { Lora } from "next/font/google"; +import { PT_Serif } from "next/font/google"; import { TRPCReactProvider } from "~/trpc/react"; export const metadata: Metadata = { title: "Lewisburg Coffee Map", - description: "A guide to coffee in Lewisburg, PA", + description: "Interactive map of coffee shops in Lewisburg, PA", icons: [{ rel: "icon", url: "/favicon.ico" }], }; -const lora = Lora({ +const ptSerif = PT_Serif({ subsets: ["latin"], - variable: "--font-lora", + weight: ["400", "700"], + variable: "--font-pt-serif", }); export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return ( - + {children} diff --git a/src/app/page.tsx b/src/app/page.tsx index 8896645..53bf5ed 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,118 +2,14 @@ import { useState } from "react"; import MapLoader from "~/components/MapLoader"; -import Navbar from "~/components/Navbar"; import Drawer from "~/components/Drawer"; - -const COFFEE_SHOPS = [ - { - id: 1, - name: "Amami Kitchen", - description: "A beloved culinary spot offering a blend of high-quality Italian espresso and American coffee bar options, alongside mouthwatering baked goods and paninis.", - lat: 40.9547, - lng: -76.8841, - address: "103 S 6th St, Lewisburg, PA 17837", - phone: "(570) 490-7857", - website: "https://www.amamiespresso.com", - image: "https://images.unsplash.com/photo-1554118811-1e0d58224f24?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 2, - name: "Culture Coffee", - description: "A modern coffee shop focusing on unique brewing methods for specialty coffee and traditional techniques for matcha. Known for its 'Red Velvet Latte' and croissants.", - lat: 40.9660, - lng: -76.8820, - address: "216 St. John St, Lewisburg, PA 17837", - phone: "(570) 601-7903", - website: "https://www.instagram.com/culturecoffeee_", - image: "https://images.unsplash.com/photo-1509042239860-f550ce710b93?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 3, - name: "Bucknell 7th St Cafe", - description: "Bucknell's ultimate on-campus dessert and coffee shop. A cozy spot for students and visitors to enjoy milkshakes, ice cream, and specialty espresso drinks.", - lat: 40.9547, - lng: -76.8837, - address: "420 S 7th St, Lewisburg, PA 17837", - phone: "(570) 577-1240", - website: "https://www.bucknell.edu/life-bucknell/dining-services/places-eat", - image: "https://images.unsplash.com/photo-1559925393-8be0ec4767c8?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 4, - name: "Tastecraft Cafe", - description: "Downtown cafe known for its in-house roasted coffee and over 20 flavors of French macarons. A perfect spot to relax with a fresh brew and a sweet treat.", - lat: 40.9635, - lng: -76.8885, - address: "512 Market St, Lewisburg, PA 17837", - phone: "(570) 768-5340", - website: "https://www.tastecraftcafe.com", - image: "https://images.unsplash.com/photo-1556742049-0cfed4f7a07d?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 5, - name: "Paris Bakery", - description: "Authentic French bakery offering legendary croissants, pain au chocolat, and artisanal breads. Experience a taste of France in the heart of Lewisburg.", - lat: 40.9645, - lng: -76.8845, - address: "335 Market St, Lewisburg, PA 17837", - phone: "(570) 884-2138", - website: "https://parisbakery.cafe", - image: "https://images.unsplash.com/photo-1509440159596-0249088772ff?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 6, - name: "CycleUp Coffee", - description: "A unique bike shop cafe serving as a community hub. Enjoy coffee, light bites, and bike services in a cozy, cycling-themed atmosphere.", - lat: 40.9640, - lng: -76.8860, - address: "429 Market St, Lewisburg, PA 17837", - phone: "(570) 413-1705", - website: "https://www.cycleupcafe.com", - image: "https://images.unsplash.com/photo-1521017432531-fbd92d768814?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 7, - name: "Cornerstone Kitchen", - description: "Located in the Miller Center, offering fresh, healthy, and delicious cafe food. A place to connect over real food and a shared table.", - lat: 40.9610, - lng: -76.8970, - address: "120 Hardwood Dr, Lewisburg, PA 17837", - phone: "(570) 556-4191", - website: "https://millercenterlewisburg.com/cornerstone-kitchen", - image: "https://images.unsplash.com/photo-1498837167922-ddd27525d352?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 8, - name: "Gram's Eatery", - description: "A local favorite for homestyle breakfast and brunch. Known for generous portions, locally sourced ingredients, and a welcoming atmosphere.", - lat: 40.9642, - lng: -76.8837, - address: "21 N 3rd St, Lewisburg, PA 17837", - phone: "(570) 522-0230", - website: "https://www.facebook.com/gramseaterylewisburg", - image: "https://images.unsplash.com/photo-1533777857889-4be7c70b33f7?q=80&w=1000&auto=format&fit=crop" - }, - { - id: 9, - name: "DC Coffee", - description: "Charming cafe offering gourmet coffee, lattes, and a full breakfast and lunch menu. A cozy spot with a friendly, hometown feel.", - lat: 40.9650, - lng: -76.8825, - address: "235 Market St, Lewisburg, PA 17837", - phone: "(570) 966-6400", - website: "https://dccoffeeandteacafe.com", - image: "https://images.unsplash.com/photo-1497935586351-b67a49e012bf?q=80&w=1000&auto=format&fit=crop" - }, -]; +import { COFFEE_SHOPS } from "~/lib/data"; export default function Home() { const [selectedShop, setSelectedShop] = useState(null); return (
- - {/* Map Background */}
{shop && ( -
+ {/* Header Image */} -
+
{shop.name} + {/* Top Fade/Shadow */} +
+ {/* Bottom Fade */}
- + +
{/* Content */} -
-

{shop.name}

+ +
+

{shop.name}

-
-
- - {shop.address} -
- {shop.phone && ( -
- - {shop.phone} +
+
+ + {shop.address}
- )} - {shop.website && ( - + + + +
+
+

About

+

+ {shop.description} +

+
+ +
- )} -
- -
-
-

About

-

- {shop.description} -

+
-
- - {/* Footer Actions */} - -
+ + )}
); diff --git a/src/components/Map.tsx b/src/components/Map.tsx index 614a741..0adc30e 100644 --- a/src/components/Map.tsx +++ b/src/components/Map.tsx @@ -6,6 +6,7 @@ import L from 'leaflet'; import { useEffect } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { Coffee } from 'lucide-react'; +import Navbar from "./Navbar"; interface CoffeeShop { id: number; @@ -26,22 +27,24 @@ interface MapProps { const Map = ({ shops, onShopSelect }: MapProps) => { useEffect(() => { - // No longer need default icon fix as we are using custom icons + // Fix for Leaflet default icon not found + // @ts-expect-error Fix for Leaflet default icon not found + delete L.Icon.Default.prototype._getIconUrl; + L.Icon.Default.mergeOptions({ + iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png', + iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png', + }); }, []); const createCustomIcon = () => { - const iconMarkup = renderToStaticMarkup( -
- -
-
- ); - - return L.divIcon({ - html: iconMarkup, - className: 'custom-marker', // Add a class for potential extra styling + return new L.DivIcon({ + className: 'custom-icon', + html: `
+ +
`, iconSize: [32, 32], - iconAnchor: [16, 32], // Anchor at bottom center + iconAnchor: [16, 32], popupAnchor: [0, -32], }); }; @@ -50,11 +53,14 @@ const Map = ({ shops, onShopSelect }: MapProps) => { return ( + -
-
- -
-

- Lewisburg Coffee Map -

+ const map = useMap(); + const [showAbout, setShowAbout] = useState(false); + + return ( + <> +
+ +
+ +

+ Lewisburg Coffee +

+
+ +
+ {/* */} + + + +
+
+
+ + {/* About Dialog Overlay */} + {showAbout && ( +
+ + + +
+
+ +
+

Lewisburg Coffee Map

+

+ Explore the best coffee spots in Lewisburg, PA. + Curated for coffee enthusiasts. +

+ +
+ +
+

Map Data © OpenStreetMap contributors

+

Tiles © CARTO

+

Built with Next.js, Tailwind, and Leaflet

+
-
- {/* Placeholder for future links or actions */} -
- - ); + +
+ )} + + ); } diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..ede3d0e --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,60 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "~/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean + }) { + const Comp = asChild ? Slot : "button" + + return ( + + ) +} + +export { Button, buttonVariants } diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..bac41d2 --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,92 @@ +import * as React from "react" + +import { cn } from "~/lib/utils" + +function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function CardFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardAction, + CardDescription, + CardContent, +} diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx new file mode 100644 index 0000000..424eb4e --- /dev/null +++ b/src/components/ui/scroll-area.tsx @@ -0,0 +1,58 @@ +"use client" + +import * as React from "react" +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" + +import { cn } from "~/lib/utils" + +function ScrollArea({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + {children} + + + + + ) +} + +function ScrollBar({ + className, + orientation = "vertical", + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { ScrollArea, ScrollBar } diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 0000000..5d90a5d --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,28 @@ +"use client" + +import * as React from "react" +import * as SeparatorPrimitive from "@radix-ui/react-separator" + +import { cn } from "~/lib/utils" + +function Separator({ + className, + orientation = "horizontal", + decorative = true, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Separator } diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx new file mode 100644 index 0000000..c016b5c --- /dev/null +++ b/src/components/ui/sheet.tsx @@ -0,0 +1,139 @@ +"use client" + +import * as React from "react" +import * as SheetPrimitive from "@radix-ui/react-dialog" +import { XIcon } from "lucide-react" + +import { cn } from "~/lib/utils" + +function Sheet({ ...props }: React.ComponentProps) { + return +} + +function SheetTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function SheetClose({ + ...props +}: React.ComponentProps) { + return +} + +function SheetPortal({ + ...props +}: React.ComponentProps) { + return +} + +function SheetOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SheetContent({ + className, + children, + side = "right", + ...props +}: React.ComponentProps & { + side?: "top" | "right" | "bottom" | "left" +}) { + return ( + + + + {children} + + + Close + + + + ) +} + +function SheetHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function SheetFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function SheetTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function SheetDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + Sheet, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +} diff --git a/src/lib/data.ts b/src/lib/data.ts new file mode 100644 index 0000000..fe0843c --- /dev/null +++ b/src/lib/data.ts @@ -0,0 +1,112 @@ +export const COFFEE_SHOPS = [ + { + id: 1, + name: "Amami Kitchen", + description: "A beloved culinary spot offering a blend of high-quality Italian espresso and American coffee bar options, alongside mouthwatering baked goods and paninis.", + lat: 40.9610911, + lng: -76.8895662, + address: "103 S 6th St, Lewisburg, PA 17837", + phone: "(570) 490-7857", + website: "https://www.amamiespresso.com", + image: "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/24/e0/57/64/we-can-t-wait-to-serve.jpg?w=500&h=-1&s=1" + }, + { + id: 2, + name: "Culture Coffee", + description: "A modern coffee shop focusing on unique brewing methods for specialty coffee and traditional techniques for matcha. Known for its 'Red Velvet Latte' and croissants.", + lat: 40.9662287, + lng: -76.8880419, + address: "216 St. John St, Lewisburg, PA 17837", + phone: "(570) 601-7903", + website: "https://www.instagram.com/culturecoffeee_", + image: "https://lh3.googleusercontent.com/gps-cs-s/AG0ilSwqBStEoCw_piT-LQMybbAZJLcYVBjASVbNNyl6F5uazGR8Bs9DLvZrijlhg-8q5h1cDhRU6sOnXkRXCljQAFMgMKhATMm0j7tlleitpX75jm61vlHl6dJJ5GQHbrYxOqaNiyl5sw=s1360-w1360-h1020-rw" + }, + { + id: 3, + name: "Bucknell 7th St Cafe", + description: "Bucknell's ultimate on-campus dessert and coffee shop. A cozy spot for students and visitors to enjoy milkshakes, ice cream, and specialty espresso drinks.", + lat: 40.9577855, + lng: -76.8873363, + address: "420 S 7th St, Lewisburg, PA 17837", + phone: "(570) 577-1240", + website: "https://www.bucknell.edu/life-bucknell/dining-services/places-eat", + image: "https://www.bucknell.edu/sites/default/files/styles/wysiwyg_left_right/public/libris/C00001GOQFVeT0YE/G0000Szz5oTniLSw/247thStreetCafe002.jpg" + }, + { + id: 4, + name: "Tastecraft Cafe", + description: "Downtown cafe known for its in-house roasted coffee and over 20 flavors of French macarons. A perfect spot to relax with a fresh brew and a sweet treat.", + lat: 40.9629894, + lng: -76.8901154, + address: "512 Market St, Lewisburg, PA 17837", + phone: "(570) 768-5340", + website: "https://www.tastecraftcafe.com", + image: "https://s3-media0.fl.yelpcdn.com/bphoto/x_plvYaNq4hWJcBm5VAmxA/348s.jpg" + }, + { + id: 5, + name: "Paris Bakery & Café", + description: "Authentic French bakery offering legendary croissants, pain au chocolat, and artisanal breads. Experience a taste of France in the heart of Lewisburg.", + lat: 40.9636596, + lng: -76.8880942, + address: "335 Market St, Lewisburg, PA 17837", + phone: "(570) 884-2138", + website: "https://parisbakery.cafe", + image: "https://lh3.googleusercontent.com/gps-cs-s/AG0ilSzM-rGl_-KGgtp5l6H7-7_x6d_JovpFXsHDonjdHCTCG6-1xslBf0by3-O1FuNyvhTVx7v7JujiiF6WhnKR1xFxFJmEuQMYPn5C0tC6KysPegZdGTQAJ81aBupHvxmnBMA0dzhr5v3dIeU=w408-h544-k-no" + }, + { + id: 6, + name: "CycleUp Coffee", + description: "A unique bike shop cafe serving as a community hub. Enjoy coffee, light bites, and bike services in a cozy, cycling-themed atmosphere.", + lat: 40.9633399, + lng: -76.8867171, + address: "429 Market St, Lewisburg, PA 17837", + phone: "(570) 413-1705", + website: "https://www.cycleupcafe.com", + image: "https://lh3.googleusercontent.com/p/AF1QipPuvWYqs_ApxBUQrTFWB8qujODjIuihtQU8-ceO=w408-h408-k-no" + }, + { + id: 7, + name: "Cornerstone Kitchen", + description: "Located in the Miller Center, offering fresh, healthy, and delicious cafe food. A place to connect over real food and a shared table.", + lat: 40.9612627, + lng: -76.8997786, + address: "120 Hardwood Dr, Lewisburg, PA 17837", + phone: "(570) 556-4191", + website: "https://millercenterlewisburg.com/cornerstone-kitchen", + image: "https://lh3.googleusercontent.com/p/AF1QipM0qi8mIvgz0xz5xM1rOsN_WgNJoaetFyHX9DbW=w408-h271-k-no" + }, + { + id: 8, + name: "Gram's Eatery", + description: "A local favorite for homestyle breakfast and brunch. Known for generous portions, locally sourced ingredients, and a welcoming atmosphere.", + lat: 40.9648479, + lng: -76.8880754, + address: "21 N 3rd St, Lewisburg, PA 17837", + phone: "(570) 522-0230", + website: "https://www.facebook.com/gramseaterylewisburg", + image: "data:image/jpeg;base64,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" + }, + { + id: 9, + name: "Starbucks Coffee", + description: "Charming cafe offering gourmet coffee, lattes, and a full breakfast and lunch menu. A cozy spot with a friendly, hometown feel.", + lat: 40.980728, + lng: -76.898398, + address: "7431 Westbranch Hwy, Lewisburg, PA 17837", + phone: "(570) 452-2370", + website: "https://www.starbucks.com/store-locator/store/1010326/", + image: "https://images.unsplash.com/photo-1497935586351-b67a49e012bf?q=80&w=1000&auto=format&fit=crop" + }, + { + id: 10, + name: "Barnes & Noble Café", + description: "Barnes & Noble Café at Bucknell University. Serving Starbucks coffee and a variety of pastries and sandwiches in a comfortable bookstore setting.", + lat: 40.963941, + lng: -76.8889565, + address: "400 Market St, Lewisburg, PA 17837", + phone: "(570) 577-3960", + website: "https://bucknell.bncollege.com", + image: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ2UsV1D3Wb9yjMc1q5fYSdWOIrOW8ds3yWQQ&s" + } +]; \ No newline at end of file