shimane-u-fest-map

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

page.tsx (3584B)


      1 "use client";
      2 import { useState } from "react";
      3 import {
      4   APIProvider,
      5   Map,
      6   Marker,
      7   MapEvent, // MapEvent型をインポートに追加 (もしあれば)
      8 } from "@vis.gl/react-google-maps";
      9 import styles from "./page.module.css";
     10 
     11 // 座標の型を定義
     12 type Coords = {
     13   lat: number;
     14   lng: number;
     15 } | null;
     16 
     17 export default function Home() {
     18   const [currentPosition, setCurrentPosition] = useState<Coords>(null);
     19   const [copied, setCopied] = useState(false);
     20 
     21   // MapコンポーネントのonClickイベントハンドラ
     22   const handleMapClick = (e: any) => {
     23     // イベントオブジェクトから緯度経度情報が取得できることを確認
     24     console.log(e.type);
     25     if (e.type == "click") {
     26       const coords: any = e.detail.latLng;
     27       setCurrentPosition(coords);
     28       setCopied(false); // 新しい座標が選ばれたらコピー状態をリセット
     29       console.log(
     30         `新しい座標: Lat ${coords.lat.toFixed(6)}, Lng ${coords.lng.toFixed(6)}`,
     31       );
     32     } else {
     33       setCurrentPosition(null);
     34       setCopied(false);
     35     }
     36   };
     37   const handleCopy = async () => {
     38     if (!currentPosition) return;
     39 
     40     const lat = currentPosition.lat.toFixed(6);
     41     const lng = currentPosition.lng.toFixed(6);
     42     const textToCopy = `lat: ${lat}, lng: ${lng}`;
     43 
     44     try {
     45       await navigator.clipboard.writeText(textToCopy);
     46       setCopied(true);
     47       setTimeout(() => setCopied(false), 2000); // 2秒後にメッセージを非表示
     48     } catch (err) {
     49       console.error("Failed to copy text: ", err);
     50       // エラー処理(例:alert('コピーに失敗しました'))
     51       setCurrentPosition(null);
     52     }
     53   };
     54 
     55   const defaultCenter = { lat: 35.486404, lng: 133.06863 };
     56 
     57   return (
     58     <div>
     59       <main>
     60         <div className={styles.mapContainer}>
     61           <APIProvider
     62             apiKey={process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ""}
     63           >
     64             <Map
     65               style={{ width: "100%", height: "85vh" }}
     66               defaultCenter={defaultCenter}
     67               defaultZoom={17}
     68               gestureHandling={"greedy"}
     69               disableDefaultUI={false}
     70               mapId={process.env.NEXT_PUBLIC_MAP_ID || ""}
     71               // useMapEventsの代わりにMapコンポーネントに直接onClickを渡す
     72               onClick={handleMapClick}
     73             >
     74               {/* マーカーを直接描画する */}
     75               {currentPosition && <Marker position={currentPosition} />}
     76             </Map>
     77           </APIProvider>
     78         </div>
     79       </main>
     80       <footer className={styles.footer}>
     81         <div className={styles.coordinateDisplay}>
     82           {currentPosition ? (
     83             <div>
     84               <p>
     85                 **タップした座標:** <br />
     86                 lat: {currentPosition.lat.toFixed(6)}, lng:{" "}
     87                 {currentPosition.lng.toFixed(6)}
     88               </p>
     89               <button
     90                 onClick={handleCopy}
     91                 style={{
     92                   marginLeft: "10px",
     93                   padding: "5px 10px",
     94                   backgroundColor: copied ? "#4CAF50" : "#007BFF",
     95                   color: "white",
     96                   border: "none",
     97                   borderRadius: "5px",
     98                   cursor: "pointer",
     99                 }}
    100               >
    101                 {copied ? "コピーしました!" : "座標をコピー"}
    102               </button>
    103             </div>
    104           ) : (
    105             <p>地図上の任意の場所をタップしてください。</p>
    106           )}
    107         </div>
    108       </footer>
    109     </div>
    110   );
    111 }