From 0c63f7df24f80dffe15166b0202d7a695cdbfbd8 Mon Sep 17 00:00:00 2001 From: KimDoHyun Date: Sat, 3 May 2025 02:09:09 +0900 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=EB=A7=88=EC=BB=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/a.webp | Bin 0 -> 1280 bytes src/assets/b.webp | Bin 0 -> 1234 bytes src/assets/c.webp | Bin 0 -> 1354 bytes src/assets/d.webp | Bin 0 -> 1386 bytes src/assets/f.webp | Bin 0 -> 1244 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/assets/a.webp create mode 100644 src/assets/b.webp create mode 100644 src/assets/c.webp create mode 100644 src/assets/d.webp create mode 100644 src/assets/f.webp diff --git a/src/assets/a.webp b/src/assets/a.webp new file mode 100644 index 0000000000000000000000000000000000000000..14153b5eacaa815572c52889b197b6a4994c5a40 GIT binary patch literal 1280 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 literal 0 HcmV?d00001 diff --git a/src/assets/d.webp b/src/assets/d.webp new file mode 100644 index 0000000000000000000000000000000000000000..8240da5a7830bdde1d48dd62edbb554fb5553cfd GIT binary patch literal 1386 zcmV-w1(o_zNk&Fu1pok7MM6+kP&il$0000G0000#002J#06|PpNC5)?00E$O+qNl5 z7JpupZQHhO+qP}nw%fLC+qUgA0-fu_i+AJP8xb)9qF-#_fd@bTFC6{vndD5f4L;Y`*0@TWYuadf)|4cd*~_)seTKPEad@K1mzMi&&rf@7Y* ze`66B7RG>=+DXD4UIuuryuGzR_99Ody~R1e`=xEo%7dRKYWs3uR#P3ishrgOucL1`=UX0MoyS8VZ!+S zjq{ro`w2etv?_#Qz61`55}0zPw23SNx@xV0-wOs^#`K3eCWZcl^IEUK2?@RxVuueO zyXwVk;Hy#watgjtDjtEZW?}JHe+JlZ(gUcj(+@HVXh^B=AfvEB!Auybvm9O*6Vq&E#e{t8)XKP^tr*HaP{?>)Z|dlu7|Nn(TwSb#8>CN>za?Cdc7M zozrlYQhQ*Z$u)3BXFEKrv{Eo8>Z{j0-9=gCxH9Jum#Xk zNB)9MX3+@~CQMlKI*`@SWDA4~D%}d77+k?LJX%aYgI7d(8Zanmg~{tJ#B>O-U8{T) zUh@L-%{zVN%9SgpcP^?g#-TTX4qEakFe^ZP9`H*@Z4!`D$4;$(fuo{cI0bmSn2qA^ z0<_YTlK_tu(kt`?!24pcP7L7LQd*^-$3NGG+~?z~Hacy;#{XAgE1lyIK2$8R;zuIH z-79vVj01mdtz=et+uy{`C~v7-07Rcy*QJcFY?t*-0DnI~0 z06vj8nMft0BB3l2zF@Et32Y6sWpwerPtHHs_ZSODq#o1GfAa6J2RIKf9RNPe{s2F- zbpUz*e#LsQ|K0W={@wqBd;qN^K`ChXrMcNGJF1Hm=X9Cp$wNg1(R8Pvh@)SAsDJMB5ABRrtaz4?U;~)Gs6i3x9aaV=U z@5#05xARjEiWt03(?Z88d=WDz!CCzMS?tJ!nGl_cn>lP2_j7C5AsVX60!YM*7hO&f zhE%YekO?#tAl}?@>-x2S|E&>BJLf_$wl!x(V0-@x@0CQ5;|en_&27~~?&K@J*U!sD zQ=gX$L%N{A;EV^vK#dfgAN_*B{}`+F94{ajqR&zy&+u7x^jFkozyD?{ia~esDen0G z=+!>RQ^EflVHY-_49DzlEI|e$98cGe@hJU#*^Hs@z&Fa(8hP{nYQ?SmUsOi5sFVk^U z7v80#F5~I7SkM>m;ht8=k}b%7 literal 0 HcmV?d00001 diff --git a/src/assets/f.webp b/src/assets/f.webp new file mode 100644 index 0000000000000000000000000000000000000000..883217cdc7d639783fd776bf185fff212088e421 GIT binary patch literal 1244 zcmV<21S9)WNk&H01ONb6MM6+kP&il$0000G0000#002J#06|PpNWTIA00E$O+qNl5 zR)1cUZQHhO+qP}nuC{I4wr!PdE6}k%ymT+S4K5&!vD7WZvXsZxW!i(kEf|HNQNI-dl1yKiPO%-rv7 z{EuXFVR8caw1I?f^cldH1?|lTu1)bo(VKc5_$jZgF-bUFTa@b_0Y1rOr(qQKlo9nZ zdx4!+a_)r_6~to2laOp}V+SPKiq#JP!|xgOD#c*4Sl$kd*1I3}XE(}JwtVW68G>>g zfg=D_jHCRt*b_6*8$5^mS}9CnFmS>TUnQ*X!^Bsakx zrJONn9%{WPwgO7(bb!m5T*!O{dh5)BFU1A<1{Ubt43D_+7~HD!FzgPu?>+yUGtF*- zhjpHV4dH?d7;S*(bRK~nTCvw7MmynAotxp_aO*|$ez-+vC4At51jN|@J_=> zoiadm7it5wbmSB)abX!mGb=p-zq{}!d@jl(fG#FElQ3JM8?aKVU>v^m3}iQZiiC@N z12oc-H-IrFk~<>dCjdtxYD0kY`w{-}HsnPg|JKu~{~!KSS* zUoL2=MF7O#UeGL`FMqRz@5Bk-Cbr)SN_qL%vCEiWDP*l$+)Qze*uTrpksJ;bx?p9v zxVXf|SDq7@_vj@Xi<^V=9u-&L&^lMlnbMb)#)!Lfb>8zFihQYYv9!2cE2c16+};@O z1JALH--bC~MqICUEyNIUf4a>RCzKtUvqy z%acA*`7&IuFX=oHCQEuh{Giwd09H^qAnpMG0PqR`odGI906+jfg*25%r6VFCIr4o_ zpb&{{4ZH)JTJ<58etkP_@alEak!VU! z9kz_SsURa2DL)@a#-Y017XTf9V`GAAr-SCRS6GkQIsg4#J`Xx-pgu|$==|ULu1~fF zmw^7k!Q|X@Baz~_wW4jwm-*?*hNSnX*A=+4b;(}7AG8Fr))Eyl%OA-LZ4cg1m`$Vues9Qr8 Date: Sat, 3 May 2025 02:09:30 +0900 Subject: [PATCH 2/7] =?UTF-8?q?refactor:=20grade=20=EC=83=89=EC=83=81=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20theme=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/theme.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/styles/theme.ts b/src/styles/theme.ts index 066a964..c6e056e 100644 --- a/src/styles/theme.ts +++ b/src/styles/theme.ts @@ -14,6 +14,13 @@ export const theme = { 700: '#333333', }, error: '#CD1A1A', + grade: { + A: '#4CAF50', + B: '#8BC34A', + C: '#FFC107', + D: '#FF9800', + F: '#F44336', + }, }, fonts: { sizes: { From 3fc2fe556afc805ab46c654ca5d5d9f6596c8e72 Mon Sep 17 00:00:00 2001 From: KimDoHyun Date: Sat, 3 May 2025 02:10:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EB=B0=8F=20grade=20=EC=83=89=EC=83=81=20=ED=86=B5?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/MapPage/BottomSheet.tsx | 80 +++++++++++--- src/pages/MapPage/MapPage.tsx | 2 - .../MapPage/components/ListContainer.tsx | 41 +++---- src/pages/MapPage/components/SearchResult.tsx | 102 ++++++++++++++++++ .../MapPage/components/map/MapComponent.tsx | 22 ++-- 5 files changed, 192 insertions(+), 55 deletions(-) create mode 100644 src/pages/MapPage/components/SearchResult.tsx diff --git a/src/pages/MapPage/BottomSheet.tsx b/src/pages/MapPage/BottomSheet.tsx index a749bc2..984a08a 100644 --- a/src/pages/MapPage/BottomSheet.tsx +++ b/src/pages/MapPage/BottomSheet.tsx @@ -5,6 +5,8 @@ import { BottomSheetProps } from './interface'; import ListContainer from './components/ListContainer'; import CommentList from './components/comment/CommentList'; import NoInfo from './components/NoInfo'; +import SearchResult from './components/SearchResult'; +import { Slope } from '../../apis/slopeMap'; const BottomSheet: React.FC = ({ slopeData, @@ -75,6 +77,40 @@ const BottomSheet: React.FC = ({ scrollWrapperRef.current.style.overflow = 'auto'; } }; + + const countGrades = (slopes: Slope[]) => { + const counts = { + aCount: 0, + bCount: 0, + cCount: 0, + dCount: 0, + fCount: 0, + }; + + for (let i = 0; i < slopes.length; i++) { + const grade = slopes[i].priority.grade.toUpperCase(); + + switch (grade) { + case 'A': + counts.aCount++; + break; + case 'B': + counts.bCount++; + break; + case 'C': + counts.cCount++; + break; + case 'D': + counts.dCount++; + break; + case 'F': + counts.fCount++; + break; + } + } + return counts; + }; + return ( @@ -103,22 +139,36 @@ const BottomSheet: React.FC = ({ return ; } } else { + const { aCount, bCount, cCount, dCount, fCount } = + countGrades(slopeData); return ( - - {!slopeData || slopeData.length === 0 ? ( -
데이터 조회 중
- ) : ( - slopeData.map((item, index) => ( - { - onItemClick(item, index); - }} - > - )) - )} -
+ <> + + + {!slopeData || slopeData.length === 0 ? ( +
데이터 조회 중
+ ) : ( + slopeData.map((item, index) => ( + { + onItemClick(item, index); + }} + > + )) + )} +
+ ); } })()} diff --git a/src/pages/MapPage/MapPage.tsx b/src/pages/MapPage/MapPage.tsx index f48fa4b..95cfc93 100644 --- a/src/pages/MapPage/MapPage.tsx +++ b/src/pages/MapPage/MapPage.tsx @@ -9,8 +9,6 @@ import SearchComponent from './components/map/Search'; import { Slope, slopeMapAPI } from '../../apis/slopeMap'; import MyLocationIcon from '@mui/icons-material/MyLocationRounded'; const MapPage = () => { - // console.log(escarpmentData); - // console.log(escarpmentData); const [selectedMarkerId, setSelectedMarkerId] = useState(null); const [allTextShow, setAllTextShow] = useState(false); const [userLocation, setUserLocation] = useState( diff --git a/src/pages/MapPage/components/ListContainer.tsx b/src/pages/MapPage/components/ListContainer.tsx index 380b0a0..52bf656 100644 --- a/src/pages/MapPage/components/ListContainer.tsx +++ b/src/pages/MapPage/components/ListContainer.tsx @@ -4,20 +4,20 @@ import { ListProps } from '../interface'; const ListContainer: React.FC = ({ item, onClick }) => { if (!item) return null; - const grade = item.disaster?.riskLevel.includes('A') + const grade = item.priority?.grade.includes('A') ? 'A' - : item.disaster?.riskLevel.includes('B') + : item.priority?.grade.includes('B') ? 'B' - : item.disaster?.riskLevel.includes('C') + : item.priority?.grade.includes('C') ? 'C' - : item.disaster?.riskLevel.includes('D') + : item.priority?.grade.includes('D') ? 'D' : 'F'; return ( - {grade} + {grade} @@ -69,38 +69,25 @@ const GradeBackground = styled.div<{ $grade: string }>` justify-content: center; align-items: center; flex-shrink: 0; - background-color: ${({ $grade }) => { + background-color: ${({ $grade, theme }) => { switch ($grade) { case 'A': - return 'rgba(46, 204, 113, 0.15)'; // #2ecc71 with opacity + return theme.colors.grade.A; case 'B': - return 'rgba(241, 196, 15, 0.15)'; // #f1c40f with opacity + return theme.colors.grade.B; case 'C': - return 'rgba(230, 126, 34, 0.15)'; // #e67e22 with opacity + return theme.colors.grade.C; case 'D': - return 'rgba(231, 76, 60, 0.15)'; // #e74c3c with opacity - default: - return 'rgba(51, 51, 51, 0.15)'; // #333333 with opacity + return theme.colors.grade.D; + case 'F': + return theme.colors.grade.F; } }}; `; -const GradeText = styled.div<{ $grade: string }>` +const GradeText = styled.div` font-size: 20px; font-weight: 600; - color: ${({ $grade }) => { - switch ($grade) { - case 'A': - return '#2ecc71'; - case 'B': - return '#f1c40f'; - case 'C': - return '#e67e22'; - case 'D': - return '#e74c3c'; - default: - return '#333'; - } - }}; + color: ${({ theme }) => theme.colors.grey[100]}; `; const TitleWrapper = styled.div` diff --git a/src/pages/MapPage/components/SearchResult.tsx b/src/pages/MapPage/components/SearchResult.tsx new file mode 100644 index 0000000..85577fc --- /dev/null +++ b/src/pages/MapPage/components/SearchResult.tsx @@ -0,0 +1,102 @@ +import styled from 'styled-components'; + +interface SearchResultProps { + resultCount: number; + gradeCount: { + A: number; + B: number; + C: number; + D: number; + F: number; + }; +} + +const SearchResult = ({ resultCount, gradeCount }: SearchResultProps) => { + return ( + + + 검색결과 {resultCount}건 + + + {Object.entries(gradeCount).map(([grade, count]) => ( + + {grade} + {count} + + ))} + + + ); +}; + +export default SearchResult; + +const Container = styled.div` + display: flex; + align-items: center; + width: 100%; + padding: 10px 25px; + background-color: #f8f9fa; + border-radius: 8px; + margin: 10px 0px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +`; + +const ResultCount = styled.div` + font-size: 15px; + margin-right: 15px; + color: #333; + font-weight: 500; +`; + +const Bold = styled.span` + font-weight: 700; + color: #0b5275; +`; + +const GradeWrapper = styled.div` + display: flex; + gap: 10px; +`; + +interface GradeProps { + grade: string; +} + +const GradeItem = styled.div` + display: flex; + align-items: center; +`; + +const GradeLabel = styled.div` + width: 22px; + height: 22px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + font-weight: 700; + font-size: 13px; + color: white; + background-color: ${({ grade, theme }) => { + switch (grade) { + case 'A': + return theme.colors.grade.A; + case 'B': + return theme.colors.grade.B; + case 'C': + return theme.colors.grade.C; + case 'D': + return theme.colors.grade.D; + case 'F': + return theme.colors.grade.F; + } + }}; +`; + +const GradeCount = styled.div` + font-size: 14px; + font-weight: 600; + margin-left: 4px; + color: #333; +`; diff --git a/src/pages/MapPage/components/map/MapComponent.tsx b/src/pages/MapPage/components/map/MapComponent.tsx index 5c5584f..fd14964 100644 --- a/src/pages/MapPage/components/map/MapComponent.tsx +++ b/src/pages/MapPage/components/map/MapComponent.tsx @@ -6,11 +6,11 @@ import { Marker, } from 'react-naver-maps'; import { useState, useEffect } from 'react'; -import AmarkerIcon from '../../../../assets/a.png'; -import BmarkerIcon from '../../../../assets/b.png'; -import CmarkerIcon from '../../../../assets/c.png'; -import DmarkerIcon from '../../../../assets/d.png'; -import FmarkerIcon from '../../../../assets/f.png'; +import AmarkerIcon from '../../../../assets/a.webp'; +import BmarkerIcon from '../../../../assets/b.webp'; +import CmarkerIcon from '../../../../assets/c.webp'; +import DmarkerIcon from '../../../../assets/d.webp'; +import FmarkerIcon from '../../../../assets/f.webp'; import UserPosIcon from '../../../../assets/current_position.png'; import { MapComponentProps } from '../../interface'; declare global { @@ -169,13 +169,13 @@ const MapComponent: React.FC = ({ {escarpmentData.length > 0 ? escarpmentData.map((item, index) => { // console.log(item); - const grade = item.disaster?.riskLevel.includes('A') + const grade = item.priority?.grade.includes('A') ? 'A' - : item.disaster?.riskLevel.includes('B') + : item.priority?.grade.includes('B') ? 'B' - : item.disaster?.riskLevel.includes('C') + : item.priority?.grade.includes('C') ? 'C' - : item.disaster?.riskLevel.includes('D') + : item.priority?.grade.includes('D') ? 'D' : 'F'; @@ -205,7 +205,7 @@ const MapComponent: React.FC = ({
${ selectedMarkerId === index || allTextShow - ? `
+ ? `
`, From 5facdf43475983ba4a84c1166b473cbf279e0d93 Mon Sep 17 00:00:00 2001 From: KimDoHyun Date: Sat, 3 May 2025 03:20:25 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EC=9C=84=EC=84=B1=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20mapStore=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/MapPage/MapPage.tsx | 187 ++++-------- src/pages/MapPage/components/ButtonGroup.tsx | 185 +++++++++++ .../MapPage/components/map/MapComponent.tsx | 26 +- src/pages/MapPage/mapStore.ts | 286 ++++++++++++++++++ 4 files changed, 554 insertions(+), 130 deletions(-) create mode 100644 src/pages/MapPage/components/ButtonGroup.tsx create mode 100644 src/pages/MapPage/mapStore.ts diff --git a/src/pages/MapPage/MapPage.tsx b/src/pages/MapPage/MapPage.tsx index 95cfc93..f06f78f 100644 --- a/src/pages/MapPage/MapPage.tsx +++ b/src/pages/MapPage/MapPage.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useEffect } from 'react'; import styled from 'styled-components'; @@ -6,142 +6,71 @@ import BottomSheet from './BottomSheet'; import MapComponent from './components/map/MapComponent'; import SearchComponent from './components/map/Search'; -import { Slope, slopeMapAPI } from '../../apis/slopeMap'; -import MyLocationIcon from '@mui/icons-material/MyLocationRounded'; +import { useMapStore } from './mapStore'; +import ButtonGroup from './components/ButtonGroup'; const MapPage = () => { - const [selectedMarkerId, setSelectedMarkerId] = useState(null); - const [allTextShow, setAllTextShow] = useState(false); - const [userLocation, setUserLocation] = useState( - null - ); - const [slopeData, setSlopeData] = useState([]); - - const [searchMod, setSearchMod] = useState(false); - const [bottomSheetHeight, setBottomSheetHeight] = useState(200); //bottomsheet 높이 조절 state - - const fetchSlopes = useCallback(async () => { - //위치정보가 없는 경우 호출 안함 - if (!userLocation?.lat() || !userLocation?.lng()) return; - - try { - const data = await slopeMapAPI.fetchNearbySlopes( - userLocation.lat(), - userLocation.lng() - ); - setSlopeData(data || []); - } catch (error) { - console.error('Error fetching slopes:', error); - setSlopeData([]); - } - }, [userLocation]); + const { + selectedMarkerId, + allTextShow, + userLocation, + slopeData, + searchMod, + bottomSheetHeight, + mapInstance, + setAllTextShow, + setBottomSheetHeight, + fetchSlopes, + handleSearch, + chooseSelectItem, + moveToMyLocation, + setUserLocation, + setMapInstance, + setSelectedMarkerId, + } = useMapStore(); useEffect(() => { if (!searchMod) fetchSlopes(); }, [userLocation, searchMod, fetchSlopes]); - const [mapInstance, setMapInstance] = useState(null); - - //검색 핸들 callback - const handleSearch = useCallback( - (searchValue: string) => { - if (searchValue === '') { - setSearchMod(false); - fetchSlopes(); - setSelectedMarkerId(null); - return; - } - setSelectedMarkerId(null); - setSearchMod(true); - - const searchSlope = async () => { - if (!userLocation?.lat() || !userLocation?.lng()) return; //위치정보가 없는 경우 호출 안함 - // console.log('Searching for:', searchValue); - // console.log('Searching Mod:', searchMod); - try { - const data = await slopeMapAPI.searchSlopes( - searchValue, - userLocation.lat(), - userLocation.lng() - ); - setSlopeData(data || []); - if (mapInstance && data) { - const coordinates = data[0].location.coordinates.start.coordinates; - mapInstance.panTo( - new naver.maps.LatLng(coordinates[1], coordinates[0]) - ); - } - } catch (error) { - console.error('Error search slopes:', error); - setSlopeData([]); - } - }; - searchSlope(); - }, - [userLocation] - ); - - //아이템 선택 - const chooseSelectItem = useCallback( - (item: Slope, index: number) => { - if (mapInstance && item) { - // 지도 이동 - const coordinates = item.location.coordinates.start.coordinates; - mapInstance.panTo( - new naver.maps.LatLng(coordinates[1], coordinates[0]) - ); - - // 마커 선택 상태 변경 - setSelectedMarkerId((prevId) => (prevId === index ? null : index)); - } - }, - [mapInstance] - ); - //내 위치로 이동 - const moveToMyLocation = useCallback(() => { - if (!mapInstance || !userLocation) return; - - // 줌 레벨 먼저 변경 - mapInstance.setZoom(15); - - // 약간 지연 후 위치 이동 - setTimeout(() => { - mapInstance.panTo(userLocation); - }, 100); - - fetchSlopes(); - }, [mapInstance, userLocation, fetchSlopes]); return ( - - - { - setSelectedMarkerId(null); + <> + + + { + setSelectedMarkerId(null); + }} + searchMod={searchMod} + /> + + + {/* { + setAllTextShow(!allTextShow); }} - searchMod={searchMod} - /> - - + > + {allTextShow ? '위성지도' : '일반지도'} + { - // console.log(allTextShow); - // console.log(allTextShow); setAllTextShow(!allTextShow); }} > @@ -149,8 +78,10 @@ const MapPage = () => { - - + */} + + + ); }; diff --git a/src/pages/MapPage/components/ButtonGroup.tsx b/src/pages/MapPage/components/ButtonGroup.tsx new file mode 100644 index 0000000..f061b9b --- /dev/null +++ b/src/pages/MapPage/components/ButtonGroup.tsx @@ -0,0 +1,185 @@ +// import styled from 'styled-components' +// import { useMapStore } from '../mapStore'; +// import MyLocationIcon from '@mui/icons-material/MyLocationRounded'; + +// const ButtonGroup = () => { +// const {allTextShow,setAllTextShow,moveToMyLocation}=useMapStore(); +// return ( +// +// { +// setAllTextShow(!allTextShow); +// }} +// > +// {allTextShow ? '위성지도' : '일반지도'} +// +// { +// setAllTextShow(!allTextShow); +// }} +// > +// {allTextShow ? '전체표기' : '개별표기'} +// +// +// +// +// +// ); +// }; + +// export default ButtonGroup; + +// const Container=styled.div` +// position: absolute; +// top: 50px; +// right: 10px; +// ` +// const AllShowButton = styled.button<{ $isSelect: boolean }>` +// position: absolute; +// top: 50px; +// right: 10px; +// border: none; +// border-radius: 8px; +// height: 30px; +// padding: 5px 10px; +// box-shadow: ${({ theme }) => theme.shadows.sm}; +// font-weight: ${({ theme }) => theme.fonts.weights.bold}; +// font-size: ${({ theme }) => theme.fonts.sizes.ms}; +// background-color: ${({ $isSelect, theme }) => +// $isSelect ? theme.colors.primaryDark : '#fff'}; +// color: ${({ $isSelect, theme }) => +// !$isSelect ? theme.colors.primaryDark : '#fff'}; +// &:focus { +// outline: none; +// } +// transition: all 0.15s ease-in-out; + +// &:active { +// transform: scale(1.1); +// } +// `; + +// const MyPosition = styled.button` +// position: absolute; +// top: 90px; +// right: 10px; +// border: none; +// border-radius: 8px; +// padding: 5px 10px; +// box-shadow: ${({ theme }) => theme.shadows.sm}; +// font-weight: 550; +// background-color: #fff; +// transition: all 0.15s ease-in-out; +// &:hover { +// background-color: ${({ theme }) => theme.colors.grey[200]}; +// } +// &:active { +// transform: scale(1.1); +// } +// `; +import styled from 'styled-components'; +import { useMapStore, MapTypeId } from '../mapStore'; +import MyLocationIcon from '@mui/icons-material/MyLocationRounded'; + +const ButtonGroup = () => { + const { + allTextShow, + setAllTextShow, + moveToMyLocation, + mapTypeId, + setMapTypeId, + } = useMapStore(); + + return ( + + { + setMapTypeId( + mapTypeId === MapTypeId.NORMAL ? MapTypeId.HYBRID : MapTypeId.NORMAL + ); + }} + > + {mapTypeId === MapTypeId.HYBRID ? '일반지도' : '위성지도'} + + + { + setAllTextShow(!allTextShow); + }} + > + {allTextShow ? '전체표기' : '개별표기'} + + + + + + + ); +}; + +export default ButtonGroup; + +const Container = styled.div` + position: absolute; + top: 50px; + right: 10px; + display: flex; + flex-direction: column; + gap: 10px; + z-index: 1000; +`; + +// 버튼 기본 스타일을 공통으로 분리 +const BaseButton = styled.button` + border: none; + border-radius: 8px; + padding: 5px 10px; + box-shadow: ${({ theme }) => theme.shadows.sm}; + transition: all 0.15s ease-in-out; + + &:focus { + outline: none; + } + + &:active { + transform: scale(1.1); + } +`; + +// 지도 타입 변경 버튼 +const MapTypeButton = styled(BaseButton)<{ $isSelect: boolean }>` + height: 30px; + font-weight: ${({ theme }) => theme.fonts.weights.bold}; + font-size: ${({ theme }) => theme.fonts.sizes.ms}; + background-color: ${({ $isSelect, theme }) => + $isSelect ? theme.colors.primaryDark : '#fff'}; + color: ${({ $isSelect, theme }) => + !$isSelect ? theme.colors.primaryDark : '#fff'}; +`; + +// 텍스트 표시 방식 변경 버튼 +const TextDisplayButton = styled(BaseButton)<{ $isSelect: boolean }>` + height: 30px; + font-weight: ${({ theme }) => theme.fonts.weights.bold}; + font-size: ${({ theme }) => theme.fonts.sizes.ms}; + background-color: ${({ $isSelect, theme }) => + $isSelect ? theme.colors.primaryDark : '#fff'}; + color: ${({ $isSelect, theme }) => + !$isSelect ? theme.colors.primaryDark : '#fff'}; +`; + +// 내 위치로 이동 버튼 +const LocationButton = styled(BaseButton)` + display: flex; + align-items: center; + justify-content: center; + background-color: #fff; + + &:hover { + background-color: ${({ theme }) => theme.colors.grey[200]}; + } +`; diff --git a/src/pages/MapPage/components/map/MapComponent.tsx b/src/pages/MapPage/components/map/MapComponent.tsx index fd14964..a42e06e 100644 --- a/src/pages/MapPage/components/map/MapComponent.tsx +++ b/src/pages/MapPage/components/map/MapComponent.tsx @@ -13,6 +13,7 @@ import DmarkerIcon from '../../../../assets/d.webp'; import FmarkerIcon from '../../../../assets/f.webp'; import UserPosIcon from '../../../../assets/current_position.png'; import { MapComponentProps } from '../../interface'; +import { MapTypeId, useMapStore } from '../../mapStore'; declare global { interface Window { ReactNativeWebView?: { @@ -32,10 +33,30 @@ const MapComponent: React.FC = ({ setMapInstance, onMarkerClick, }) => { + const { mapTypeId, setIsMapReady } = useMapStore(); const navermaps = useNavermaps(); const [_errorMessage, setErrorMessage] = useState(null); - // console.log(errorMessage); - // console.log(escarpmentData); + + //지도가 준비된 경우 + useEffect(() => { + if (mapInstance) setIsMapReady(true); + }, [mapInstance, setIsMapReady]); + + const getNaverMapTypeId = () => { + if (!navermaps) return undefined; + + switch (mapTypeId) { + case MapTypeId.SATELLITE: + return navermaps.MapTypeId.SATELLITE; + case MapTypeId.HYBRID: + return navermaps.MapTypeId.HYBRID; + case MapTypeId.TERRAIN: + return navermaps.MapTypeId.TERRAIN; + case MapTypeId.NORMAL: + default: + return navermaps.MapTypeId.NORMAL; + } + }; //앱에서 위치 수신 useEffect(() => { @@ -140,6 +161,7 @@ const MapComponent: React.FC = ({ setMapInstance(ref); } }} + mapTypeId={getNaverMapTypeId()} > void; +// setAllTextShow: (show: boolean) => void; +// setUserLocation: (location: naver.maps.LatLng | null) => void; +// setSlopeData: (data: Slope[]) => void; +// setSearchMod: (mod: boolean) => void; +// setBottomSheetHeight: (height: number) => void; +// setMapInstance: (map: naver.maps.Map | null) => void; +// setMapTypeId: (typeId: naver.maps.MapTypeId) => void; + +// // 비즈니스 로직 +// fetchSlopes: () => Promise; +// handleSearch: (searchValue: string) => void; +// chooseSelectItem: (item: Slope, index: number) => void; +// moveToMyLocation: () => void; +// closeInfo: () => void; +// } + +// export const useMapStore = create((set, get) => ({ +// // 초기 상태 +// selectedMarkerId: null, +// allTextShow: false, +// userLocation: null, +// slopeData: [], +// searchMod: false, +// bottomSheetHeight: 200, +// mapInstance: null, +// mapTypeId: naver.maps.MapTypeId.NORMAL, + +// // 액션 +// setSelectedMarkerId: (id) => set({ selectedMarkerId: id }), +// setAllTextShow: (show) => set({ allTextShow: show }), +// setUserLocation: (location) => set({ userLocation: location }), +// setSlopeData: (data) => set({ slopeData: data }), +// setSearchMod: (mod) => set({ searchMod: mod }), +// setBottomSheetHeight: (height) => set({ bottomSheetHeight: height }), +// setMapInstance: (map) => set({ mapInstance: map }), +// setMapTypeId: (typeId) => set({ mapTypeId: typeId }), + +// // 비즈니스 로직 +// fetchSlopes: async () => { +// const { userLocation } = get(); +// if (!userLocation?.lat() || !userLocation?.lng()) return; + +// try { +// const data = await slopeMapAPI.fetchNearbySlopes( +// userLocation.lat(), +// userLocation.lng() +// ); +// set({ slopeData: data || [] }); +// } catch (error) { +// console.error('Error fetching slopes:', error); +// set({ slopeData: [] }); +// } +// }, + +// handleSearch: async (searchValue) => { +// const { fetchSlopes, userLocation, mapInstance } = get(); + +// if (searchValue === '') { +// set({ searchMod: false, selectedMarkerId: null }); +// fetchSlopes(); +// return; +// } + +// set({ selectedMarkerId: null, searchMod: true }); + +// if (!userLocation?.lat() || !userLocation?.lng()) return; + +// try { +// const data = await slopeMapAPI.searchSlopes( +// searchValue, +// userLocation.lat(), +// userLocation.lng() +// ); +// set({ slopeData: data || [] }); + +// if (mapInstance && data && data.length > 0) { +// const coordinates = data[0].location.coordinates.start.coordinates; +// mapInstance.panTo( +// new naver.maps.LatLng(coordinates[1], coordinates[0]) +// ); +// } +// } catch (error) { +// console.error('Error search slopes:', error); +// set({ slopeData: [] }); +// } +// }, + +// chooseSelectItem: (item, index) => { +// const { mapInstance, selectedMarkerId } = get(); + +// if (mapInstance && item) { +// const coordinates = item.location.coordinates.start.coordinates; +// mapInstance.panTo(new naver.maps.LatLng(coordinates[1], coordinates[0])); + +// set({ selectedMarkerId: selectedMarkerId === index ? null : index }); +// } +// }, + +// moveToMyLocation: () => { +// const { mapInstance, userLocation, fetchSlopes } = get(); + +// if (!mapInstance || !userLocation) return; + +// mapInstance.setZoom(15); + +// setTimeout(() => { +// mapInstance.panTo(userLocation); +// }, 100); + +// fetchSlopes(); +// }, + +// closeInfo: () => { +// set({ selectedMarkerId: null }); +// }, +// })); +import { create } from 'zustand'; +import { Slope, slopeMapAPI } from '../../apis/slopeMap'; + +// 문자열 상수로 맵 타입 정의 +export enum MapTypeId { + NORMAL = 'NORMAL', + SATELLITE = 'SATELLITE', + HYBRID = 'HYBRID', + TERRAIN = 'TERRAIN', +} + +export interface MapState { + // 맵 상태 + selectedMarkerId: number | null; + allTextShow: boolean; + userLocation: naver.maps.LatLng | null; + slopeData: Slope[]; + searchMod: boolean; + bottomSheetHeight: number; + mapInstance: naver.maps.Map | null; + mapTypeId: MapTypeId; + isMapReady: boolean; // 추가: 맵이 완전히 로드되었는지 확인하는 플래그 + + // 액션 + setSelectedMarkerId: (id: number | null) => void; + setAllTextShow: (show: boolean) => void; + setUserLocation: (location: naver.maps.LatLng | null) => void; + setSlopeData: (data: Slope[]) => void; + setSearchMod: (mod: boolean) => void; + setBottomSheetHeight: (height: number) => void; + setMapInstance: (map: naver.maps.Map | null) => void; + setMapTypeId: (typeId: MapTypeId) => void; + setIsMapReady: (isReady: boolean) => void; // 추가: 맵 준비 상태 설정 + + // 비즈니스 로직 + fetchSlopes: () => Promise; + handleSearch: (searchValue: string) => void; + chooseSelectItem: (item: Slope, index: number) => void; + moveToMyLocation: () => void; + closeInfo: () => void; +} + +export const useMapStore = create((set, get) => ({ + // 초기 상태 + selectedMarkerId: null, + allTextShow: false, + userLocation: null, + slopeData: [], + searchMod: false, + bottomSheetHeight: 200, + mapInstance: null, + mapTypeId: MapTypeId.NORMAL, + isMapReady: false, // 초기값: 맵 미준비 상태 + + // 액션 + setSelectedMarkerId: (id) => set({ selectedMarkerId: id }), + setAllTextShow: (show) => set({ allTextShow: show }), + setUserLocation: (location) => set({ userLocation: location }), + setSlopeData: (data) => set({ slopeData: data }), + setSearchMod: (mod) => set({ searchMod: mod }), + setBottomSheetHeight: (height) => set({ bottomSheetHeight: height }), + setMapInstance: (map) => set({ mapInstance: map }), + setMapTypeId: (typeId) => set({ mapTypeId: typeId }), + setIsMapReady: (isReady) => set({ isMapReady: isReady }), + + // 비즈니스 로직 + fetchSlopes: async () => { + const { userLocation, isMapReady } = get(); + // 맵이 준비되지 않았거나 위치 정보가 없으면 중단 + if (!isMapReady || !userLocation?.lat() || !userLocation?.lng()) return; + + try { + const data = await slopeMapAPI.fetchNearbySlopes( + userLocation.lat(), + userLocation.lng() + ); + set({ slopeData: data || [] }); + } catch (error) { + console.error('Error fetching slopes:', error); + set({ slopeData: [] }); + } + }, + + handleSearch: async (searchValue) => { + const { fetchSlopes, userLocation, mapInstance, isMapReady } = get(); + // 맵이 준비되지 않았으면 중단 + if (!isMapReady) return; + + if (searchValue === '') { + set({ searchMod: false, selectedMarkerId: null }); + fetchSlopes(); + return; + } + + set({ selectedMarkerId: null, searchMod: true }); + + if (!userLocation?.lat() || !userLocation?.lng()) return; + + try { + const data = await slopeMapAPI.searchSlopes( + searchValue, + userLocation.lat(), + userLocation.lng() + ); + set({ slopeData: data || [] }); + + if (mapInstance && data && data.length > 0) { + const coordinates = data[0].location.coordinates.start.coordinates; + mapInstance.panTo( + new naver.maps.LatLng(coordinates[1], coordinates[0]) + ); + mapInstance.panTo( + new naver.maps.LatLng(coordinates[1], coordinates[0]) + ); + } + } catch (error) { + console.error('Error search slopes:', error); + set({ slopeData: [] }); + } + }, + + chooseSelectItem: (item, index) => { + const { mapInstance, selectedMarkerId, isMapReady } = get(); + + // 맵이 준비되지 않았으면 중단 + if (!isMapReady || !mapInstance) return; + + if (item) { + const coordinates = item.location.coordinates.start.coordinates; + mapInstance.panTo(new naver.maps.LatLng(coordinates[1], coordinates[0])); + + set({ selectedMarkerId: selectedMarkerId === index ? null : index }); + } + }, + + moveToMyLocation: () => { + const { mapInstance, userLocation, fetchSlopes, isMapReady } = get(); + + // 맵이 준비되지 않았으면 중단 + if (!isMapReady || !mapInstance || !userLocation) return; + + mapInstance.setZoom(15); + + setTimeout(() => { + mapInstance.panTo(userLocation); + }, 100); + + fetchSlopes(); + }, + + closeInfo: () => { + set({ selectedMarkerId: null }); + }, +})); From efdab5a9697f05616ea5fa4de79a139604ef5ae9 Mon Sep 17 00:00:00 2001 From: KimDoHyun Date: Sat, 3 May 2025 04:47:05 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EB=B0=98=EC=98=81=ED=95=9C=20=EC=A0=95=EB=B3=B4=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EB=82=B4=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/MapPage/components/InfoTable.tsx | 60 +++++++++++++++---- .../MapPage/components/ListContainer.tsx | 2 + 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/pages/MapPage/components/InfoTable.tsx b/src/pages/MapPage/components/InfoTable.tsx index a19b23c..02ae269 100644 --- a/src/pages/MapPage/components/InfoTable.tsx +++ b/src/pages/MapPage/components/InfoTable.tsx @@ -3,13 +3,13 @@ import { InfotableProps } from '../interface'; const InfoTable: React.FC = ({ selectItem, onCloseInfo }) => { if (!selectItem) return null; - const grade = selectItem.disaster?.riskLevel?.includes('A') + const grade = selectItem.priority?.grade?.includes('A') ? 'A' - : selectItem.disaster?.riskLevel?.includes('B') + : selectItem.priority?.grade?.includes('B') ? 'B' - : selectItem.disaster?.riskLevel?.includes('C') + : selectItem.priority?.grade?.includes('C') ? 'C' - : selectItem.disaster?.riskLevel?.includes('D') + : selectItem.priority?.grade?.includes('D') ? 'D' : 'F'; return ( @@ -35,22 +35,38 @@ const InfoTable: React.FC = ({ selectItem, onCloseInfo }) => { {selectItem?.management?.department || ''} - - {selectItem?.location?.province || ''}{' '} + {selectItem?.location?.province || ''} {selectItem?.location?.city || ''} {selectItem?.location?.district || ''} {selectItem?.location?.address || ''} + + {selectItem?.priority?.usage && ( + + + {selectItem.priority.usage} + + )} + + + {selectItem.priority.slopeNature} + + + + {selectItem.priority.slopeType} + {grade} + + - + {selectItem?.location?.coordinates?.start?.coordinates?.[1] && selectItem?.location?.coordinates?.start?.coordinates?.[0] @@ -63,6 +79,20 @@ const InfoTable: React.FC = ({ selectItem, onCloseInfo }) => { : '좌표 정보 없음'} + + + + {selectItem?.location?.coordinates?.end?.coordinates?.[1] && + selectItem?.location?.coordinates?.end?.coordinates?.[0] + ? `위도: ${selectItem.location.coordinates.end.coordinates[1] + .toFixed(6) + .toString()}° + 경도: ${selectItem.location.coordinates.end.coordinates[0] + .toFixed(6) + .toString()}°` + : '좌표 정보 없음'} + + ); @@ -134,16 +164,18 @@ const AddressValue = styled(Value)` `; const GradeValue = styled(Value)<{ $grade: string }>` - color: ${({ $grade }) => { + color: ${({ $grade, theme }) => { switch ($grade) { case 'A': - return '#2ecc71'; + return theme.colors.grade.A; case 'B': - return '#f1c40f'; + return theme.colors.grade.B; case 'C': - return '#e67e22'; + return theme.colors.grade.C; case 'D': - return '#e74c3c'; + return theme.colors.grade.D; + case 'F': + return theme.colors.grade.F; default: return '#333'; } @@ -162,3 +194,7 @@ const CloseButton = styled.button` } padding: 8px 15px; `; + +const Line = styled.div` + border-bottom: 1px dashed ${({ theme }) => theme.colors.grey[200]}; +`; diff --git a/src/pages/MapPage/components/ListContainer.tsx b/src/pages/MapPage/components/ListContainer.tsx index 52bf656..12c5b7d 100644 --- a/src/pages/MapPage/components/ListContainer.tsx +++ b/src/pages/MapPage/components/ListContainer.tsx @@ -81,6 +81,8 @@ const GradeBackground = styled.div<{ $grade: string }>` return theme.colors.grade.D; case 'F': return theme.colors.grade.F; + default: + return '#333'; } }}; `; From 35e4922b0fe2b1cc931133b0b3bc8a7a91e39267 Mon Sep 17 00:00:00 2001 From: KimDoHyun Date: Sat, 3 May 2025 04:54:41 +0900 Subject: [PATCH 6/7] fix: unused var delete --- src/pages/MapPage/MapPage.tsx | 46 ----------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/pages/MapPage/MapPage.tsx b/src/pages/MapPage/MapPage.tsx index f06f78f..2519f4b 100644 --- a/src/pages/MapPage/MapPage.tsx +++ b/src/pages/MapPage/MapPage.tsx @@ -17,12 +17,10 @@ const MapPage = () => { searchMod, bottomSheetHeight, mapInstance, - setAllTextShow, setBottomSheetHeight, fetchSlopes, handleSearch, chooseSelectItem, - moveToMyLocation, setUserLocation, setMapInstance, setSelectedMarkerId, @@ -95,47 +93,3 @@ const BaseBackground = styled.div` overscroll-behavior: none; position: relative; `; - -const AllShowButton = styled.button<{ $isSelect: boolean }>` - position: absolute; - top: 50px; - right: 10px; - border: none; - border-radius: 8px; - height: 30px; - padding: 5px 10px; - box-shadow: ${({ theme }) => theme.shadows.sm}; - font-weight: ${({ theme }) => theme.fonts.weights.bold}; - font-size: ${({ theme }) => theme.fonts.sizes.ms}; - background-color: ${({ $isSelect, theme }) => - $isSelect ? theme.colors.primaryDark : '#fff'}; - color: ${({ $isSelect, theme }) => - !$isSelect ? theme.colors.primaryDark : '#fff'}; - &:focus { - outline: none; - } - transition: all 0.15s ease-in-out; - - &:active { - transform: scale(1.1); - } -`; - -const MyPosition = styled.button` - position: absolute; - top: 90px; - right: 10px; - border: none; - border-radius: 8px; - padding: 5px 10px; - box-shadow: ${({ theme }) => theme.shadows.sm}; - font-weight: 550; - background-color: #fff; - transition: all 0.15s ease-in-out; - &:hover { - background-color: ${({ theme }) => theme.colors.grey[200]}; - } - &:active { - transform: scale(1.1); - } -`; From 82f720c882fd4b36536388c7431e1f34a19e491e Mon Sep 17 00:00:00 2001 From: KimDoHyun Date: Sat, 3 May 2025 04:54:59 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20githubaction=20yaml=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/front-build.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/front-build.yaml b/.github/workflows/front-build.yaml index d54b06a..17c6acd 100644 --- a/.github/workflows/front-build.yaml +++ b/.github/workflows/front-build.yaml @@ -34,6 +34,11 @@ jobs: - name: install npm dependencies run: npm install + - name: Create .env file + run: | + echo "VITE_NAVER_MAP_ID=${{ secrets.VITE_NAVER_MAP_ID }}" >> .env + echo "VITE_SERVER_ADDRESS=${{ secrets.VITE_SERVER_ADDRESS }}" >> .env + - name: react build run: npm run build