diff --git a/src/apis/hooks/useGetDetailRestSpots.ts b/src/apis/hooks/useGetDetailRestSpots.ts index c2a0352..b43b34c 100644 --- a/src/apis/hooks/useGetDetailRestSpots.ts +++ b/src/apis/hooks/useGetDetailRestSpots.ts @@ -1,15 +1,15 @@ import { useQuery } from '@tanstack/react-query' import apiClient from '../apiClient' -import { DetailRestSpot } from '@/types' +import { DetailRestSpot, RestAreaDetailInfoList } from '@/types' interface Request { - restareaId: string | undefined + restAreaId: number } -const useGetDetailRestSpots = ({ restareaId }: Request) => { +const useGetDetailRestSpots = ({ restAreaId }: Request) => { const getDetailRestSpots = async () => { const response = await apiClient.get( - `/restarea/detail?restareaId=${restareaId}`, + `/restarea/detail?restareaId=${restAreaId}`, ) return response.data.data } @@ -17,7 +17,7 @@ const useGetDetailRestSpots = ({ restareaId }: Request) => { return useQuery({ queryKey: ['detailRestSpots'], queryFn: getDetailRestSpots, - enabled: !!restareaId, + enabled: !!restAreaId, }) } diff --git a/src/pages/NaverPage/components/InputSubmit/inputText.css b/src/pages/NaverPage/components/InputSubmit/inputText.css index ab7cd74..358cb05 100644 --- a/src/pages/NaverPage/components/InputSubmit/inputText.css +++ b/src/pages/NaverPage/components/InputSubmit/inputText.css @@ -1,144 +1,144 @@ /*!* index.css *!*/ .inputText { - position: relative; - width: 100%; - height: 2.5rem; - box-sizing: border-box; - overflow: visible; + position: relative; + width: 100%; + height: 2.5rem; + box-sizing: border-box; + overflow: visible; } .inputText input { - position: relative; - margin-bottom: 1px; - width: 100%; - height: 100%; - border: 1px solid rgb(0, 0, 0, 0.5); - border-top: 1px solid rgb(0, 0, 0, 0.1); - border-bottom: none; - padding: 1rem; + position: relative; + margin-bottom: 1px; + width: 100%; + height: 100%; + border: 1px solid rgb(0, 0, 0, 0.5); + border-top: 1px solid rgb(0, 0, 0, 0.1); + border-bottom: none; + padding: 1rem; } .inputText.selected input { - padding-left: 1.5rem; + padding-left: 1.5rem; } .inputText.selected:before { - content: '\f111'; - font-family: 'Font Awesome 5 Free', serif; - font-size: 0.5rem; + content: '\f111'; + font-family: 'Font Awesome 5 Free', serif; + font-size: 0.5rem; - display: flex; - justify-content: center; - align-items: center; + display: flex; + justify-content: center; + align-items: center; - z-index: 1; - position: absolute; - top:0; - left: 0.7rem; - height: inherit; + z-index: 1; + position: absolute; + top: 0; + left: 0.7rem; + height: inherit; } .inputText.selected.start:before { - color: rgb(70, 201, 105); - text-shadow: 0 0 1px rgb(70, 201, 105); + color: rgb(70, 201, 105); + text-shadow: 0 0 1px rgb(70, 201, 105); } .inputText.selected.goal:before { - color: rgb(232, 61, 90); - text-shadow: 0 0 1px rgb(232, 61, 90); + color: rgb(232, 61, 90); + text-shadow: 0 0 1px rgb(232, 61, 90); } .inputText:first-child input { - border-top: 1px solid rgb(0, 0, 0, 0.5); - border-radius: 5px 5px 0 0; + border-top: 1px solid rgb(0, 0, 0, 0.5); + border-radius: 5px 5px 0 0; } .inputText:last-child input { - border-bottom: 1px solid rgb(0, 0, 0, 0.5); - border-radius: 0 0 5px 5px; + border-bottom: 1px solid rgb(0, 0, 0, 0.5); + border-radius: 0 0 5px 5px; } -.inputText input[type=text]:focus { - outline: none; - border: 1px solid dodgerblue; - box-shadow: 0 0 3px rgb(30, 144, 255, 0.5); - z-index: 1; /* 포커스된 요소의 z-index를 높여서 그림자가 잘리지 않도록 설정 */ +.inputText input[type='text']:focus { + outline: none; + border: 1px solid dodgerblue; + box-shadow: 0 0 3px rgb(30, 144, 255, 0.5); + z-index: 1; /* 포커스된 요소의 z-index를 높여서 그림자가 잘리지 않도록 설정 */ } .inputText input::placeholder { - color: rgb(51, 51, 51, 0.5); - opacity: 50%; + color: rgb(51, 51, 51, 0.5); + opacity: 50%; } .resultBox { - position: absolute; - top: 98%; - z-index: 2; - width: 100%; - background-color: white; - border: 1px solid dodgerblue; - border-top: 1px solid rgb(0, 0, 0, 0.1); - border-radius: 0 0 5px 5px; - box-shadow: 2px 2px 3px rgb(30, 144, 255, 0.2); - text-shadow: 0 0 1px rgb(0, 0, 0, 0.1); + position: absolute; + top: 98%; + z-index: 2; + width: 100%; + background-color: white; + border: 1px solid dodgerblue; + border-top: 1px solid rgb(0, 0, 0, 0.1); + border-radius: 0 0 5px 5px; + box-shadow: 2px 2px 3px rgb(30, 144, 255, 0.2); + text-shadow: 0 0 1px rgb(0, 0, 0, 0.1); } .resultBox > div { - position: relative; - letter-spacing: -0.05em; - padding: 0.5rem 1.5rem; - margin-bottom: 2px; - overflow: hidden; - box-sizing: border-box; - cursor: pointer; + position: relative; + letter-spacing: -0.05em; + padding: 0.5rem 1.5rem; + margin-bottom: 2px; + overflow: hidden; + box-sizing: border-box; + cursor: pointer; } .resultBox > div:hover { - background-color: rgb(0, 0, 0, 0.1); - box-shadow: 0 2px 2px rgb(0, 0, 0, 0.2); - box-sizing: border-box; + background-color: rgb(0, 0, 0, 0.1); + box-shadow: 0 2px 2px rgb(0, 0, 0, 0.2); + box-sizing: border-box; } .resultBox div p:nth-child(1):before { - position: absolute; - top: 50%; - left: -1.5rem; - transform: translateY(-50%); + position: absolute; + top: 50%; + left: -1.5rem; + transform: translateY(-50%); - content: '\f3c5'; - font-family: 'Font Awesome 5 Free', serif; - font-size: 1em; - line-height: 1.5rem /* 20px */; - color: rgb(51, 51, 51, 0.6); - font-weight: 600; /* 필요에 따라 가중치를 조정합니다 */ - margin-left: 0.5em; /* 아이콘과 텍스트 사이의 간격 */ + content: '\f3c5'; + font-family: 'Font Awesome 5 Free', serif; + font-size: 1em; + line-height: 1.5rem /* 20px */; + color: rgb(51, 51, 51, 0.6); + font-weight: 600; /* 필요에 따라 가중치를 조정합니다 */ + margin-left: 0.5em; /* 아이콘과 텍스트 사이의 간격 */ } .resultBox div p:nth-child(1) { - position: relative; - float: left; - font-size: 0.8rem; - line-height: 1.5rem; - color: rgb(0, 0, 0, 1); - margin-left: 0.7rem; + position: relative; + float: left; + font-size: 0.8rem; + line-height: 1.5rem; + color: rgb(0, 0, 0, 1); + margin-left: 0.7rem; } .resultBox div p:nth-child(2) { - float: right; - font-size: 0.6rem; - line-height: 1.5rem; - color: rgb(0, 0, 0, 0.4); + float: right; + font-size: 0.6rem; + line-height: 1.5rem; + color: rgb(0, 0, 0, 0.4); } .resultBox div p:nth-child(3) { - clear: both; - font-size: 0.725rem; - line-height: 1.5rem; - color: rgb(0, 0, 0, 0.8); - margin-left: 1.2em; - - white-space: nowrap; /* 텍스트를 한 줄로 유지 */ - overflow: hidden; /* 넘치는 콘텐츠를 숨김 */ - text-overflow: ellipsis; /* 넘치는 텍스트를 말줄임표로 표시 */ -} \ No newline at end of file + clear: both; + font-size: 0.725rem; + line-height: 1.5rem; + color: rgb(0, 0, 0, 0.8); + margin-left: 1.2em; + + white-space: nowrap; /* 텍스트를 한 줄로 유지 */ + overflow: hidden; /* 넘치는 콘텐츠를 숨김 */ + text-overflow: ellipsis; /* 넘치는 텍스트를 말줄임표로 표시 */ +} diff --git a/src/pages/NaverPage/components/PathInfo/index.tsx b/src/pages/NaverPage/components/PathInfo/index.tsx index 46b570f..b0dd9e4 100644 --- a/src/pages/NaverPage/components/PathInfo/index.tsx +++ b/src/pages/NaverPage/components/PathInfo/index.tsx @@ -58,8 +58,6 @@ const PathInfo = ({ }) } - console.log(``) - return (

diff --git a/src/pages/NaverPage/components/RestAreaInfo/index.css b/src/pages/NaverPage/components/RestAreaInfo/index.css index 395797b..3d8401d 100644 --- a/src/pages/NaverPage/components/RestAreaInfo/index.css +++ b/src/pages/NaverPage/components/RestAreaInfo/index.css @@ -1,40 +1,40 @@ /* RestAreaInfo.css */ .restAreaInfo { - display: flex; - flex-direction: column; - height: 100%; - box-sizing: border-box; - overflow-y: auto; - scrollbar-width: none; /* 스크롤바 안 보이게 설정 */ + display: flex; + flex-direction: column; + height: 100%; + box-sizing: border-box; + overflow-y: auto; + scrollbar-width: none; /* 스크롤바 안 보이게 설정 */ } .restAreaInfo .slideBtn.active { - position: absolute; - width: 2.75rem; - height: 2.75rem; - border: 1px solid rgb(0, 0, 0, 0.1); - border-left: none; - border-radius: 0 5px 5px 0; - background-color: white; - cursor: pointer; + position: absolute; + width: 2.75rem; + height: 2.75rem; + border: 1px solid rgb(0, 0, 0, 0.1); + border-left: none; + border-radius: 0 5px 5px 0; + background-color: white; + cursor: pointer; - top: 5%; - left: 100%; + top: 5%; + left: 100%; } .restAreaInfo .slideBtn.active:after { - content: '\f00d'; /* < */ - font-family: 'Font Awesome 5 Free', serif; - font-size: 1.4em; - color: rgb(51, 51, 51, 0.6); - box-shadow: 1px 0 20px rgb(0, 0, 0, 0.1); - cursor: pointer; - display: flex; - justify-content:center; - align-items:center; - width: inherit; - height: inherit; + content: '\f00d'; /* < */ + font-family: 'Font Awesome 5 Free', serif; + font-size: 1.4em; + color: rgb(51, 51, 51, 0.6); + box-shadow: 1px 0 20px rgb(0, 0, 0, 0.1); + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + width: inherit; + height: inherit; } /* .restAreaInfo .slideBtn:hover:after { @@ -45,16 +45,16 @@ } */ .restAreaInfo > p { - /*letter-spacing: -0.1em;*/ - font-size: 0.775rem; - font-weight: 600; - color: rgb(0, 0, 0, 0.8); - padding: 0.75rem 1rem; - border-top: 1px solid rgb(0, 0, 0, 0.1); + /*letter-spacing: -0.1em;*/ + font-size: 0.775rem; + font-weight: 600; + color: rgb(0, 0, 0, 0.8); + padding: 0.75rem 1rem; + border-top: 1px solid rgb(0, 0, 0, 0.1); } .restAreaInfo > p span { - font-size: 0.83rem; - text-shadow: 0 0 1px rgb(220, 20, 60, 0.1); - color: rgb(220, 20, 60); + font-size: 0.83rem; + text-shadow: 0 0 1px rgb(220, 20, 60, 0.1); + color: rgb(220, 20, 60); } diff --git a/src/pages/NaverPage/components/RestAreaInfo/index.tsx b/src/pages/NaverPage/components/RestAreaInfo/index.tsx index 967b09f..09c6e84 100644 --- a/src/pages/NaverPage/components/RestAreaInfo/index.tsx +++ b/src/pages/NaverPage/components/RestAreaInfo/index.tsx @@ -90,6 +90,7 @@ const RestAreaInfo = ({ setHoveredRestSpot={setHoveredRestSpot} clickedRestSpot={clickedRestSpot} setClickedRestSpot={setClickedRestSpot} + restAreaId={value.restAreaId} /> ) })} diff --git a/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.css b/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.css index 9cd407d..778fc89 100644 --- a/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.css +++ b/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.css @@ -147,6 +147,155 @@ .chargingStation:before { content: '\f5e7'; } -.nextRestAreaDistance:before { - content: '\f5e7'; + +.infoOverlay { + position: fixed; + top: 0; + z-index: 1000; + width: 50%; + height: 100%; + background: rgba(0, 0, 0, 0.4); + display: flex; + align-items: center; + justify-content: center; +} + +.infoContainer { + background: #fff; + width: 100%; + max-width: 500px; + padding: 2rem; + border-radius: 8px; + position: relative; + overflow-y: auto; + max-height: 90vh; +} + +.closeBtn { + position: absolute; + top: 12px; + right: 12px; + font-size: 18px; + border: none; + background: none; + cursor: pointer; +} + +.infoList { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.infoItem { + background: #f9f9f9; + padding: 1rem; + border-radius: 10px; + display: flex; + flex-direction: column; +} + +.infoItem strong { + margin-bottom: 0.5rem; + font-size: 0.95rem; + color: #333; +} + +.infoImage { + width: 100%; + height: auto; + border-radius: 4px; +} + +.restAreaImg { + padding: 1rem; +} + +.restAreaImg img { + border-radius: 8px; +} + +.restAreaName { + font-weight: bold; + margin-left: 1rem; + font-size: 26px; +} + +.restAreaType { + text-shadow: 1px 1px 1px rgb(0, 0, 0, 0.1); + margin-left: 1rem; + color: #888; /* 연한 회색 */ +} + +.restAreaAddress p::before { + content: '\f3c5'; + font-family: 'Font Awesome 5 Free'; + font-weight: 600; + color: rgba(51, 51, 51, 0.3); + font-size: 1em; + margin-right: 0.5em; +} + +.restAreaAddress p { + color: rgba(51, 51, 51, 0.8); +} + +.restAreaPhoneNumber p::before { + content: '\f095'; + font-family: 'Font Awesome 5 Free'; + font-weight: 600; + color: rgba(51, 51, 51, 0.3); + font-size: 1em; + margin-right: 0.5em; +} + +.restAreaPhoneNumber p { + color: rgba(51, 51, 51, 0.8); +} + +.fuelPriceTable { + width: 100%; + border-collapse: separate; + border-spacing: 0; + font-size: 14px; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.fuelPriceTable th, +.fuelPriceTable td { + padding: 8px 12px; + border-bottom: 1px solid #ddd; + text-align: left; + background-color: #fff; + border-right: 1px solid #eee; +} + +.fuelPriceTable th:last-child, +.fuelPriceTable td:last-child { + border-right: none; +} + +.fuelPriceTable thead th { + background-color: #f5f5f5; + font-weight: bold; +} + +.fuelPriceTable tr:last-child td { + border-bottom: none; /* 마지막 줄은 밑줄 제거 */ +} + +.moreInfo p::before { + content: '\f002'; + font-family: 'Font Awesome 5 Free'; + font-weight: 600; + color: rgba(51, 51, 51, 0.3); + font-size: 1em; + margin-right: 0.5em; +} + +.moreInfo { + color: rgba(51, 51, 51, 0.8); + text-align: center; } diff --git a/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.tsx b/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.tsx index 449ef51..2cc37a8 100644 --- a/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.tsx +++ b/src/pages/NaverPage/components/RestAreaInfo/restAreaInfoContent.tsx @@ -1,5 +1,7 @@ import './restAreaInfoContent.css' -import { Dispatch, SetStateAction } from 'react' +import { Dispatch, SetStateAction, useEffect, useState } from 'react' +import { useGetDetailRestSpots } from '@/apis/hooks' +import { DetailRestSpot } from '@/types' interface RestAreaInfoContentProps { type: string @@ -16,6 +18,7 @@ interface RestAreaInfoContentProps { setHoveredRestSpot: Dispatch> clickedRestSpot: string setClickedRestSpot: Dispatch> + restAreaId: number } const RestAreaInfoContent = ({ @@ -31,9 +34,16 @@ const RestAreaInfoContent = ({ hoveredRestSpot, clickedRestSpot, setClickedRestSpot, + restAreaId, }: RestAreaInfoContentProps) => { + const [showDetail, setShowDetail] = useState(false) + const [detailRestSpots, setDetailRestSpots] = useState< + DetailRestSpot | undefined + >() + const handleUrlClick = () => { - window.open(naverMapUrl, '_blank') + //window.open(naverMapUrl, '_blank') + setShowDetail(true) trackNaverMapDetail() } @@ -44,6 +54,20 @@ const RestAreaInfoContent = ({ }) } + const { + data: detailRestSpotsData, + isFetching: detailRestSpotsFetching, + isLoading: detailRestSpotsLoading, + } = useGetDetailRestSpots({ + restAreaId: restAreaId, + }) + + useEffect(() => { + if (!detailRestSpotsLoading) { + setDetailRestSpots(detailRestSpotsData) + } + }, [detailRestSpotsData, detailRestSpotsLoading]) + const trackClickRestSpotArea = () => { console.log(``) setClickedRestSpot(name) @@ -83,6 +107,63 @@ const RestAreaInfoContent = ({

+ + {detailRestSpots && ( +
+
+ +
+
+ +
+
+
{detailRestSpotsData?.name}
+
+
+
{detailRestSpotsData?.category}
+
+
+

{detailRestSpotsData?.address}

+
+
+

{detailRestSpotsData?.phoneNumber}

+
+
+ 주유소, 충전소 + + + + + + + + + + + + + + + + + + + + + +
유종가격 (원)
휘발유{detailRestSpotsData?.gasolinePrice}
경유{detailRestSpotsData?.dieselPrice}
LPG{detailRestSpotsData?.lpgPrice}
+
+
+ +

정보 더 보기

+
+
+
+
+
+ )} ) } diff --git a/src/types/index.ts b/src/types/index.ts index 7c53802..ec0471e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -64,14 +64,33 @@ export interface RestSpot { naverMapUrl: string nextRestAreaDistance: number } +interface RestAreaDetailInfo { + id: number + mainImage: string + name: string + category: string // 예: "고속도로 휴게소" 또는 "졸음쉼터" + address: string + phoneNumber: string + naverMapUrl: string + gasolinePrice: number + dieselPrice: number + lpgPrice: number +} +export interface RestAreaDetailInfoList { + restAreas: RestAreaDetailInfo[] +} export interface DetailRestSpot { - mainPngUrl: string + id: number + mainImage: string name: string category: string - addresss: string + address: string phoneNumber: string naverMapUrl: string + gasolinePrice: number + dieselPrice: number + lpgPrice: number } export type RouteHistory = {