Showing
10 changed files
with
221 additions
and
25 deletions
| ... | @@ -25,7 +25,7 @@ | ... | @@ -25,7 +25,7 @@ |
| 25 | Learn how to configure a non-root public URL by running `npm run build`. | 25 | Learn how to configure a non-root public URL by running `npm run build`. |
| 26 | --> | 26 | --> |
| 27 | <title>Momokji</title> | 27 | <title>Momokji</title> |
| 28 | - <script src="https://dapi.kakao.com/v2/maps/sdk.js?appkey=059ebad3d5ccd28178357c542b8c80d1 | 28 | + <script src="https://dapi.kakao.com/v2/maps/sdk.js?appkey=059ebad3d5ccd28178357c542b8c80d1&libraries=services |
| 29 | "></script> | 29 | "></script> |
| 30 | </head> | 30 | </head> |
| 31 | <body> | 31 | <body> | ... | ... |
src/components/Foodlist.css
0 → 100644
File mode changed
src/components/Foodlist.js
0 → 100644
| 1 | +import React from "react"; | ||
| 2 | +import PropTypes from "prop-types"; | ||
| 3 | +import "./Foodlist.css"; | ||
| 4 | + | ||
| 5 | +//img의 alt와 title은 사진에 마우스 올렸을 때 나오는 제목 표시하기 위함 | ||
| 6 | +//css를 하기 위해서 style={{}}를 사용할 수 있다. | ||
| 7 | +function Foodlist({ id, year, title, summary, poster, genres }) { | ||
| 8 | + return ( | ||
| 9 | + <Link | ||
| 10 | + to={{ | ||
| 11 | + pathname: `/movie/${id}`, | ||
| 12 | + state: { | ||
| 13 | + year, | ||
| 14 | + title, | ||
| 15 | + summary, | ||
| 16 | + poster, | ||
| 17 | + genres, | ||
| 18 | + }, | ||
| 19 | + }} | ||
| 20 | + > | ||
| 21 | + <div className="movie"> | ||
| 22 | + <img src={poster} alt={title} title={title} /> | ||
| 23 | + <div className="movie__data"> | ||
| 24 | + <h3 className="movie__title">{title}</h3> | ||
| 25 | + <h5 className="movie__year">{year}</h5> | ||
| 26 | + <ul className="movie__genres"> | ||
| 27 | + {genres.map((genre, index) => ( | ||
| 28 | + //map은 (현재값, 인덱스) 두개의 아규먼트를 넘김 | ||
| 29 | + //key값이 없으면 오류가 나기때문에 index로 key를 만들어서 제공한다 | ||
| 30 | + <li key={index} className="genres__genre"> | ||
| 31 | + {genre} | ||
| 32 | + </li> | ||
| 33 | + ))} | ||
| 34 | + </ul> | ||
| 35 | + <p className="movie__summary">{summary.slice(0, 180) + "..."}</p> | ||
| 36 | + </div> | ||
| 37 | + </div> | ||
| 38 | + </Link> | ||
| 39 | + ); | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +Foodlist.propTypes = { | ||
| 43 | + id: PropTypes.number.isRequired, | ||
| 44 | + year: PropTypes.number.isRequired, | ||
| 45 | + title: PropTypes.string.isRequired, | ||
| 46 | + summary: PropTypes.string.isRequired, | ||
| 47 | + poster: PropTypes.string.isRequired, | ||
| 48 | + genres: PropTypes.arrayOf(PropTypes.string).isRequired, | ||
| 49 | +}; | ||
| 50 | + | ||
| 51 | +export default Foodlist; |
src/components/Map.js
deleted
100644 → 0
| 1 | -/*global kakao*/ | ||
| 2 | -import React, { useEffect } from "react"; | ||
| 3 | - | ||
| 4 | -const Location = () => { | ||
| 5 | - useEffect(() => { | ||
| 6 | - var container = document.getElementById("map"); | ||
| 7 | - var options = { | ||
| 8 | - center: new kakao.maps.LatLng(37.365264512305174, 127.10676860117488), | ||
| 9 | - level: 3, | ||
| 10 | - }; | ||
| 11 | - var map = new kakao.maps.Map(container, options); | ||
| 12 | - }, []); | ||
| 13 | - | ||
| 14 | - return <div></div>; | ||
| 15 | -}; | ||
| 16 | - | ||
| 17 | -export default Location; |
src/components/MapContainer.css
0 → 100644
File mode changed
| ... | @@ -4,7 +4,9 @@ import styled from "styled-components"; | ... | @@ -4,7 +4,9 @@ import styled from "styled-components"; |
| 4 | 4 | ||
| 5 | const { kakao } = window; | 5 | const { kakao } = window; |
| 6 | 6 | ||
| 7 | +var map; | ||
| 7 | var nowlat, nowlon; | 8 | var nowlat, nowlon; |
| 9 | +var infowindow = new kakao.maps.InfoWindow({ zIndex: 1 }); | ||
| 8 | 10 | ||
| 9 | class MapContainer extends Component { | 11 | class MapContainer extends Component { |
| 10 | constructor(props) { | 12 | constructor(props) { |
| ... | @@ -41,7 +43,7 @@ class MapContainer extends Component { | ... | @@ -41,7 +43,7 @@ class MapContainer extends Component { |
| 41 | //return locPosition; | 43 | //return locPosition; |
| 42 | }); | 44 | }); |
| 43 | } else { | 45 | } else { |
| 44 | - // HTML5의 GeoLocation을 사용할 수 없을때 마 | 46 | + // HTML5의 GeoLocation을 사용할 수 없을때, 사용자가 위치정보 거부했을 땐 |
| 45 | nowlat = 37.506502; // 위도 | 47 | nowlat = 37.506502; // 위도 |
| 46 | nowlon = 127.053617; // 경도커 표시 위치와 인포윈도우 내용을 설정합니다 | 48 | nowlon = 127.053617; // 경도커 표시 위치와 인포윈도우 내용을 설정합니다 |
| 47 | 49 | ||
| ... | @@ -52,7 +54,6 @@ class MapContainer extends Component { | ... | @@ -52,7 +54,6 @@ class MapContainer extends Component { |
| 52 | callback(); | 54 | callback(); |
| 53 | } | 55 | } |
| 54 | }; | 56 | }; |
| 55 | - | ||
| 56 | getMap = () => { | 57 | getMap = () => { |
| 57 | this.getLocation(() => { | 58 | this.getLocation(() => { |
| 58 | this.setState({ lat: nowlat, lon: nowlon }); | 59 | this.setState({ lat: nowlat, lon: nowlon }); |
| ... | @@ -62,7 +63,56 @@ class MapContainer extends Component { | ... | @@ -62,7 +63,56 @@ class MapContainer extends Component { |
| 62 | level: 7, | 63 | level: 7, |
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 65 | - const map = new window.kakao.maps.Map(container, options); | 66 | + map = new window.kakao.maps.Map(container, options); |
| 67 | + | ||
| 68 | + // 장소 검색 객체를 생성합니다 | ||
| 69 | + console.log(kakao.maps); | ||
| 70 | + var ps = new kakao.maps.services.Places(); | ||
| 71 | + | ||
| 72 | + // 키워드로 장소를 검색합니다 | ||
| 73 | + ps.keywordSearch("닭갈비", this.placesSearchCB, { | ||
| 74 | + radius: 1000, | ||
| 75 | + location: new kakao.maps.LatLng(nowlat, nowlon), | ||
| 76 | + }); | ||
| 77 | + ps.keywordSearch("칼국수", this.placesSearchCB, { | ||
| 78 | + radius: 1000, | ||
| 79 | + location: new kakao.maps.LatLng(nowlat, nowlon), | ||
| 80 | + }); | ||
| 81 | + }); | ||
| 82 | + }; | ||
| 83 | + // 키워드 검색 완료 시 호출되는 콜백함수 입니다 | ||
| 84 | + placesSearchCB = (data, status, pagination) => { | ||
| 85 | + if (status === kakao.maps.services.Status.OK) { | ||
| 86 | + console.log(data); | ||
| 87 | + // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해 | ||
| 88 | + // LatLngBounds 객체에 좌표를 추가합니다 | ||
| 89 | + var bounds = new kakao.maps.LatLngBounds(); | ||
| 90 | + | ||
| 91 | + for (var i = 0; i < data.length; i++) { | ||
| 92 | + this.displayMarker(data[i]); | ||
| 93 | + bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x)); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다 | ||
| 97 | + map.setBounds(bounds); | ||
| 98 | + } | ||
| 99 | + }; | ||
| 100 | + | ||
| 101 | + // 지도에 마커를 표시하는 함수입니다 | ||
| 102 | + displayMarker = (place) => { | ||
| 103 | + // 마커를 생성하고 지도에 표시합니다 | ||
| 104 | + var marker = new kakao.maps.Marker({ | ||
| 105 | + map: map, | ||
| 106 | + position: new kakao.maps.LatLng(place.y, place.x), | ||
| 107 | + }); | ||
| 108 | + | ||
| 109 | + // 마커에 클릭이벤트를 등록합니다 | ||
| 110 | + kakao.maps.event.addListener(marker, "click", function () { | ||
| 111 | + // 마커를 클릭하면 장소명이 인포윈도우에 표출됩니다 | ||
| 112 | + infowindow.setContent( | ||
| 113 | + `<div style="padding:5px;font-size:12px;"><a href="${place.place_url}" target="_blank">${place.place_name}</a></div>` | ||
| 114 | + ); | ||
| 115 | + infowindow.open(map, marker); | ||
| 66 | }); | 116 | }); |
| 67 | }; | 117 | }; |
| 68 | 118 | ||
| ... | @@ -76,8 +126,10 @@ class MapContainer extends Component { | ... | @@ -76,8 +126,10 @@ class MapContainer extends Component { |
| 76 | } | 126 | } |
| 77 | 127 | ||
| 78 | const MapContents = styled.div` | 128 | const MapContents = styled.div` |
| 79 | - width: 500px; | 129 | + width: 100%; |
| 80 | - height: 400px; | 130 | + height: 100%; |
| 131 | + position: relative; | ||
| 132 | + overflow: hidden; | ||
| 81 | `; | 133 | `; |
| 82 | 134 | ||
| 83 | export default MapContainer; | 135 | export default MapContainer; | ... | ... |
src/components/Weather.css
0 → 100644
File mode changed
src/components/Weather.js
0 → 100644
File mode changed
| 1 | +@import url("https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap"); | ||
| 2 | +body { | ||
| 3 | + background-color: #facac0; | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +.map-container { | ||
| 7 | + width: 100%; | ||
| 8 | + display: flex; | ||
| 9 | + justify-content: center; | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +header { | ||
| 13 | + display: flex; | ||
| 14 | + justify-content: center; | ||
| 15 | + font-family: "Nanum Pen Script", cursive; | ||
| 16 | + font-size: 55px; | ||
| 17 | + font-weight: 800; | ||
| 18 | +} | ||
| 19 | +header > div { | ||
| 20 | + width: 400px; | ||
| 21 | +} | ||
| 22 | +h1 { | ||
| 23 | + /*text-align: center;*/ | ||
| 24 | + margin: 10px 25px; | ||
| 25 | + font-size: 55px; | ||
| 26 | +} | ||
| 27 | +#weather { | ||
| 28 | +} | ||
| 29 | +#day { | ||
| 30 | +} | ||
| 31 | +.js-input { | ||
| 32 | + text-align: center; | ||
| 33 | +} | ||
| 34 | +.align-right { | ||
| 35 | + text-align: right; | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +/*div { | ||
| 39 | + font-size: 30px; | ||
| 40 | + text-align: center; | ||
| 41 | +}*/ | ||
| 42 | + | ||
| 43 | +.main { | ||
| 44 | + width: 60%; | ||
| 45 | + margin: 10px 30px; | ||
| 46 | + display: grid; | ||
| 47 | + grid-template-columns: 3fr 1fr; | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +.main .contents { | ||
| 51 | + min-height: 500px; | ||
| 52 | + background-color: white; | ||
| 53 | + margin-right: 10px; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +.main .sidebar { | ||
| 57 | + min-height: 500px; | ||
| 58 | + background-color: white; | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +.footer { | ||
| 62 | + margin-top: 10px; | ||
| 63 | + background-color: white; | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +@media (max-width: 600px) { | ||
| 67 | + /*가로 너비가 600px 이하일 때 아래 스타일 적용*/ | ||
| 68 | + header { | ||
| 69 | + width: auto; | ||
| 70 | + } | ||
| 71 | + .main { | ||
| 72 | + display: block; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + .main .contents { | ||
| 76 | + margin-bottom: 10px; | ||
| 77 | + margin-right: 0px; | ||
| 78 | + } | ||
| 79 | + .main .sidebar { | ||
| 80 | + min-height: 0; | ||
| 81 | + } | ||
| 82 | +} | ||
| 83 | +/**/ | ||
| 1 | .map_wrap, | 84 | .map_wrap, |
| 2 | .map_wrap * { | 85 | .map_wrap * { |
| 3 | margin: 0; | 86 | margin: 0; | ... | ... |
| 1 | import React, { useEffect } from "react"; | 1 | import React, { useEffect } from "react"; |
| 2 | import MapContainer from "../components/MapContainer"; | 2 | import MapContainer from "../components/MapContainer"; |
| 3 | -import Map from "../components/Map"; | 3 | +import "./Home.css"; |
| 4 | 4 | ||
| 5 | const Home = () => { | 5 | const Home = () => { |
| 6 | return ( | 6 | return ( |
| 7 | <div> | 7 | <div> |
| 8 | - <MapContainer /> | 8 | + <header> |
| 9 | + <div> | ||
| 10 | + {/*<Weather />*/} | ||
| 11 | + <h1>오늘은</h1> | ||
| 12 | + <div className="js-input"> | ||
| 13 | + <span id="weather">비가 오는</span> <span id="day">일요일</span> | ||
| 14 | + </div> | ||
| 15 | + <h1 className="align-right">이네요.</h1> | ||
| 16 | + </div> | ||
| 17 | + </header> | ||
| 18 | + <div className="map-container"> | ||
| 19 | + <div className="main"> | ||
| 20 | + <div className="contents"> | ||
| 21 | + <div className="food-list"> | ||
| 22 | + <ul> | ||
| 23 | + {/*<Foodlist />*/} | ||
| 24 | + <li>닭갈비</li> | ||
| 25 | + <li>칼국수</li> | ||
| 26 | + </ul> | ||
| 27 | + </div> | ||
| 28 | + <div className="map_wrap"> | ||
| 29 | + <MapContainer /> | ||
| 30 | + </div> | ||
| 31 | + </div> | ||
| 32 | + <div className="sidebar">사이드바 영역입니다.</div> | ||
| 33 | + </div> | ||
| 34 | + </div> | ||
| 35 | + <div className="footer">푸터 영역입니다.</div> | ||
| 9 | </div> | 36 | </div> |
| 10 | ); | 37 | ); |
| 11 | }; | 38 | }; | ... | ... |
-
Please register or login to post a comment