diff --git a/src/app/message/chat/[roomId]/ChatRoomPage.tsx b/src/app/message/chat/[roomId]/ChatRoomPage.tsx index 2ca35d29..64931a6d 100644 --- a/src/app/message/chat/[roomId]/ChatRoomPage.tsx +++ b/src/app/message/chat/[roomId]/ChatRoomPage.tsx @@ -96,7 +96,7 @@ const ChatRoomPage = ({ accessToken, roomId, userId }: IProps) => { } return ( -
+
{/* 채팅 화면 */}
{ + return new QueryClient({ + defaultOptions: { + queries: { + staleTime: 60 * 1000, // 1분 + }, + }, + }); +}; + export default async function MessagePage() { const cookieStore = await cookies(); const accessToken = cookieStore.get('accessToken')?.value || null; - const queryClient = new QueryClient(); + const queryClient = getQueryClient(); const me = await API.userService.getMeSkipRedirect(); const userId = me.userId; - // 첫 페이지 우선 prefetch - await queryClient.prefetchInfiniteQuery({ - queryKey: ['followers', userId], - queryFn: async () => { - return await API.followerService.getFollowers({ - userId, - cursor: undefined, - size: INITIAL_PAGE_SIZE, - }); - }, - initialPageParam: undefined, - getNextPageParam: (lastPage) => { - return lastPage.nextCursor ?? undefined; - }, - pages: 1, - }); + await Promise.all([ + // 팔로워 목록 prefetch + queryClient.prefetchInfiniteQuery({ + queryKey: followKeys.followers(userId), + queryFn: async () => { + return await API.followerService.getFollowers({ + userId, + cursor: undefined, + size: INITIAL_PAGE_SIZE, + }); + }, + initialPageParam: undefined, + getNextPageParam: (lastPage) => { + return lastPage.nextCursor ?? undefined; + }, + pages: 1, + }), + + // 채팅 목록 prefetch + queryClient.prefetchQuery({ + queryKey: ['chatList', userId], + queryFn: async () => { + return await API.chatService.getChatRooms(); + }, + }), + ]); // dehydrate로 직렬화 const dehydratedState = dehydrate(queryClient); diff --git a/src/components/pages/chat/chat-list/index.tsx b/src/components/pages/chat/chat-list/index.tsx index 81ac268e..a728c0b4 100644 --- a/src/components/pages/chat/chat-list/index.tsx +++ b/src/components/pages/chat/chat-list/index.tsx @@ -46,8 +46,8 @@ export const ChatList = ({ userId, accessToken }: IProps) => { className='flex cursor-pointer items-center gap-3 bg-white p-5 transition hover:bg-gray-50' onClick={() => handleClick(chat.chatRoomId)} > - {/* 프로필 이미지 - 이미지 수정 필요💥💥*/} - + {/* 프로필 이미지 */} + {/* 텍스트 영역 */}
@@ -57,7 +57,7 @@ export const ChatList = ({ userId, accessToken }: IProps) => { 'text-text-sm-medium line-clamp-1 overflow-hidden break-all text-gray-700', )} > - {chat.lastMessage ? chat.lastMessage.content : '아직 대화가 없습니다.'} + {chat.lastMessage.content}
diff --git a/src/components/pages/chat/chat-user-list/index.tsx b/src/components/pages/chat/chat-user-list/index.tsx index 3974f225..fc8a8257 100644 --- a/src/components/pages/chat/chat-user-list/index.tsx +++ b/src/components/pages/chat/chat-user-list/index.tsx @@ -9,6 +9,20 @@ import { useGetParticipants } from '@/hooks/use-chat'; import { UserOutModal } from './UserOutModal'; +interface UserProps { + user: { + userId: number; + nickName: string; + profileImage: string; + profileMessage?: string; + isOwner: boolean; + }; + roomId: number; + roomType: 'DM' | 'GROUP'; + isManaging: boolean; + index: number; +} + interface UserListProps { onClose: () => void; roomId: number; @@ -16,9 +30,45 @@ interface UserListProps { userId: number; } +const User = ({ user, roomId, roomType, isManaging, index }: UserProps) => { + const { open } = useModal(); + + return ( +
+
+ +
+ +
+
{user.nickName}
+
+ {user.profileMessage || '상태 메시지가 없습니다.'} +
+
+ + {roomType === 'GROUP' && user.isOwner && ( + + 방장 + + )} + + {isManaging && index !== 0 && ( + + )} +
+ ); +}; + export const UserList = ({ onClose, roomId, roomType, userId }: UserListProps) => { const [isManaging, setIsManaging] = useState(false); - const { open } = useModal(); const { data } = useGetParticipants(roomId); const isCurrentUserOwner = data?.participants.some( @@ -60,42 +110,13 @@ export const UserList = ({ onClose, roomId, roomType, userId }: UserListProps) =
{sortedParticipants.map((user, index) => (
-
-
- -
- -
-
{user.nickName}
-
- {user.profileMessage || '상태 메시지가 없습니다.'} -
-
- - {roomType === 'GROUP' && user.isOwner ? ( - - 방장 - - ) : null} - - {isManaging && index !== 0 && ( - - )} -
+
))}
diff --git a/src/components/pages/message/message-following-card/index.stories.tsx b/src/components/pages/message/message-following-card/index.stories.tsx index 587322f2..94cd4439 100644 --- a/src/components/pages/message/message-following-card/index.stories.tsx +++ b/src/components/pages/message/message-following-card/index.stories.tsx @@ -33,7 +33,6 @@ export const FollowingCardTable: Story = { nickname: '', profileImage: '', profileMessage: '', - type: 'following', }, render: () => ( @@ -49,11 +48,7 @@ export const FollowingCardTable: Story = { @@ -65,7 +60,6 @@ export const FollowingCardTable: Story = { @@ -73,48 +67,28 @@ export const FollowingCardTable: Story = { diff --git a/src/components/pages/message/message-following-card/index.test.tsx b/src/components/pages/message/message-following-card/index.test.tsx index aa8ce850..1a6e63ad 100644 --- a/src/components/pages/message/message-following-card/index.test.tsx +++ b/src/components/pages/message/message-following-card/index.test.tsx @@ -37,38 +37,14 @@ describe('FollowingCard 컴포넌트 테스트', () => { }); }); - test('type=following 일 때 테스트', () => { - render(); + test('렌더링 테스트', () => { + render(); expect(screen.getByText('메세지')).toBeInTheDocument(); }); - test('type=message & count > 0 일 때 테스트', () => { - render(); - - const badge = screen.getByText('5'); - - expect(badge).toBeInTheDocument(); - expect(badge).not.toHaveClass('opacity-0'); - }); - - test('type=message & count = 0 일 때 테스트', () => { - render(); - - const badge = screen.getByText('0'); - - expect(badge).toBeInTheDocument(); - expect(badge).toHaveClass('opacity-0'); - }); - - test('count > 99 인 경우 "99+" 를 보여주는지 테스트.', () => { - render(); - - expect(screen.getByText('99+')).toBeInTheDocument(); - }); - test('팔로잉 카드 클릭 시 router.push() 호출되는지 테스트.', () => { - render(); + render(); fireEvent.click(screen.getByTestId('following-card')); @@ -76,7 +52,7 @@ describe('FollowingCard 컴포넌트 테스트', () => { }); test('메시지 버튼 클릭 시 DM 생성 후 채팅방으로 이동되는지 테스트.', async () => { - render(); + render(); fireEvent.click(screen.getByText('메세지')); diff --git a/src/components/pages/message/message-following-card/index.tsx b/src/components/pages/message/message-following-card/index.tsx index 577cd2be..18a49fa8 100644 --- a/src/components/pages/message/message-following-card/index.tsx +++ b/src/components/pages/message/message-following-card/index.tsx @@ -4,15 +4,12 @@ import { useState } from 'react'; import { ProfileImage } from '@/components/shared'; import { useCreateDMChat } from '@/hooks/use-chat/use-chat-dm'; -import { cn } from '@/lib/utils'; interface FollowingCardProps { userId: number; nickname: string; profileImage: string; profileMessage: string; - type: 'following' | 'message'; - count?: number; onMessageClick?: () => void; } @@ -21,8 +18,6 @@ export const FollowingCard = ({ nickname, profileImage, profileMessage, - type, - count = 0, }: FollowingCardProps) => { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); @@ -57,34 +52,18 @@ export const FollowingCard = ({
{nickname} - - {profileMessage} - + {profileMessage}
- {/* 탭이 following 인지 message인지에 따라 달라지는 요소. */} - {type === 'following' ? ( - - ) : ( - - {count > 99 ? '99+' : count} - - )} + + ); }; diff --git a/src/components/pages/message/message-following-content/index.tsx b/src/components/pages/message/message-following-content/index.tsx index 5bdc172c..53dbc6df 100644 --- a/src/components/pages/message/message-following-content/index.tsx +++ b/src/components/pages/message/message-following-content/index.tsx @@ -9,6 +9,7 @@ import { TabNavigation } from '@/components/shared'; import { useInfiniteScroll } from '@/hooks/use-group/use-group-infinite-list'; import { useIntersectionObserver } from '@/hooks/use-intersection-observer'; import { INTERSECTION_OBSERVER_THRESHOLD } from '@/lib/constants/group-list'; +import { followKeys } from '@/lib/query-key/query-key-follow'; const SOCIAL_TABS = [ { label: '팔로잉', value: 'following' }, @@ -40,7 +41,7 @@ export const FollowingContent = ({ initialUserId, accessToken }: FollowingConten size, }); }, - queryKey: ['followers', initialUserId], + queryKey: followKeys.followers(initialUserId), completedMessage: '모든 팔로잉을 불러왔습니다.', enabled: !!initialUserId, }); @@ -81,7 +82,7 @@ export const FollowingContent = ({ initialUserId, accessToken }: FollowingConten {/* 5. 완료 메시지 */} {!hasNextPage && (
- {completedMessage} + {completedMessage}
)} diff --git a/src/components/pages/message/message-following-list/index.tsx b/src/components/pages/message/message-following-list/index.tsx index 9e12d117..fec9ad0e 100644 --- a/src/components/pages/message/message-following-list/index.tsx +++ b/src/components/pages/message/message-following-list/index.tsx @@ -17,7 +17,6 @@ export const FollowingList = ({ items }: FollowingListProps) => { nickname={item.nickname} profileImage={item.profileImage} profileMessage={item.profileMessage} - type='following' userId={item.userId} /> ))} diff --git a/src/components/pages/message/message-following-search/index.tsx b/src/components/pages/message/message-following-search/index.tsx index 69efd1e4..20c046ea 100644 --- a/src/components/pages/message/message-following-search/index.tsx +++ b/src/components/pages/message/message-following-search/index.tsx @@ -12,7 +12,6 @@ export const FollowingSearch = ({ userId }: { userId: number }) => { className='bg-mono-white mb-2 flex items-center gap-5 px-5 py-4 transition-all hover:cursor-pointer hover:opacity-80' onClick={() => { open(); - console.log('hi'); }} >
diff --git a/src/components/ui/button/index.test.tsx b/src/components/ui/button/index.test.tsx index 4de8fe8a..dc41efd5 100644 --- a/src/components/ui/button/index.test.tsx +++ b/src/components/ui/button/index.test.tsx @@ -21,7 +21,7 @@ describe('버튼 컴포넌트 테스트', () => { const button = screen.getByRole('button'); - expect(button).toHaveClass('bg-mint-400'); + expect(button).toHaveClass('bg-mint-500'); expect(button).toHaveClass('text-mono-white'); expect(button).toHaveClass('text-text-md-bold'); expect(button).toHaveClass('w-full'); diff --git a/src/components/ui/button/index.tsx b/src/components/ui/button/index.tsx index 99dff9ae..97f15eca 100644 --- a/src/components/ui/button/index.tsx +++ b/src/components/ui/button/index.tsx @@ -7,15 +7,14 @@ import { cn } from '@/lib/utils'; const buttonVariants = cva('bg-mono-white w-full border transition select-none', { variants: { variant: { - primary: 'bg-mint-400 text-text-md-bold text-mono-white hover:bg-mint-600 active:bg-mint-700', + primary: 'bg-mint-500 text-mono-white hover:bg-mint-600 active:bg-mint-700', secondary: - 'border-mint-500 text-text-sm-semibold text-mint-500 active:text-mint-700 active:border-mint-600 hover:bg-gray-50 active:bg-gray-100', - tertiary: - 'text-text-sm-semibold border-gray-400 text-gray-600 hover:bg-gray-50 active:bg-gray-100', + 'border-mint-500 text-mint-500 active:text-mint-700 active:border-mint-600 hover:bg-gray-50 active:bg-gray-100', + tertiary: ' border-gray-400 text-gray-600 hover:bg-gray-50 active:bg-gray-100', }, size: { - md: 'h-13 rounded-2xl', - sm: 'h-10 rounded-xl', + md: 'h-13 rounded-2xl text-text-md-bold', + sm: 'h-10 rounded-xl text-text-sm-semibold', }, disabled: { true: '!cursor-not-allowed',
Following 기본 팔로잉 카드 - +
Message 읽지 않은 메시지 없음 - +
Message 읽지 않은 메시지 1개 - +
Message 읽지 않은 메시지 10개 - +
Message 읽지 않은 메시지 99개 이상 - +