diff --git a/index.html b/index.html index a13a95c..c360b32 100644 --- a/index.html +++ b/index.html @@ -3,16 +3,23 @@ - + UNITRIP +
- + crossorigin="anonymous"> + diff --git a/src/Router.tsx b/src/Router.tsx index 5bf95e0..56a8035 100644 --- a/src/Router.tsx +++ b/src/Router.tsx @@ -6,6 +6,7 @@ import ErrorReportPage from './views/ErrorReport/pages/ErrorReportPage'; import LoginCallBack from './views/Login/components/LoginCallBack'; import SignUpPage from './views/Login/pages/SignUpPage'; import MainPage from './views/Main/pages/MainPage'; +import MapPage from './views/Map/pages/MapPage'; import Mypage from './views/Mypage/pages/Mypage'; import SearchPage from './views/Search/pages/SearchPage'; import SearchResultPage from './views/Search/pages/SearchResultPage'; @@ -35,6 +36,10 @@ const router = createBrowserRouter([ element: , }, { path: '/error-report', element: }, + { + path: '/map', + element: , + }, // { // path: "*", // element: , diff --git a/src/apis/index.ts b/src/apis/index.ts index d55fc45..8857b96 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -1,5 +1,4 @@ import axios, { AxiosInstance } from 'axios'; - const client: AxiosInstance = axios.create({ baseURL: import.meta.env.BASE_URL, }); diff --git a/src/apis/public/locationBasedList1.ts b/src/apis/public/locationBasedList1.ts new file mode 100644 index 0000000..04ad6fc --- /dev/null +++ b/src/apis/public/locationBasedList1.ts @@ -0,0 +1,36 @@ +/** 위치기반 관광정보 조회 API */ +import { getLocationBasedList1Res } from '@/types/locationBasedList1'; +import { Response } from '@/types/public'; + +import { publicDataClient } from '..'; + +interface locationBasedList1Params { + pageNo: number; + numOfRows: number; + MobileOS: 'IOS' | 'AND' | 'WIN' | 'ETC'; + mapX: string | undefined; + mapY: string | undefined; + radius: string; + contentTypeId: number; +} + +export const getLocationBasedList1 = async ( + paramsInfo: locationBasedList1Params, +) => { + let params = `MobileApp=UNITRIP&_type=json&arrange=O&serviceKey=${import.meta.env.VITE_PUBLIC_DATA_SERVICE_KEY}`; + + for (const [key, value] of Object.entries(paramsInfo)) { + params += `&${key}=${value}`; + } + + const { + data: { + response: { + body: { items }, + }, + }, + } = await publicDataClient.get>( + `/locationBasedList1?${params}`, + ); + return items; +}; diff --git a/src/assets/icon/icon-refresh-mono.svg b/src/assets/icon/icon-refresh-mono.svg new file mode 100644 index 0000000..2b04ae0 --- /dev/null +++ b/src/assets/icon/icon-refresh-mono.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/icon_map_favorite.svg b/src/assets/icon/icon_map_favorite.svg new file mode 100644 index 0000000..0eb1a6b --- /dev/null +++ b/src/assets/icon/icon_map_favorite.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/icon/icon_map_search_active.svg b/src/assets/icon/icon_map_search_active.svg new file mode 100644 index 0000000..c9fce56 --- /dev/null +++ b/src/assets/icon/icon_map_search_active.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/icon/icon_map_search_inactive.svg b/src/assets/icon/icon_map_search_inactive.svg new file mode 100644 index 0000000..80b1526 --- /dev/null +++ b/src/assets/icon/icon_map_search_inactive.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/icon/index.ts b/src/assets/icon/index.ts index ae5d419..dab9f60 100644 --- a/src/assets/icon/index.ts +++ b/src/assets/icon/index.ts @@ -50,7 +50,13 @@ export { default as PhysicalTypeIcon } from './icon_physical_type.svg?react'; export { default as BigInfoIcon } from './icon_big_info.svg?react'; export { default as HeartFillMonoIcon } from './icon-heart-fill-mono.svg?react'; -// Universal icon +//Map +export { default as RefreshMonoIcon } from './icon-refresh-mono.svg?react'; +export { default as MapFavoirteIcon } from './icon_map_favorite.svg?react'; +export { default as MapSearchActiveIcon } from './icon_map_search_active.svg?react'; +export { default as MapSearchInactiveIcon } from './icon_map_search_inactive.svg?react'; + +// Universal Detail export { default as AudioGuideActiveIcon } from './icon_audioguide_active.svg?react'; export { default as AudioGuideInActiveIcon } from './icon_audioguide_inactive.svg?react'; export { default as AuditoriumActiveIcon } from './icon_auditorium_active.svg?react'; @@ -81,8 +87,6 @@ export { default as PromotionActiveIcon } from './icon_promotion_active.svg?reac export { default as PromotionInActiveIcon } from './icon_promotion_inactive.svg?react'; export { default as PublicTransportActiveIcon } from './icon_publictransport_active.svg?react'; export { default as PublicTransportInActiveIcon } from './icon_publictransport_inactive.svg?react'; -export { default as PublicTransportDefaultIcon } from './publictransport_default.svg?react'; -export { default as PublicTransportSelectedIcon } from './publictransport_selected.svg?react'; export { default as RestroomActiveIcon } from './icon_restroom_active.svg?react'; export { default as RestroomInActiveIcon } from './icon_restroom_inactive.svg?react'; export { default as RouteActiveIcon } from './icon_route_active.svg?react'; @@ -93,39 +97,20 @@ export { default as StrollerActiveIcon } from './icon_stroller_active.svg?react' export { default as StrollerInActiveIcon } from './icon_stroller_inactive.svg?react'; export { default as TicketOfficeActiveIcon } from './icon_ticketoffice_active.svg?react'; export { default as TicketOfficeInActiveIcon } from './icon_ticketoffice_inactive.svg?react'; -export { default as TicketOfficeDefaultIcon } from './ticketoffice_default.svg?react'; -export { default as TicketOfficeSelectedIcon } from './ticketoffice_selected.svg?react'; export { default as VideoGuideActiveIcon } from './icon_videoguide_active.svg?react'; export { default as VideoGuideInActiveIcon } from './icon_videoguide_inactive.svg?react'; export { default as WheelChairAcitveIcon } from './icon_wheelchair_active.svg?react'; export { default as WheelChairInAcitveIcon } from './icon_wheelchair_inactive.svg?react'; -export { default as EmptyPhotoIcon } from './icon_empty_photo.svg?react'; export { default as ArrowBackIconIosDownIcon } from './icon-arrow-back-ios-down.svg?react'; export { default as ArrowBackIconIosUpIcon } from './icon-arrow-back-ios-up.svg?react'; +export { default as EmptyPhotoIcon } from './icon_empty_photo.svg?react'; -export { default as ParkingDefaultIcon } from './parking_default.svg?react'; -export { default as ParkingSelectedIcon } from './parking_selected.svg?react'; -export { default as PromotionDefaultIcon } from './promotion_default.svg?react'; -export { default as PromotionSelectedIcon } from './promotion_selected.svg?react'; -export { default as RestroomDefaultIcon } from './promotion_default.svg?react'; -export { default as RestroomSelectedIcon } from './promotion_selected.svg?react'; -export { default as RouteDefaultIcon } from './route_default.svg?react'; -export { default as RouteSelectedIcon } from './route_selected.svg?react'; -export { default as WheelChairDefaultIcon } from './wheelchair_default.svg?react'; -export { default as WheelChairSelectedIcon } from './wheelchair_selected.svg?react'; -export { default as LactationRoomDefaultIcon } from './lactationroom_default.svg?react'; -export { default as LactationRoomSelectedIcon } from './lactationroom_selected.svg?react'; -export { default as SignGuideDefaultIcon } from './signguide_default.svg?react'; -export { default as SignGuideSelectedIcon } from './signguide_selected.svg?react'; -export { default as StrollerDefaultIcon } from './stroller_default.svg?react'; -export { default as StrollerSelectedIcon } from './stroller_selected.svg?react'; -export { default as VideoGuideDefaultIcon } from './videoguide_default.svg?react'; -export { default as VideoGuideSelectedIcon } from './videoguide_selected.svg?react'; +//Universal Filter export { default as AudioGuideDefaultIcon } from './audioguide_default.svg?react'; -export { default as AudioGuideInSelectedIcon } from './audioguide_selected.svg?react'; +export { default as AudioGuideSelectedIcon } from './audioguide_selected.svg?react'; export { default as AuditoriumDefaultIcon } from './auditorium_default.svg?react'; -export { default as AuditoriumSelectedIcon } from './audioguide_selected.svg?react'; +export { default as AuditoriumSelectedIcon } from './auditorium_selected.svg?react'; export { default as BabySpareChairDefaultIcon } from './babysparechair_default.svg?react'; export { default as BabySpareChairSelectedIcon } from './babysparechair_selected.svg?react'; export { default as BigPrintDefaultIcon } from './bigprint_default.svg?react'; @@ -140,7 +125,29 @@ export { default as ExitDefaultIcon } from './exit_default.svg?react'; export { default as ExitSelectedIcon } from './exit_selected.svg?react'; export { default as GuideHumanDefaultIcon } from './guidehuman_default.svg?react'; export { default as GuideHumanSelectedIcon } from './guidehuman_selected.svg?react'; -export { default as GuideSystemDefaultIcon } from './guidehuman_default.svg?react'; -export { default as GuideSystemSelectedIcon } from './guidehuman_selected.svg?react'; +export { default as GuideSystemDefaultIcon } from './guidesystem_default.svg?react'; +export { default as GuideSystemSelectedIcon } from './guidesystem_selected.svg?react'; export { default as HelpDogDefaultIcon } from './helpdog_default.svg?react'; export { default as HelpDogSelectedIcon } from './helpdog_selected.svg?react'; +export { default as LactationRoomDefaultIcon } from './lactationroom_default.svg?react'; +export { default as LactationRoomSelectedIcon } from './lactationroom_selected.svg?react'; +export { default as ParkingDefaultIcon } from './parking_default.svg?react'; +export { default as ParkingSelectedIcon } from './parking_selected.svg?react'; +export { default as PromotionDefaultIcon } from './promotion_default.svg?react'; +export { default as PromotionSelectedIcon } from './promotion_selected.svg?react'; +export { default as PublicTransportDefaultIcon } from './publictransport_default.svg?react'; +export { default as PublicTransportSelectedIcon } from './publictransport_selected.svg?react'; +export { default as RestroomDefaultIcon } from './restroom_default.svg?react'; +export { default as RestroomSelectedIcon } from './restroom_selected.svg?react'; +export { default as RouteDefaultIcon } from './route_default.svg?react'; +export { default as RouteSelectedIcon } from './route_selected.svg?react'; +export { default as SignGuideDefaultIcon } from './signguide_default.svg?react'; +export { default as SignGuideSelectedIcon } from './signguide_selected.svg?react'; +export { default as StrollerDefaultIcon } from './stroller_default.svg?react'; +export { default as StrollerSelectedIcon } from './stroller_selected.svg?react'; +export { default as TicketOfficeDefaultIcon } from './ticketoffice_default.svg?react'; +export { default as TicketOfficeSelectedIcon } from './ticketoffice_selected.svg?react'; +export { default as VideoGuideDefaultIcon } from './videoguide_default.svg?react'; +export { default as VideoGuideSelectedIcon } from './videoguide_selected.svg?react'; +export { default as WheelChairDefaultIcon } from './wheelchair_default.svg?react'; +export { default as WheelChairSelectedIcon } from './wheelchair_selected.svg?react'; diff --git a/src/assets/image/img_default.png b/src/assets/image/img_default.png new file mode 100644 index 0000000..ee843bd Binary files /dev/null and b/src/assets/image/img_default.png differ diff --git a/src/assets/image/img_kakaomap_marker.png b/src/assets/image/img_kakaomap_marker.png new file mode 100644 index 0000000..d14d9fb Binary files /dev/null and b/src/assets/image/img_kakaomap_marker.png differ diff --git a/src/assets/image/index.ts b/src/assets/image/index.ts index 46e5d68..a1128ed 100644 --- a/src/assets/image/index.ts +++ b/src/assets/image/index.ts @@ -11,7 +11,9 @@ export { default as Sample10Image } from './img10.jpeg'; export { default as Sample11Image } from './img11.jpeg'; export { default as Sample12Image } from './img12.jpeg'; export { default as BackgroundImage } from './img_background.png'; +export { default as DefaultImage } from './img_default.png'; export { default as ErrorReportCompleteImage } from './img_error_report_complete.png'; +export { default as KakaoMarkerImage } from './img_kakaomap_marker.png'; export { default as MapImage } from './img_map.png'; export { default as ProfileImg } from './img_profile_default.png'; export { default as RequestImage } from './img_request_outline.png'; diff --git a/src/components/BottomSheet.tsx b/src/components/BottomSheet.tsx index 22aa276..966e408 100644 --- a/src/components/BottomSheet.tsx +++ b/src/components/BottomSheet.tsx @@ -11,6 +11,7 @@ interface BottomSheetProps { buttonText?: string; noButton?: boolean; bottomSheetCss?: SerializedStyles; + sheetBackgroundCss?: SerializedStyles; children: ReactNode; } @@ -20,6 +21,7 @@ interface BottomSheetProps { * @param buttonText button text * @param noButton button 여부 * @param bottomSheetCss 바텀시트 css 오버라이딩 + * @param sheetBackgroundCss 바텀시트 배경 css 오버라이딩 */ const BottomSheet = (props: BottomSheetProps) => { const { @@ -28,6 +30,7 @@ const BottomSheet = (props: BottomSheetProps) => { buttonText, noButton, bottomSheetCss, + sheetBackgroundCss, children, } = props; @@ -42,7 +45,12 @@ const BottomSheet = (props: BottomSheetProps) => { }; const portalContent = ( -
+
css` position: absolute; bottom: 0; + overflow: auto; width: 100vw; height: ${height}; - border-radius: 1.2rem 1.2rem 0rem 0rem; + border-radius: 1.2rem 1.2rem 0 0; background-color: white; - - overflow: auto; `; const buttonCotainerCss = css` position: fixed; - left: 0; bottom: 1.2rem; + left: 0; width: 100vw; padding: 0 2rem; @@ -109,11 +116,11 @@ const buttonCotainerCss = css` const buttonCss = css` width: 100%; padding: 1.4rem 0; - border-radius: 1.2rem; - color: ${COLORS.brand1}; background-color: ${COLORS.brand2}; + color: ${COLORS.brand1}; + ${FONTS.Body3}; `; diff --git a/src/constants/REGION_LIST.ts b/src/constants/REGION_LIST.ts index 973cfcc..6616857 100644 --- a/src/constants/REGION_LIST.ts +++ b/src/constants/REGION_LIST.ts @@ -105,7 +105,7 @@ export const REGION_LIST = [ '종촌동', '고운동', '보람동', - ' 대평동', + '대평동', '소담동', '반곡동', ], @@ -244,7 +244,7 @@ export const REGION_LIST = [ '영암군', '무안군', '함평군', - ' 영광군', + '영광군', '장성군', '완도군', '진도군', @@ -273,7 +273,7 @@ export const REGION_LIST = [ '성주군', '칠곡군', '예천군', - ' 봉화군', + '봉화군', '울진군', '울릉군', ], diff --git a/src/constants/facilities.tsx b/src/constants/facilities.tsx index cc8c854..b42eab7 100644 --- a/src/constants/facilities.tsx +++ b/src/constants/facilities.tsx @@ -2,7 +2,7 @@ import { AudioGuideActiveIcon, AudioGuideDefaultIcon, AudioGuideInActiveIcon, - AudioGuideInSelectedIcon, + AudioGuideSelectedIcon, AuditoriumActiveIcon, AuditoriumDefaultIcon, AuditoriumInActiveIcon, @@ -197,7 +197,7 @@ export const VISUAL_FACILITIES: Facility[] = [ active: , inactive: , default: , - selected: , + selected: , }, { name: '큰 활자', diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index 0351bab..c0fbfb4 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -8,6 +8,10 @@ declare global { authorize(options: { redirectUri: string }): void; }; }; + + /* eslint-disable @typescript-eslint/no-explicit-any */ + kakao: any; + /* eslint-enable @typescript-eslint/no-explicit-any */ } } diff --git a/src/types/kakao.d.ts b/src/types/kakao.d.ts new file mode 100644 index 0000000..bcd0aaf --- /dev/null +++ b/src/types/kakao.d.ts @@ -0,0 +1,61 @@ +declare namespace kakao.maps { + class Map { + constructor(container: HTMLElement, options: MapOptions); + getCenter(): LatLng; + setCenter(latlng: LatLng | Coords): void; + getLevel(): number; + setLevel(level: number); + } + + interface MapOptions { + center: LatLng; + level: number; + } + + class LatLng { + constructor(lat: number, lng: number); + + La: number; + Ma: number; + } + + class LatLng { + La: number; + Ma: number; + } + + class Size { + constructor(XSize: number, YSize: number); + } + + class Point { + constructor(X: number, Y: number); + } + + class MarkerImage { + constructor(string, Size, Point); + } + + class Marker { + constructor({ map, position, image }) { + this.map = map; + this.position = position; // LatLng 타입 + this.image = image; // MarkerImage 타입 + } + + map: kakao.maps.Map | undefined; + setMap: React.Dispatch>; + } + + namespace event { + interface Listener { + (event: Event): void; + } + + function addListener( + target: Marker, + eventName: string, + listener: Listener, + ): void; + } +} diff --git a/src/types/locationBasedList1.ts b/src/types/locationBasedList1.ts new file mode 100644 index 0000000..4db19ed --- /dev/null +++ b/src/types/locationBasedList1.ts @@ -0,0 +1,39 @@ +export interface locationBasedList1Res { + tel: 'string'; + title: 'string'; + firstimage: 'string'; + createdtime: 'string'; + dist: 'string'; + cat2: 'string'; + contentid: 'string'; + contenttypeid: 'string'; + addr1: 'string'; + addr2: 'string'; + areacode: 'string'; + booktour: 'string'; + cat1: 'string'; + mlevel: 'string'; + modifiedtime: 'string'; + sigungucode: 'string'; + cpyrhtDivCd: 'string'; + firstimage2: 'string'; + mapx: 'string'; + mapy: 'string'; + cat3: 'string'; +} + +export interface getLocationBasedList1Res { + header: { + resultMsg: 'string'; + resultCode: 'string'; + }; + body: { + pageNo: number; + totalCount: number; + items: + | { + item: locationBasedList1Res[]; + } + | ''; + }; +} diff --git a/src/views/Map/components/BottomSheetContent.tsx b/src/views/Map/components/BottomSheetContent.tsx new file mode 100644 index 0000000..41a7dda --- /dev/null +++ b/src/views/Map/components/BottomSheetContent.tsx @@ -0,0 +1,95 @@ +/** 바텀시트 내부 맵핑 할 내용들 */ + +import { css } from '@emotion/react'; + +import { DefaultImage } from '@/assets/image'; +import { COLORS, FONTS } from '@/styles/constants'; + +interface contentProps { + title: string; + address: string; + image: string; + contentId: string; +} + +const BottomSheetContent = (props: contentProps) => { + const { title, address, image, contentId } = props; + const isImageNone = image === ''; + + return ( +
console.log(contentId)}> +
+
+

{title}

+ 관광지 +
+

{address}

+
+ {`${title} +
+ ); +}; + +export default BottomSheetContent; + +const contentContainer = css` + display: flex; + gap: 1rem; + justify-content: space-between; + + width: 100%; + padding: 4rem 1.7rem 10.5rem; +`; + +const textSection = css` + display: flex; + gap: 0.2rem; + flex-direction: column; + max-width: 22.9rem; +`; + +const titleSectionCss = css` + display: flex; + gap: 0.5rem; + align-items: center; + + width: 100%; +`; + +const titleText = (type: string) => css` + ${type === 'title' + ? css` + overflow: hidden; + + max-width: 80%; + + text-overflow: ellipsis; + + color: ${COLORS.brand1}; + white-space: nowrap; + ${FONTS.H4}; + ` + : css` + width: 20%; + + color: ${COLORS.gray4}; + white-space: nowrap; + ${FONTS.Body5}; + `} +`; + +const addressText = css` + color: ${COLORS.gray6}; + ${FONTS.Body4}; + font-weight: 400; +`; + +const imageCss = css` + width: 8.3rem; + height: 8.3rem; + border-radius: 1rem; +`; diff --git a/src/views/Map/components/SearchBottomSheet.tsx b/src/views/Map/components/SearchBottomSheet.tsx new file mode 100644 index 0000000..968f0db --- /dev/null +++ b/src/views/Map/components/SearchBottomSheet.tsx @@ -0,0 +1,39 @@ +import { css } from '@emotion/react'; + +import BottomSheet from '@/components/BottomSheet'; + +import BottomSheetContent from './BottomSheetContent'; + +interface searchBottomSheetProps { + title: string; + address: string; + image: string; + contentId: string; + closeBottomSheet: () => void; +} + +/** 주변 여행지 검색 시 보여지는 바텀시트 */ +const SearchBottomSheet = (props: searchBottomSheetProps) => { + const { title, address, image, contentId, closeBottomSheet } = props; + + return ( +
+ + + +
+ ); +}; + +export default SearchBottomSheet; diff --git a/src/views/Map/constants/POSITION_LATLNG.ts b/src/views/Map/constants/POSITION_LATLNG.ts new file mode 100644 index 0000000..7812e9d --- /dev/null +++ b/src/views/Map/constants/POSITION_LATLNG.ts @@ -0,0 +1,329 @@ +// const [selectedRegion, setSelectedRegion] = useState({ city: '', town: '' }); +export const POSITION_LATLNG = [ + { + city: '서울특별시', + town: [ + { key: '종로구', lat: 37.5973, lng: 126.9777 }, + { key: '중구', lat: 37.560938, lng: 126.996027 }, + { key: '용산구', lat: 37.530981, lng: 126.980214 }, + { key: '성동구', lat: 37.558083, lng: 127.039217 }, + { key: '광진구', lat: 37.5498, lng: 127.0823 }, + { key: '동대문구', lat: 37.5793, lng: 127.0382 }, + { key: '중랑구', lat: 37.606, lng: 127.0895 }, + { key: '성북구', lat: 37.6109, lng: 127.0227 }, + { key: '강북구', lat: 37.6392, lng: 127.0252 }, + { key: '도봉구', lat: 37.6681, lng: 127.0283 }, + { key: '노원구', lat: 37.6551, lng: 127.0777 }, + { key: '은평구', lat: 37.6043, lng: 126.933 }, + { key: '서대문구', lat: 37.5795, lng: 126.9655 }, + { key: '마포구', lat: 37.5523, lng: 126.9143 }, + { key: '양천구', lat: 37.5188, lng: 126.8647 }, + { key: '강서구', lat: 37.5502, lng: 126.8491 }, + { key: '구로구', lat: 37.4955, lng: 126.8845 }, + { key: '금천구', lat: 37.4573, lng: 126.9018 }, + { key: '영등포구', lat: 37.5254, lng: 126.8957 }, + { key: '동작구', lat: 37.5035, lng: 126.9485 }, + { key: '관악구', lat: 37.4783, lng: 126.9514 }, + { key: '서초구', lat: 37.4839, lng: 127.0335 }, + { key: '강남구', lat: 37.4969, lng: 127.0276 }, + { key: '송파구', lat: 37.5144, lng: 127.1059 }, + { key: '강동구', lat: 37.5506, lng: 127.1399 }, + ], + }, + { + city: '부산광역시', + town: [ + { key: '중구', lat: 35.1035, lng: 129.0403 }, + { key: '서구', lat: 35.096, lng: 129.014 }, + { key: '동구', lat: 35.1104, lng: 129.0407 }, + { key: '영도구', lat: 35.0729, lng: 129.1008 }, + { key: '부산진구', lat: 35.1595, lng: 129.059 }, + { key: '남구', lat: 35.129, lng: 129.0755 }, + { key: '북구', lat: 35.1846, lng: 129.0182 }, + { key: '강서구', lat: 35.164, lng: 128.9475 }, + { key: '해운대구', lat: 35.1587, lng: 129.1605 }, + { key: '사하구', lat: 35.1145, lng: 128.9791 }, + { key: '금정구', lat: 35.2283, lng: 129.0871 }, + { key: '연제구', lat: 35.1809, lng: 129.1052 }, + { key: '수영구', lat: 35.1568, lng: 129.1164 }, + { key: '사상구', lat: 35.1485, lng: 128.9882 }, + { key: '기장군', lat: 35.2296, lng: 129.2272 }, + ], + }, + { + city: '대구광역시', + town: [ + { key: '중구', lat: 35.8656, lng: 128.5911 }, + { key: '동구', lat: 35.8833, lng: 128.6104 }, + { key: '서구', lat: 35.869, lng: 128.5889 }, + { key: '남구', lat: 35.8483, lng: 128.6011 }, + { key: '북구', lat: 35.9002, lng: 128.609 }, + { key: '수성구', lat: 35.8549, lng: 128.6171 }, + { key: '달서구', lat: 35.8352, lng: 128.5805 }, + { key: '달성군', lat: 35.706, lng: 128.5138 }, + { key: '군위군', lat: 36.0525, lng: 128.6178 }, + ], + }, + { + city: '인천광역시', + town: [ + { key: '중구', lat: 37.4802, lng: 126.6157 }, + { key: '동구', lat: 37.4765, lng: 126.6202 }, + { key: '미추홀구', lat: 37.452, lng: 126.6544 }, + { key: '연수구', lat: 37.4449, lng: 126.6515 }, + { key: '남동구', lat: 37.4531, lng: 126.7383 }, + { key: '부평구', lat: 37.4931, lng: 126.7245 }, + { key: '계양구', lat: 37.5217, lng: 126.726 }, + { key: '서구', lat: 37.4903, lng: 126.6519 }, + { key: '강화군', lat: 37.7034, lng: 126.4845 }, + { key: '옹진군', lat: 37.4761, lng: 126.5224 }, + ], + }, + { + city: '광주광역시', + town: [ + { key: '동구', lat: 35.1585, lng: 126.9222 }, + { key: '서구', lat: 35.1437, lng: 126.8835 }, + { key: '남구', lat: 35.1342, lng: 126.8915 }, + { key: '북구', lat: 35.1661, lng: 126.9184 }, + { key: '광산구', lat: 35.1709, lng: 126.7987 }, + ], + }, + { + city: '대전광역시', + town: [ + { key: '중구', lat: 36.3228, lng: 127.4295 }, + { key: '서구', lat: 36.3396, lng: 127.382 }, + { key: '동구', lat: 36.328, lng: 127.455 }, + { key: '유성구', lat: 36.3664, lng: 127.345 }, + { key: '대덕구', lat: 36.325, lng: 127.448 }, + ], + }, + { + city: '세종특별자치시', + town: [ + { key: '조치원읍', lat: 36.4844, lng: 127.2867 }, + { key: '연기면', lat: 36.4759, lng: 127.254 }, + { key: '연동면', lat: 36.4976, lng: 127.2653 }, + { key: '부강면', lat: 36.4873, lng: 127.3048 }, + { key: '금남면', lat: 36.5152, lng: 127.3383 }, + { key: '장군면', lat: 36.4879, lng: 127.3749 }, + { key: '연서면', lat: 36.5097, lng: 127.3669 }, + { key: '전의면', lat: 36.4835, lng: 127.3181 }, + { key: '전동면', lat: 36.4982, lng: 127.3823 }, + { key: '소정면', lat: 36.4873, lng: 127.3528 }, + { key: '한솔동', lat: 36.487, lng: 127.282 }, + { key: '새롬동', lat: 36.4875, lng: 127.2825 }, + { key: '나성동', lat: 36.4878, lng: 127.286 }, + { key: '다정동', lat: 36.485, lng: 127.2725 }, + { key: '도담동', lat: 36.4931, lng: 127.2869 }, + { key: '어진동', lat: 36.4825, lng: 127.295 }, + { key: '해밀동', lat: 36.4864, lng: 127.2878 }, + { key: '아름동', lat: 36.4857, lng: 127.2834 }, + { key: '종촌동', lat: 36.4902, lng: 127.2837 }, + { key: '고운동', lat: 36.4668, lng: 127.2908 }, + { key: '보람동', lat: 36.489, lng: 127.28 }, + { key: '대평동', lat: 36.4851, lng: 127.292 }, + { key: '소담동', lat: 36.4843, lng: 127.2905 }, + { key: '반곡동', lat: 36.4905, lng: 127.284 }, + ], + }, + { + city: '경기도', + town: [ + { key: '수원특례시', lat: 37.2636, lng: 127.0286 }, + { key: '성남시', lat: 37.4372, lng: 127.1288 }, + { key: '의정부시', lat: 37.7382, lng: 127.0505 }, + { key: '안양시', lat: 37.3943, lng: 126.9257 }, + { key: '부천시', lat: 37.4812, lng: 126.782 }, + { key: '광명시', lat: 37.4786, lng: 126.8832 }, + { key: '동두천시', lat: 37.9022, lng: 127.0614 }, + { key: '평택시', lat: 37.0812, lng: 127.0861 }, + { key: '안산시', lat: 37.3213, lng: 126.8294 }, + { key: '고양특례시', lat: 37.6575, lng: 126.834 }, + { key: '과천시', lat: 37.4801, lng: 126.9931 }, + { key: '구리시', lat: 37.6005, lng: 127.1267 }, + { key: '남양주시', lat: 37.6356, lng: 127.2187 }, + { key: '오산시', lat: 37.1472, lng: 127.0674 }, + { key: '시흥시', lat: 37.398, lng: 126.7918 }, + { key: '군포시', lat: 37.3594, lng: 126.9492 }, + { key: '의왕시', lat: 37.3388, lng: 126.998 }, + { key: '하남시', lat: 37.5505, lng: 127.2011 }, + { key: '용인특례시', lat: 37.2419, lng: 127.177 }, + { key: '파주시', lat: 37.7592, lng: 126.7701 }, + { key: '이천시', lat: 37.2841, lng: 127.488 }, + { key: '안성시', lat: 37.0145, lng: 127.2748 }, + { key: '김포시', lat: 37.628, lng: 126.7064 }, + { key: '화성시', lat: 37.2056, lng: 126.8357 }, + { key: '광주시', lat: 37.4023, lng: 127.2531 }, + { key: '양주시', lat: 37.7575, lng: 127.0362 }, + { key: '포천시', lat: 37.8958, lng: 127.1985 }, + { key: '여주시', lat: 37.2966, lng: 127.6316 }, + { key: '연천군', lat: 37.8685, lng: 127.0583 }, + { key: '가평군', lat: 37.8341, lng: 127.491 }, + { key: '양평군', lat: 37.4892, lng: 127.445 }, + ], + }, + { + city: '강원특별자치도', + town: [ + { key: '춘천시', lat: 37.8834, lng: 127.729 }, + { key: '원주시', lat: 37.3494, lng: 127.3674 }, + { key: '강릉시', lat: 37.7515, lng: 128.876 }, + { key: '동해시', lat: 37.5162, lng: 129.1169 }, + { key: '태백시', lat: 37.1601, lng: 128.9869 }, + { key: '속초시', lat: 38.2065, lng: 128.5911 }, + { key: '삼척시', lat: 38.4421, lng: 128.4591 }, + { key: '홍천군', lat: 37.6167, lng: 127.8912 }, + { key: '횡성군', lat: 37.3396, lng: 127.8492 }, + { key: '영월군', lat: 37.1892, lng: 127.1209 }, + { key: '평창군', lat: 37.4701, lng: 128.3937 }, + { key: '정선군', lat: 37.3334, lng: 128.653 }, + { key: '철원군', lat: 38.211, lng: 127.3832 }, + { key: '화천군', lat: 38.1004, lng: 127.6575 }, + { key: '양구군', lat: 38.1126, lng: 127.972 }, + { key: '인제군', lat: 38.1342, lng: 128.2322 }, + { key: '고성군', lat: 38.3602, lng: 128.5799 }, + { key: '양양군', lat: 38.062, lng: 128.65 }, + ], + }, + { + city: '충청북도', + town: [ + { key: '청주시', lat: 36.6356, lng: 127.4895 }, + { key: '충주시', lat: 37.0045, lng: 127.9258 }, + { key: '제천시', lat: 37.1412, lng: 128.195 }, + { key: '보은군', lat: 36.3715, lng: 127.724 }, + { key: '옥천군', lat: 36.2875, lng: 127.6463 }, + { key: '영동군', lat: 36.1435, lng: 127.494 }, + { key: '증평군', lat: 36.767, lng: 127.4894 }, + { key: '진천군', lat: 37.0706, lng: 127.3604 }, + { key: '괴산군', lat: 36.6627, lng: 127.7526 }, + { key: '음성군', lat: 36.9083, lng: 127.6468 }, + { key: '단양군', lat: 36.9714, lng: 128.3748 }, + ], + }, + { + city: '충청남도', + town: [ + { key: '천안시', lat: 36.8045, lng: 127.1229 }, + { key: '공주시', lat: 36.4602, lng: 127.1105 }, + { key: '보령시', lat: 36.3662, lng: 126.589 }, + { key: '아산시', lat: 36.7992, lng: 127.002 }, + { key: '서산시', lat: 36.7741, lng: 126.4531 }, + { key: '논산시', lat: 36.2044, lng: 127.7319 }, + { key: '계룡시', lat: 36.3034, lng: 127.2878 }, + { key: '당진시', lat: 36.7711, lng: 126.5979 }, + { key: '금산군', lat: 36.1442, lng: 127.7175 }, + { key: '부여군', lat: 36.2959, lng: 126.9319 }, + { key: '서천군', lat: 36.0654, lng: 126.8055 }, + { key: '청양군', lat: 36.4676, lng: 126.7991 }, + { key: '홍성군', lat: 36.6104, lng: 126.6739 }, + { key: '예산군', lat: 36.6788, lng: 126.8286 }, + { key: '태안군', lat: 36.754, lng: 126.2918 }, + ], + }, + { + city: '전북특별자치도', + town: [ + { key: '전주시', lat: 35.8269, lng: 127.148 }, + { key: '군산시', lat: 35.9659, lng: 126.7351 }, + { key: '익산시', lat: 35.948, lng: 126.9706 }, + { key: '정읍시', lat: 35.5861, lng: 126.85 }, + { key: '남원시', lat: 35.36, lng: 127.375 }, + { key: '김제시', lat: 35.816, lng: 126.8832 }, + { key: '완주군', lat: 35.8969, lng: 127.166 }, + { key: '진안군', lat: 35.6855, lng: 127.3624 }, + { key: '무주군', lat: 35.6751, lng: 127.6931 }, + { key: '장수군', lat: 35.6754, lng: 127.7101 }, + { key: '임실군', lat: 35.5653, lng: 127.2637 }, + { key: '순창군', lat: 35.4256, lng: 127.1516 }, + { key: '고창군', lat: 35.4176, lng: 126.6887 }, + { key: '부안군', lat: 35.6833, lng: 126.7561 }, + ], + }, + { + city: '전라남도', + town: [ + { key: '목포시', lat: 34.8109, lng: 126.395 }, + { key: '여수시', lat: 34.7604, lng: 127.6627 }, + { key: '순천시', lat: 34.9485, lng: 127.4878 }, + { key: '나주시', lat: 35.0146, lng: 126.6905 }, + { key: '광양시', lat: 34.9502, lng: 127.7009 }, + { key: '담양군', lat: 35.3368, lng: 126.9888 }, + { key: '곡성군', lat: 35.3461, lng: 127.3142 }, + { key: '구례군', lat: 35.1614, lng: 127.7249 }, + { key: '고흥군', lat: 34.5963, lng: 127.1421 }, + { key: '보성군', lat: 34.7747, lng: 127.0803 }, + { key: '화순군', lat: 35.0162, lng: 127.2763 }, + { key: '장흥군', lat: 34.694, lng: 126.9427 }, + { key: '강진군', lat: 34.5902, lng: 126.7282 }, + { key: '해남군', lat: 34.5637, lng: 126.5853 }, + { key: '영암군', lat: 34.6856, lng: 126.6822 }, + { key: '무안군', lat: 34.984, lng: 126.622 }, + { key: '함평군', lat: 35.0323, lng: 126.573 }, + { key: '영광군', lat: 35.184, lng: 126.4614 }, + { key: '장성군', lat: 35.3529, lng: 126.8837 }, + { key: '완도군', lat: 34.3231, lng: 126.7465 }, + { key: '진도군', lat: 34.4421, lng: 126.2563 }, + { key: '신안군', lat: 34.7578, lng: 125.3913 }, + ], + }, + { + city: '경상북도', + town: [ + { key: '포항시', lat: 36.0194, lng: 129.3433 }, + { key: '경주시', lat: 35.8406, lng: 129.2113 }, + { key: '김천시', lat: 36.1393, lng: 128.1127 }, + { key: '안동시', lat: 36.5665, lng: 128.7204 }, + { key: '구미시', lat: 36.1132, lng: 128.348 }, + { key: '영주시', lat: 36.8253, lng: 128.6129 }, + { key: '영천시', lat: 35.9786, lng: 128.9344 }, + { key: '상주시', lat: 36.4382, lng: 128.1557 }, + { key: '문경시', lat: 36.5918, lng: 128.1844 }, + { key: '경산시', lat: 35.8355, lng: 128.7335 }, + { key: '의성군', lat: 36.1687, lng: 128.8873 }, + { key: '청송군', lat: 36.4453, lng: 129.0484 }, + { key: '영양군', lat: 36.6721, lng: 129.1344 }, + { key: '영덕군', lat: 36.4207, lng: 129.3671 }, + { key: '청도군', lat: 35.6897, lng: 128.7042 }, + { key: '고령군', lat: 35.6008, lng: 128.2719 }, + { key: '성주군', lat: 35.7793, lng: 128.2354 }, + { key: '칠곡군', lat: 35.995, lng: 128.4748 }, + { key: '예천군', lat: 36.6347, lng: 128.4584 }, + { key: '봉화군', lat: 36.9167, lng: 128.7676 }, + { key: '울진군', lat: 36.9981, lng: 129.4047 }, + { key: '울릉군', lat: 37.4825, lng: 130.8981 }, + ], + }, + { + city: '경상남도', + town: [ + { key: '창원시', lat: 35.2285, lng: 128.674 }, + { key: '진주시', lat: 35.1795, lng: 128.1148 }, + { key: '통영시', lat: 34.8402, lng: 128.4335 }, + { key: '사천시', lat: 34.9611, lng: 128.592 }, + { key: '김해시', lat: 35.228, lng: 128.8827 }, + { key: '밀양시', lat: 35.4872, lng: 128.7481 }, + { key: '거제시', lat: 34.9009, lng: 128.6207 }, + { key: '양산시', lat: 35.3295, lng: 129.0006 }, + { key: '의령군', lat: 35.3883, lng: 128.4071 }, + { key: '함안군', lat: 35.2188, lng: 128.452 }, + { key: '창녕군', lat: 35.2859, lng: 128.5475 }, + { key: '고성군', lat: 34.9347, lng: 128.5143 }, + { key: '남해군', lat: 34.8355, lng: 128.8511 }, + { key: '하동군', lat: 35.1049, lng: 127.759 }, + { key: '산청군', lat: 35.323, lng: 127.9116 }, + { key: '함양군', lat: 35.3991, lng: 127.5893 }, + { key: '거창군', lat: 35.6948, lng: 127.8896 }, + { key: '합천군', lat: 35.5481, lng: 128.0912 }, + ], + }, + { + city: '제주특별자치도', + town: [ + { key: '제주시', lat: 33.4996, lng: 126.5312 }, + { key: '서귀포시', lat: 33.2548, lng: 126.5604 }, + ], + }, +]; diff --git a/src/views/Map/pages/MapPage.tsx b/src/views/Map/pages/MapPage.tsx new file mode 100644 index 0000000..90bda3d --- /dev/null +++ b/src/views/Map/pages/MapPage.tsx @@ -0,0 +1,248 @@ +import { css } from '@emotion/react'; +import { useEffect, useRef, useState } from 'react'; + +import { + MapFavoirteIcon, + MapSearchActiveIcon, + MapSearchInactiveIcon, + RefreshMonoIcon, +} from '@/assets/icon'; +import MenuBar from '@/components/MenuBar'; +import { COLORS, FONTS } from '@/styles/constants'; +import { locationBasedList1Res } from '@/types/locationBasedList1'; + +import SearchBottomSheet from '../components/SearchBottomSheet'; +import { createKakaoMap } from '../utils/createKakaoMap'; +import { createMapPin } from '../utils/createMapPin'; +import { getMapCenter } from '../utils/getMapCenter'; +import { setDefaultLocation } from '../utils/setDefaultLoctaion'; + +export interface locType { + lat: number | undefined; + lng: number | undefined; +} + +export interface bottomSheetType { + title: string; + address: string; + image: string; + contentId: string; +} + +export type mapType = kakao.maps.Map | undefined; + +const MapPage = () => { + const [map, setMap] = useState(); // 카카오맵 관리 + const [markers, setMarkers] = useState([]); // 주변여행지 검색 시 마커 리스트 + const [region, setRegion] = useState({ city: '', town: '' }); // 사용자 지정 지역 + const [defaultLoc, setDefaultLoc] = useState(); // 사용자 지정 지역 좌표 + const [getLocActive, setGetLocActive] = useState(false); // 위치 허용에 따른 아이콘 변화 + + // 바텀시트 내용 + const [bottomSheetContent, setBottomSheetContent] = useState( + { + title: '', + address: '', + image: '', + contentId: '', + }, + ); + + const [isPinClicked, setIsPinClicked] = useState(false); // 핀 클릭 바텀시트 + + const apiRes = useRef(); + + /** 기본 사용자의 위치에 따른 위도, 경도 값 업데이트 */ + useEffect(() => { + setRegion({ city: '서울특별시', town: '광진구' }); + const currentTown = setDefaultLocation(region.city, region.town); + setDefaultLoc({ + lat: currentTown?.lat, + lng: currentTown?.lng, + }); + }, [region.city, region.town]); + + /** '/map' 진입시, 사용자가 회원가입 할 때 등록했던 지역을 기준으로 지도 띄우기 */ + useEffect(() => { + const kakaoMap = createKakaoMap(defaultLoc, 5); + setMap(kakaoMap); + }, [defaultLoc]); + + const openBottomSheet = () => { + setIsPinClicked(true); + }; + + const closeBottomSheet = () => { + setIsPinClicked(false); + }; + + /** 사용자의 현재 위치 (위도, 경도) 받아오기 */ + const getCurrentLoc = () => { + if ('geolocation' in navigator) { + navigator.geolocation.getCurrentPosition( + (position) => { + const latlng = new kakao.maps.LatLng( + position.coords.latitude, + position.coords.longitude, + ); + if (map) { + clearMarker(); + map.setCenter(latlng); + map.setLevel(4); + } + setGetLocActive(true); + }, + (err) => { + alert('동의 거부 - 권한 재설정 필요'); + console.log(err); + }, + ); + } else { + //브라우저가 geolocation 지원 X + alert('해당 브라우저에서 현재 위치를 가져올 수 없습니다.'); + } + }; + + /** 지도에서 마커 제거, 마커 state 초기화 */ + const clearMarker = () => { + markers.forEach((marker) => marker.setMap(null)); + setMarkers([]); + }; + + //주변 여행지 찾기 클릭 시 지도 중심좌표 값 받아오기 & 공공api 검색 / 지도에 핀 박기 + const onClickSearch = async () => { + const response = await getMapCenter(map); + + if (map && response && response.item) { + clearMarker(); + + apiRes.current = response.item; + + const { curMarkers } = createMapPin( + apiRes.current, + map, + setBottomSheetContent, + openBottomSheet, + ); + + if (curMarkers) { + curMarkers.forEach((marker) => { + marker.setMap(map); + }); + + setMarkers(curMarkers); + map.setLevel(6); + } + } + }; + + return ( +
+
+
+ +
+ {!isPinClicked ? ( +
+ + +
+ ) : null} +
+
+ {isPinClicked && ( + + )} + +
+
+ ); +}; + +export default MapPage; + +const MapContainer = css` + position: relative; + + width: 100%; + height: 100dvh; +`; + +const buttonSection = css` + position: absolute; + z-index: 2; + + width: 100%; +`; + +const topButtonSection = css` + display: flex; + justify-content: flex-end; + + width: 100%; + padding: 0.5rem 1.3rem 0.5rem 0; +`; + +const bottomButtonSection = css` + display: flex; + justify-content: center; + align-items: center; + position: relative; + position: fixed; + bottom: 10.3rem; + + width: 100%; + padding-right: 1.3rem; +`; + +const searchButton = css` + display: flex; + gap: 0.4rem; + justify-content: center; + align-items: center; + position: absolute; + bottom: 1.4rem; + + width: 17.7rem; + height: 3.9rem; + padding: 0.9rem 1.6rem; + border-radius: 1rem; + + background-color: ${COLORS.brand1}; + + color: ${COLORS.white}; + + ${FONTS.Body3}; +`; + +const rightButton = css` + position: absolute; + right: 1.3rem; + bottom: 1.1rem; +`; + +const bottomSection = css` + position: relative; +`; + +const menuBarCss = css` + position: absolute; + z-index: 1000; +`; diff --git a/src/views/Map/utils/createKakaoMap.ts b/src/views/Map/utils/createKakaoMap.ts new file mode 100644 index 0000000..14b5032 --- /dev/null +++ b/src/views/Map/utils/createKakaoMap.ts @@ -0,0 +1,15 @@ +import { locType } from '../pages/MapPage'; + +const { kakao } = window; + +export const createKakaoMap = (loc: locType | undefined, level: number) => { + if (loc?.lat && loc?.lng) { + const container = document.getElementById('map'); + const options = { + center: new kakao.maps.LatLng(loc.lat, loc.lng), + level: level, + }; + const kakaoMap = new kakao.maps.Map(container, options); + return kakaoMap; + } +}; diff --git a/src/views/Map/utils/createMapPin.ts b/src/views/Map/utils/createMapPin.ts new file mode 100644 index 0000000..e589a27 --- /dev/null +++ b/src/views/Map/utils/createMapPin.ts @@ -0,0 +1,70 @@ +import { KakaoMarkerImage } from '@/assets/image'; +import { locationBasedList1Res } from '@/types/locationBasedList1'; + +import { bottomSheetType, mapType } from '../pages/MapPage'; + +interface responseType { + title: string; + latlng: kakao.maps.LatLng; + address: string; + image: string; + contentId: string; +} + +export const createMapPin = ( + apiRes: locationBasedList1Res[] | undefined, + kakaoMap: mapType | undefined, + setBottomSheet: React.Dispatch>, + openBottomSheet: () => void, +) => { + if (!apiRes || apiRes.length === 0) { + console.log('검색 결과가 없습니다.'); + return { markers: [], kakaoMap: null }; + } + + const response: responseType[] = []; + const imageSrc = KakaoMarkerImage; + const imageSize = new kakao.maps.Size(25, 40); + const imageOption = { offset: new kakao.maps.Point(27, 69) }; + + const markerImage = new kakao.maps.MarkerImage( + imageSrc, + imageSize, + imageOption, + ); + + apiRes?.forEach((item) => { + response.push({ + title: item.title, + latlng: new kakao.maps.LatLng(Number(item.mapy), Number(item.mapx)), + address: item.addr1, + image: item.firstimage, + contentId: item.contentid, + }); + }); + + const markers: kakao.maps.Marker[] = []; + + response.forEach((item) => { + const marker = new kakao.maps.Marker({ + map: kakaoMap, + position: item.latlng, + image: markerImage, + }); + + /** 마커마다 클릭 이벤트 생성 */ + kakao.maps.event.addListener(marker, 'click', function () { + setBottomSheet({ + title: item.title, + address: item.address, + image: item.image, + contentId: item.contentId, + }); + openBottomSheet(); + }); + + markers.push(marker); + }); + + return { curMarkers: markers }; +}; diff --git a/src/views/Map/utils/getMapCenter.ts b/src/views/Map/utils/getMapCenter.ts new file mode 100644 index 0000000..24b26a8 --- /dev/null +++ b/src/views/Map/utils/getMapCenter.ts @@ -0,0 +1,23 @@ +import { getLocationBasedList1 } from '@/apis/public/locationBasedList1'; + +import { mapType } from '../pages/MapPage'; + +export const getMapCenter = async (map: mapType | undefined) => { + if (map) { + try { + const response = await getLocationBasedList1({ + pageNo: 1, + numOfRows: 10, + MobileOS: 'ETC', + mapX: map.getCenter().La.toString(), + mapY: map.getCenter().Ma.toString(), + radius: '3000', + contentTypeId: 12, + }); + + return response; + } finally { + console.log('finish'); + } + } +}; diff --git a/src/views/Map/utils/setDefaultLoctaion.ts b/src/views/Map/utils/setDefaultLoctaion.ts new file mode 100644 index 0000000..2b6ed38 --- /dev/null +++ b/src/views/Map/utils/setDefaultLoctaion.ts @@ -0,0 +1,9 @@ +import { POSITION_LATLNG } from '../constants/POSITION_LATLNG'; + +/** 저장된 유저 정보로 default 위도, 경도 검색 */ +export const setDefaultLocation = (city: string, town: string) => { + const currentCity = POSITION_LATLNG.find((item) => item.city === city); + const currentTown = currentCity?.town.find((item) => item.key === town); + + return currentTown; +};