diff --git a/components/favorite/favorite.place.boxes.tsx b/components/favorite/favorite.place.boxes.tsx new file mode 100644 index 0000000..e69c8c3 --- /dev/null +++ b/components/favorite/favorite.place.boxes.tsx @@ -0,0 +1,69 @@ +import React from 'react'; +import Link from 'next/link'; +import { PoPoAxios } from '@/lib/axios.instance'; +import { + Card, + Grid, + Image, + Button, + Icon, + ButtonGroup, +} from 'semantic-ui-react'; + +import { IPlace } from '@/types/favorite.interface'; + +const FavoritePlaceBoxes = ({ placeList }: { placeList: IPlace[] }) => { + const handleDelete = async (deleteURI: string) => { + PoPoAxios.delete(`/${deleteURI}`, { withCredentials: true }) + .then(() => { + window.location.reload(); + }) + .catch((err) => { + const errMsg = err.response.data.message; + alert(`삭제에 실패했습니다.\n${errMsg}`); + }); + }; + + return ( + + {placeList.map((place: IPlace) => ( + + + {place.name} + + {place.name} + + +
+ + + + + + +
+
+ ))} +
+ ); +}; + +export default FavoritePlaceBoxes; diff --git a/components/favorite/favorite.place.choice.tsx b/components/favorite/favorite.place.choice.tsx new file mode 100644 index 0000000..8fe253a --- /dev/null +++ b/components/favorite/favorite.place.choice.tsx @@ -0,0 +1,55 @@ +import React, { useState } from 'react'; +import { PoPoAxios } from '@/lib/axios.instance'; +import { Form } from 'semantic-ui-react'; + +import { IPlace } from '@/types/favorite.interface'; + +const FavoritePlaceChoice = ({ + placeList, + userId, +}: { + placeList: IPlace[]; + userId: string; +}) => { + const [placeId, setPlaceId] = useState(''); + + function handleSubmit() { + PoPoAxios.post( + '/favorite-place', + { + place_id: placeId, + user_id: userId, + }, + { withCredentials: true }, + ) + .then(() => { + alert('즐겨찾기에 추가되었습니다.'); + window.location.reload(); + }) + .catch((error) => { + alert(`예약 생성에 실패했습니다: ${error.response.data.message}`); + }); + } + + return ( +
+
+ { + return { + key: place.uuid, + text: place.name, + value: place.uuid, + }; + })} + placeholder="장소를 선택해주세요." + onChange={(e, { value }) => setPlaceId(value as string)} + /> + + +
+ ); +}; + +export default FavoritePlaceChoice; diff --git a/components/navbar/menu.item.user.tsx b/components/navbar/menu.item.user.tsx index f4b42eb..2d9a051 100644 --- a/components/navbar/menu.item.user.tsx +++ b/components/navbar/menu.item.user.tsx @@ -37,6 +37,7 @@ const MenuItemUser = () => { + diff --git a/pages/auth/my-favorite.tsx b/pages/auth/my-favorite.tsx new file mode 100644 index 0000000..346ccf4 --- /dev/null +++ b/pages/auth/my-favorite.tsx @@ -0,0 +1,102 @@ +import { Container } from 'semantic-ui-react'; +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; +import { PoPoAxios } from '@/lib/axios.instance'; + +import Layout from '@/components/layout'; +import FavoritePlaceBoxes from '@/components/favorite/favorite.place.boxes'; +import FavoritePlaceChoice from '@/components/favorite/favorite.place.choice'; + +import { IPlace, IFavoritePlace } from '@/types/favorite.interface'; + +interface MyInformation { + email: string; + name: string; + userType: string; + createdAt: Date; +} + +const MyInfoPage = () => { + const router = useRouter(); + + const [myInfo, setMyInfo] = useState({ + email: '', + name: '', + userType: '', + createdAt: new Date(), + }); + const [totalPlaceList, setTotalPlaceList] = useState([] as IPlace[]); + const [placeList, setPlaceList] = useState([] as IPlace[]); + + useEffect(() => { + PoPoAxios.get('/auth/myInfo', { withCredentials: true }) + .then((res) => setMyInfo(res.data)) + .catch(() => { + alert('로그인 후 조회할 수 있습니다.'); + router.push('/auth/login'); + }); + + const fetchTotalPlaces = async () => { + try { + const totalPlacesRes = await PoPoAxios.get('/place'); + setTotalPlaceList(totalPlacesRes.data); + } catch (error) { + console.error('Error fetching total places:', error); + } + }; + fetchTotalPlaces(); + + const fetchFavoritePlaces = async (userId: string) => { + try { + const favoritePlacesRes = await PoPoAxios.get( + `/favorite-place/user_id/${userId}`, + ); + const favoritePlaces = favoritePlacesRes.data; + console.log('favoritePlaces:', favoritePlaces); + + if (favoritePlaces.length > 0) { + favoritePlaces.map((favoritePlace) => { + PoPoAxios.get(`/place/${favoritePlace.place_id}`) + .then((res) => { + const cur = res.data; + cur.favorite_id = favoritePlace.uuid; + setPlaceList((prev) => [...prev, cur]); + }) + .catch((error) => { + console.error('Error fetching place information:', error); + }); + }); + } + } catch (error) { + console.error('Error fetching favorite places:', error); + } + }; + if (myInfo.email) { + fetchFavoritePlaces(myInfo.email.replace('@postech.ac.kr', '')); + } + }, [router, myInfo.email]); + + return ( + + +

내 즐겨찾기

+ + {placeList.length < 3 && ( + + )} +
+
+ ); +}; + +export default MyInfoPage; diff --git a/types/favorite.interface.ts b/types/favorite.interface.ts new file mode 100644 index 0000000..df40749 --- /dev/null +++ b/types/favorite.interface.ts @@ -0,0 +1,15 @@ +export interface IFavoritePlace { + uuid: string; + user_id: string; + place_id: string; + created_at: string; +} + +export interface IPlace { + favorite_id: string; + uuid: string; + name: string; + location: string; + region: string; + image_url: string; +}