Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/apis/getBookmarkData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { instance } from '@/apis/api';
import type { GetBookmarkRequest, GetBookmarkResponse } from '@manchui-api';

Expand Down Expand Up @@ -27,4 +25,4 @@ export async function getBookmarkData(request: GetBookmarkRequest): Promise<GetB
console.log('getBookmarkData 함수에서 오류 발생', e);
throw new Error('찜한 모임 데이터를 불러오는데 실패했습니다.');
}
}
}
14 changes: 14 additions & 0 deletions src/apis/getChatMessageData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { instance } from '@/apis/api';
import type { GetChatListResponse } from '@manchui-api';

export async function getChatMessageData(roomId: string, lastMessageId: number | undefined) {
try {
const queryParams = lastMessageId ? `?lastMessageId=${lastMessageId}&limit=20` : '?limit=20';
const res = await instance.get<GetChatListResponse>(`/api/chat/list/${roomId}${queryParams}`);

return res.data;
} catch (e) {
console.error('getChatMessageData 함수에서 오류 발생:', e);
throw new Error('채팅 데이터를 불러오는데 실패했습니다.');
}
}
2 changes: 1 addition & 1 deletion src/apis/getGatheringData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export async function getGatheringData(request: GetGatheringRequest): Promise<Ge
const { size, sort, query, category, location, startDate, endDate, cursor } = request;

const params = {
cursor,
cursor: cursor?.toString(),
size: size?.toString(),
...(sort && { sort }),
...(query && { query }),
Expand Down
13 changes: 13 additions & 0 deletions src/apis/getRoomUsersData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { instance } from '@/apis/api';
import type { RoomUserResponse } from '@manchui-api';

export async function getRoomUserData(roomId: string) {
try {
const res = await instance.get<RoomUserResponse>(`/api/chat/user/list/${roomId}`);

return res.data;
} catch (e) {
console.error('getRoomUserData 함수에서 오류 발생:', e);
throw new Error('채팅방 유저 데이터를 불러오는데 실패했습니다.');
}
}
4 changes: 2 additions & 2 deletions src/components/bookmark/BookmarkBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as m from 'framer-motion/m';

/* eslint-disable tailwindcss/no-custom-classname */
export default function BookmarkBanner({ isError }: { isError: boolean }) {
export default function BookmarkBanner() {
return (
<m.div
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
className="mt-[60px] flex h-bookmark-banner min-w-[340px] items-center justify-center bg-blue-800 text-16-20-response font-semibold text-white"
>
{isError ? '잠시 후 다시 시도해주세요.' : '마감되기 전에 지금 바로 참여해보세요'}
마감되기 전에 지금 바로 참여해보세요
</m.div>
);
}
31 changes: 0 additions & 31 deletions src/components/bookmark/BookmarkCardList/index.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/bookmark/BookmarkContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default function BookmarkContainer({ children }: { children: React.ReactNode }) {
return <div className="mx-auto flex w-full min-w-[340px] flex-col items-center justify-center pt-6 px-4 mobile:pt-[54px]">{children}</div>;
return <div className="mx-auto flex w-full flex-col items-center justify-center pt-14 px-5">{children}</div>;
}
22 changes: 0 additions & 22 deletions src/components/bookmark/BookmarkFilter/index.tsx

This file was deleted.

16 changes: 14 additions & 2 deletions src/components/bookmark/BookmarkHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@ import type { GetBookmarkResponse } from '@manchui-api';

export default function BookmarkHeader({ data }: { data?: GetBookmarkResponse['data'] }) {
return (
<div className="flex w-full items-center gap-2 pb-6 mobile:flex-row mobile:justify-between mobile:pb-[30px]">
<div className="flex w-full items-center justify-between gap-2 pb-6">
<div className="flex items-center gap-1 text-pretty">
<h1 className="text-bookmark-title font-bold">찜한 모임</h1>
<h1 className="text-xl font-bold tablet:text-2xl">찜한 모임</h1>
<span className="rounded-xl bg-red-400 px-2 text-sm font-bold text-white">{data?.gatheringCount}</span>
</div>
<SearchBar />
</div>
);
}

export function BookmarkHeaderSkeleton() {
return (
<div className="flex w-full items-center justify-between pb-6">
<div className="flex items-center gap-1 text-nowrap">
<h1 className="text-xl font-bold tablet:text-2xl">찜한 모임</h1>
<span className="rounded-xl bg-red-400 px-2 text-sm font-bold text-white">0</span>
</div>
<SearchBar />
</div>
);
}
38 changes: 38 additions & 0 deletions src/components/bookmark/BookmarkSection/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import CardItem from '@/components/main/CardSection/CardItem';
import { MessageWithLink } from '@/components/main/MainCardSection/CardSection';
import ErrorBoundary from '@/components/shared/ErrorBoundary';
import NoData from '@/components/shared/NoData';
import PaginationBtn from '@/components/shared/PaginationBtn';
import type { GetBookmarkResponse } from '@manchui-api';

interface BookmarkSectionProps {
bookmark?: GetBookmarkResponse['data'];
isError: boolean;
isLoading: boolean;
}

function BookmarkSectionContent({ bookmark, isLoading, isError }: BookmarkSectionProps) {
return (
<>
<ul className="grid grid-cols-2 gap-5 tablet:grid-cols-3 pc:grid-cols-4">
{bookmark?.gatheringList.map((data) => <CardItem key={data.gatheringId} data={data} />)}
</ul>
{bookmark?.gatheringCount === 0 && <NoData use="main" />}
{!isLoading && !isError && bookmark?.gatheringCount !== 0 && <PaginationBtn page={bookmark?.page ?? 0} totalPage={bookmark?.totalPage ?? 0} />}
</>
);
}

export default function BookmarkSection({ bookmark, isLoading, isError }: BookmarkSectionProps) {
return (
<ErrorBoundary
fallbackComponent={
<div className="relative top-[100px]">
<MessageWithLink message="네트워크 연결을 확인해주세요." buttonText="다시 시도하기" onClick={() => window.location.reload()} />
</div>
}
>
<BookmarkSectionContent bookmark={bookmark} isLoading={isLoading} isError={isError} />
</ErrorBoundary>
);
}
25 changes: 17 additions & 8 deletions src/components/detail/FloatingBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,33 @@ export function FloatingBar({ gatherings, id }: DetailPageBaseType) {
<span className="text-base font-semibold text-blue-800">당신의 취미가 특별해지는 시간 🎮</span>
<span className="text-sm font-medium text-blue-800">모임 참여로 새로운 즐거움을 발견하세요.</span>
</div>
<button
type="button"
onClick={() => router.push(`/detail/${id}/chat?roomId=${gatherings.roomId}`)}
className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white"
>
웹소켓 테스트
</button>
{isClosed ? (
<Button label="마감되었습니다" size="primary" variant="primary" disabled />
) : findUserId ? (
<div className="flex gap-2">
<CancelButton gatherings={gatherings} id={id} />
<ShareButton />
<button
type="button"
onClick={() => router.push(`/detail/${id}/chat?roomId=${gatherings.roomId}`)}
className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white"
>
실시간 문의하기
</button>
</div>
) : isDisabled ? (
<Button label="마감되었습니다" size="primary" variant="primary" disabled />
) : (
<AttendanceButton gatherings={gatherings} id={id} />
<div className="flex gap-2">
<AttendanceButton gatherings={gatherings} id={id} />
<button
type="button"
onClick={() => router.push(`/detail/${id}/chat?roomId=${gatherings.roomId}`)}
className="rounded-xl bg-blue-800 px-5 py-2 text-sm font-bold text-white"
>
실시간 문의하기
</button>
</div>
)}
</footer>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/main/CardSection/CardItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function CardItem({ data }: { data: GetGatheringResponse['data'][
await queryClient.invalidateQueries({ queryKey: ['main'] });
await queryClient.invalidateQueries({ queryKey: ['bookmark'] });
} catch (error) {
console.error('API 요청에 실패했습니다:', error);
console.error('찜하기 실패:', error);
setIsHearted((prevHearted) => !prevHearted);
}
};
Expand Down
15 changes: 9 additions & 6 deletions src/components/main/CardSection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,28 @@ function CardSectionContent() {
const sentinelRef = useRef<HTMLDivElement>(null);
const isIntersecting = useIntersectionObserver(sentinelRef);

const { mainData, isError, hasNextPage, fetchNextPage } = useGetGatheringData({
const { mainData, hasNextPage, fetchNextPage } = useGetGatheringData({
query: keyword,
location,
category,
sort: closeDate,
startDate: dateStart,
endDate: dateEnd,
cursor: undefined,
});

useEffect(() => {
if (isIntersecting && hasNextPage) void fetchNextPage();
}, [isIntersecting, hasNextPage, fetchNextPage]);

return (
<div className="px-5">
<ul className="grid grid-cols-2 gap-5 tablet:grid-cols-3 pc:grid-cols-4">{mainData?.map((data) => <CardItem key={data.gatheringId} data={data} />)}</ul>
{mainData?.length === 0 && <NoData use="main" />}
{!isError && <div ref={sentinelRef} className="h-10 w-full flex-shrink-0 opacity-0" />}
</div>
<>
<div className="px-5">
<ul className="grid grid-cols-2 gap-5 tablet:grid-cols-3 pc:grid-cols-4">{mainData?.map((data) => <CardItem key={data.gatheringId} data={data} />)}</ul>
{mainData?.length === 0 && <NoData use="main" />}
</div>
{hasNextPage && <div ref={sentinelRef} className="h-10 w-full flex-shrink-0 opacity-0" />}
</>
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/main/HeaderSection/FilterList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function FilterList() {
}, [isLoggedIn, router]);

return (
<div className="relative my-6 flex items-center text-nowrap text-[14px]">
<div className="relative my-6 flex w-full items-center text-nowrap text-[14px]">
<div className="flex items-center gap-2 overflow-x-auto leading-[100%] after:absolute after:right-0 after:top-0 after:h-full after:w-32 after:bg-gradient-to-l after:from-white after:via-white after:to-transparent">
<div className="scrollbar-hide flex h-9 items-center gap-2 overflow-x-auto">
{/* 필터 버튼들 */}
Expand Down
7 changes: 5 additions & 2 deletions src/hooks/useGetBookmarkData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import { getBookmarkData } from '@/apis/getBookmarkData';
import type { GetBookmarkRequest, GetBookmarkResponse } from '@manchui-api';
import { keepPreviousData, useQuery } from '@tanstack/react-query';

const useGetBookmarkData = (request: GetBookmarkRequest) =>
useQuery<GetBookmarkResponse>({
const useGetBookmarkData = (request: GetBookmarkRequest) => {
const { data, isLoading, isError } = useQuery<GetBookmarkResponse>({
queryKey: ['bookmark', request],
queryFn: () => getBookmarkData(request),
placeholderData: keepPreviousData,
});

return { bookmark: data?.data, isLoading, isError };
};

export default useGetBookmarkData;
25 changes: 25 additions & 0 deletions src/hooks/useGetChattingData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { getChatMessageData } from '@/apis/getChatMessageData';
import { getRoomUserData } from '@/apis/getRoomUsersData';
import type { GetChatListResponse, RoomUserResponse } from '@manchui-api';
import { keepPreviousData, useInfiniteQuery, useQuery } from '@tanstack/react-query';

export default function useGetChattingData(roomId: string) {
const { data: roomData } = useQuery<RoomUserResponse>({
queryKey: ['roomUsers', roomId],
queryFn: () => getRoomUserData(roomId),
});

const {
data: chatData,
hasNextPage,
fetchNextPage,
} = useInfiniteQuery<GetChatListResponse>({
queryKey: ['chatMessages', roomId],
queryFn: ({ pageParam }) => getChatMessageData(roomId, pageParam as number | undefined),
getNextPageParam: (lastPage) => (lastPage.data.hasNext ? lastPage.data.nextCursor : undefined),
initialPageParam: undefined,
placeholderData: keepPreviousData,
});

return { chatData, roomUser: roomData?.data.userInfoList, hasNextPage, fetchNextPage };
}
6 changes: 3 additions & 3 deletions src/hooks/useGetGatheringData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import type { GetGatheringRequest, GetGatheringResponse } from '@manchui-api';
import { keepPreviousData, useInfiniteQuery } from '@tanstack/react-query';

const useGetGatheringData = (request: GetGatheringRequest) => {
const { data, isLoading, isError, hasNextPage, fetchNextPage } = useInfiniteQuery<GetGatheringResponse>({
const { data, hasNextPage, fetchNextPage } = useInfiniteQuery<GetGatheringResponse>({
queryKey: ['main', request],
queryFn: ({ pageParam = request.cursor }) => getGatheringData({ ...request, size: 8, cursor: pageParam as number | undefined }),
queryFn: ({ pageParam }) => getGatheringData({ ...request, size: 8, cursor: pageParam as number | undefined }),
getNextPageParam: (lastPage) => lastPage.data.nextCursor || undefined,
initialPageParam: undefined,
placeholderData: keepPreviousData,
});

const mainDataFlat = data?.pages.map((page) => page.data.gatheringList).flat();

return { mainData: mainDataFlat, isLoading, isError, hasNextPage, fetchNextPage };
return { mainData: mainDataFlat, hasNextPage, fetchNextPage };
};

export default useGetGatheringData;
2 changes: 1 addition & 1 deletion src/hooks/useIntersectionObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
export default function useIntersectionObserver(
elementRef: RefObject<HTMLElement>,
options: IntersectionObserverInit = {
threshold: 0,
threshold: 0.1,
root: null,
rootMargin: '0px',
},
Expand Down
Loading