diff --git a/api/userInfo.ts b/api/userInfo.ts index 57a4e60..6aa635a 100644 --- a/api/userInfo.ts +++ b/api/userInfo.ts @@ -1,4 +1,5 @@ -import { UserInfoProps } from '../context/UserInfoProvider.tsx'; +import { UserInfoProps } from '@/context/UserInfoProvider.tsx'; +import { RoomSearch } from '@/public/types/room'; import { fetchData } from '.'; export const getProfile = async () => { @@ -9,3 +10,19 @@ export const getProfile = async () => { }, }); }; + +export const getLikedRooms = async (page: number) => { + let result; + try { + result = await fetchData>(`/api/v1/my/rooms/like/${page}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (error) { + console.error('userInfo Error', error); + throw Error('no Liked Rooms', error as Error); + } + return result; +}; diff --git a/components/Nav/Nav.tsx b/components/Nav/Nav.tsx index e100ece..bbae5fc 100644 --- a/components/Nav/Nav.tsx +++ b/components/Nav/Nav.tsx @@ -46,10 +46,6 @@ export default function Nav({ initMenu, profile }: NavProps) { ); }; - useEffect(() => { - console.log('userInfoData in Nav', profile); - }, [profile]); - return (
{menus.map((menu, index) => { diff --git a/pages/index.tsx b/pages/index.tsx index 9804f70..7d7fb4a 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -78,7 +78,6 @@ function Home() { try { const data = await getProfile(); if (data != null) { - console.log('data info userProfile', data); setProfile(data); } } catch (error) { diff --git a/pages/liked/index.tsx b/pages/liked/index.tsx index 2ccdf4c..eba1711 100644 --- a/pages/liked/index.tsx +++ b/pages/liked/index.tsx @@ -1,17 +1,82 @@ /* eslint-disable react/no-unstable-nested-components */ -import React from 'react'; +import React, { useRef, useEffect, useState } from 'react'; import NoLiked from '@/public/icons/noLiked.svg'; import useModal from '@/hooks/useModal'; import DefaultLayout from '@/components/layouts/DefaultLayout'; -import { Nav, Typography } from '@/components/index.tsx'; +import { Nav, Typography, Chip } from '@/components/index.tsx'; import { useRouter } from 'next/router'; +import { RoomSearch } from '@/public/types/room'; +import { getLikedRooms } from '@/api/userInfo'; +import FilterImg from '@/public/icons/filter.svg'; +import Filter from '@/components/Filter/Filter.tsx'; +import isEmpty from 'lodash-es/isEmpty'; // TODO 데이터가 구체화되면 바꿔줘야함 interface MyPostingProps { roomInfo: any | null; } +const FILTER_LABEL: Record = { + locationIds: 'Location', + maxDeposit: 'Deposit', + maxMonthlyRent: 'Monthly rent', + availableDate: 'Date available', + types: 'Type of housing', + furnishingTypes: 'Furnishing', +}; export default function Liked({ roomInfo }: MyPostingProps) { const router = useRouter(); + const { openModal, closeModal } = useModal(); + const [page, setPage] = useState(0); + const [filters, setFilters] = useState([]); + const [rooms, setRooms] = useState([]); + const [searchParams, setSearchParams] = useState>({}); + const [totalElements, setTotalElements] = useState(0); + const target = useRef(null); + const options = { + threshold: 1.0, + }; + const callback = async (entries: IntersectionObserverEntry[]) => { + const [{ isIntersecting }] = entries; + if (isIntersecting) { + setPage((prev) => prev + 1); + } + }; + + // useEffect(() => { + // (async () => { + // try { + // const data = await getLikedRooms(page); + // if (data?.error) { + // setRooms([]); + // } else { + // setRooms((prevRooms) => [...prevRooms, ...(data?.content || [])]); + // setTotalElements(data?.totalElements || 0); + // } + // } catch (error) { + // setRooms([]); + // } + // })(); + // }, [page]); + + useEffect(() => { + (async () => { + try { + const result = await getLikedRooms(page); + if (result?.error) { + // 비동기 함수 내부에서 에러를 처리하고 적절한 값을 반환하도록 구현되었을 때 + setRooms([]); + } + if (target?.current) { + const observer = new IntersectionObserver(callback, options); + observer.observe(target.current); + } + } catch (error) { + setRooms([]); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [router.query]); + /** * 좋아요 없을 때 보여주는 Component */ @@ -47,10 +112,91 @@ export default function Liked({ roomInfo }: MyPostingProps) { }; const LikedComponent = () => { + // 옵션 제거 시 실행될 함수 + const [clickedChip, setClickedChip] = useState(''); + const makeFilters = (filterParams: Record) => { + const resultFilter: string[] = []; + Object.keys(filterParams).forEach((key) => { + if (!isEmpty(filterParams[key])) { + resultFilter.push(FILTER_LABEL[key]); + } + }); + setFilters(() => [...resultFilter]); + }; + const getChildData = async (childData: Record) => { + makeFilters(childData); + setPage(0); + setSearchParams(childData); + setRooms([]); + }; + const openFilterPopup = () => { + openModal({ + props: { + title: 'Filters', + size: 'full', + custom: true, + customHeader: false, + }, + children: , + }); + }; + const handleChipClick = (label: React.SetStateAction) => { + setClickedChip(label); + }; + const handleOptionRemove = (option: string, index: number) => { + const resultFilters = filters.filter((item) => item !== option); + setFilters(() => [...resultFilters]); + + const selectedOption = Object.keys(FILTER_LABEL).find((key) => { + return FILTER_LABEL[key] === option; + }); + setPage(0); + setRooms([]); + setSearchParams((prev) => { + return { + ...prev, + [selectedOption as string]: '', + }; + }); + + // 선택된 칩이 없거나 클릭된 칩이 삭제된 칩인 경우에 맨 처음 칩을 clickedChip으로 설정 + if ((clickedChip || '') === '') { + setClickedChip(filters?.[0]); + } + }; + const handlePropsClick = (option: string, index: number) => { + let result = false; + if ((clickedChip || '') !== '' && filters.length > 1) { + result = filters[0] === option; + } else if (filters.length === 1) { + result = option === filters[0]; + } + return result; + }; return (
+
+ + {filters.map((label, index) => { + return ( +
+ handleOptionRemove?.(label, index)} + onChipClick={() => handleChipClick?.(label)} + clicked={handlePropsClick?.(label, index)} + /> +
+ ); + })} +
- There are {`${(roomInfo || []).length} rooms`} in total! + There are {`${totalElements} rooms`} in total! {/* {rooms.map((room, idx) => (
@@ -65,6 +211,7 @@ export default function Liked({ roomInfo }: MyPostingProps) {
+
); }; @@ -72,7 +219,7 @@ export default function Liked({ roomInfo }: MyPostingProps) { /** * 좋아요 있을 때 보여주는 Component (TODO : 구체화 해줘야함) */ - return (roomInfo || []).length === 0 ? : ; + return (rooms || []).length === 0 ? : ; } Liked.getLayout = function getLayout(page: React.ReactElement) { diff --git a/pages/login.tsx b/pages/login.tsx index e8174d9..00035b0 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -34,7 +34,6 @@ export default function Login() { try { const data = await getProfile(); if (data != null) { - console.log('data info userProfile', data); setUserInfoData(data); } } catch (error) { diff --git a/public/types/common.ts b/public/types/common.ts index 3bdf420..f5af11a 100644 --- a/public/types/common.ts +++ b/public/types/common.ts @@ -25,4 +25,5 @@ interface ReturnData { sort: Sort; totalElements: number; totalPages: number; + error?: string; }