Skip to content

Commit

Permalink
[FE] Feat/#588 현재 위치 이동 버튼 (#589)
Browse files Browse the repository at this point in the history
* feat: 지도 위 현재 위치로 버튼 추가

* design: 현재 위치 아이콘 변경 및 위치 변경

* refactor: Toast로 사용자에게 위치 정보 상태를 명시

---------

Co-authored-by: semnil5202 <semnil5202@gmail.com>
  • Loading branch information
jiwonh423 and semnil5202 authored Oct 16, 2023
1 parent ff18a09 commit 45d395d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 33 deletions.
9 changes: 9 additions & 0 deletions frontend/src/assets/currentLocationBtn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 52 additions & 8 deletions frontend/src/components/Map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { useContext, useLayoutEffect, useRef, useState } from 'react';
import { styled } from 'styled-components';

import CurrentLocation from '../../assets/currentLocationBtn.svg';
import { LayoutWidthContext } from '../../context/LayoutWidthContext';
import { MarkerContext } from '../../context/MarkerContext';
import useAnimateClickedPin from '../../hooks/useAnimateClickedPin';
import useClickedCoordinate from '../../hooks/useClickedCoordinate';
import useFocusToMarker from '../../hooks/useFocusToMarkers';
import useGeoLocation from '../../hooks/useGeolocation';
import useMapClick from '../../hooks/useMapClick';
import useToast from '../../hooks/useToast';
import useUpdateCoordinates from '../../hooks/useUpdateCoordinates';
import Flex from '../common/Flex';

Expand All @@ -18,6 +21,30 @@ function Map() {
const [mapInstance, setMapInstance] = useState<TMap | null>(null);

const mapContainer = useRef(null);
const location = useGeoLocation();
const { showToast } = useToast();

const handleCurrentLocationClick = () => {
if (!location.loaded) {
showToast('info', '위치 정보를 불러오는 중입니다.');
return;
}

if (location.error) {
showToast('error', '위치 정보 사용을 허용해주세요.');
return;
}

if (mapInstance) {
mapInstance.setCenter(
new Tmapv3.LatLng(
Number(location.coordinates.lat),
Number(location.coordinates.lng),
),
);
mapInstance.setZoom(15);
}
};

useLayoutEffect(() => {
if (!Tmapv3 || !mapContainer.current) return;
Expand Down Expand Up @@ -47,17 +74,24 @@ function Map() {
useAnimateClickedPin(mapInstance, markers);

return (
<MapFlex
aria-label="괜찮을지도 지도 이미지"
flex="1"
id="map"
ref={mapContainer}
height="calc(var(--vh, 1vh) * 100)"
$minWidth={width}
/>
<MapContainer>
<MapFlex
aria-label="괜찮을지도 지도 이미지"
flex="1"
id="map"
ref={mapContainer}
height="calc(var(--vh, 1vh) * 100)"
$minWidth={width}
/>
<CurrentLocationIcon onClick={handleCurrentLocationClick} />
</MapContainer>
);
}

const MapContainer = styled.div`
position: relative;
`;

const MapFlex = styled(Flex)`
& {
canvas {
Expand All @@ -71,4 +105,14 @@ const MapFlex = styled(Flex)`
}
`;

const CurrentLocationIcon = styled(CurrentLocation)`
position: absolute;
cursor: pointer;
bottom: 40px;
right: 12px;
width: 40px;
height: 40px;
z-index: 10;
`;

export default Map;
2 changes: 1 addition & 1 deletion frontend/src/components/common/Input/Autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import styled from 'styled-components';

import { getPoiApi } from '../../../apis/getPoiApi';
import { Poi } from '../../../types/Poi';
import Input from '.';
import Text from '../Text';
import Input from '.';

interface AutocompleteProps {
defaultValue?: string;
Expand Down
43 changes: 19 additions & 24 deletions frontend/src/hooks/useGeolocation.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,46 @@
import { useEffect, useState } from 'react';

interface locationType {
type GeoLocationState = {
loaded: boolean;
currentLocation?: { latitude: number; longitude: number };
coordinates: { lat: string | number; lng: string | number };
error?: { code: number; message: string };
}
};

const useGeolocation = () => {
const [location, setLocation] = useState<locationType>({
const useGeoLocation = () => {
const [location, setLocation] = useState<GeoLocationState>({
loaded: false,
currentLocation: { latitude: 0, longitude: 0 },
coordinates: { lat: '', lng: '' },
});

// 성공에 대한 로직
const onSuccess = (location: {
coords: { latitude: number; longitude: number };
}) => {
const onSuccess = (location: any) => {
setLocation({
loaded: true,
currentLocation: {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
coordinates: {
lat: location.coords.latitude,
lng: location.coords.longitude,
},
});
};

// 에러에 대한 로직
const onError = (error: { code: number; message: string }) => {
const onError = (error: any) => {
setLocation({
loaded: true,
error,
coordinates: { lat: '', lng: '' },
error: {
code: error.code,
message: error.message,
},
});
};

useEffect(() => {
// navigator 객체 안에 geolocation이 없다면
// 위치 정보가 없는 것.
if (!('geolocation' in navigator)) {
onError({
code: 0,
message: 'Geolocation not supported',
});
onError({ code: 0, message: 'Geolocation not supported' });
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}, [location]);
}, []);

return location;
};

export default useGeolocation;
export default useGeoLocation;

0 comments on commit 45d395d

Please sign in to comment.