diff --git a/.firebase/hosting.YnVpbGQ.cache b/.firebase/hosting.YnVpbGQ.cache
index 6cfaf2d..f228ddf 100644
--- a/.firebase/hosting.YnVpbGQ.cache
+++ b/.firebase/hosting.YnVpbGQ.cache
@@ -1,15 +1,15 @@
robots.txt,1725691795409,b2090cf9761ef60aa06e4fab97679bd43dfa5e5df073701ead5879d7c68f1ec5
manifest.json,1725691795408,4368aeaf848ae2e048765562c289452f33ad2a175c4b1951ea8bdf2ada0d5b10
-index.html,1725749057871,effc881b82c9d3c89ee011b5ffb8dafb953803f2ac2de53235fe47d2f9983b74
logo512.png,1725691795407,212b102aa09e51b3b3e06647e81f7801a61333e171f6582e8124379aabccb41d
logo192.png,1725691795406,79e2b749561016bc8af300ea19f48347ceed3cb1a54f48ae456172eca45e08f0
-asset-manifest.json,1725749057871,a8269c53ccbff485f0c05c52cc060c9db9fb8241b26989acfeee1e5138bdfa55
favicon.ico,1725691795404,27edce7be5922cf0bef7d4136f69b5bfbdd5bf8c13c7b026f71187d41a00aa7d
-static/js/main.db631921.js.LICENSE.txt,1725749057877,92ec6870e0d50ef16c11a5af58e8bae63fc674a797281dae6198d723b4582cff
-static/js/453.ed3810f9.chunk.js.map,1725749057877,b580f924df88443006fe2c2050df639443c362a4697c20b3a6bd730b8bbd83b0
-static/js/453.ed3810f9.chunk.js,1725749057877,ad49a5ec5043145417a4fe58d70d740daa4764cb309e9bb4bcc93dfbdf2b5643
-static/css/main.79d19d76.css,1725749057877,8532eb1bc08eefe39074a437fdd2823b7e14851191c7cd07f96140abf432a5b4
-static/css/main.79d19d76.css.map,1725749057877,863af17a469ff836e46a378ba7cf2a08b3d4a827991c0be88c37d888414ad7c9
-static/media/poster.0fad7cc42115f255a281.png,1725749057877,f3025012e905a2fd748b83ff036dc7fd5dbc6b6aa6493435a0c7a60db866b5bf
-static/js/main.db631921.js,1725749057878,8665bc87d6ae3290e1fcd49e18c2c356b1bafd522c781980eb1048fd9ed4f032
-static/js/main.db631921.js.map,1725749057878,906088b6f783d5ea680d84a43f521330163825d2a8fa738b7546888a52ab1dfd
+index.html,1725753484979,153961d4989c6d46bcc5c97b2e9c10d3790e35a5d888ceb86d3098fcdb5b430c
+asset-manifest.json,1725753484979,22c4614a5b692c852c53d856a32c2abffa3a164ccde683a3ba3351f9b4202082
+static/js/main.ec691045.js.LICENSE.txt,1725753484993,30f88fcb7f8d73132245dec8d321969add3035e37dbd531f61107e638f8efae4
+static/js/453.ed3810f9.chunk.js,1725753484993,ad49a5ec5043145417a4fe58d70d740daa4764cb309e9bb4bcc93dfbdf2b5643
+static/js/453.ed3810f9.chunk.js.map,1725753484995,b580f924df88443006fe2c2050df639443c362a4697c20b3a6bd730b8bbd83b0
+static/css/main.79d19d76.css,1725753484993,8532eb1bc08eefe39074a437fdd2823b7e14851191c7cd07f96140abf432a5b4
+static/css/main.79d19d76.css.map,1725753484995,863af17a469ff836e46a378ba7cf2a08b3d4a827991c0be88c37d888414ad7c9
+static/media/poster.0fad7cc42115f255a281.png,1725753484993,f3025012e905a2fd748b83ff036dc7fd5dbc6b6aa6493435a0c7a60db866b5bf
+static/js/main.ec691045.js,1725753484995,849f70ba603fde8c7486961ea3fb0ffc350c24a351254ff97759f3b3900e6d41
+static/js/main.ec691045.js.map,1725753484995,88483bea13905e9d56d917ffdbb246fd33d6bc708e8f0e9322b38a2046e6fb4a
diff --git a/package-lock.json b/package-lock.json
index b6b456c..e9e444f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "my-app",
"version": "0.1.0",
"dependencies": {
+ "@react-google-maps/api": "^2.19.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -3044,6 +3045,23 @@
"resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.1.tgz",
"integrity": "sha512-jmEnr/pk0yVkA7mIlHNnxCi+wWzOFUg0WyIotgkKAb2u1J7fAeDBcVNSTjTihbAYNusCLQdW5s9IJ5qwnEufcQ=="
},
+ "node_modules/@googlemaps/js-api-loader": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
+ "integrity": "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ }
+ },
+ "node_modules/@googlemaps/markerclusterer": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.5.3.tgz",
+ "integrity": "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "supercluster": "^8.0.1"
+ }
+ },
"node_modules/@grpc/grpc-js": {
"version": "1.9.15",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz",
@@ -4178,6 +4196,33 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
},
+ "node_modules/@react-google-maps/api": {
+ "version": "2.19.3",
+ "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.19.3.tgz",
+ "integrity": "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A==",
+ "dependencies": {
+ "@googlemaps/js-api-loader": "1.16.2",
+ "@googlemaps/markerclusterer": "2.5.3",
+ "@react-google-maps/infobox": "2.19.2",
+ "@react-google-maps/marker-clusterer": "2.19.2",
+ "@types/google.maps": "3.55.2",
+ "invariant": "2.2.4"
+ },
+ "peerDependencies": {
+ "react": "^16.8 || ^17 || ^18",
+ "react-dom": "^16.8 || ^17 || ^18"
+ }
+ },
+ "node_modules/@react-google-maps/infobox": {
+ "version": "2.19.2",
+ "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.19.2.tgz",
+ "integrity": "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg=="
+ },
+ "node_modules/@react-google-maps/marker-clusterer": {
+ "version": "2.19.2",
+ "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz",
+ "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="
+ },
"node_modules/@remix-run/router": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.1.tgz",
@@ -4989,6 +5034,11 @@
"@types/send": "*"
}
},
+ "node_modules/@types/google.maps": {
+ "version": "3.55.2",
+ "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.2.tgz",
+ "integrity": "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw=="
+ },
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -10982,6 +11032,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/ipaddr.js": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
@@ -13949,6 +14007,11 @@
"node": ">=4.0"
}
},
+ "node_modules/kdbush": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
+ "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -18610,6 +18673,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/supercluster": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
+ "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
+ "dependencies": {
+ "kdbush": "^4.0.2"
+ }
+ },
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
diff --git a/package.json b/package.json
index 55f951d..0a27b74 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@react-google-maps/api": "^2.19.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
diff --git a/src/App.js b/src/App.js
index f7a82db..3370dab 100644
--- a/src/App.js
+++ b/src/App.js
@@ -12,6 +12,9 @@ import Gallery from './components/Gallery.js';
import MapComponent from './components/ArtMap.js';
import DetailComponent from './components/ArtDetail.js';
+import ArtInfo from './components/record.js';
+import Component from './components/GetLocation.js';
+
//////////////// json data //////////////////
import artDataJson from './data/artData.json';
@@ -37,12 +40,13 @@ function App() {
{/*
加載中...
; + // 檢查 currentLocation 是否存在,否則不渲染 + if (!artPiece || !currentLocation) return加載中...
; const isCheckInEnabled = distance && distance < 50; @@ -56,13 +88,13 @@ const DetailComponent = () => {作者: {artPiece.作者}
設置地點: {artPiece.設置地點}
場域: {artPiece.場域}
{artPiece.作品說明}
- + {distance && (距離當前位置: {distance < 1000 ? `${distance} 公尺` : `${(distance / 1000).toFixed(2)} 公里`} @@ -78,8 +110,9 @@ const DetailComponent = () => { {isCheckInEnabled ? "打卡" : `距離需小於50公尺,當前距離: ${distance} 公尺`} -
{error}
}正在加載位置...
; + } + + // 計算每個藝術品與使用者的距離,並排序 const sortedArtData = artData.map((item) => { const artLocation = { - latitude: parseFloat(item.緯度), // Convert string to number - longitude: parseFloat(item.經度), // Convert string to number + latitude: parseFloat(item.緯度), + longitude: parseFloat(item.經度), }; - const distance = haversineDistance(currentLocation, artLocation).toFixed(1); // Calculate distance + const distance = haversineDistance(currentLocation, artLocation).toFixed(1); // 計算距離 return { ...item, distance }; }); - - // Sort by distance + + // 依距離進行排序 sortedArtData.sort((a, b) => a.distance - b.distance); return (