Skip to content

Commit

Permalink
Feat: 저장한 여행지 서버api, 공공api 연결 (#74)
Browse files Browse the repository at this point in the history
* chore: 파일명 수정

* feat: detail페이지 즐겨찾기 api 연결

* feat: 마이페이지 저장한 리스트 연결

* feat: Map 저장한 여행지 연결

* feat: 사용자 로그인X시 Map 기본 위치 설정

* feat: map 로그인 되어있을 때만 바텀시트 open
  • Loading branch information
doyn511 authored Oct 2, 2024
1 parent 8a57495 commit b09aa6e
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 85 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { useLocation } from 'react-router-dom';

import { unitripSupabase } from '@/utils/supabaseClient';

const toggleFavorite = async () => {
const toggleFavorite = async (contentId: number) => {
const kakaoId = sessionStorage.getItem('kakao_id');

const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const place = queryParams.get('contentId');

const { data, error: fetchError } = await unitripSupabase
.from('USER')
.select('favorite_list')
Expand All @@ -20,9 +14,11 @@ const toggleFavorite = async () => {

const currentFavorites = data[0].favorite_list || [];
//기존 배열에 해당 장소가 존재하면 제거, 존재하지 않으면 추가
const updatedFavorites = currentFavorites.includes(place)
? currentFavorites.filter((favorite: number) => favorite !== Number(place))
: [...currentFavorites, Number(place)];
const updatedFavorites = currentFavorites.includes(contentId)
? currentFavorites.filter(
(favorite: number) => favorite !== Number(contentId),
)
: [...currentFavorites, Number(contentId)];

const { error } = await unitripSupabase
.from('USER')
Expand Down
17 changes: 13 additions & 4 deletions src/views/Detail/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import { css } from '@emotion/react';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';

import toggleFavorite from '@/apis/supabase/toggleFavorite';
import { ArrowLeftIcon, HeartFilledIcon, HeartGrayIcon } from '@/assets/icon';
import LoginModal from '@/components/LoginModal';

const Header = () => {
const [isFavorite, setIsFavorite] = useState<boolean>(false);
interface headerProps {
isFavorite: boolean;
setIsFavorite: React.Dispatch<React.SetStateAction<boolean>>;
}

const Header = (props: headerProps) => {
const { isFavorite, setIsFavorite } = props;
const { contentId } = useParams();

const [activateModal, setActivateModal] = useState(false);

const isLoggedIn = sessionStorage.getItem('kakao_id');
const navigate = useNavigate();

const favoriteOnClick = () => {
const favoriteOnClick = async () => {
if (isLoggedIn) {
await toggleFavorite(Number(contentId));
setIsFavorite(!isFavorite);
} else {
setActivateModal(true);
Expand Down
41 changes: 37 additions & 4 deletions src/views/Detail/pages/DetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { css } from '@emotion/react';
import { useEffect, useRef, useState } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';

import getUserData from '@/apis/supabase/getUserData';
import { DefaultImage } from '@/assets/image';
import { useAsyncEffect } from '@/hooks/use-async-effect';
import { COLORS, FONTS } from '@/styles/constants';

import ErrorReport from '../components/ErrorReport';
Expand Down Expand Up @@ -58,7 +60,11 @@ const DetailPage = () => {
useFee: '',
});

const [isFavorite, setIsFavorite] = useState(false);

const contentTypeId = useRef('12');
const contentIdList = useRef<number[]>([]); //서버에서 받아온 contentnId List
const kakaoId = sessionStorage.getItem('kakao_id');

useEffect(() => {
const fetchData = async () => {
Expand All @@ -69,6 +75,20 @@ const DetailPage = () => {
fetchData();
}, []);

/** 서버 통신 -> favorite_list 받아오기 */
useAsyncEffect(async () => {
if (!kakaoId) return;

const userData = await getUserData(Number(kakaoId));
if (userData) {
contentIdList.current = userData.favorite_list;

contentIdList.current.includes(Number(contentId))
? setIsFavorite(true)
: setIsFavorite(false);
}
}, [isFavorite]);

const getDetailCommon1Res = async () => {
const res = await getDetailCommonRes(Number(contentId));

Expand All @@ -79,7 +99,7 @@ const DetailPage = () => {
info: {
addr: item[0].addr1 !== '' ? item[0].addr1 : '-',
tel: item[0].tel !== '' ? item[0].tel : '-',
useTime: '',
useTime: '-',
},
imageUrl: item[0].firstimage !== '' ? item[0].firstimage : DefaultImage,
});
Expand All @@ -106,12 +126,25 @@ const DetailPage = () => {
...prev,
info: {
...prev.info,
useTime: item[0].usetime !== '' ? item[0].usetime : '-',
useTime:
contentTypeId.current === '12'
? item[0].usetime && item[0].usetime !== ''
? item[0].usetime
: '-'
: contentTypeId.current === '14'
? item[0].usetimeculture && item[0].usetimeculture !== ''
? item[0].usetimeculture
: '-'
: '-',
},
}));

setDetailInfo({
restDate: item[0].restdate !== '' ? item[0].restdate : '-',
restDate: item[0].restdate
? item[0].restdate !== ''
? item[0].restdate
: '-'
: '-',
useTime:
contentTypeId.current === '12'
? item[0].usetime && item[0].usetime !== ''
Expand Down Expand Up @@ -140,7 +173,7 @@ const DetailPage = () => {
return (
<div css={detailContainer}>
<div css={backgroundImg(placeInfo.imageUrl)}>
<Header />
<Header isFavorite={isFavorite} setIsFavorite={setIsFavorite} />
<span css={title}>{placeInfo.title}</span>
</div>
<PlaceInfo placeInfo={placeInfo.info} />
Expand Down
6 changes: 3 additions & 3 deletions src/views/Map/components/BottomSheetContent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** 바텀시트 내부 맵핑 할 내용들 */

import { css } from '@emotion/react';
import { useNavigate } from 'react-router-dom';

import { DefaultImage } from '@/assets/image';
import { COLORS, FONTS } from '@/styles/constants';
Expand All @@ -16,11 +17,10 @@ const BottomSheetContent = (props: contentProps) => {
const { title, address, image, contentId } = props;
const isImageNone = image === '';

// const navigate = useNavigate();
const navigate = useNavigate();

const onClickContent = () => {
console.log(contentId);
// navigate('/detail');
navigate(`/${contentId}`);
};

return (
Expand Down
80 changes: 57 additions & 23 deletions src/views/Map/pages/MapPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { css } from '@emotion/react';
import { useEffect, useRef, useState } from 'react';

import getUserData from '@/apis/supabase/getUserData';
import {
CloseBottomSheetIcon,
MapFavoirteIcon,
Expand All @@ -10,12 +11,12 @@ import {
} from '@/assets/icon';
import LoginModal from '@/components/LoginModal';
import MenuBar from '@/components/MenuBar';
import { useAsyncEffect } from '@/hooks/use-async-effect';
import { COLORS, FONTS } from '@/styles/constants';
import { locationBasedList1Res } from '@/types/locationBasedList1';

import FavoriteBottomSheet from '../components/FavoriteBottomSheet';
import PinBottomSheet from '../components/PinBottomSheet';
import { DUMMY } from '../constants/DUMMY';
import { createFavoritePin } from '../utils/createFavoritePin';
import { createKakaoMap } from '../utils/createKakaoMap';
import { createMapPin } from '../utils/createMapPin';
Expand Down Expand Up @@ -48,7 +49,7 @@ const MapPage = () => {
const [getLocActive, setGetLocActive] = useState(false); // 위치 허용에 따른 아이콘 변화
const [activateModal, setActivateModal] = useState(false);

const isLoggedIn = sessionStorage.getItem('kako_id');
const kakaoId = sessionStorage.getItem('kakao_id');

// 바텀시트 내용
const [bottomSheetContent, setBottomSheetContent] = useState<bottomSheetType>(
Expand All @@ -66,11 +67,15 @@ const MapPage = () => {

const apiRes = useRef<locationBasedList1Res[]>([]); // 주변 여행지 검색 플로우 결과 저장
const favoriteList = useRef<bottomSheetType[]>([]); // 저장한 여행지(공통정보api) 플로우 결과 저장
const contentIdList = useRef<number[]>([]);

/** 지도 진입 시, */
useAsyncEffect(async () => {
await getUserLoc();
}, []);

/** 기본 사용자의 위치에 따른 위도, 경도 값 업데이트 */
useEffect(() => {
// 서버에서 사용자 위치 받아와 저장하는 set하는 로직 필요
setRegion({ city: '서울특별시', town: '광진구' });
const currentTown = setDefaultLocation(region.city, region.town);
setDefaultLoc({
lat: currentTown?.lat,
Expand All @@ -84,28 +89,57 @@ const MapPage = () => {
setMap(kakaoMap);
}, [defaultLoc]);

/** 저장한 여행지 목록 버튼 클릭 */
const onClickFavorite = async () => {
if (isLoggedIn) {
if (map) {
clearMarker();

const res = await createFavoritePin(
DUMMY, // 서버에서 받아온 contentId list로 대체 필요
map,
setBottomSheetContent,
openPinBottomSheet,
);

if (res) {
favoriteList.current = res.favoriteList;
setFavMarkers(res.defaultMarker);
}

openFavoriteBottomSheet();
/** 지도 진입 시 서버에 요청 전송해 사용자 위치 받아오기 */
const getUserLoc = async () => {
if (kakaoId) {
const response = await getUserData(Number(kakaoId));
if (response) {
setRegion({
city: response.region.split(' ')[0],
town: response.region.split(' ')[1],
});
}
} else {
setRegion({
city: '서울특별시',
town: '중구',
});
}
};

/** 저장한 여행지 버튼 클릭 시 서버에 요청 전송 */
const getFavList = async () => {
if (!kakaoId) {
setActivateModal(true);
} else {
const response = await getUserData(Number(kakaoId));
if (response) {
contentIdList.current = response.favorite_list;
}
}
};

/** 저장한 여행지 목록 버튼 클릭 */
const onClickFavorite = async () => {
await getFavList(); // 서버에서 contentId 리스트 받아오기

if (map) {
clearMarker();

// 하트 마커 그리기
const res = await createFavoritePin(
contentIdList.current,
map,
setBottomSheetContent,
openPinBottomSheet,
);

if (res) {
favoriteList.current = res.favoriteList;
setFavMarkers(res.defaultMarker);
}

kakaoId && openFavoriteBottomSheet();
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/views/Map/utils/createFavoritePin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface bottomSheetInfoType {
}

export const createFavoritePin = async (
idList: contentIdListType[],
idList: number[],
kakaoMap: mapType | undefined,
setBottomSheetContent: React.Dispatch<React.SetStateAction<bottomSheetType>>,
openPinBottomSheet: (state: string) => void,
Expand Down
8 changes: 2 additions & 6 deletions src/views/Map/utils/getDetailCommon.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { getDetailCommon1 } from '@/apis/public/detailCommon1';

import { contentIdListType } from './createFavoritePin';

export interface favoriteListType {
title: string;
address: string;
Expand All @@ -11,17 +9,15 @@ export interface favoriteListType {
contentId: string;
}

export const getDetailCommonRes = async (
contentIdList: contentIdListType[],
) => {
export const getDetailCommonRes = async (contentIdList: number[]) => {
const favoriteList: favoriteListType[] = [];

const promises = contentIdList.map(async (id) => {
const response = await getDetailCommon1({
numOfRows: 20,
pageNo: 1,
MobileOS: 'ETC',
contentId: Number(id.contentId),
contentId: Number(id),
defaultYN: 'Y',
firstImageYN: 'Y',
addrinfoYN: 'Y',
Expand Down
21 changes: 17 additions & 4 deletions src/views/Mypage/components/Favorite.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
import { css } from '@emotion/react';
import { useState } from 'react';
import { Link } from 'react-router-dom';

import getUserData from '@/apis/supabase/getUserData';
import EmptyFavList from '@/components/EmptyFavList';
import { useAsyncEffect } from '@/hooks/use-async-effect';
import { COLORS, FONTS } from '@/styles/constants';

import FavoritePlaceList from './FavoritePlaceList';

const favoriteList = [];

const Favorite = () => {
const [favoriteList, setFavoriteList] = useState<number[]>([]);

useAsyncEffect(async () => {
const kakaoId = sessionStorage.getItem('kakao_id');
if (!kakaoId) return;

const userData = await getUserData(Number(kakaoId));
if (userData) {
setFavoriteList(userData.favorite_list);
}
}, []);

return (
<>
{favoriteList.length === 0 ? (
{favoriteList.length <= 1 ? (
<div css={messageContainer}>
<EmptyFavList />
<Link to="/" css={homeBtn}>
홈으로 이동하기
</Link>
</div>
) : (
<FavoritePlaceList />
<FavoritePlaceList favoriteList={favoriteList} />
)}
</>
);
Expand Down
Loading

0 comments on commit b09aa6e

Please sign in to comment.