본문 바로가기
개인공부/메인프로젝트

카카오맵 - 드디어 검색기능 성공!!!!!

by 뭉지야 2023. 5. 16.
728x90

드디어 카카오지도 검색 기능 성공했다.
진짜 하루종일 잡고 있었네................
몇번을 고치고 한지 모르겠다

 

//Map

// 지도 컴포넌트

import React, { useEffect } from "react";

declare global {
  interface Window {
    kakao: any;
  }
}
interface SearchProps {
  Place: string;
}
const MapComponent: React.FC<SearchProps> = ({ Place }) => {
  useEffect(() => {
    const infowindow = new window.kakao.maps.InfoWindow({ zIndex: 1 });
    const container = document.getElementById("map");
    const options = {
      center: new window.kakao.maps.LatLng(33.450701, 126.570667),
      level: 3,
    };

    const map = new window.kakao.maps.Map(container, options);
    const ps = new window.kakao.maps.services.Places();

    ps.keywordSearch(Place, placesSearchCB);

    function placesSearchCB(data: any, status: any) {
      if (status === window.kakao.maps.services.Status.OK) {
        const bounds = new window.kakao.maps.LatLngBounds();

        for (let i = 0; i < data.length; i++) {
          displayMarker(data[i]);
          bounds.extend(new window.kakao.maps.LatLng(data[i].y, data[i].x));
        }
        map.setBounds(bounds);
      }
    }
    function displayMarker(place: any) {
      const marker = new window.kakao.maps.Marker({
        map: map,
        position: new window.kakao.maps.LatLng(place.y, place.x),
      });
      window.kakao.maps.event.addListener(marker, "click", function () {
        infowindow.setContent('<div style="padding:5px;font-size:12px;">' + place.place_name + "</div>");
        infowindow.open(map, marker);
      });
    }
  }, [Place]);

  return (
    <div>
      <div id="map" style={{ width: "700px", height: "50vh" }}></div>
      <script
        type="text/javascript"
        src="//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.REACT_APP_KAKAO_MAP_KEY}&libraries=services"
      ></script>
    </div>
  );
};

export default MapComponent;
//index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="Web site created using create-react-app" />
    <script
      type="text/javascript"
      src="//dapi.kakao.com/v2/maps/sdk.js?appkey=%REACT_APP_KAKAO_MAP_KEY%&libraries=services"
    ></script>
    <!-- <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> -->
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <!-- <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> -->
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
//Place

//지도페이지

import React, { useState } from "react";
import styled from "styled-components";
import MapComponent from "./Map";

const TotalStyled = styled.section`
  /* border: 10px solid black; */
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f7f7f7;
`;
const PlaceContainer = styled.div`
  border: 5px solid black;
  width: 100vw;
  height: 100vh;
  max-width: 1250px;
  margin-top: 150px; //호버됬을때가 150이래서 일단 150으로 설정함.
  display: flex;
  flex-direction: column;
`;
//상단검색부분
const SearchPartStyled = styled.div`
  border: 3px solid black;
  flex-grow: 1.5;
  display: flex;
  justify-content: center;
  align-items: flex-end;
`;
//지도+리스트부분 전체묶은거
const MapBodyStyled = styled.div`
  border: 5px solid red;
  display: flex;
  flex-direction: row;
  flex-grow: 7.5;
`;
//왼쪽지도부분
const MapPartStyled = styled.div`
  border: 3px solid blue;
  flex-grow: 7;
`;
//오른쪽리스트부분
const ListPartStyled = styled.div`
  border: 3px solid black;
  flex-grow: 3;
`;
const MapBottomStyled = styled.div`
  border: 3px solid black;
  flex-grow: 1;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const Place = () => {
  const [inputText, setInputText] = useState("");
  const [searchPlace, setSearchPlace] = useState("");

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    // console.log(e.target.value);
    setInputText(e.target.value);
  };
  const handleSubmit = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    setSearchPlace(inputText);
    // console.log(inputText);
    setInputText("");
  };

  return (
    <>
      <TotalStyled>
        <PlaceContainer>
          <SearchPartStyled>
            <input type="text" placeholder="매장을 검색하세요" onChange={onChange} value={inputText}></input>
            <button onClick={handleSubmit}>조회</button>
          </SearchPartStyled>
          <MapBodyStyled>
            <MapPartStyled>
              지도부분
              <MapComponent Place={searchPlace} />
            </MapPartStyled>
            <ListPartStyled>리스트부분</ListPartStyled>
          </MapBodyStyled>
          <MapBottomStyled>
            <button>선택</button>
          </MapBottomStyled>
        </PlaceContainer>
      </TotalStyled>
    </>
  );
};

export default Place;
728x90