Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE][Feat] 현재 위치로 이동 버튼 구현 및 add-channel footer 사라지지 않도록 구현 #444

Merged
merged 7 commits into from
Dec 5, 2024
1 change: 0 additions & 1 deletion frontend/src/api/channel.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ export const deleteChannel = (channelId: string): Promise<ResponseDto<deleteChan
}
})
.catch(err => {
console.log(channelId);
console.error(err);
fnReject('msg.RESULT_FAILED');
});
Expand Down
85 changes: 49 additions & 36 deletions frontend/src/component/bottomsheet/BottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import React, { useState, useRef } from 'react';
import { MdClear } from 'react-icons/md';
import classNames from 'classnames';
import { SetCurrentLocationButton } from '../setCurrentLocationButton/SetCurrentLocationButton';

interface IBottomSheetProps {
map: naver.maps.Map | null;
lat: number | null;
lng: number | null;
minHeight: number;
maxHeight: number;
backgroundColor: string;
children: React.ReactNode;
}

export const BottomSheet = ({
map,
lat,
lng,
minHeight,
maxHeight,
backgroundColor,
Expand Down Expand Up @@ -52,10 +59,6 @@ export const BottomSheet = ({
window.addEventListener('mouseup', handleMouseUp);
};

const handleClose = () => {
setSheetHeight(minHeight);
};

const [, setScrollPosition] = useState(0);
const [touchStartY, setTouchStartY] = useState<number | null>(null);

Expand Down Expand Up @@ -83,42 +86,52 @@ export const BottomSheet = ({
};

return (
<div
className="transition-height absolute bottom-0 left-0 right-0 overflow-hidden rounded-t-2xl bg-white shadow-lg duration-700 ease-out"
style={{
backgroundColor: `${backgroundColor}`,
height: `${sheetHeight * 100}vh`,
}}
onTouchStart={e => e.stopPropagation()}
onTouchMove={e => e.stopPropagation()}
onTouchEnd={e => e.stopPropagation()}
>
<>
<div
className="flex items-center justify-center pb-6 pt-2"
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onMouseDown={handleMouseDown}
className={classNames('absolute bottom-14 z-[5000]')}
style={{
height: `${sheetHeight * 100}vh`,
transition: 'height 0.3s ease-out',
}}
>
<div className="h-1.5 w-12 rounded-full bg-gray-300" />
<SetCurrentLocationButton map={map} lat={lat} lng={lng} isMain />
</div>

<div className="absolute right-2 top-2">
<button
onClick={handleClose}
className="flex h-[30px] w-[30px] items-center justify-center rounded-full bg-gray-200"
>
<MdClear size={18} color="grayscale-850" />
</button>
</div>

<div
className="h-[calc(100%-60px)] overflow-auto pb-5"
onTouchStart={handleContentTouchStart}
onTouchMove={handleContentTouchMove}
onMouseDown={handleContentTouchEnd}
className="transition-height absolute bottom-0 left-0 right-0 overflow-hidden rounded-t-2xl bg-white shadow-lg duration-700 ease-out"
style={{
backgroundColor: `${backgroundColor}`,
height: `${sheetHeight * 100}vh`,
}}
onTouchStart={e => e.stopPropagation()}
onTouchMove={e => e.stopPropagation()}
onTouchEnd={e => e.stopPropagation()}
>
{children}
<div
className="transition-height absolute bottom-0 left-0 right-0 overflow-hidden rounded-t-2xl bg-white shadow-lg duration-700 ease-out"
style={{
backgroundColor: `${backgroundColor}`,
height: `${sheetHeight * 100}vh`,
}}
>
<div
className="flex items-center justify-center pb-6 pt-2"
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onMouseDown={handleMouseDown}
>
<div className="h-1.5 w-12 rounded-full bg-gray-300" />
</div>

<div
className="h-[calc(100%-60px)] overflow-auto pb-5"
onTouchStart={handleContentTouchStart}
onTouchMove={handleContentTouchMove}
onMouseDown={handleContentTouchEnd}
>
{children}
</div>
</div>
</div>
</div>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import { useCanvasInteraction } from '@/hooks/useCanvasInteraction';
import { useRedrawCanvas } from '@/hooks/useRedraw';
import { ZoomSlider } from '@/component/zoomslider/ZoomSlider';
import { ICluster, useCluster } from '@/hooks/useCluster';
import { SetCurrentLocationButton } from '@/component/setCurrentLocationButton/SetCurrentLocationButton';

export const MapCanvasForView = forwardRef<naver.maps.Map | null, IMapCanvasViewProps>(
({ lat, lng, alpha, otherLocations, guests, width, height }: IMapCanvasViewProps, ref) => {
(
{ lat, lng, alpha, otherLocations, guests, width, height, isMain }: IMapCanvasViewProps,
ref,
) => {
const mapRef = useRef<HTMLDivElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
const [projection, setProjection] = useState<naver.maps.MapSystemProjection | null>(null);
const [map, setMap] = useState<naver.maps.Map | null>(null);
const { createClusters } = useCluster();
const [clusters, setClusters] = useState<ICluster[] | null>(null);

useImperativeHandle(ref, () => map as naver.maps.Map);
const [center, setCenter] = useState<IPoint>();

useEffect(() => {
if (!mapRef.current) return;
Expand All @@ -38,6 +41,8 @@ export const MapCanvasForView = forwardRef<naver.maps.Map | null, IMapCanvasView
};
}, [lat, lng]);

useImperativeHandle(ref, () => map as naver.maps.Map);

const latLngToCanvasPoint = (latLng: IPoint): ICanvasPoint | null => {
if (!map || !projection || !canvasRef.current) return null;
const coord = projection.fromCoordToOffset(new naver.maps.LatLng(latLng.lat, latLng.lng));
Expand Down Expand Up @@ -113,19 +118,28 @@ export const MapCanvasForView = forwardRef<naver.maps.Map | null, IMapCanvasView
}
};

const handleCenterChanged = () => {
if (map) {
const currentCenter = map.getCenter();
const point = { lat: currentCenter.x, lng: currentCenter.y };
setCenter(point);
}
};

// 컴포넌트가 처음 마운트될 때 즉시 실행
updateClusters();

const intervalId = setInterval(() => {
updateClusters();
handleCenterChanged();
}, 100);

return () => clearInterval(intervalId); // 컴포넌트 언마운트 시 인터벌 클리어
}, [guests, map]);

useEffect(() => {
redrawCanvas();
}, [guests, otherLocations, lat, lng, alpha, clusters, handleWheel]);
}, [guests, otherLocations, lat, lng, alpha, clusters, handleWheel, center]);

return (
<div
Expand Down Expand Up @@ -157,6 +171,7 @@ export const MapCanvasForView = forwardRef<naver.maps.Map | null, IMapCanvasView
>
<ZoomSlider map={map} redrawCanvas={redrawCanvas} />
</div>
{!isMain && <SetCurrentLocationButton map={map} lat={lat} lng={lng} />}
</div>
);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import classNames from 'classnames';
import { MdMyLocation } from 'react-icons/md';

interface ISetCurruntLocationButton {
map: naver.maps.Map | null;
lat: number | null;
lng: number | null;
isMain?: boolean;
}

export const SetCurrentLocationButton = (props: ISetCurruntLocationButton) => {
const handleCurrentLocationButton = () => {
if (props.lat && props.lng) {
props.map?.setCenter(new window.naver.maps.LatLng(props.lat, props.lng));
props.map?.setZoom(14);
}
};

return (
<button
type="button"
onClick={() => handleCurrentLocationButton()}
className={classNames(
'bg-blueGray-800 shadow-floatButton z-[5000] flex h-12 w-12 items-center justify-center rounded-full text-white',
props.isMain ? 'relative bottom-0 left-2' : 'absolute bottom-5 left-5',
)}
>
<MdMyLocation className="h-6 w-6" />
</button>
);
};
1 change: 1 addition & 0 deletions frontend/src/lib/types/canvasInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ export interface IMapCanvasViewProps {
guests?: IGuestDataInMapProps[] | null;
width: string;
height: string;
isMain: boolean;
}
3 changes: 1 addition & 2 deletions frontend/src/pages/AddChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ export const AddChannel = () => {
marker_style: user.marker_style,
})),
};
const response = await createChannel(channelData);
console.log('채널 생성 성공:', response);
await createChannel(channelData);
} catch (error) {
console.error('채널 생성 실패:', error);
}
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/pages/DrawRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import { getAddressFromCoordinates } from '@/utils/map/getAddress';

export const DrawRoute = () => {
const { users, setUsers } = useContext(UserContext);
const { setFooterTitle, setFooterActive, setFooterOnClick, resetFooterContext } =
useContext(FooterContext);
const {
setFooterTitle,
setFooterActive,
setFooterOnClick,
setFooterTransparency,
resetFooterContext,
} = useContext(FooterContext);
const { currentUser, setCurrentUser } = useContext(CurrentUserContext);
const params = useParams<Record<string, string | undefined>>();
const navigate = useNavigate();
Expand Down Expand Up @@ -51,6 +56,7 @@ export const DrawRoute = () => {

useEffect(() => {
setFooterTitle('사용자 경로 추가 완료');
setFooterTransparency(false);
setFooterActive(buttonActiveType.PASSIVE);
const user = getUser();
if (user) {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/GuestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const GuestView = () => {
width="100%"
height="100%"
guests={[guestInfo]}
isMain={false}
/>
) : (
<LoadingSpinner />
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/HostView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ export const HostView = () => {
guests={mapProps}
otherLocations={filteredOtherLocations}
ref={mapRef}
isMain={false}
/>
) : (
<LoadingSpinner />
Expand Down
21 changes: 19 additions & 2 deletions frontend/src/pages/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const Main = () => {
setFooterActive,
resetFooterContext,
} = useContext(FooterContext);
const mapRef = useRef<naver.maps.Map | null>(null);
const { lat, lng, alpha, error } = getUserLocation();
const [otherLocations, setOtherLocations] = useState<any[]>([]);
const MIN_HEIGHT = 0.15;
Expand Down Expand Up @@ -212,7 +213,9 @@ export const Main = () => {
lat={lat}
lng={lng}
alpha={alpha}
ref={mapRef}
otherLocations={otherLocations}
isMain
/>
) : (
<LoadingSpinner />
Expand All @@ -226,7 +229,14 @@ export const Main = () => {
</main>

{isUserLoggedIn ? (
<BottomSheet minHeight={MIN_HEIGHT} maxHeight={MAX_HEIGHT} backgroundColor="#FFFFFF">
<BottomSheet
map={mapRef.current}
lat={lat}
lng={lng}
minHeight={MIN_HEIGHT}
maxHeight={MAX_HEIGHT}
backgroundColor="#FFFFFF"
>
{channels.map(item => (
<Fragment key={item.id}>
<Content
Expand All @@ -243,7 +253,14 @@ export const Main = () => {
<div className="h-10" />
</BottomSheet>
) : (
<BottomSheet minHeight={MIN_HEIGHT} maxHeight={MAX_HEIGHT} backgroundColor="#F1F1F1F2">
<BottomSheet
map={mapRef.current}
lat={lat}
lng={lng}
minHeight={MIN_HEIGHT}
maxHeight={MAX_HEIGHT}
backgroundColor="#F1F1F1F2"
>
<div className="h-full w-full cursor-pointer" onClick={handleLoginRequest}>
<div className="absolute left-1/2 top-[20%] flex -translate-x-1/2 transform cursor-pointer flex-col p-6 text-center">
<p className="text-grayscale-175 mb-5 text-lg font-normal">로그인을 진행하여</p>
Expand Down
Loading