Skip to content

Commit 88ca5a6

Browse files
authored
Merge pull request #75 from puppypawpaw/Refactor/Chat
Refactor/chat
2 parents 2ef4a1c + 7b8dd01 commit 88ca5a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+396
-251
lines changed

app/(main)/community/error.tsx

-19
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,12 @@ export default function Error({
1010
error: Error & { digest?: string };
1111
reset: () => void;
1212
}) {
13-
const login = async () => {
14-
const response = await fetch(`/api/auth`, {
15-
method: 'POST',
16-
body: JSON.stringify({
17-
18-
password: '1234',
19-
}),
20-
mode: 'cors',
21-
cache: 'no-cache',
22-
credentials: 'include',
23-
headers: {
24-
'Content-Type': 'application/json',
25-
},
26-
});
27-
console.log(response);
28-
};
2913
useEffect(() => {
3014
console.error(error);
3115
}, [error]);
3216

3317
return (
3418
<div className="flex flex-col items-center justify-center w-full h-screen gap-10">
35-
<button type="button" onClick={login}>
36-
awd
37-
</button>
3819
<h2 className="header1">예기치 못한 오류가 발생하였습니다.🙉</h2>
3920
<div className="flex gap-2 w-80">
4021
<Button fullWidth>메인으로</Button>

app/(main)/community/page.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export const metadata: Metadata = {
1212
export default function CommunityPage() {
1313
return (
1414
<main className="flex flex-col flex-1 w-full h-full gap-10 p-8 overflow-x-hidden tablet:mt-0">
15-
<h1 className="header2">참여중인 채팅방</h1>
1615
<EnteredChatList />
1716
<RecommendChatList />
1817
<TrendingChatList />

app/(main)/page.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import RecommendPlace from '@/components/pages/main/RecommendPlace';
44

55
export default function Home() {
66
return (
7-
<main className="flex-1 w-full flex p-8 gap-10 mt-0 overflow-y-scroll h-full items-start">
7+
<main className="flex items-start flex-1 w-full h-full gap-10 p-8 mt-0 overflow-y-scroll">
88
<Feed />
9-
<aside className="sticky top-0 flex-col justify-between hidden w-3/6 h-screen py-4 tablet:flex">
9+
<aside className="sticky top-0 flex-col justify-between hidden w-3/6 h-full tablet:flex">
1010
<SimpleChatCardList />
1111
<RecommendPlace />
1212
</aside>

app/layout.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ export default function RootLayout({
1616
}) {
1717
return (
1818
<html lang="ko" className={myFont.className}>
19+
<head>
20+
<link rel="icon" href="/image.png" />
21+
</head>
1922
<ReactQueryProvider>
2023
<body>
2124
<ToastContainer limit={5} />

app/not-found.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Button from '@/components/ui/Button';
2+
3+
export default function NotFound() {
4+
return (
5+
<div className="flex flex-col items-center justify-center h-full max-w-xs gap-3 m-auto">
6+
<h2 className="mb-5 header1">앗! 잠시만요.</h2>
7+
<p className="mb-5 text-center whitespace-pre-wrap body2">
8+
원하시는 페이지를 찾을 수 없어요. <br />
9+
찾으시려는 페이지의 주소가 잘못 입력되었거나,
10+
<br />
11+
페이지 주소가 변경 또는 삭제되어 더는 사용하실 수 없습니다. 입력하신
12+
페이지의 주소가 정확한지 다시 한번 확인해주세요.
13+
</p>
14+
<Button fullWidth to="/">
15+
홈으로 이동
16+
</Button>
17+
</div>
18+
);
19+
}

components/pages/chat/ChatRoom/ChatItem.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ChatType } from '@/types/types';
33
import { format } from 'date-fns';
44
import { ko } from 'date-fns/locale';
55
import Image from 'next/image';
6+
import { CHAT_EVENT } from '@/constant/chat';
67

78
export default function ChatItem({ ...chat }: ChatType) {
89
const {
@@ -42,7 +43,7 @@ export default function ChatItem({ ...chat }: ChatType) {
4243
</div>
4344
);
4445
}
45-
if (chatType === 'JOIN' || chatType === 'LEAVE') {
46+
if (CHAT_EVENT.includes(chatType)) {
4647
return <div className="self-center mb-5 text-grey-500 body4">{data}</div>;
4748
}
4849
if (chatType === 'IMAGE') {
@@ -58,7 +59,7 @@ export default function ChatItem({ ...chat }: ChatType) {
5859
width={200}
5960
height={200}
6061
priority
61-
className="rounded-md"
62+
className="w-40 h-40 rounded-md"
6263
/>
6364
<span className="self-end w-fit caption2 text-grey-500">
6465
{format(new Date(createdDate), 'aa h:mm', { locale: ko })}

components/pages/chat/ChatRoom/ChatRoom.tsx

+9-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { CompatClient } from '@stomp/stompjs';
55
import { useEffect, useRef, useState } from 'react';
66
import { ChatType } from '@/types/types';
77
import useSocket from '@/hooks/common/useSocket';
8+
import { useQueryClient } from '@tanstack/react-query';
9+
import { queryKeys } from '@/constant/query-keys';
10+
import { CHAT_EVENT } from '@/constant/chat';
811
import ChatRoomBox from './ChatRoomBox';
912
import ChatRoomHeader from './ChatRoomHeader';
1013
import ChatInput from './ChatInput';
@@ -20,7 +23,7 @@ export default function ChatRoom({
2023
const [chatText, onChangeValue, resetValue] = useInput('');
2124
const stompClient = useRef<CompatClient>();
2225
const { createClient } = useSocket();
23-
26+
const queryClient = useQueryClient();
2427
const sendChat = () => {
2528
if (chatText.trim().length !== 0) {
2629
const isConnected = stompClient.current?.connected;
@@ -48,14 +51,14 @@ export default function ChatRoom({
4851
stompClient.current = createClient(
4952
process.env.NEXT_PUBLIC_SOCKET_URL as string,
5053
);
51-
stompClient.current.debug = (debug) => {
52-
console.log('debug', debug);
53-
};
5454
stompClient.current.connect({}, () => {
5555
stompClient.current?.subscribe(
5656
`/sub/chatroom/${roomId}/message`,
57-
({ body }) => {
58-
const newChat = JSON.parse(body);
57+
(chat) => {
58+
const newChat = JSON.parse(chat.body);
59+
if (CHAT_EVENT.includes(newChat.chatType)) {
60+
queryClient.invalidateQueries([queryKeys.CHATROOM_USER_LIST]);
61+
}
5962
setCurrentChatList((prevChatList) => [...prevChatList, newChat]);
6063
},
6164
);

components/pages/chat/ChatRoom/ChatRoomBox.tsx

+28-24
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import useGetChatHistory from '@/hooks/queries/useGetChatHistory';
33
import { ChatType } from '@/types/types';
44
import useGetUserInfo from '@/hooks/queries/useGetUserInfo';
55
import { Fragment, useRef } from 'react';
6-
import useChatScroll from '@/hooks/common/useChatScroll';
6+
77
import makeDateSection from '@/utils/makeDateSection';
8+
9+
import useChatScroll from '@/hooks/common/useChatScroll';
810
import ChatItem from './ChatItem';
911

1012
export default function ChatRoomBox({
@@ -13,41 +15,43 @@ export default function ChatRoomBox({
1315
currentChatList: ChatType[];
1416
}) {
1517
const roomId = usePathname().split('/')[2];
16-
const {
17-
data: chatHistory,
18-
hasNextPage,
19-
isFetchingNextPage,
20-
fetchNextPage,
21-
} = useGetChatHistory(roomId);
18+
const { data: chatHistory, fetchNextPage } = useGetChatHistory(roomId);
2219
const { data: userInfo } = useGetUserInfo();
23-
const chatRef = useRef<HTMLDivElement>(null);
20+
const chatContainerRef = useRef<HTMLDivElement>(null);
2421
const bottomRef = useRef<HTMLDivElement>(null);
22+
const chatListRef = useRef<HTMLDivElement>(null);
23+
const loadMoreRef = useRef<HTMLDivElement>(null);
2524
useChatScroll({
26-
chatRef,
25+
chatContainerRef,
2726
bottomRef,
28-
count: currentChatList.length,
2927
beforeChatLoadMore: fetchNextPage,
30-
shouldLoadMore: !isFetchingNextPage && !!hasNextPage,
28+
chatListRef,
29+
loadMoreRef,
3130
});
3231

3332
const mergedChatList = [...(chatHistory?.pages ?? []), ...currentChatList];
3433
const chatListWithDateSection = makeDateSection(
3534
mergedChatList && mergedChatList,
3635
);
37-
3836
return (
39-
<div className="flex flex-col flex-1 p-4 overflow-y-scroll " ref={chatRef}>
40-
{Object.entries(chatListWithDateSection).map(
41-
([date, chatList], index) => (
42-
// eslint-disable-next-line react/no-array-index-key
43-
<Fragment key={`date-${index}`}>
44-
<div className="mb-5 text-center text-grey-500 body4">{date}</div>
45-
{chatList.map((chat) => (
46-
<ChatItem key={chat.id} {...chat} userId={userInfo!.userId} />
47-
))}
48-
</Fragment>
49-
),
50-
)}
37+
<div
38+
className="flex flex-col flex-1 p-4 overflow-y-scroll "
39+
ref={chatContainerRef}
40+
>
41+
<div ref={loadMoreRef} />
42+
<div className="flex flex-col" ref={chatListRef}>
43+
{Object.entries(chatListWithDateSection).map(
44+
([date, chatList], index) => (
45+
// eslint-disable-next-line react/no-array-index-key
46+
<Fragment key={`date-${index}`}>
47+
<div className="mb-5 text-center text-grey-500 body4">{date}</div>
48+
{chatList.map((chat) => (
49+
<ChatItem key={chat.id} {...chat} userId={userInfo!.userId} />
50+
))}
51+
</Fragment>
52+
),
53+
)}
54+
</div>
5155
<div ref={bottomRef} />
5256
</div>
5357
);

components/pages/chat/ChatRoom/ChatUserList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function ChatUserList({ roomId }: { roomId: string }) {
4949
image={user.imageUrl}
5050
name={user.nickname}
5151
petName={
52-
user.briefIntroduction ?? '나의 반려견을 등록해주세요.🐶'
52+
user.briefIntroduction ?? '한줄소개를 아직 안정했어요.🐾'
5353
}
5454
/>
5555
</li>

components/pages/chat/ChatRoom/DeleteChatRoomButton.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ export default function DeleteChatRoomButton({ roomId }: { roomId: string }) {
1717
Toast.success('채팅방을 삭제했어요.🐶');
1818
router.replace('/community');
1919
} catch (error) {
20-
console.error(error);
21-
Toast.error('채팅방을 삭제하지 못했어요.🧐 잠시후 다시 시도해주세요.');
20+
if (error instanceof Error) {
21+
Toast.error(error.message);
22+
}
2223
} finally {
2324
setOpen(false);
2425
}

components/pages/community/EnteredChatList.tsx

+22-12
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,31 @@ import { SwiperSlide } from 'swiper/react';
44
import useGetEnteredChatList from '@/hooks/queries/useGetEnteredChatList';
55
import ImageChatCard from '@/components/ui/ChatCard/ImageChatCard';
66
import EnteredChatLoading from '@/components/ui/Loading/EnteredChatLoading';
7+
import FlexBox from '@/components/ui/FlexBox';
78
import Carousel from './Carousel';
89

910
export default function EnteredChatList() {
10-
const { data, isLoading } = useGetEnteredChatList();
11-
if (isLoading) {
12-
return <EnteredChatLoading />;
13-
}
11+
const { data: chatList, isLoading } = useGetEnteredChatList();
12+
1413
return (
15-
<Carousel>
16-
{data &&
17-
data.map((list) => (
18-
<SwiperSlide key={list.id}>
19-
<ImageChatCard {...list} />
20-
</SwiperSlide>
21-
))}
22-
</Carousel>
14+
<FlexBox direction="column" className="">
15+
<div className="flex flex-col w-full gap-2">
16+
<h1 className="w-full header2">참여중인 채팅방</h1>
17+
{chatList?.length === 0 && (
18+
<div className="w-full header4">현재 참여중인 채팅방이 없어요.</div>
19+
)}
20+
</div>
21+
{isLoading ? (
22+
<EnteredChatLoading />
23+
) : (
24+
<Carousel>
25+
{chatList?.map((list) => (
26+
<SwiperSlide key={list.id}>
27+
<ImageChatCard {...list} />
28+
</SwiperSlide>
29+
))}
30+
</Carousel>
31+
)}
32+
</FlexBox>
2333
);
2434
}

components/pages/community/TrendingChatList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import useGetTrendingChatList from '@/hooks/queries/useGetTrendingChatList';
66
import TrendingChatListLoading from '@/components/ui/Loading/TrendingChatListLoading';
77

88
export default function TrendingChatList() {
9-
const { data, Observer } = useGetTrendingChatList();
9+
const { data, Observer } = useGetTrendingChatList({ size: 9 });
1010
return (
1111
<>
1212
<FlexBox direction="column" className="gap-3 tablet:gap-5">

components/pages/main/RecommendPlace.tsx

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import { useCallback, useMemo, useState } from 'react';
44
import { useJsApiLoader, GoogleMap } from '@react-google-maps/api';
5-
import Link from 'next/link';
65
import Image from 'next/image';
76
import FlexBox from '@/components/ui/FlexBox';
87
import ArrowClockIcon from '@/public/ArrowClockwise.svg';
@@ -88,7 +87,7 @@ export default function RecommendPlace() {
8887
);
8988

9089
return (
91-
<FlexBox direction="column" className="w-full gap-3">
90+
<FlexBox direction="column" className="w-full gap-3 ">
9291
<h3 className="flex items-center justify-between w-full header3">
9392
<p>
9493
<span className="text-primary-300">수박이</span>와 가기 좋은 장소
@@ -97,13 +96,14 @@ export default function RecommendPlace() {
9796
<ArrowClockIcon />
9897
</button>
9998
</h3>
100-
<Link
101-
href={`/${placeDetail?.place_id}`}
102-
className="w-full rounded-[10px] shadow-chatCard p-5 h-64 gap-5 flex flex-col"
103-
>
99+
<div className="w-full rounded-[10px] shadow-chatCard p-5 h-64 gap-5 flex flex-col">
104100
<Image
105-
src="/default.png"
106-
alt="d"
101+
src={
102+
placeDetail?.photos
103+
? placeDetail.photos[0].getUrl()
104+
: '/default.png'
105+
}
106+
alt={placeDetail?.name ?? '매장 사진'}
107107
width={300}
108108
height={100}
109109
priority
@@ -123,7 +123,7 @@ export default function RecommendPlace() {
123123
{placeDetail && placeDetail.formatted_address}
124124
</p>
125125
</FlexBox>
126-
</Link>
126+
</div>
127127
</FlexBox>
128128
);
129129
}
+16-13
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
'use client';
22

33
import FlexBox from '@/components/ui/FlexBox';
4-
import RightButton from '@/public/ChatCard/arrow-right.svg';
5-
import LeftButton from '@/public/ChatCard/arrow-left.svg';
64
import SimpleChatCard from '@/components/ui/ChatCard/SimpleChatCard';
5+
import useGetTrendingChatList from '@/hooks/queries/useGetTrendingChatList';
6+
import SimpleChatListLoading from '@/components/ui/Loading/SimpleChatListLoading';
77

88
export default function SimpleChatCardList() {
9+
const { data, isLoading } = useGetTrendingChatList({ size: 9 });
910
return (
1011
<FlexBox
1112
direction="column"
@@ -14,18 +15,20 @@ export default function SimpleChatCardList() {
1415
>
1516
<FlexBox justify="between" className="w-full">
1617
<h3 className="header3">지금 뜨고있는 채팅방 🔥</h3>
17-
<FlexBox className="gap-4">
18-
<button type="button">
19-
<RightButton />
20-
</button>
21-
<button type="button">
22-
<LeftButton />
23-
</button>
24-
</FlexBox>
2518
</FlexBox>
26-
<SimpleChatCard />
27-
<SimpleChatCard />
28-
<SimpleChatCard />
19+
<ul className="flex flex-col gap-2 p-2 overflow-y-scroll h-72 2xl:h-96 scrollbar-hide">
20+
{isLoading ? (
21+
<SimpleChatListLoading />
22+
) : (
23+
data?.pages.map((page) =>
24+
page.content.map((list) => (
25+
<li key={list.id}>
26+
<SimpleChatCard {...list} />
27+
</li>
28+
)),
29+
)
30+
)}
31+
</ul>
2932
</FlexBox>
3033
);
3134
}

0 commit comments

Comments
 (0)