diff --git a/frontend/src/apis/channel/dto.ts b/frontend/src/apis/channel/dto.ts index 13e363b..dbc25ea 100644 --- a/frontend/src/apis/channel/dto.ts +++ b/frontend/src/apis/channel/dto.ts @@ -36,7 +36,7 @@ interface Reaction { users: string[]; } -interface Message { +export interface Message { messageId: string; user: User; content: string; diff --git a/frontend/src/apis/dm/dto.ts b/frontend/src/apis/dm/dto.ts index dc8997c..2632f04 100644 --- a/frontend/src/apis/dm/dto.ts +++ b/frontend/src/apis/dm/dto.ts @@ -1,8 +1,5 @@ -interface DMParticipant { - userId: string; - username: string; - profileImage: string; -} +import { User } from '@/types/user'; +import { Message } from '../channel/dto'; interface DMLastMessage { senderId: string; @@ -10,9 +7,9 @@ interface DMLastMessage { createdAt: string; } -export interface DMItem { +interface DMItem { dmId: string; - participants: DMParticipant[]; + participants: User[]; lastMessage: DMLastMessage; unreadCount: number; } @@ -21,3 +18,10 @@ export interface DMListResponseDto { userId: string; dms: DMItem[]; } + +export interface DMResponseDto { + dmId: string; + participants: User[]; + isGroup: boolean; + messages: Record; +} diff --git a/frontend/src/apis/dm/index.ts b/frontend/src/apis/dm/index.ts index 3d92e85..b85d0ea 100644 --- a/frontend/src/apis/dm/index.ts +++ b/frontend/src/apis/dm/index.ts @@ -1,7 +1,12 @@ -import { DMListResponseDto } from '@/apis/dm/dto'; +import { DMListResponseDto, DMResponseDto } from '@/apis/dm/dto'; import https from '@/lib/https'; export const getDMList = async (): Promise => { const { data } = await https.get('/api/dms'); return data; }; + +export const getDMMessage = async (dmId: string): Promise => { + const { data } = await https.get(`api/dms/${dmId}`); + return data; +}; diff --git a/frontend/src/components/dm/DMContent.tsx b/frontend/src/components/dm/DMContent.tsx new file mode 100644 index 0000000..7b9e858 --- /dev/null +++ b/frontend/src/components/dm/DMContent.tsx @@ -0,0 +1,40 @@ +import { useParams } from 'react-router'; +import Message from '../common/Message'; +import DMInfo from './DMInfo'; +import { useGetDMMessages } from '@/hooks/dm/useGetDMMessages'; +import DateBadge from '../common/DateBadge'; + +const DMContent = () => { + const { dmId } = useParams(); + const { data, isLoading, isError } = useGetDMMessages(dmId!); + + if (isLoading) return

로딩중입니다.

; + if (isError) return

에러

; + + return ( +
+ {data && data?.participants.length > 0 && ( + + )} + {data?.messages ? ( + Object.entries(data.messages).map(([date, messages]) => ( +
+ + {messages.map(msg => ( + + ))} +
+ )) + ) : ( +

메시지 없음

+ )} +
+ ); +}; + +export default DMContent; diff --git a/frontend/src/components/dm/sideBar/DMList.tsx b/frontend/src/components/dm/sideBar/DMList.tsx index 5adc1ee..3415c8b 100644 --- a/frontend/src/components/dm/sideBar/DMList.tsx +++ b/frontend/src/components/dm/sideBar/DMList.tsx @@ -1,41 +1,41 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; -import { User } from '@/types/user'; +import { DMItem } from '@/types/dm'; +import clsx from 'clsx'; +import { useNavigate, useParams } from 'react-router'; -interface DMListProps { - participants: User; - senderId: string; - content: string; - createdAt: string; - unreadCount: number; -} +//@TODO 단체 채팅일 경우 고려해야함 -const DMList = ({ - participants, - senderId, - content, - createdAt, - unreadCount, -}: DMListProps) => { - const date = new Date(createdAt); +const DMList = ({ dmId, participants, lastMessage, unreadCount }: DMItem) => { + const date = new Date(lastMessage.createdAt); + const { workspaceId, dmId: currentDMId } = useParams(); + const navigate = useNavigate(); const month = date.getMonth() + 1; const day = date.getDate(); return ( -
- +
{ + navigate(`/workspace/${workspaceId}/dm/${dmId}`); + }} + > + - {participants.username} + {participants[0].username}
-
+
- {participants.displayName} + {participants[0].displayName} -
+

{`${month}월 ${day}일`}

{unreadCount > 0 && (
@@ -45,7 +45,9 @@ const DMList = ({

- {participants.userId === senderId ? `나 : ${content}` : content} + {participants[0].userId === lastMessage.senderId + ? `나 : ${lastMessage.content}` + : lastMessage.content}

diff --git a/frontend/src/components/dm/sideBar/SideBar.tsx b/frontend/src/components/dm/sideBar/SideBar.tsx index 90e4116..3a8af2c 100644 --- a/frontend/src/components/dm/sideBar/SideBar.tsx +++ b/frontend/src/components/dm/sideBar/SideBar.tsx @@ -1,44 +1,20 @@ +import { useParams } from 'react-router'; import DMList from './DMList'; import SideBarHeader from './SideBarHeader'; - -//여기는 나중에 API 연결하면 바뀔 부분! -const DM_DATA = [ - { - participants: { - userId: '1', - username: '안연아', - displayName: '안연아(웹FE)', - profileImage: 'https://github.com/shadcn.png', - isActive: true, - }, - senderId: '1', - content: '안녕하세요! 채팅 테스트입니다.', - createdAt: '2025-01-25T12:34:56Z', - unreadCount: 0, - }, - { - participants: { - userId: '1', - username: '안연아', - displayName: '안연아(웹FE)', - profileImage: 'https://github.com/shadcn.png', - isActive: true, - }, - senderId: '3', - content: '안녕하세요! 채팅 테스트입니다.', - createdAt: '2025-01-25T12:34:56Z', - unreadCount: 2, - }, -]; +import useGetDMListQuery from '@/hooks/dm/useGetDMListQuery'; const SideBar = () => { + const { workspaceId } = useParams(); + const { data, isLoading, isError } = useGetDMListQuery(workspaceId!); + + if (isLoading) return

로딩중입니다.

; + if (isError) return

로딩중입니다.

; + return ( -
+
- {DM_DATA.map((dm, index) => ( - - ))} + {data?.dms.map((dm, index) => )}
); diff --git a/frontend/src/components/frame/workspace/MainNavigationSidebar.tsx b/frontend/src/components/frame/workspace/MainNavigationSidebar.tsx index b6cf13c..d703951 100644 --- a/frontend/src/components/frame/workspace/MainNavigationSidebar.tsx +++ b/frontend/src/components/frame/workspace/MainNavigationSidebar.tsx @@ -10,7 +10,7 @@ const MainNavigationSidebar = () => { const { channelList } = useWorkspaceChannelListQuery(workspaceId!); return ( -
+
{icons.map((item, index) => { return ( { } } if (item.type === 'DM') { - navigate(`/workspace/${workspaceId}/dm`); + navigate(`/workspace/${workspaceId}/dm/1`); } if (item.type === 'ETC') console.log('더보기 클릭'); }} diff --git a/frontend/src/components/workspace/WorkspaceChannelPanel/WorkspaceDMs.tsx b/frontend/src/components/workspace/WorkspaceChannelPanel/WorkspaceDMs.tsx index 179c989..e9f3769 100644 --- a/frontend/src/components/workspace/WorkspaceChannelPanel/WorkspaceDMs.tsx +++ b/frontend/src/components/workspace/WorkspaceChannelPanel/WorkspaceDMs.tsx @@ -1,7 +1,7 @@ -import { DMItem } from '@/apis/dm/dto'; import { Button } from '@/components/ui/button'; import WorkspaceAccordionSection from '@/components/workspace/WorkspaceAccordionList'; import WorkspaceDirectMessageListItem from '@/components/workspace/WorkspaceChannelPanel/WorkspaceDirectMessageListItem'; +import { DMItem } from '@/types/dm'; import { MdOutlineAddBox } from 'react-icons/md'; interface WorkspaceDMsProps { @@ -16,7 +16,7 @@ const WorkspaceDMs = ({ dmList, onAddColleauge }: WorkspaceDMsProps) => { ))}