Skip to content

Commit

Permalink
feat: 지도 클릭 이벤트, 지역설정, 술제품 화면 랜더링 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
leejiho9898 committed Oct 1, 2023
1 parent 17bc517 commit 5fc3a9e
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 55 deletions.
154 changes: 108 additions & 46 deletions apps/jurumarble/src/app/map/components/MapContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,41 @@ import useDrinksMapService from "../services/useDrinksMapService";
import { Map, MapMarker } from "react-kakao-maps-sdk";
import { useToggle } from "@react-hookz/web";
import RegionBottomSheet from "./RegionBottomsheet";
import DrinkItem from "app/stemp/components/DrinkItem";
import { ExImg1 } from "public/images";
import RegionSmallSelect from "./RegionSmallSelect";
import { DRINK_INFO_SORT_LIST } from "lib/constants";

const MapContainer = () => {
const [on, toggle] = useToggle();
const mapRef = useRef<kakao.maps.Map>(null);
const [mapXY, setMapXY] = useState({
startX: 0,
startY: 0,
endX: 0,
endY: 0,
startX: 33.64225953272826,
startY: 119.06076029979886,
endX: 40.856225138838,
endY: 132.02500466772065,
});

const { drinksList, subscribe } = useDrinksMapService({
const { drinksList } = useDrinksMapService({
startX: mapXY.startX,
startY: mapXY.startY,
endX: mapXY.endX,
endY: mapXY.endY,
page: 0,
size: 100,
});
const [sortBy, setSortBy] = useState("ByPopularity");

const onChangeDrinkInfoSortOption = (sortOption: string) => {
setSortBy(sortOption);
};

const [state, setState] = useState({
// 지도의 초기 위치 서울 시청
center: { lat: 37.5662952, lng: 126.9779 },
center: { lat: 36.75158343784174, lng: 127.90408370095267 },
// 지도 위치 변경시 panto를 이용할지에 대해서 정의
isPanto: false,
level: 13,
});

useEffect(() => {
Expand All @@ -39,6 +51,32 @@ const MapContainer = () => {
}, 1000);
}, []);

const onIdleMap = () => {
const map = mapRef.current;
if (map) {
const bounds = map.getBounds();
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
setMapXY({
startX: sw.getLat(),
startY: sw.getLng(),
endX: ne.getLat(),
endY: ne.getLng(),
});
}
};

const setChangeMapCenter = (lat: number, lng: number) => {
setState({
center: { lat, lng },
isPanto: true,
level: 11,
});
setTimeout(() => {
onIdleMap();
}, 100);
};

return (
<Container>
<TopBox>
Expand All @@ -57,51 +95,64 @@ const MapContainer = () => {
여행지의 우리술을 확인할 수 있어요
</div>
</TopBox>
<MapBox>
<Map // 지도를 표시할 Container
center={state.center}
isPanto={state.isPanto}
style={{
// 지도의 크기
width: "100%",
height: "375px",
}}
ref={mapRef}
level={14} // 지도의 확대 레벨
onIdle={() => {
const map = mapRef.current;
if (map) {
const bounds = map.getBounds();
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
setMapXY({
startX: sw.getLat(),
startY: sw.getLng(),
endX: ne.getLat(),
endY: ne.getLng(),
});
}

<Map // 지도를 표시할 Container
center={state.center}
isPanto={state.isPanto}
style={{
// 지도의 크기
width: "100%",
height: "375px",
}}
ref={mapRef}
level={state.level} // 지도의 확대 레벨
onIdle={() => onIdleMap()}
>
<MapMarker // 마커를 생성합니다
position={{
// 마커가 표시될 위치입니다
lat: 37.5662952,
lng: 126.9779,
}}
>
/>
{drinksList.map(({ latitude, longitude }) => (
<MapMarker // 마커를 생성합니다
position={{
// 마커가 표시될 위치입니다
lat: 37.5662952,
lng: 126.9779,
lat: latitude,
lng: longitude,
}}
/>
{drinksList.map(({ latitude, longitude }) => (
<MapMarker // 마커를 생성합니다
position={{
// 마커가 표시될 위치입니다
lat: latitude,
lng: longitude,
}}
/>
))}
</Map>
</MapBox>
<RegionBottomSheet onToggleDrinkSearchModal={toggle} on={on} />
))}
</Map>
<FilterBox>
<RegionSmallSelect
defaultOption={sortBy}
onChangeSortOption={onChangeDrinkInfoSortOption}
options={DRINK_INFO_SORT_LIST}
/>
</FilterBox>
<DrinkBox>
{drinksList.map(({ drinkId, name, region, latitude, longitude }) => (
<DrinkItem
drinkInfo={{
id: drinkId,
name: name,
productName: region,
image: ExImg1 as unknown as string,
}}
onClickReplaceDrinkInfo={() => {
setChangeMapCenter(latitude, longitude);
}}
selectedDrinkList={[]}
/>
))}
</DrinkBox>
<RegionBottomSheet
setChangeMapCenter={setChangeMapCenter}
onToggleDrinkSearchModal={toggle}
on={on}
/>
</Container>
);
};
Expand Down Expand Up @@ -132,6 +183,17 @@ const SettingWrapper = styled.div`
justify-content: space-between;
`;

const MapBox = styled.div``;
const FilterBox = styled.div`
display: flex;
justify-content: flex-end;
padding: 16px 20px 32px 20px;
`;

const DrinkBox = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
padding: 0 20px;
`;

export default MapContainer;
19 changes: 12 additions & 7 deletions apps/jurumarble/src/app/map/components/RegionBottomsheet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, Portal } from "components/index";
import { REGION_LIST } from "lib/constants";
import { REGION_LIST_BOUNDS } from "lib/constants";
import { transitions } from "lib/styles";
import Image from "next/image";
import React from "react";
Expand All @@ -9,9 +9,10 @@ import styled, { css } from "styled-components";
interface Props {
on: boolean;
onToggleDrinkSearchModal: () => void;
setChangeMapCenter: (lat: number, lng: number) => void;
}

const RegionBottomSheet = ({ on, onToggleDrinkSearchModal }: Props) => {
const RegionBottomSheet = ({ on, onToggleDrinkSearchModal, setChangeMapCenter }: Props) => {
if (!on) return null;

return (
Expand All @@ -32,11 +33,15 @@ const RegionBottomSheet = ({ on, onToggleDrinkSearchModal }: Props) => {
/>{" "}
</SelectBox>
<List>
{REGION_LIST.map(({ label, value }) => (
<RegionItem>{label}</RegionItem>
))}
{REGION_LIST.map(({ label, value }) => (
<RegionItem>{label}</RegionItem>
{REGION_LIST_BOUNDS.map(({ label, value, lat, long }) => (
<RegionItem
onClick={() => {
setChangeMapCenter(lat, long);
onToggleDrinkSearchModal();
}}
>
{label}
</RegionItem>
))}
</List>
<ButtonWrapper>
Expand Down
59 changes: 59 additions & 0 deletions apps/jurumarble/src/app/map/components/RegionSmallSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import styled, { css } from "styled-components";
import { useToggle } from "@monorepo/hooks";
import SvgIcExpandMore from "src/assets/icons/components/IcExpandMore";
import { Select } from "components/selectBox";

interface Props {
defaultOption: string;
onChangeSortOption: (id: string) => void;
options: { value: string; label: string }[];
}

function RegionSmallSelect({ defaultOption, onChangeSortOption, options }: Props) {
const [isOpen, onToggleOpen] = useToggle();

return (
<SelectStyled isOpen={isOpen}>
<Select
defaultValue={defaultOption}
onChangeSelectedOption={onChangeSortOption}
options={options}
isOpen={isOpen}
onToggleOpen={onToggleOpen}
>
<SvgIcExpandMore width={20} height={20} />
</Select>
</SelectStyled>
);
}

const SelectStyled = styled.span<{ isOpen: boolean }>`
${({ theme, isOpen }) => css`
${theme.typography.button01};
color: ${theme.colors.black_03};
width: 85px;
/* height: 40px; */
.selected-label {
border: 1px solid ${theme.colors.line_01};
border-radius: 8px;
padding: 10px 12px;
}
svg {
${isOpen && "transform: rotateX( 180deg )"}
}
#select-list {
width: 100px;
height: 78px;
display: flex;
flex-direction: column;
align-items: center;
padding: 8px 0;
gap: 20px;
}
#indicator {
display: flex;
}
`}
`;

export default RegionSmallSelect;
10 changes: 9 additions & 1 deletion apps/jurumarble/src/app/stemp/components/DrinkItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import styled, { css, useTheme } from "styled-components";
import useDrinkStempService from "../service/useDrinkStempService";

interface Props {
drinkInfo: DrinkInfo;
drinkInfo:
| DrinkInfo
| {
id: number;
name: string;
productName: string;
image: string;
};
onClickReplaceDrinkInfo: (e: React.MouseEvent<HTMLButtonElement>) => void;
selectedDrinkList?: string[];
}
Expand Down Expand Up @@ -54,6 +61,7 @@ const Container = styled.button<{ selected: boolean | undefined }>`
padding: 16px;
border-radius: 16px;
cursor: pointer;
width: 100%;
${({ theme, selected }) =>
selected &&
css`
Expand Down
2 changes: 1 addition & 1 deletion apps/jurumarble/src/components/BottomBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const NAVIGATION_LIST = [
},
{
name: "술도장",
path: "/stamp",
path: "/stemp",
icon: <SvgIcMark width={24} height={24} />,
},
{
Expand Down
20 changes: 20 additions & 0 deletions apps/jurumarble/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ export const REGION_LIST = [
{ value: "JEJU", label: "제주" },
];

export const REGION_LIST_BOUNDS = [
{ value: "SEOUL", label: "서울", lat: 37.53391, long: 126.9775 },
{ value: "INCHEON", label: "인천", lat: 37.45323333333334, long: 126.70735277777779 },
{ value: "DAEJEON", label: "대전", lat: 36.347119444444445, long: 127.38656666666667 },
{ value: "DAEGU", label: "대구", lat: 35.868541666666665, long: 128.60355277777776 },
{ value: "GWANGJU", label: "광주", lat: 35.156974999999996, long: 126.85336388888888 },
{ value: "BUSAN", label: "부산", lat: 35.17701944444444, long: 129.07695277777776 },
{ value: "ULSAN", label: "울산", lat: 35.53540833333333, long: 129.3136888888889 },
{ value: "SEJONG", label: "세종", lat: 36.4800121, long: 127.289069 },
{ value: "GYEONGGI", label: "경기도", lat: 37.39067, long: 126.7888 },
{ value: "GANGWON", label: "강원도", lat: 38.642618, long: 127.170231 },
{ value: "CHUNGBUK", label: "충청북도", lat: 36.6325, long: 127.49358611111111 },
{ value: "CHUNGNAM", label: "충청남도", lat: 36.32387222222223, long: 127.42295555555556 },
{ value: "GYEONGBUK", label: "경상북도", lat: 36.491286, long: 128.889433 },
{ value: "GYEONGNAM", label: "경상남도", lat: 35.459369, long: 128.214826 },
{ value: "JEONBUK", label: "전라북도", lat: 35.81727, long: 127.11105277777777 },
{ value: "JEONNAM", label: "전라남도", lat: 34.813044444444444, long: 126.465 },
{ value: "JEJU", label: "제주", lat: 33.48569444444445, long: 126.50033333333333 },
];

export const DRINK_VOTE_SORT_LIST = [
{ value: "ByPopularity", label: "인기순" },
{ value: "ByTime", label: "최신순" },
Expand Down

0 comments on commit 5fc3a9e

Please sign in to comment.