From 8d57d2e78dc5314bd50159ef5a9a678f84e71fb0 Mon Sep 17 00:00:00 2001 From: Hee Suh <53266682+hee-suh@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:28:53 +0900 Subject: [PATCH] feat: add map view to place page (#168) * refactor: make getMarkerType reusable * refactor: rename place-box to place-detail * refactor: make place-map-popup more scalable * feat: add map view for single place * feat: add gps button to place-map * chore: remove console.log * refactor: make place related types readable * refactor: make register page as server component * refactor: refactor file structure under place - use route groups i/o conditional branching with path * refactor: remove brackets from className * refactor: improve type definitions for Place* --- src/app/map/[mapId]/page.tsx | 25 ++-- .../map/[mapId]/place-list-bottom-sheet.tsx | 12 +- src/app/place/[placeId]/(detail)/layout.tsx | 38 ++++++ .../[placeId]/{ => (detail)}/like-tooltip.tsx | 0 .../place/[placeId]/{ => (detail)}/page.tsx | 8 +- .../{ => (detail)}/place-delete-modal.tsx | 0 .../place-detail.tsx} | 14 +- .../{ => (detail)}/place-liked-users.tsx | 0 .../{ => (detail)}/place-top-information.tsx | 0 src/app/place/[placeId]/loading.tsx | 4 +- src/app/place/[placeId]/{ => map}/layout.tsx | 13 +- src/app/place/[placeId]/map/page.tsx | 19 +++ src/app/place/[placeId]/map/place-map-box.tsx | 54 ++++++++ src/app/place/[placeId]/register/page.tsx | 64 ++------- .../[mapId]/[id]/liked-place-panel.tsx | 4 +- src/app/profile/[mapId]/[id]/place-item.tsx | 4 +- .../[mapId]/[id]/registered-place-panel.tsx | 4 +- .../search/[query]/result-place-map-popup.tsx | 4 +- src/app/search/[query]/result-search-box.tsx | 10 +- src/app/search/[query]/result-search-list.tsx | 12 +- src/app/search/search-box.tsx | 4 +- src/app/search/suggest-place-list.tsx | 4 +- src/components/korrk-kakao-map.tsx | 56 +++----- src/components/place/kakao-rating.tsx | 6 +- .../place/place-auto-search-item.tsx | 4 +- src/components/place/place-map-popup.tsx | 53 ++++---- src/components/place/types.ts | 4 +- src/components/tag-list.tsx | 4 +- src/constants/place.ts | 9 +- src/models/api/place.ts | 128 ++++++++++-------- src/models/kakao-map.ts | 2 +- src/services/marker.ts | 23 ++++ src/utils/api/index.ts | 20 +-- src/utils/format.ts | 35 ++--- src/utils/tags.ts | 4 +- 35 files changed, 370 insertions(+), 275 deletions(-) create mode 100644 src/app/place/[placeId]/(detail)/layout.tsx rename src/app/place/[placeId]/{ => (detail)}/like-tooltip.tsx (100%) rename src/app/place/[placeId]/{ => (detail)}/page.tsx (62%) rename src/app/place/[placeId]/{ => (detail)}/place-delete-modal.tsx (100%) rename src/app/place/[placeId]/{place-box.tsx => (detail)/place-detail.tsx} (96%) rename src/app/place/[placeId]/{ => (detail)}/place-liked-users.tsx (100%) rename src/app/place/[placeId]/{ => (detail)}/place-top-information.tsx (100%) rename src/app/place/[placeId]/{ => map}/layout.tsx (67%) create mode 100644 src/app/place/[placeId]/map/page.tsx create mode 100644 src/app/place/[placeId]/map/place-map-box.tsx create mode 100644 src/services/marker.ts diff --git a/src/app/map/[mapId]/page.tsx b/src/app/map/[mapId]/page.tsx index 3b6ad54a..a0e919e3 100644 --- a/src/app/map/[mapId]/page.tsx +++ b/src/app/map/[mapId]/page.tsx @@ -21,7 +21,7 @@ import PlaceMapPopup from '@/components/place/place-map-popup' import useFetch from '@/hooks/use-fetch' import useMeasure from '@/hooks/use-measure' import type { TagItem } from '@/models/api/maps' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import { getMapIdFromCookie, updateMapIdCookie } from '@/services/map-id' import { api } from '@/utils/api' import { onboardingStorage, visitedMapIdsStorage } from '@/utils/storage' @@ -64,8 +64,8 @@ const MapMain = ({ params: { mapId } }: { params: { mapId: string } }) => { const [selectedFilterNames, setSelectedFilterNames] = useState(INITIAL_FILTER_IDS) - const [filteredPlace, setFilteredPlace] = useState(null) - const [selectedPlace, setSelectedPlace] = useState(null) + const [filteredPlace, setFilteredPlace] = useState(null) + const [selectedPlace, setSelectedPlace] = useState(null) const [mapIdFromCookie, setMapIdFromCookie] = useState('') @@ -83,7 +83,7 @@ const MapMain = ({ params: { mapId } }: { params: { mapId: string } }) => { notify.error(error.message) } - const handleClickPlace = (place: PlaceType) => { + const handleClickPlace = (place: KorrkPlace) => { if (selectedPlace?.place.id === place.place.id) { setSelectedPlace(null) return @@ -251,7 +251,7 @@ const MapMain = ({ params: { mapId } }: { params: { mapId: string } }) => { - + places={filteredPlace} selectedPlace={selectedPlace} onClickMap={() => setSelectedPlace(null)} @@ -297,13 +297,16 @@ const MapMain = ({ params: { mapId } }: { params: { mapId: string } }) => { /> ) : ( - + > + + )} ) diff --git a/src/app/map/[mapId]/place-list-bottom-sheet.tsx b/src/app/map/[mapId]/place-list-bottom-sheet.tsx index 98816ffb..aa89100b 100644 --- a/src/app/map/[mapId]/place-list-bottom-sheet.tsx +++ b/src/app/map/[mapId]/place-list-bottom-sheet.tsx @@ -10,13 +10,13 @@ import EmptyPlaceList from '@/components/place/empty-place-list' import PlaceListItem from '@/components/place/place-list-item' import useFetch from '@/hooks/use-fetch' import { APIError } from '@/models/api/index' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import { useInfiniteScroll } from '@/hooks/use-infinite-scroll' import { api } from '@/utils/api' import { revalidatePlaces } from '@/app/actions' interface PlaceListBottomSheetProps { - places: PlaceType[] | null + places: KorrkPlace[] | null mapId: string selectedFilter?: FilterIdsType onClickFilterButton: VoidFunction @@ -31,8 +31,8 @@ const PlaceListBottomSheet = forwardRef< { places, mapId, selectedFilter, onClickFilterButton, onRefreshOldPlace }, ref, ) => { - const [placeList, setPlaceList] = useState([]) - const { data: slicedPlaceList, listRef } = useInfiniteScroll({ + const [placeList, setPlaceList] = useState([]) + const { data: slicedPlaceList, listRef } = useInfiniteScroll({ totalData: places || [], itemsPerPage: 10, }) @@ -46,14 +46,14 @@ const PlaceListBottomSheet = forwardRef< (selectedFilter?.category !== 'all' ? 1 : 0) + (selectedFilter?.tags.length ?? 0) - const getIsLike = (place: PlaceType): boolean => { + const getIsLike = (place: KorrkPlace): boolean => { if (typeof userId === 'undefined') return false if (place.likedUser?.some((liked) => liked.id === userId)) return true return false } - const handleLike = async (place: PlaceType) => { + const handleLike = async (place: KorrkPlace) => { if (!userId) return try { setPlaceList((prevPlaces) => diff --git a/src/app/place/[placeId]/(detail)/layout.tsx b/src/app/place/[placeId]/(detail)/layout.tsx new file mode 100644 index 00000000..eaa65023 --- /dev/null +++ b/src/app/place/[placeId]/(detail)/layout.tsx @@ -0,0 +1,38 @@ +'use client' + +import type { ReactNode } from 'react' +import { usePathname } from 'next/navigation' + +import AccessibleIconButton from '@/components/common/accessible-icon-button' +import useSafeRouter from '@/hooks/use-safe-router' + +const PlaceDetailLayout = ({ children }: { children: ReactNode }) => { + const router = useSafeRouter() + const pathname = usePathname() + + return ( +
+
+ router.back()} + /> + + { + router.push(`${pathname}/map`) + }} + /> +
+ + {children} +
+ ) +} + +export default PlaceDetailLayout diff --git a/src/app/place/[placeId]/like-tooltip.tsx b/src/app/place/[placeId]/(detail)/like-tooltip.tsx similarity index 100% rename from src/app/place/[placeId]/like-tooltip.tsx rename to src/app/place/[placeId]/(detail)/like-tooltip.tsx diff --git a/src/app/place/[placeId]/page.tsx b/src/app/place/[placeId]/(detail)/page.tsx similarity index 62% rename from src/app/place/[placeId]/page.tsx rename to src/app/place/[placeId]/(detail)/page.tsx index 8c457e2e..4ca0231c 100644 --- a/src/app/place/[placeId]/page.tsx +++ b/src/app/place/[placeId]/(detail)/page.tsx @@ -3,9 +3,9 @@ import dynamic from 'next/dynamic' import { getMapId } from '@/services/map-id' import { api } from '@/utils/api' -const PlaceBox = dynamic(() => import('./place-box'), { ssr: false }) +const PlaceDetail = dynamic(() => import('./place-detail'), { ssr: false }) -const PlaceDetail = async ({ params }: { params?: { placeId?: number } }) => { +const Place = async ({ params }: { params?: { placeId?: number } }) => { const mapId = (await getMapId()) || '' const response = !!mapId && !!params?.placeId @@ -16,7 +16,7 @@ const PlaceDetail = async ({ params }: { params?: { placeId?: number } }) => { : null const place = response?.data - return place && + return place && } -export default PlaceDetail +export default Place diff --git a/src/app/place/[placeId]/place-delete-modal.tsx b/src/app/place/[placeId]/(detail)/place-delete-modal.tsx similarity index 100% rename from src/app/place/[placeId]/place-delete-modal.tsx rename to src/app/place/[placeId]/(detail)/place-delete-modal.tsx diff --git a/src/app/place/[placeId]/place-box.tsx b/src/app/place/[placeId]/(detail)/place-detail.tsx similarity index 96% rename from src/app/place/[placeId]/place-box.tsx rename to src/app/place/[placeId]/(detail)/place-detail.tsx index 011cb33f..ee770e19 100644 --- a/src/app/place/[placeId]/place-box.tsx +++ b/src/app/place/[placeId]/(detail)/place-detail.tsx @@ -18,7 +18,7 @@ import useFetch from '@/hooks/use-fetch' import useSafeRouter from '@/hooks/use-safe-router' import useUserGeoLocation from '@/hooks/use-user-geo-location' import { APIError } from '@/models/api/index' -import type { PlaceDetail } from '@/models/api/place' +import type { PlaceDetail as PlaceDetailType } from '@/models/api/place' import { api } from '@/utils/api' import { formatDistance, getDistance } from '@/utils/location' import { roundToNthDecimal } from '@/utils/number' @@ -26,13 +26,14 @@ import { allowUserPositionStorage } from '@/utils/storage' import cn from '@/utils/cn' import { sendGAEvent } from '@next/third-parties/google' import { revalidatePlaces } from '@/app/actions' +import type { MapInfo } from '@/models/map' -interface PlaceBoxProps { - place: PlaceDetail - mapId: string +interface PlaceDetailProps { + place: PlaceDetailType + mapId: MapInfo['id'] } -const PlaceBox = ({ place, mapId }: PlaceBoxProps) => { +const PlaceDetail = ({ place, mapId }: PlaceDetailProps) => { let createdById = place.createdBy?.id ?? -1 const { data: createdUser } = useFetch(() => api.users.id.get(createdById), { enabled: createdById !== -1, @@ -40,6 +41,7 @@ const PlaceBox = ({ place, mapId }: PlaceBoxProps) => { const [isLikePlace, setIsLikePlace] = useState(false) const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false) const [isRecentlyLike, setIsRecentlyLike] = useState(null) + const router = useSafeRouter() const isAlreadyPick = place.isRegisteredPlace const { userLocation } = useUserGeoLocation() @@ -270,4 +272,4 @@ const PlaceBox = ({ place, mapId }: PlaceBoxProps) => { ) } -export default PlaceBox +export default PlaceDetail diff --git a/src/app/place/[placeId]/place-liked-users.tsx b/src/app/place/[placeId]/(detail)/place-liked-users.tsx similarity index 100% rename from src/app/place/[placeId]/place-liked-users.tsx rename to src/app/place/[placeId]/(detail)/place-liked-users.tsx diff --git a/src/app/place/[placeId]/place-top-information.tsx b/src/app/place/[placeId]/(detail)/place-top-information.tsx similarity index 100% rename from src/app/place/[placeId]/place-top-information.tsx rename to src/app/place/[placeId]/(detail)/place-top-information.tsx diff --git a/src/app/place/[placeId]/loading.tsx b/src/app/place/[placeId]/loading.tsx index 143fb077..f95114a6 100644 --- a/src/app/place/[placeId]/loading.tsx +++ b/src/app/place/[placeId]/loading.tsx @@ -2,7 +2,7 @@ import Icon from '@/components/common/icon' import Skeleton from '@/components/common/skeleton' import PlaceDivider from '@/components/place/place-divider' -const PlaceBoxSkeleton = () => { +const PlaceDetailSkeleton = () => { return (
@@ -77,4 +77,4 @@ const PlaceBoxSkeleton = () => { ) } -export default PlaceBoxSkeleton +export default PlaceDetailSkeleton diff --git a/src/app/place/[placeId]/layout.tsx b/src/app/place/[placeId]/map/layout.tsx similarity index 67% rename from src/app/place/[placeId]/layout.tsx rename to src/app/place/[placeId]/map/layout.tsx index 7a776c0f..307f2fdf 100644 --- a/src/app/place/[placeId]/layout.tsx +++ b/src/app/place/[placeId]/map/layout.tsx @@ -1,17 +1,12 @@ 'use client' import type { ReactNode } from 'react' -import { usePathname, useRouter } from 'next/navigation' import AccessibleIconButton from '@/components/common/accessible-icon-button' +import useSafeRouter from '@/hooks/use-safe-router' -const PlaceDetailLayout = ({ children }: { children: ReactNode }) => { - const router = useRouter() - const pathname = usePathname() - - if (pathname.includes('register')) { - return <>{children} - } +const PlaceMapLayout = ({ children }: { children: ReactNode }) => { + const router = useSafeRouter() return (
@@ -28,4 +23,4 @@ const PlaceDetailLayout = ({ children }: { children: ReactNode }) => { ) } -export default PlaceDetailLayout +export default PlaceMapLayout diff --git a/src/app/place/[placeId]/map/page.tsx b/src/app/place/[placeId]/map/page.tsx new file mode 100644 index 00000000..a55a7ee0 --- /dev/null +++ b/src/app/place/[placeId]/map/page.tsx @@ -0,0 +1,19 @@ +import PlaceMapBox from '@/app/place/[placeId]/map/place-map-box' +import { getMapId } from '@/services/map-id' +import { api } from '@/utils/api' + +const PlaceMap = async ({ params }: { params?: { placeId?: number } }) => { + const mapId = (await getMapId()) || '' + const response = + !!mapId && !!params?.placeId + ? await api.place.mapId.kakao.kakaoPlaceId.get({ + mapId, + kakaoPlaceId: params?.placeId ?? -1, + }) + : null + const place = response?.data + + return place && +} + +export default PlaceMap diff --git a/src/app/place/[placeId]/map/place-map-box.tsx b/src/app/place/[placeId]/map/place-map-box.tsx new file mode 100644 index 00000000..a79f0b58 --- /dev/null +++ b/src/app/place/[placeId]/map/place-map-box.tsx @@ -0,0 +1,54 @@ +'use client' + +import GPSButton from '@/components/kakao-map/gps-button' +import KakaoMap from '@/components/kakao-map/kakao-map' +import Marker from '@/components/kakao-map/marker' +import PlaceMapPopup from '@/components/place/place-map-popup' +import useSafeRouter from '@/hooks/use-safe-router' +import type { PlaceDetail } from '@/models/api/place' +import type { ClassName } from '@/models/common' +import type { MapInfo } from '@/models/map' +import { getMarkerType } from '@/services/marker' +import cn from '@/utils/cn' + +interface PlaceMapBoxProps extends ClassName { + place: PlaceDetail + mapId: MapInfo['id'] +} + +const PlaceMapBox = ({ className, place, mapId }: PlaceMapBoxProps) => { + const type = getMarkerType(place.category, true) + const router = useSafeRouter() + + return ( +
+ + + +
+ + + +
+
+
+ ) +} + +export default PlaceMapBox diff --git a/src/app/place/[placeId]/register/page.tsx b/src/app/place/[placeId]/register/page.tsx index 6d80aee2..fe092d5a 100644 --- a/src/app/place/[placeId]/register/page.tsx +++ b/src/app/place/[placeId]/register/page.tsx @@ -1,59 +1,23 @@ -'use client' - -import { useEffect, useState } from 'react' - import RegisterBox from './register-box' - -import { notify } from '@/components/common/custom-toast' -import LoadingIndicator from '@/components/common/loading-indicator' -import { APIError } from '@/models/api/index' -import type { TagItem } from '@/models/api/maps' -import type { PlaceDetail } from '@/models/api/place' import { getMapId } from '@/services/map-id' import { api } from '@/utils/api' -const PlaceRegister = ({ params }: { params?: { placeId?: number } }) => { - const [place, setPlace] = useState(null) - const [tags, setTags] = useState([]) - const [mapId, setMapId] = useState('') - - useEffect(() => { - const fetchTags = async () => { - try { - const validMapId = await getMapId() - - if (!validMapId || !params?.placeId) { - throw new Error('잘못된 접근입니다.') - } - setMapId(validMapId) - - const { data: tagData } = await api.maps.id.tag.get(validMapId) - setTags(tagData) - const { data: placeData } = - await api.place.mapId.kakao.kakaoPlaceId.get({ - mapId: validMapId, - kakaoPlaceId: params.placeId, - }) - setPlace(placeData) - } catch (error) { - if (error instanceof APIError) { - notify.error(error.message) - return - } - notify.error('예상치 못한 오류가 발생했습니다.') - } - } - fetchTags() - }, [mapId, params?.placeId]) +const PlaceRegister = async ({ params }: { params?: { placeId?: number } }) => { + const mapId = (await getMapId()) || '' + const responsePlace = + !!mapId && !!params?.placeId + ? await api.place.mapId.kakao.kakaoPlaceId.get({ + mapId, + kakaoPlaceId: params?.placeId ?? -1, + }) + : null + const place = responsePlace?.data + const responseTags = + !!mapId && !!params?.placeId ? await api.maps.id.tag.get(mapId) : null + const tags = responseTags?.data return ( - <> - {place ? ( - - ) : ( - - )} - + place && tags && ) } diff --git a/src/app/profile/[mapId]/[id]/liked-place-panel.tsx b/src/app/profile/[mapId]/[id]/liked-place-panel.tsx index 77ae1d43..988d97e8 100644 --- a/src/app/profile/[mapId]/[id]/liked-place-panel.tsx +++ b/src/app/profile/[mapId]/[id]/liked-place-panel.tsx @@ -1,4 +1,4 @@ -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import type { MapInfo } from '@/models/map' import type { User } from '@/models/user' import { api } from '@/utils/api' @@ -20,7 +20,7 @@ const LikedPlacePanel = ({ userId: User['id'] mapId: MapInfo['id'] }) => { - const [places, setPlaces] = useState() + const [places, setPlaces] = useState() const [showMorePlace, setShowMorePlace] = useState(false) const renderPlaces = () => { diff --git a/src/app/profile/[mapId]/[id]/place-item.tsx b/src/app/profile/[mapId]/[id]/place-item.tsx index 008a4747..42e4895d 100644 --- a/src/app/profile/[mapId]/[id]/place-item.tsx +++ b/src/app/profile/[mapId]/[id]/place-item.tsx @@ -13,7 +13,7 @@ import PickChip from '@/components/pick-chip' import TagList from '@/components/tag-list' import useFetch from '@/hooks/use-fetch' import { APIError } from '@/models/api' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import type { ClassName } from '@/models/common' import { api } from '@/utils/api' import cn from '@/utils/cn' @@ -22,7 +22,7 @@ import { getStarByScore } from '@/utils/score' import { revalidatePlaces } from '@/app/actions' interface PlaceItemProps extends ClassName { - selectedPlace: PlaceType + selectedPlace: KorrkPlace mapId: string onRefreshOldPlace?: VoidFunction } diff --git a/src/app/profile/[mapId]/[id]/registered-place-panel.tsx b/src/app/profile/[mapId]/[id]/registered-place-panel.tsx index 3df22def..291ceb4f 100644 --- a/src/app/profile/[mapId]/[id]/registered-place-panel.tsx +++ b/src/app/profile/[mapId]/[id]/registered-place-panel.tsx @@ -1,4 +1,4 @@ -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import type { MapInfo } from '@/models/map' import type { User } from '@/models/user' import { api } from '@/utils/api' @@ -19,7 +19,7 @@ const RegisterededPlacePanel = ({ userId: User['id'] mapId: MapInfo['id'] }) => { - const [places, setPlaces] = useState() + const [places, setPlaces] = useState() const [showMorePlace, setShowMorePlace] = useState(false) const renderPlaces = () => { diff --git a/src/app/search/[query]/result-place-map-popup.tsx b/src/app/search/[query]/result-place-map-popup.tsx index 8804fcb1..67b3599d 100644 --- a/src/app/search/[query]/result-place-map-popup.tsx +++ b/src/app/search/[query]/result-place-map-popup.tsx @@ -15,7 +15,7 @@ import PickChip from '@/components/pick-chip' import TagList from '@/components/tag-list' import useFetch from '@/hooks/use-fetch' import { APIError } from '@/models/api' -import type { PlaceDetail, SearchPlace } from '@/models/api/place' +import type { PlaceDetail, PlaceItem } from '@/models/api/place' import type { ClassName } from '@/models/common' import type { MapInfo } from '@/models/map' import { api } from '@/utils/api' @@ -26,7 +26,7 @@ import { revalidatePlaces } from '@/app/actions' interface ResultPlaceMapPopupProps extends ClassName { mapId: MapInfo['id'] - kakaoId: SearchPlace['kakaoId'] + kakaoId: PlaceItem['kakaoId'] } const ResultPlaceMapPopup = forwardRef( diff --git a/src/app/search/[query]/result-search-box.tsx b/src/app/search/[query]/result-search-box.tsx index 4a9b9a07..1be67093 100644 --- a/src/app/search/[query]/result-search-box.tsx +++ b/src/app/search/[query]/result-search-box.tsx @@ -9,7 +9,7 @@ import ResultSearchListBox from './result-search-list' import { notify } from '@/components/common/custom-toast' import KorrkKakaoMap from '@/components/korrk-kakao-map' import useMeasure from '@/hooks/use-measure' -import { type SearchPlace } from '@/models/api/place' +import { type PlaceItem } from '@/models/api/place' import type { ClassName } from '@/models/common' import type { MapInfo } from '@/models/map' import { getMapId } from '@/services/map-id' @@ -29,8 +29,8 @@ const ResultSearchBox = ({ query, className }: ResultSearchBoxProps) => { const [mapId, setMapId] = useState('') // TODO: useFetch에 status 추가 및 useFetch로 데이터 관리 const [status, setStatus] = useState('pending') // 'pending' | 'fetching' | 'success' | 'error' - const [places, setPlaces] = useState([]) - const [selectedPlace, setSelectedPlace] = useState(null) + const [places, setPlaces] = useState([]) + const [selectedPlace, setSelectedPlace] = useState(null) const [center, setCenter] = useState<{ lat: number; lng: number } | null>( null, ) @@ -85,7 +85,7 @@ const ResultSearchBox = ({ query, className }: ResultSearchBoxProps) => { } useEffect(() => { - const moveCenterToFirstPlace = (searchResultPlaces: SearchPlace[]) => { + const moveCenterToFirstPlace = (searchResultPlaces: PlaceItem[]) => { if (searchResultPlaces.length === 0) return setCenter({ lat: searchResultPlaces[0].y, lng: searchResultPlaces[0].x }) } @@ -152,7 +152,7 @@ const ResultSearchBox = ({ query, className }: ResultSearchBoxProps) => { {isMapView ? ( <> - + places={places} selectedPlace={selectedPlace} topOfBottomBounds={bottomBounds.top} diff --git a/src/app/search/[query]/result-search-list.tsx b/src/app/search/[query]/result-search-list.tsx index 3db70ed9..0a2bcf7d 100644 --- a/src/app/search/[query]/result-search-list.tsx +++ b/src/app/search/[query]/result-search-list.tsx @@ -8,7 +8,7 @@ import PlaceListItem from '@/components/place/place-list-item' import useFetch from '@/hooks/use-fetch' import { useIsomorphicLayoutEffect } from '@/hooks/use-isomorphic-layout-effect' import useUserGeoLocation from '@/hooks/use-user-geo-location' -import type { SearchPlace } from '@/models/api/place' +import type { PlaceItem } from '@/models/api/place' import type { ClassName } from '@/models/common' import type { MapInfo } from '@/models/map' import { api } from '@/utils/api' @@ -18,7 +18,7 @@ import { allowUserPositionStorage } from '@/utils/storage' import { revalidatePlaces } from '@/app/actions' interface ResultSearchListBoxProps extends ClassName { - places: SearchPlace[] + places: PlaceItem[] mapId: MapInfo['id'] } @@ -52,7 +52,7 @@ const ResultSearchListBox = ({ } }, [likeInfoPlaces.length, places, user?.id]) - const calculateNumOfLike = (place: SearchPlace, isLikePlace: boolean) => { + const calculateNumOfLike = (place: PlaceItem, isLikePlace: boolean) => { const initialNumOfLike = place.likedUser?.length || 0 if (!user?.id) return initialNumOfLike @@ -64,7 +64,7 @@ const ResultSearchListBox = ({ return initialNumOfLike } - const optimisticUpdateLikeOrUnLike = (placeId: SearchPlace['placeId']) => { + const optimisticUpdateLikeOrUnLike = (placeId: PlaceItem['placeId']) => { const willUpdateIndex = places.findIndex( (place) => place.placeId === placeId, ) @@ -83,7 +83,7 @@ const ResultSearchListBox = ({ } } - const handleLikePlace = async (placeId: SearchPlace['placeId']) => { + const handleLikePlace = async (placeId: PlaceItem['placeId']) => { try { if (!mapId) return optimisticUpdateLikeOrUnLike(placeId) @@ -92,7 +92,7 @@ const ResultSearchListBox = ({ } catch (error) {} } - const handleUnLikePlace = async (placeId: SearchPlace['placeId']) => { + const handleUnLikePlace = async (placeId: PlaceItem['placeId']) => { try { if (!mapId) return optimisticUpdateLikeOrUnLike(placeId) diff --git a/src/app/search/search-box.tsx b/src/app/search/search-box.tsx index d2330154..2424ae62 100644 --- a/src/app/search/search-box.tsx +++ b/src/app/search/search-box.tsx @@ -13,7 +13,7 @@ import debounce from 'lodash.debounce' import { notify } from '@/components/common/custom-toast' import Typography from '@/components/common/typography' import useSafeRouter from '@/hooks/use-safe-router' -import type { SearchPlace } from '@/models/api/place' +import type { PlaceItem } from '@/models/api/place' import type { MapInfo } from '@/models/map' import { getMapId } from '@/services/map-id' import { api } from '@/utils/api' @@ -34,7 +34,7 @@ const SearchBox = () => { const [query, setQuery] = useState(search) // TODO: useFetch에 status 추가 및 useFetch로 데이터 관리 const [status, setStatus] = useState('pending') // 'pending' | 'fetching' | 'success' | 'error' - const [suggestedPlaces, setSuggestedPlaces] = useState([]) + const [suggestedPlaces, setSuggestedPlaces] = useState([]) const isShowRecentKeywords = query === '' && !!recentKeywords.length && diff --git a/src/app/search/suggest-place-list.tsx b/src/app/search/suggest-place-list.tsx index 47e89cd4..afffa45b 100644 --- a/src/app/search/suggest-place-list.tsx +++ b/src/app/search/suggest-place-list.tsx @@ -1,11 +1,11 @@ import PlaceAutoSearchItem from '@/components/place/place-auto-search-item' import useUserGeoLocation from '@/hooks/use-user-geo-location' -import type { SearchPlace } from '@/models/api/place' +import type { PlaceItem } from '@/models/api/place' import { formatDistance, getDistance } from '@/utils/location' import { allowUserPositionStorage } from '@/utils/storage' interface SuggestPlaceListProps { - places: SearchPlace[] + places: PlaceItem[] query: string } diff --git a/src/components/korrk-kakao-map.tsx b/src/components/korrk-kakao-map.tsx index a32e1baa..75b262a7 100644 --- a/src/components/korrk-kakao-map.tsx +++ b/src/components/korrk-kakao-map.tsx @@ -1,20 +1,19 @@ -import type { IconKey } from './common/icon' +import { getMarkerType } from '@/services/marker' import CurrentPositionSearchButton from './kakao-map/current-position-search-button' import FloatingButtonBox from './kakao-map/floating-button-box' import KakaoMap from './kakao-map/kakao-map' import Marker from './kakao-map/marker' import { - type PlaceType, - type SearchPlace, - isPlaceType, - isSearchPlace, + type KorrkPlace, + type PlaceItem, + isKorrkPlace, + isPlaceItem, } from '@/models/api/place' import type { ClassName } from '@/models/common' -import { removeAllSpaces } from '@/utils/category' import cn from '@/utils/cn' -interface KorrkKakaoMapProps +interface KorrkKakaoMapProps extends ClassName { places?: T[] | null center?: Parameters[0]['center'] @@ -28,28 +27,7 @@ interface KorrkKakaoMapProps onClickPlace: (place: T) => void } -const getMarkerType = ( - category: string, - isPick: boolean, -): Extract< - IconKey, - | 'cafe' - | 'restaurant' - | 'bar' - | 'selectedCafe' - | 'selectedRestaurant' - | 'selectedBar' -> => { - const trimmedCategory = removeAllSpaces(category) - - if (['호프', '요리주점'].includes(trimmedCategory)) - return isPick ? 'selectedBar' : 'bar' - if (['카페', '디저트'].includes(trimmedCategory)) - return isPick ? 'selectedCafe' : 'cafe' - return isPick ? 'selectedRestaurant' : 'restaurant' -} - -const KorrkKakaoMap = ({ +const KorrkKakaoMap = ({ className, selectedPlace, center, @@ -78,34 +56,32 @@ const KorrkKakaoMap = ({ onCenterChanged={onCenterChangeMap} > {places?.map((place) => { - const isPlace = isPlaceType(place) - const isSearchPlaceType = isSearchPlace(place) + const isKorrkPlaceType = isKorrkPlace(place) + const isPlaceItemType = isPlaceItem(place) const isSelected = (() => { - if (isPlace && isPlaceType(selectedPlace)) { + if (isKorrkPlaceType && isKorrkPlace(selectedPlace)) { return selectedPlace.place.id === place.place.id } - if (isSearchPlaceType && isSearchPlace(selectedPlace)) { + if (isPlaceItemType && isPlaceItem(selectedPlace)) { return selectedPlace.kakaoId === place.kakaoId } return false })() const type = getMarkerType( - isSearchPlaceType + isPlaceItemType ? place.category : place.place.kakaoPlace.category, isSelected, ) return ( onClickPlace(place)} diff --git a/src/components/place/kakao-rating.tsx b/src/components/place/kakao-rating.tsx index 7fe6f808..1f67d246 100644 --- a/src/components/place/kakao-rating.tsx +++ b/src/components/place/kakao-rating.tsx @@ -1,14 +1,14 @@ import ExternalLink from '@/components/common/external-link' import Icon from '@/components/common/icon' import Typography from '@/components/common/typography' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import type { ClassName } from '@/models/common' import cn from '@/utils/cn' import { roundToNthDecimal } from '@/utils/number' interface KakaoRatingProps extends ClassName { rating: number - placeId: PlaceType['place']['kakaoPlace']['id'] + placeId: KorrkPlace['place']['kakaoPlace']['id'] } const MAX_STAR = 5 @@ -31,7 +31,7 @@ const getNumberOfStarIcons = (rating: number) => { return { roundedRating, fullIcons, halfIcon, emptyIcons } } -const toKakaoMapURL = (placeId: PlaceType['place']['kakaoPlace']['id']) => +const toKakaoMapURL = (placeId: KorrkPlace['place']['kakaoPlace']['id']) => `https://place.map.kakao.com/${placeId}` const KakaoRating = ({ className, rating, placeId }: KakaoRatingProps) => { diff --git a/src/components/place/place-auto-search-item.tsx b/src/components/place/place-auto-search-item.tsx index 8b5d80d2..ddb0fcad 100644 --- a/src/components/place/place-auto-search-item.tsx +++ b/src/components/place/place-auto-search-item.tsx @@ -4,13 +4,13 @@ import Link from 'next/link' import Icon from '@/components/common/icon' import Typography from '@/components/common/typography' -import type { SearchPlace } from '@/models/api/place' +import type { PlaceItem } from '@/models/api/place' import type { ClassName } from '@/models/common' import cn from '@/utils/cn' import { recentSearchStorage } from '@/utils/storage' interface PlaceAutoSearchItemProps extends ClassName { - place: SearchPlace + place: PlaceItem query: string distance: string | null } diff --git a/src/components/place/place-map-popup.tsx b/src/components/place/place-map-popup.tsx index 315bbd76..c4ad65c2 100644 --- a/src/components/place/place-map-popup.tsx +++ b/src/components/place/place-map-popup.tsx @@ -2,8 +2,6 @@ import { type ForwardedRef, forwardRef, useEffect, useState } from 'react' -import Link from 'next/link' - import { notify } from '@/components/common/custom-toast' import Icon from '@/components/common/icon' import ProxyImage from '@/components/common/proxy-image' @@ -13,7 +11,11 @@ import PickChip from '@/components/pick-chip' import TagList from '@/components/tag-list' import useFetch from '@/hooks/use-fetch' import { APIError } from '@/models/api' -import type { PlaceType } from '@/models/api/place' +import { + isKorrkPlace, + type PlaceDetail, + type KorrkPlace, +} from '@/models/api/place' import type { ClassName } from '@/models/common' import { api } from '@/utils/api' import cn from '@/utils/cn' @@ -23,27 +25,35 @@ import PlacePopupSkeleton from '@/components/place/place-popup-skeleton' import { revalidatePlaces } from '@/app/actions' interface PlaceMapPopupProps extends ClassName { - selectedPlace: PlaceType + selectedPlace: KorrkPlace | PlaceDetail mapId: string - onRefreshOldPlace?: VoidFunction } const PlaceMapPopup = forwardRef( - ({ selectedPlace, className, mapId, onRefreshOldPlace }, ref) => { + ({ selectedPlace, className, mapId }, ref) => { const [isLikePlace, setIsLikePlace] = useState(false) const { data: user } = useFetch(api.users.me.get, { key: ['user'], }) + const { refetch } = useFetch(() => api.place.mapId.get(mapId), { + key: ['places', mapId], + enabled: !!mapId, + }) const isLoading = !selectedPlace || !user - const place = selectedPlace.place + const isKorrkPlaceType = isKorrkPlace(selectedPlace) + const place = isKorrkPlaceType ? selectedPlace.place : selectedPlace + const kakaoPlace = isKorrkPlaceType + ? selectedPlace.place.kakaoPlace + : selectedPlace + const isRegisteredPlace = !!place.id const getNumOfLike = () => { const initialNumOfLike = selectedPlace.likedUser?.length || 0 if (!user?.id) return initialNumOfLike - if (selectedPlace.likedUser.some((liked) => liked.id === user.id)) { + if (selectedPlace.likedUser?.some((liked) => liked.id === user.id)) { if (isLikePlace) return initialNumOfLike return initialNumOfLike - 1 } @@ -67,9 +77,7 @@ const PlaceMapPopup = forwardRef( notify.error(error.message) } } finally { - if (onRefreshOldPlace) { - onRefreshOldPlace() - } + refetch() } } @@ -89,13 +97,10 @@ const PlaceMapPopup = forwardRef( notify.error(error.message) } } finally { - if (onRefreshOldPlace) { - onRefreshOldPlace() - } + refetch() } } - const kakaoPlace = place.kakaoPlace const tags = selectedPlace.tags const pick = { isLiked: isLikePlace, @@ -108,9 +113,11 @@ const PlaceMapPopup = forwardRef( useEffect(() => { if (!user) return - setIsLikePlace( - selectedPlace.likedUser.some((liked) => liked.id === user.id), - ) + if (selectedPlace.likedUser) { + setIsLikePlace( + selectedPlace.likedUser.some((liked) => liked.id === user.id), + ) + } }, [user, selectedPlace]) return ( @@ -121,11 +128,7 @@ const PlaceMapPopup = forwardRef( {isLoading ? ( } /> ) : ( - +
@@ -167,7 +170,7 @@ const PlaceMapPopup = forwardRef(
- {pick && ( + {isRegisteredPlace && pick && (
(
{!!tags?.length && } - +
)}
) diff --git a/src/components/place/types.ts b/src/components/place/types.ts index 7017f31c..140c8582 100644 --- a/src/components/place/types.ts +++ b/src/components/place/types.ts @@ -1,7 +1,7 @@ import type { MouseEventHandler } from 'react' import type { TagItem } from '@/models/api/maps' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import type { CategoryIcon } from '@/models/map' import type { User } from '@/models/user' @@ -12,7 +12,7 @@ export interface LikeUser { } export interface PlaceProps { - placeId: PlaceType['place']['id'] + placeId: KorrkPlace['place']['id'] name: string address: string distance?: string diff --git a/src/components/tag-list.tsx b/src/components/tag-list.tsx index e0956cc8..15dc14ce 100644 --- a/src/components/tag-list.tsx +++ b/src/components/tag-list.tsx @@ -2,13 +2,13 @@ import Chip from '@/components/common/chip' import type { TagItem } from '@/models/api/maps' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' import type { ClassName } from '@/models/common' import cn from '@/utils/cn' import { changeSpaceToHyphen } from '@/utils/tags' interface TagListProps extends ClassName { - placeId: PlaceType['place']['id'] + placeId: KorrkPlace['place']['id'] tags: TagItem[] | string[] tagColorScheme?: | 'neutral-400' diff --git a/src/constants/place.ts b/src/constants/place.ts index 76af4cf5..0923704b 100644 --- a/src/constants/place.ts +++ b/src/constants/place.ts @@ -1,10 +1,11 @@ -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' -export const PLACE_LIST_DATA: PlaceType[] = [ +export const PLACE_LIST_DATA: KorrkPlace[] = [ { place: { id: 1, kakaoPlace: { + score: 4, mainPhotoUrl: '1', id: 1, name: 'Sarang Restaurant', @@ -56,6 +57,7 @@ export const PLACE_LIST_DATA: PlaceType[] = [ place: { id: 2, kakaoPlace: { + score: 2, mainPhotoUrl: '1', id: 2, name: 'Han River Sushi', @@ -104,6 +106,7 @@ export const PLACE_LIST_DATA: PlaceType[] = [ place: { id: 3, kakaoPlace: { + score: 0, mainPhotoUrl: '1', id: 3, name: 'Gyeongbok Palace BBQ', @@ -152,6 +155,7 @@ export const PLACE_LIST_DATA: PlaceType[] = [ place: { id: 4, kakaoPlace: { + score: 1, mainPhotoUrl: '1', id: 4, name: 'Namdaemun Noodles', @@ -200,6 +204,7 @@ export const PLACE_LIST_DATA: PlaceType[] = [ place: { id: 5, kakaoPlace: { + score: 4.3, mainPhotoUrl: '1', id: 5, name: 'Insadong Cafe', diff --git a/src/models/api/place.ts b/src/models/api/place.ts index 6b3a05a6..8874bbb2 100644 --- a/src/models/api/place.ts +++ b/src/models/api/place.ts @@ -2,55 +2,64 @@ import type { LikeUser } from '@/components/place/types' import type { TagItem } from './maps' import type { KakaoPlaceDetail } from '@/models/kakao-map' -import type { CategoryIcon, MapInfo } from '@/models/map' +import type { MapInfo } from '@/models/map' import type { Creator } from '@/models/user' -export interface PlaceType { +interface Coordinates { + x: KakaoPlaceDetail['x'] + y: KakaoPlaceDetail['y'] +} + +interface BaseKakaoPlace { + kakaoId: KakaoPlaceDetail['id'] + category: KakaoPlaceDetail['category'] + categoryIconCode: KakaoPlaceDetail['categoryIconCode'] + address: KakaoPlaceDetail['address'] + score: KakaoPlaceDetail['score'] +} + +// 등록된 곳 +export interface KorrkPlace { place: { id: number kakaoPlace: KakaoPlaceDetail - x: number - y: number - } + } & Coordinates tags: TagItem[] comments: unknown[] likedUser: Pick[] createdBy: { - id: number - nickname: string + id: Creator['id'] + nickname: Creator['nickname'] } createdAt: string updatedAt: string } -export interface SearchPlace { +// 검색할 수 있는 모든 장소 +export interface PlaceItem extends BaseKakaoPlace, Coordinates { + placeName: KakaoPlaceDetail['name'] + isRegisteredPlace: boolean - kakaoId: PlaceType['place']['kakaoPlace']['id'] - category: string - categoryIconCode: CategoryIcon - x: number - y: number - placeName: string - address: string - placeId: PlaceType['place']['id'] - tags: string[] - createdBy?: Creator - score: number - likedUser: Pick[] + + placeId: KorrkPlace['place']['id'] + createdBy?: KorrkPlace['createdBy'] + likedUser: KorrkPlace['likedUser'] + + tags: TagItem['name'][] } -export const isSearchPlace = ( - place: PlaceType | SearchPlace | null | undefined, -): place is SearchPlace => { +export const isKorrkPlace = ( + place: KorrkPlace | PlaceItem | PlaceDetail | null | undefined, +): place is KorrkPlace => { if (!place) return false - return 'isRegisteredPlace' in place + return 'place' in place } -export const isPlaceType = ( - place: PlaceType | SearchPlace | null | undefined, -): place is PlaceType => { +export const isPlaceItem = ( + place: KorrkPlace | PlaceItem | null | undefined, +): place is PlaceItem => { if (!place) return false - return 'place' in place + return 'isRegisteredPlace' in place } export interface PlaceMenuItem { @@ -58,36 +67,39 @@ export interface PlaceMenuItem { price: string photo: string } -export interface PlaceDetail { - id: PlaceType['place']['id'] - kakaoId: PlaceType['place']['kakaoPlace']['id'] - mapId: MapInfo['id'] - isRegisteredPlace: boolean - likedUser?: LikeUser[] - tags: TagItem[] - createdBy?: PlaceType['createdBy'] - name: string - category: string - categoryIconCode: CategoryIcon - address: string - x: number - y: number - menuList: PlaceMenuItem[] - mainPhotoUrl: string - photoList: string[] - score: number + +interface OpenTime { + dayOfWeek: string + timeName: string + timeSE: string +} + +interface OffDay { + holidayName: string + weekAndDay: string + temporaryHolidays: string +} + +// 검색할 수 있는 모든 곳의 상세 정보 +export interface PlaceDetail extends BaseKakaoPlace, Coordinates { + name: KakaoPlaceDetail['name'] + menuList: KakaoPlaceDetail['menuList'] + mainPhotoUrl: KakaoPlaceDetail['mainPhotoUrl'] + photoList: KakaoPlaceDetail['photoList'] + createdAt: KakaoPlaceDetail['createdAt'] + updatedAt: KakaoPlaceDetail['updatedAt'] + commentCnt: number blogReviewCnt: number - openTimeList: { - dayOfWeek: string - timeName: string - timeSE: string - }[] - offDayList: { - holidayName: string - weekAndDay: string - temporaryHolidays: string - }[] - createdAt: string - updatedAt: string + openTimeList: OpenTime[] + offDayList: OffDay[] + + isRegisteredPlace: PlaceItem['isRegisteredPlace'] + + id: KorrkPlace['place']['id'] + tags: KorrkPlace['tags'] + createdBy?: KorrkPlace['createdBy'] + + mapId: MapInfo['id'] + likedUser?: LikeUser[] } diff --git a/src/models/kakao-map.ts b/src/models/kakao-map.ts index c7ee69ac..b5f2c6dc 100644 --- a/src/models/kakao-map.ts +++ b/src/models/kakao-map.ts @@ -34,5 +34,5 @@ export interface KakaoPlaceDetail { createdAt: Date // '2024-06-29T18:08:11.692Z' updatedAt: Date // '2024-06-29T18:11:05.368Z' mainPhotoUrl: string - score?: number + score: number } diff --git a/src/services/marker.ts b/src/services/marker.ts new file mode 100644 index 00000000..72de1435 --- /dev/null +++ b/src/services/marker.ts @@ -0,0 +1,23 @@ +import type { IconKey } from '@/components/common/icon' +import { removeAllSpaces } from '@/utils/category' + +export const getMarkerType = ( + category: string, + isPick: boolean, +): Extract< + IconKey, + | 'cafe' + | 'restaurant' + | 'bar' + | 'selectedCafe' + | 'selectedRestaurant' + | 'selectedBar' +> => { + const trimmedCategory = removeAllSpaces(category) + + if (['호프', '요리주점'].includes(trimmedCategory)) + return isPick ? 'selectedBar' : 'bar' + if (['카페', '디저트'].includes(trimmedCategory)) + return isPick ? 'selectedCafe' : 'cafe' + return isPick ? 'selectedRestaurant' : 'restaurant' +} diff --git a/src/utils/api/index.ts b/src/utils/api/index.ts index e383395d..8c30aa8c 100644 --- a/src/utils/api/index.ts +++ b/src/utils/api/index.ts @@ -2,7 +2,7 @@ import { apiClientFactory } from './api-client-factory' import type { ResponseWithMessage } from '@/models/api' import type { TagItem } from '@/models/api/maps' -import type { PlaceDetail, PlaceType, SearchPlace } from '@/models/api/place' +import type { PlaceDetail, KorrkPlace, PlaceItem } from '@/models/api/place' import type { QueryParams } from '@/models/api/search' import type { InviteLink, @@ -135,7 +135,7 @@ const search = { rect, mapId, }: QueryParams & { mapId: MapInfo['id'] }): Promise< - ResponseWithMessage + ResponseWithMessage > => client.public.get(`/search/places?q=${q}&rect=${rect}&mapId=${mapId}`, { tags: ['places', mapId], @@ -144,13 +144,13 @@ const search = { } interface PlaceIdWithMapId { - placeId: PlaceType['place']['id'] + placeId: KorrkPlace['place']['id'] mapId: MapInfo['id'] } const place = { mapId: { - get: (mapId: MapInfo['id']): Promise> => + get: (mapId: MapInfo['id']): Promise> => client.secure.get(`/place/${mapId}`), userId: { get: ({ @@ -159,7 +159,7 @@ const place = { }: { mapId: MapInfo['id'] userId: User['id'] - }): Promise> => + }): Promise> => client.secure.get(`/place/${mapId}/${userId}`), }, @@ -183,7 +183,7 @@ const place = { kakaoPlaceId, }: { mapId: MapInfo['id'] - kakaoPlaceId: PlaceType['place']['kakaoPlace']['id'] + kakaoPlaceId: KorrkPlace['place']['kakaoPlace']['id'] }): Promise> => client.secure.get(`/place/${mapId}/kakao/${kakaoPlaceId}`), @@ -193,9 +193,9 @@ const place = { tagNames, }: { mapId: MapInfo['id'] - kakaoPlaceId: PlaceType['place']['kakaoPlace']['id'] + kakaoPlaceId: KorrkPlace['place']['kakaoPlace']['id'] tagNames: TagItem['name'][] - }): Promise> => + }): Promise> => client.secure.post(`/place/${mapId}/kakao/${kakaoPlaceId}`, { tagNames, }), @@ -203,7 +203,7 @@ const place = { }, }, placeId: { - get: (placeId: string): Promise> => + get: (placeId: string): Promise> => client.secure.get(`place/${placeId}`), }, differ: { @@ -229,7 +229,7 @@ const place = { }: { userId: User['id'] mapId: MapInfo['id'] - }): Promise> => + }): Promise> => client.secure.get(`/place/like/${mapId}/${userId}`), }, }, diff --git a/src/utils/format.ts b/src/utils/format.ts index 63d86849..ed25feb7 100644 --- a/src/utils/format.ts +++ b/src/utils/format.ts @@ -1,34 +1,35 @@ -import type { PlaceType, SearchPlace } from '@/models/api/place' +import type { KorrkPlace, PlaceItem } from '@/models/api/place' -export const convertSearchPlaceToPlaceType = ( - searchPlace: SearchPlace, -): PlaceType => { +export const convertplaceItemToKorrkPlace = ( + placeItem: PlaceItem, +): KorrkPlace => { return { - ...searchPlace, - likedUser: searchPlace.likedUser ?? [], + ...placeItem, + likedUser: placeItem.likedUser ?? [], createdBy: { id: -1, nickname: '', }, - tags: searchPlace.tags?.map((tag) => ({ name: tag })), + tags: placeItem.tags?.map((tag) => ({ name: tag })), place: { - id: searchPlace.kakaoId, + id: placeItem.kakaoId, kakaoPlace: { - id: searchPlace.kakaoId, - name: searchPlace.placeName, - category: searchPlace.category, - categoryIconCode: searchPlace.categoryIconCode, - address: searchPlace.address, - x: searchPlace.x, - y: searchPlace.y, + id: placeItem.kakaoId, + name: placeItem.placeName, + category: placeItem.category, + categoryIconCode: placeItem.categoryIconCode, + address: placeItem.address, + x: placeItem.x, + y: placeItem.y, + score: placeItem.score, menuList: [], photoList: [], mainPhotoUrl: '', createdAt: new Date(), updatedAt: new Date(), }, - x: searchPlace.x, - y: searchPlace.y, + x: placeItem.x, + y: placeItem.y, }, comments: [], createdAt: '', diff --git a/src/utils/tags.ts b/src/utils/tags.ts index 08e10c21..2abc1bb8 100644 --- a/src/utils/tags.ts +++ b/src/utils/tags.ts @@ -1,5 +1,5 @@ import type { TagItem } from '@/models/api/maps' -import type { PlaceType } from '@/models/api/place' +import type { KorrkPlace } from '@/models/api/place' const changeSpaceToHyphen = (name: string) => { if (typeof name !== 'string' || name === '') return @@ -8,7 +8,7 @@ const changeSpaceToHyphen = (name: string) => { } const getFitContainerWidthTags = ( - placeId: PlaceType['place']['id'], + placeId: KorrkPlace['place']['id'], currentTags: TagItem[], containerWidth: number, ) => {