-
Notifications
You must be signed in to change notification settings - Fork 9
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
Issue169 마이페이지 북마크 된 음식점 지도 뷰 추가 #170
Changes from 16 commits
277aaca
795248b
a261b1f
5ac3491
c8903fa
5d4a6a8
0dcafeb
5cf2a88
9024c1f
7639e7f
48886f9
23e7291
2980c9e
e6c211b
275ea61
1dd5be3
c45f1c4
1cd6344
4c39bd0
d992fdd
2ba24a8
1add44a
bcb1782
9a04cb0
e8381fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import type { BookmarkStore } from "types/common/bookmarkTypes"; | ||
|
||
import { ACCESS_TOKEN, ENDPOINTS } from "constants/api"; | ||
|
||
import axiosInstance from "api/axiosInstance"; | ||
|
||
const fetchBookmarkList = async () => { | ||
const accessToken = window.sessionStorage.getItem(ACCESS_TOKEN); | ||
|
||
if (!accessToken) { | ||
window.sessionStorage.removeItem(ACCESS_TOKEN); | ||
window.alert("다시 로그인 해주세요"); | ||
window.location.href = "/"; | ||
return; | ||
} | ||
|
||
const { data } = await axiosInstance.get<BookmarkStore[]>( | ||
ENDPOINTS.BOOKMARKS, | ||
{ | ||
headers: { | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
} | ||
); | ||
|
||
return data; | ||
}; | ||
|
||
export default fetchBookmarkList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import ClickedPinIcon from "../../../asset/clicked-pin-icon.svg"; | ||
import PinIcon from "../../../asset/pin-icon.svg"; | ||
import { MapMarker } from "react-kakao-maps-sdk"; | ||
|
||
import { theme } from "style/Theme"; | ||
|
||
interface EventMapMarkerProps { | ||
position: { lat: number; lng: number }; | ||
isClicked: boolean; | ||
onClick: () => void; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. props들의 네이밍을 더 구체화 하는 것이 좋을 것 같아요! 물론 지금도 maker누르면 발생하는 여부인가보다 대충 어림짐작할 수 있어도 정확한 의미 전달은 힘들어서 네이밍에 수정이 필요해보입니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 더불어서 맥락을 위해서 추가적인 설명이 필요한 prop이나 변수에는 주석을 달아주세요! 저희가 항상 만나서 이야기하고 회의할 수 있는게 아니다보니 코드 안에서의 컨텍스트도 중요합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그 부분에 대해서는 생각을 못 했네요! 코멘트로 설명 추가하고 props 명도 각각, |
||
} | ||
|
||
function EventMapMarker({ position, isClicked, onClick }: EventMapMarkerProps) { | ||
const icon = isClicked ? ClickedPinIcon : PinIcon; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아이콘을 아예 갈아치우는 방법도 있지만 컬러만 바꾸도록 할 수도 있지 않을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아이콘을 아예 갈아치우지 않고, 컬러만 바꾼다는 게 정확히 뭘 말하는 건가요?? 조금 더 자세히 설명 부탁합니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 그냥 만약 기존 방식대로 색만 바뀌는 거라면 props로 컬러 받고 svg 컴포넌트에 적용한다는 이야기였어요! |
||
|
||
return ( | ||
<MapMarker | ||
position={position} | ||
onClick={onClick} | ||
image={{ | ||
src: icon, | ||
size: { | ||
width: 36, | ||
height: 36, | ||
}, | ||
}} | ||
zIndex={isClicked ? theme.zIndex.overlay : 1} | ||
/> | ||
); | ||
} | ||
|
||
export default EventMapMarker; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { MutableRefObject } from "react"; | ||
import { Pagination, Navigation } from "swiper"; | ||
import "swiper/css"; | ||
import "swiper/css"; | ||
import "swiper/css/navigation"; | ||
import "swiper/css/pagination"; | ||
import { Swiper, SwiperRef, SwiperSlide } from "swiper/react"; | ||
|
||
interface SlideCarouselProps { | ||
children: JSX.Element[]; | ||
spaceBetween?: number; | ||
onSlideChange: (index: number) => void; | ||
swiperRef: MutableRefObject<SwiperRef | null>; | ||
} | ||
|
||
function SlideCarousel({ | ||
children, | ||
spaceBetween = 8, | ||
onSlideChange, | ||
swiperRef, | ||
}: SlideCarouselProps) { | ||
const handleSlideChange = () => { | ||
const activeSlideIndex = swiperRef.current?.swiper.realIndex ?? 0; | ||
onSlideChange(activeSlideIndex); | ||
}; | ||
|
||
return ( | ||
<Swiper | ||
ref={swiperRef} | ||
className="mySwiper" | ||
slidesPerView={1} | ||
spaceBetween={spaceBetween} | ||
loop={true} | ||
ashleysyheo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
modules={[Pagination, Navigation]} | ||
onSlideChangeTransitionEnd={handleSlideChange} | ||
> | ||
{children.map((child) => ( | ||
<SwiperSlide>{child}</SwiperSlide> | ||
))} | ||
</Swiper> | ||
); | ||
} | ||
|
||
export default SlideCarousel; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import styled, { css } from "styled-components"; | ||
|
||
export const HeaderWrapper = styled.header` | ||
display: flex; | ||
justify-content: space-between; | ||
padding: ${({ theme }) => theme.spacer.spacing3}; | ||
margin-bottom: ${({ theme }) => theme.spacer.spacing4}; | ||
background-color: white; | ||
`; | ||
|
||
export const headerStyle = css` | ||
position: absolute; | ||
left: 50%; | ||
font-weight: bold; | ||
transform: translateX(-50%); | ||
`; | ||
|
||
export const MapWrapper = styled.div` | ||
height: calc(100vh - 208px); | ||
|
||
& #react-kakao-maps-sdk-map-container { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
`; | ||
|
||
export const StoreListWrapper = styled.div` | ||
position: absolute; | ||
bottom: ${({ theme }) => theme.spacer.spacing3}; | ||
width: calc(100% - 16px); | ||
z-index: ${({ theme }) => theme.zIndex.overlay}; | ||
|
||
& li { | ||
width: calc(100% - 16px); | ||
margin: ${({ theme }) => theme.spacer.spacing3}; | ||
padding: ${({ theme }) => theme.spacer.spacing3}; | ||
border-radius: ${({ theme }) => theme.borderRadius.small}; | ||
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15); | ||
} | ||
`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
많은 슬라이더 라이브러리가 있는데 얘를 선택한 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
처음에는 직접 구현해 보려다가 시간 안에 못할 것 같아서 라이브러리를 찾아보게 되었습니다! 그래서 react-slick이랑 swiper를 살펴봤는데, 사용 방법은 둘 다 거의 비슷하더라고요. 그런데 swiper는 slide 할 때는 click 이벤트를 막아 주는 반면, react-slick은 바로 못 해주고 그걸 하기 위한 과정이 조금 복잡했어요. 그리고 이건 제대로 테스트 한건 아니지만, Xcode에서 아이폰이랑, 아이패드에서 터치해서 슬라이드 할 때 swiper를 사용할 때 제대로 원하는 인터렉션을 할 수 있었고요. 찾아보니까 swiper가 mobile first에 초점을 맞춰서 그렇다고 하더라고요!
아무래도 맛집 서비스 자체는 모바일 타겟인 것 같아서 swiper를 선택했습니다!