diff --git a/index.html b/index.html index e4b78eae..07d0bdd6 100644 --- a/index.html +++ b/index.html @@ -9,5 +9,6 @@
+ diff --git a/package-lock.json b/package-lock.json index ea0cfbb3..f766cd16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@types/xml-js": "^1.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-kakao-maps-sdk": "^1.1.27", "react-loader-spinner": "^6.1.6", "react-router-dom": "^6.26.2", "react-slick": "^0.30.2", @@ -47,6 +48,18 @@ "vite": "^5.4.1" } }, + "node_modules/@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", @@ -2243,6 +2256,11 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/kakao.maps.d.ts": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/kakao.maps.d.ts/-/kakao.maps.d.ts-0.1.40.tgz", + "integrity": "sha512-nX69MB1ok04epe3OqS+/tEeWBbU31GSQbvDPJmQRRltzzqn6t4jBsO5v1nzalUjCKzwcH2CptOc767NZ7Hbu3g==", + "license": "MIT" "node_modules/json2mq": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", @@ -2610,6 +2628,20 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-kakao-maps-sdk": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/react-kakao-maps-sdk/-/react-kakao-maps-sdk-1.1.27.tgz", + "integrity": "sha512-1EwYkYsjTDRFqysKStDasFMrFTXcLx2AyRlqMoWD7ONWhRqpjx9M874hkhEEHrnypP2eSIhhDLe0EiSKp3bd2Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.15", + "kakao.maps.d.ts": "^0.1.39" + }, + "peerDependencies": { + "react": "^16.8 || ^17 || ^18", + "react-dom": "^16.8 || ^17 || ^18" + } + }, "node_modules/react-loader-spinner": { "version": "6.1.6", "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-6.1.6.tgz", @@ -2661,6 +2693,11 @@ "react-dom": ">=16.8" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" "node_modules/react-slick": { "version": "0.30.2", "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.30.2.tgz", diff --git a/package.json b/package.json index 61a9ac75..f4a37efd 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@types/xml-js": "^1.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-kakao-maps-sdk": "^1.1.27", "react-loader-spinner": "^6.1.6", "react-router-dom": "^6.26.2", "react-slick": "^0.30.2", diff --git a/src/components/MapModal/index.tsx b/src/components/MapModal/index.tsx new file mode 100644 index 00000000..31ea23f9 --- /dev/null +++ b/src/components/MapModal/index.tsx @@ -0,0 +1,53 @@ +import { useEffect, useMemo } from 'react'; +import * as S from './styles'; +import ReactDOM from 'react-dom'; +import { H16, P16 } from '@/components/Text'; +import { Map, MapMarker } from 'react-kakao-maps-sdk'; + +interface MapModalProps { + place: string; + phone: string; + address: string; + url: string; + visible: boolean; + width?: number; + height?: number; + latitude: number; + longitude: number; + onClose: () => void; +} + +export const MapModal = ({ place, phone, address, url, visible, latitude, longitude, onClose }: MapModalProps) => { + const el = useMemo(() => document.createElement('div'), []); + + useEffect(() => { + document.body.appendChild(el); + return () => { + document.body.removeChild(el); + }; + }, [el]); + + if (!visible) return null; + + return ReactDOM.createPortal( + + + + 공연장 정보 + X + + + + {place} + 전화번호 : {phone} + 주소 : {address} + 홈페이지 : {url} + + + + + + , + el, + ); +}; diff --git a/src/components/MapModal/styles.ts b/src/components/MapModal/styles.ts new file mode 100644 index 00000000..a2eb5352 --- /dev/null +++ b/src/components/MapModal/styles.ts @@ -0,0 +1,63 @@ +import { styled } from 'styled-components'; + +export const MapModal = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(255, 255, 255, 0.9); + z-index: 1000; +`; + +export const ModalContainer = styled.div` + width: 40%; + height: 50%; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 30px; + background-color: ${props => props.theme.colors.white}; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5); + border-radius: 10px; + display: flex; + flex-direction: column; + min-width: 500px; + min-height: 500px; +`; + +export const ModalHeader = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + position: relative; + + &::after { + content: ''; + border: 1px solid ${({ theme }) => theme.colors.gray}; + position: absolute; + bottom: -10px; + left: 0; + width: 100%; + height: 1px; + } +`; + +export const ModalCloseBtn = styled.button` + border: none; + background-color: transparent; + font-size: 20px; + &:hover { + color: ${({ theme }) => theme.colors.gray}; + } +`; + +export const ModalPlaceInfo = styled.div` + display: flex; + flex-direction: column; + padding: 20px 0; + gap: 10px; + flex-grow: 1; + overflow-y: auto; +`; diff --git a/tsconfig.json b/tsconfig.json index 1ffef600..bd619570 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ] + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }], + "compilerOptions": { + "types": ["kakao.maps.d.ts"] + } } diff --git a/vite.config.ts b/vite.config.ts index 8f98d9de..f0da45d0 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -10,7 +10,7 @@ export default defineConfig({ '/api': { target: 'http://www.kopis.or.kr/openApi/restful', changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ''), + rewrite: path => path.replace(/^\/api/, ''), }, }, },