From ac3c285c2ce76697449a39315645fa7cfd361b4f Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sat, 16 Dec 2023 23:12:52 +0900 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20message=20list=20query=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/apis.ts | 5 +++++ src/apis/message/index.ts | 2 ++ src/apis/message/queries.ts | 8 ++++++++ src/apis/message/types.ts | 20 ++++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 src/apis/message/apis.ts create mode 100644 src/apis/message/index.ts create mode 100644 src/apis/message/queries.ts create mode 100644 src/apis/message/types.ts diff --git a/src/apis/message/apis.ts b/src/apis/message/apis.ts new file mode 100644 index 00000000..e15d92c2 --- /dev/null +++ b/src/apis/message/apis.ts @@ -0,0 +1,5 @@ +import type { GetMessageListReq, GetMessageListRes } from './types' +import { http } from '@utils/http' + +export const getMessageList = (params: GetMessageListReq) => + http.get('/msgrooms', params) diff --git a/src/apis/message/index.ts b/src/apis/message/index.ts new file mode 100644 index 00000000..d2186f10 --- /dev/null +++ b/src/apis/message/index.ts @@ -0,0 +1,2 @@ +export * from './types' +export * from './queries' diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts new file mode 100644 index 00000000..b72e64ba --- /dev/null +++ b/src/apis/message/queries.ts @@ -0,0 +1,8 @@ +import { useQuery } from '@tanstack/react-query' +import { getMessageList } from './apis' + +export const useGetMessageList = (page?: number) => + useQuery({ + queryKey: ['getMessageList'], + queryFn: () => getMessageList({ page: page || 0 }) + }) diff --git a/src/apis/message/types.ts b/src/apis/message/types.ts new file mode 100644 index 00000000..f30f14e2 --- /dev/null +++ b/src/apis/message/types.ts @@ -0,0 +1,20 @@ +export type GetMessageListReq = { + page: number +} + +export type GetMessageListRes = { + id: number + partner: { + id: number + imageUrl: string + nickname: string + } + post: { + id: number + title: string + } + offerPrice: number + lastContent: string + notReadCnt: number + lastSendTime: string +}[] From 45a1d42dad0713a8b60ea88b2315e74648f874ba Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sat, 16 Dec 2023 23:13:24 +0900 Subject: [PATCH 02/20] =?UTF-8?q?feat:=20message=20list=20api=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MessagePreview/MessagePreview.stories.tsx | 20 +- .../messagebox/MessagePreview/index.tsx | 35 ++-- .../messagebox/MessagePreview/types.ts | 18 +- src/pages/messagebox/index.tsx | 189 ++---------------- 4 files changed, 48 insertions(+), 214 deletions(-) diff --git a/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx b/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx index 82f84d9e..f9cca234 100644 --- a/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx +++ b/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx @@ -12,20 +12,20 @@ export default meta export const Default: StoryObj = { args: { - userInfo: { + partner: { id: 1, nickname: 'offerer', - profileImageUrl: null + imageUrl: '' }, - productInfo: { - price: 123346, - productImageUrl: null + post: { + title: '구매해요', + imageUrl: '' }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } + offerPrice: 123, + lastContent: + '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', + lastSendTime: '2시간 전', + notReadCnt: 0 }, render: args => } diff --git a/src/components/messagebox/MessagePreview/index.tsx b/src/components/messagebox/MessagePreview/index.tsx index f291cb00..36577201 100644 --- a/src/components/messagebox/MessagePreview/index.tsx +++ b/src/components/messagebox/MessagePreview/index.tsx @@ -7,9 +7,12 @@ import { toLocaleCurrency } from '@utils' export const MessagePreview = ({ id, - userInfo, - productInfo, - latestTalk, + partner, + post, + offerPrice, + lastContent, + lastSendTime, + notReadCnt, isSelected = false, onClick }: MessagePreviewProps): ReactElement => { @@ -23,31 +26,27 @@ export const MessagePreview = ({ role="button" onClick={handleClickPreview}> - + - {userInfo.nickname} - {latestTalk.createdDate} - {latestTalk.content} + {partner.nickname} + {lastSendTime} + {lastContent} - - 6 - - {`${toLocaleCurrency( - productInfo.price - )}원`} + {notReadCnt && ( + + {notReadCnt} + + )} + {`${toLocaleCurrency(offerPrice)}원`} product diff --git a/src/components/messagebox/MessagePreview/types.ts b/src/components/messagebox/MessagePreview/types.ts index 795a135c..8481c663 100644 --- a/src/components/messagebox/MessagePreview/types.ts +++ b/src/components/messagebox/MessagePreview/types.ts @@ -1,18 +1,18 @@ export type MessagePreviewProps = { id: number - userInfo: { + partner: { id: number nickname: string - profileImageUrl: string | null + imageUrl: string } - productInfo: { - price: number - productImageUrl: string | null - } - latestTalk: { - content: string - createdDate: string + post: { + title: string + imageUrl?: string } + offerPrice: number + lastContent: string + lastSendTime: string isSelected?: boolean + notReadCnt: number onClick?(id: number): void } diff --git a/src/pages/messagebox/index.tsx b/src/pages/messagebox/index.tsx index 5052d2d4..c0d5210e 100644 --- a/src/pages/messagebox/index.tsx +++ b/src/pages/messagebox/index.tsx @@ -2,6 +2,7 @@ import { css } from '@emotion/react' import styled from '@emotion/styled' import { Modal, useMedia } from '@offer-ui/react' import { useState, type ReactElement, useEffect } from 'react' +import { useGetMessageList } from '@apis/message' import useModal from '@hooks/useModal' import { MessagePreview, @@ -24,10 +25,13 @@ const TabKeys = Object.keys(TABS) as TabType[] const TabEntries = Object.entries(TABS) const MessageBoxPage = (): ReactElement => { + const getMessageListQuery = useGetMessageList() const [tab, setTab] = useState('all') const [roomId, setRoomId] = useState(null) const { isOpen, openModal, closeModal } = useModal() const { desktop, mobile, tablet } = useMedia() + const messageList = getMessageListQuery.data || [] + const messageCount = messageList.length const handleChangeTab = (currentIndex: number, nextIndex: number) => { const nextTab = TabKeys[nextIndex] @@ -62,7 +66,7 @@ const MessageBoxPage = (): ReactElement => { - 내 쪽지함 {LIST_MOCK.length} + 내 쪽지함 {messageCount}
@@ -77,14 +81,18 @@ const MessageBoxPage = (): ReactElement => {
- {LIST_MOCK.length > 0 ? ( - LIST_MOCK.map(({ id, ...messageInfo }) => ( + {messageCount > 0 ? ( + messageList.map(({ id, post, ...resInfo }) => ( )) ) : ( @@ -248,177 +256,4 @@ const DetailContainer = styled.div` `} ` -const LIST_MOCK = [ - { - id: 1, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 2, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 3, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 4, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 5, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 6, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 7, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 8, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 9, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - }, - { - id: 10, - userInfo: { - id: 1, - nickname: 'offerer', - profileImageUrl: null - }, - productInfo: { - price: 123346, - productImageUrl: null - }, - latestTalk: { - content: - '구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ? 구매 가능 할까요 ?', - createdDate: '2시간 전' - } - } -] - export default MessageBoxPage From feb4077bf181a6912255c98efdfb5cebd8865920 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sat, 16 Dec 2023 23:56:47 +0900 Subject: [PATCH 03/20] =?UTF-8?q?feat:=20message=20=EB=82=B4=EC=9A=A9=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20query=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/apis.ts | 13 ++++++++++++- src/apis/message/queries.ts | 19 +++++++++++++++++-- src/apis/message/types.ts | 15 +++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/apis/message/apis.ts b/src/apis/message/apis.ts index e15d92c2..3fa01209 100644 --- a/src/apis/message/apis.ts +++ b/src/apis/message/apis.ts @@ -1,5 +1,16 @@ -import type { GetMessageListReq, GetMessageListRes } from './types' +import type { + GetMessageListReq, + GetMessageListRes, + GetMessageRoomReq, + GetMessageRoomRes +} from './types' import { http } from '@utils/http' export const getMessageList = (params: GetMessageListReq) => http.get('/msgrooms', params) + +export const getMessageRoom = (params: GetMessageRoomReq) => + http.get( + `/msgrooms/${params.msgRoomId}/msgs`, + params + ) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index b72e64ba..c48a55cf 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -1,8 +1,23 @@ import { useQuery } from '@tanstack/react-query' -import { getMessageList } from './apis' +import { getMessageList, getMessageRoom } from './apis' +import type { GetMessageRoomReq } from './types' -export const useGetMessageList = (page?: number) => +export const useGetMessageListQuery = (page?: number) => useQuery({ queryKey: ['getMessageList'], queryFn: () => getMessageList({ page: page || 0 }) }) + +export const useGetMessageRoomQuery = ({ + msgRoomId, + ...res +}: GetMessageRoomReq) => + useQuery({ + queryKey: ['getMessageRoom', msgRoomId], + queryFn: () => + getMessageRoom({ + msgRoomId, + ...res + }), + enabled: Boolean(msgRoomId) + }) diff --git a/src/apis/message/types.ts b/src/apis/message/types.ts index f30f14e2..baac7e39 100644 --- a/src/apis/message/types.ts +++ b/src/apis/message/types.ts @@ -18,3 +18,18 @@ export type GetMessageListRes = { notReadCnt: number lastSendTime: string }[] + +export type GetMessageRoomReq = { + msgRoomId: number | null + page: number +} + +export type GetMessageRoomRes = { + content: string + member: { + id: number + imageUrl: string + nickname: string + } + sendTime: string +}[] From 365321e043e6879a33cc98413f95a35130c14583 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sun, 17 Dec 2023 00:00:13 +0900 Subject: [PATCH 04/20] =?UTF-8?q?feat:=20message=20=EB=82=B4=EC=9A=A9=20ap?= =?UTF-8?q?i=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../messagebox/Chatting/Chatting.stories.tsx | 71 +++++++++------- src/components/messagebox/Chatting/index.tsx | 26 +++--- src/components/messagebox/Chatting/types.ts | 10 ++- .../messagebox/ChattingRoom/index.tsx | 80 +++---------------- src/pages/messagebox/index.tsx | 4 +- 5 files changed, 73 insertions(+), 118 deletions(-) diff --git a/src/components/messagebox/Chatting/Chatting.stories.tsx b/src/components/messagebox/Chatting/Chatting.stories.tsx index 2aadcf1d..bea0fe67 100644 --- a/src/components/messagebox/Chatting/Chatting.stories.tsx +++ b/src/components/messagebox/Chatting/Chatting.stories.tsx @@ -12,61 +12,74 @@ export default meta const MESSAGES_MOCK = [ { - id: 10, content: 'offer 쪽지1', - receiverId: 1, - senderId: 2, - createdDate: '2021-11-11T00:12:43' + member: { + id: 1, + nickname: '주영', + imageUrl: '' + }, + sendTime: '2021-11-11T00:12:43' }, { - id: 8, content: 'offer 쪽지2', - receiverId: 1, - senderId: 2, - createdDate: '2021-12-15T00:13:49' + member: { + id: 2, + nickname: '수림', + imageUrl: '' + }, + sendTime: '2021-12-15T00:13:49' }, { - id: 6, content: ' offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3', - receiverId: 1, - senderId: 2, - createdDate: '2021-12-15T00:25:31' + member: { + id: 1, + nickname: '주영', + imageUrl: '' + }, + sendTime: '2021-12-15T00:25:31' }, { - id: 61, content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' + member: { + id: 2, + nickname: '수림', + imageUrl: '' + }, + sendTime: '2021-12-15T01:45:41' }, { - id: 62, content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' + member: { + id: 1, + nickname: '주영', + imageUrl: '' + }, + sendTime: '2021-12-15T01:45:41' }, { - id: 63, content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' + member: { + id: 1, + nickname: '주영', + imageUrl: '' + }, + sendTime: '2021-12-15T01:45:41' }, { - id: 64, content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' + member: { + id: 1, + nickname: '주영', + imageUrl: '' + }, + sendTime: '2021-12-15T01:45:41' } ] export const Default: StoryObj = { args: { userId: 1, - receiverImageUrl: 'https://picsum.photos/id/237/200/300', messages: MESSAGES_MOCK }, render: args => diff --git a/src/components/messagebox/Chatting/index.tsx b/src/components/messagebox/Chatting/index.tsx index d0d71969..85c6944e 100644 --- a/src/components/messagebox/Chatting/index.tsx +++ b/src/components/messagebox/Chatting/index.tsx @@ -4,7 +4,7 @@ import { Styled } from './styled' import type { ChattingProps } from './types' import { formatDate } from '@utils/format' -export const getDate = (createdDate = '') => createdDate.split('T')[0] +export const getDate = (sendTime = '') => sendTime.split('T')[0] // TODO: 상품 정보 버블 추가 export const Chatting = ({ @@ -14,30 +14,32 @@ export const Chatting = ({ }: ChattingProps) => { return ( - {messages.map(({ id, content, senderId, createdDate }, idx, list) => { + {messages.map(({ content, member, sendTime }, idx, list) => { const prevMessage = list.at(idx - 1) const nextMessage = list.at(idx + 1) - const isSender = senderId === userId + const isSender = member.id === userId - const currentDate = getDate(createdDate) - const prevDate = getDate(prevMessage?.createdDate) - const nextDate = getDate(nextMessage?.createdDate) + const currentDate = getDate(sendTime) + const prevDate = getDate(prevMessage?.sendTime) + const nextDate = getDate(nextMessage?.sendTime) const isPrevDateChanged = prevDate !== currentDate const isNextDateChanged = nextDate !== currentDate const commonProps = { - time: formatDate(createdDate, 'A H:m'), + time: formatDate(sendTime, 'A H:m'), isSectionStart: - senderId !== prevMessage?.senderId || isPrevDateChanged, - isSectionLast: senderId !== nextMessage?.senderId || isNextDateChanged + member.id !== prevMessage?.member.id || isPrevDateChanged, + isSectionLast: + member.id !== nextMessage?.member.id || isNextDateChanged } return ( -
+ // TODO: 메세지 키값 내려줄 수 있는지 확인하기 +
{isPrevDateChanged && ( - + - {formatDate(createdDate, 'YYYY년 M월 D일 dddd')} + {formatDate(sendTime, 'YYYY년 M월 D일 dddd')} )} diff --git a/src/components/messagebox/Chatting/types.ts b/src/components/messagebox/Chatting/types.ts index b365937d..918ee4b3 100644 --- a/src/components/messagebox/Chatting/types.ts +++ b/src/components/messagebox/Chatting/types.ts @@ -1,9 +1,11 @@ type Message = { - id: number + member: { + id: number + nickname: string + imageUrl: string + } content: string - receiverId: number - senderId: number - createdDate: string + sendTime: string } export type SendProps = { diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index e396010f..ef61ec20 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -2,10 +2,16 @@ import { Image, IconButton, Input } from '@offer-ui/react' import { Styled } from './styled' import type { ChattingRoomProps } from './types' import { Chatting } from '../Chatting' +import { useGetMessageRoomQuery } from '@apis/message' +import { useAuth } from '@hooks/useAuth' import { toLocaleCurrency } from '@utils/format' export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - // TODO: ChattingRoom Id를 통해서 컴포넌트 내부에서 패치하도록 + const getMessageRoomQuery = useGetMessageRoomQuery({ + msgRoomId: id, + page: 0 + }) + const { user } = useAuth() const handleCloseRoom = () => { onClose?.(id) @@ -15,7 +21,7 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - 황금 효정 + {user.nickname} @@ -36,7 +42,7 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - + @@ -44,71 +50,3 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { ) } - -const MESSAGES_MOCK = [ - { - id: 10, - content: 'offer 쪽지1', - receiverId: 1, - senderId: 2, - createdDate: '2021-11-11T00:12:43' - }, - { - id: 8, - content: 'offer 쪽지2', - receiverId: 1, - senderId: 2, - createdDate: '2021-12-15T00:13:49' - }, - { - id: 6, - content: - ' offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3', - receiverId: 1, - senderId: 2, - createdDate: '2021-12-15T00:25:31' - }, - { - id: 61, - content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' - }, - { - id: 62, - content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' - }, - { - id: 63, - content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' - }, - { - id: 64, - content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' - }, - { - id: 612, - content: - 'offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3 offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' - }, - { - id: 699, - content: 'offer 쪽지3', - receiverId: 2, - senderId: 1, - createdDate: '2021-12-15T01:45:41' - } -] diff --git a/src/pages/messagebox/index.tsx b/src/pages/messagebox/index.tsx index c0d5210e..fea71d1e 100644 --- a/src/pages/messagebox/index.tsx +++ b/src/pages/messagebox/index.tsx @@ -2,7 +2,7 @@ import { css } from '@emotion/react' import styled from '@emotion/styled' import { Modal, useMedia } from '@offer-ui/react' import { useState, type ReactElement, useEffect } from 'react' -import { useGetMessageList } from '@apis/message' +import { useGetMessageListQuery } from '@apis/message' import useModal from '@hooks/useModal' import { MessagePreview, @@ -25,7 +25,7 @@ const TabKeys = Object.keys(TABS) as TabType[] const TabEntries = Object.entries(TABS) const MessageBoxPage = (): ReactElement => { - const getMessageListQuery = useGetMessageList() + const getMessageListQuery = useGetMessageListQuery() const [tab, setTab] = useState('all') const [roomId, setRoomId] = useState(null) const { isOpen, openModal, closeModal } = useModal() From bb8073349533b9d1dc899343de6149a16421e7d8 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 14:57:27 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20roomId=EA=B0=80=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=ED=95=B4=EB=8B=B9=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=EB=A3=B8=20=EC=97=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../messagebox/ChattingRoom/index.tsx | 25 +++++++++-- .../MessagePreview/MessagePreview.stories.tsx | 2 +- .../messagebox/MessagePreview/index.tsx | 4 +- .../messagebox/MessagePreview/types.ts | 2 +- src/pages/messagebox/index.tsx | 45 +++++++++++++++---- src/types/scheme.ts | 3 +- 6 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index eea04cbf..f1fc0238 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -6,6 +6,16 @@ import { toLocaleCurrency } from '@utils/format' import { useGetMessageQuery } from '@apis' import { useAuth } from '@hooks' +// TODO: messageRoom 정보조회 api 붙이고 제거 +const POST_MOCK = { + offerPrice: 10000, + post: { + title: '팔아요 !', + thumbnailImageUrl: '', + price: 12000 + } +} + export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { const messageQuery = useGetMessageQuery({ msgRoomId: id, @@ -28,16 +38,23 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - product + {`${POST_MOCK.post.title}-image`} - 마르니 플렛 로퍼(black) + {POST_MOCK.post.title} 시작가 - {toLocaleCurrency(15000)}원 + {toLocaleCurrency(POST_MOCK.post.price)}원 제안가 - {toLocaleCurrency(15000)}원 + + {toLocaleCurrency(POST_MOCK.offerPrice)}원 + diff --git a/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx b/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx index f9cca234..88a1ec2a 100644 --- a/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx +++ b/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx @@ -18,7 +18,7 @@ export const Default: StoryObj = { imageUrl: '' }, post: { - title: '구매해요', + id: 1, imageUrl: '' }, offerPrice: 123, diff --git a/src/components/messagebox/MessagePreview/index.tsx b/src/components/messagebox/MessagePreview/index.tsx index 36577201..1d8c4c25 100644 --- a/src/components/messagebox/MessagePreview/index.tsx +++ b/src/components/messagebox/MessagePreview/index.tsx @@ -3,7 +3,7 @@ import type { ReactElement } from 'react' import { Styled } from './styled' import type { MessagePreviewProps } from './types' import { IMAGE } from '@constants' -import { toLocaleCurrency } from '@utils' +import { getTimeDiffText, toLocaleCurrency } from '@utils' export const MessagePreview = ({ id, @@ -30,7 +30,7 @@ export const MessagePreview = ({ {partner.nickname} - {lastSendTime} + {getTimeDiffText(lastSendTime)} {lastContent} diff --git a/src/components/messagebox/MessagePreview/types.ts b/src/components/messagebox/MessagePreview/types.ts index 8481c663..f7d029b9 100644 --- a/src/components/messagebox/MessagePreview/types.ts +++ b/src/components/messagebox/MessagePreview/types.ts @@ -6,7 +6,7 @@ export type MessagePreviewProps = { imageUrl: string } post: { - title: string + id: number imageUrl?: string } offerPrice: number diff --git a/src/pages/messagebox/index.tsx b/src/pages/messagebox/index.tsx index 511a6d52..6e201ac3 100644 --- a/src/pages/messagebox/index.tsx +++ b/src/pages/messagebox/index.tsx @@ -1,7 +1,10 @@ import { css } from '@emotion/react' import styled from '@emotion/styled' import { Modal, useMedia } from '@offer-ui/react' +import type { GetServerSideProps } from 'next' +import { useRouter } from 'next/router' import { useState, type ReactElement, useEffect } from 'react' +import { toQueryString } from '@utils/format' import { useGetMessageRooms } from '@apis' import { MessagePreview, @@ -14,6 +17,10 @@ import { IMAGE } from '@constants' import { useModal } from '@hooks' type TabType = 'all' | 'buy' | 'sell' +type RoomId = number | null +type Props = { + roomId: RoomId +} const TABS = { all: '전체', @@ -24,10 +31,19 @@ const TABS = { const TabKeys = Object.keys(TABS) as TabType[] const TabEntries = Object.entries>(TABS) -const MessageBoxPage = (): ReactElement => { +export const getServerSideProps: GetServerSideProps = async ({ + query +}) => ({ + props: { + roomId: query.roomId ? Number(query.roomId) : null + } +}) + +const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { const messageRoomsQuery = useGetMessageRooms() const [tab, setTab] = useState('all') - const [roomId, setRoomId] = useState(null) + const [roomId, setRoomId] = useState(defaultRoomId) + const router = useRouter() const { isOpen, openModal, closeModal } = useModal() const { desktop, mobile, tablet } = useMedia() const messageList = messageRoomsQuery.data || [] @@ -42,6 +58,12 @@ const MessageBoxPage = (): ReactElement => { const handleSelectRoom = (id: number) => { setRoomId(id) + router.push( + `/messagebox${toQueryString({ + roomId: String(id) + })}` + ) + if (!desktop) { openModal() } @@ -50,13 +72,23 @@ const MessageBoxPage = (): ReactElement => { const handleCloseRoom = () => { setRoomId(null) + router.push(`/messagebox`) + if (!desktop) { closeModal() } } useEffect(() => { - setRoomId(null) + if (desktop) { + closeModal() + + return + } + + if (roomId) { + openModal() + } }, [desktop, tablet, mobile]) return ( @@ -87,11 +119,8 @@ const MessageBoxPage = (): ReactElement => { key={id} id={id} isSelected={id === roomId} - post={{ - title: post.title, - imageUrl: '' - }} - onClick={handleSelectRoom} + post={post} + onClick={() => handleSelectRoom(id)} {...resInfo} /> )) diff --git a/src/types/scheme.ts b/src/types/scheme.ts index d20dc631..4f7fda45 100644 --- a/src/types/scheme.ts +++ b/src/types/scheme.ts @@ -154,7 +154,8 @@ export type OfferSummary = { export type MessageRoomInfo = { id: number partner: PartnerBrief - post: PostBrief + // dto 변경되면 수정 예정 + post: Pick & { imageUrl: string } offerPrice: number lastContent: string notReadCnt: number From 5903515b8b65ff2af537fae34206e0e1ab145258 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 18:04:51 +0900 Subject: [PATCH 06/20] =?UTF-8?q?feat:=20message=20=EB=B3=B4=EB=82=B4?= =?UTF-8?q?=EA=B8=B0=20api=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/apis.ts | 13 ++++++++++++- src/apis/message/queries.ts | 12 +++++++++--- src/apis/message/types.ts | 1 - 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/apis/message/apis.ts b/src/apis/message/apis.ts index 832700b9..5d440911 100644 --- a/src/apis/message/apis.ts +++ b/src/apis/message/apis.ts @@ -2,7 +2,9 @@ import type { GetMessageRoomsReq, GetMessageRoomsRes, GetMessageReq, - GetMessageRes + GetMessageRes, + CreateMessageReq, + CreateMessageRes } from './types' import { http } from '@utils/http' @@ -14,3 +16,12 @@ export const getMessage = (params: GetMessageReq) => `/msgrooms/${params.msgRoomId}/msgs`, params ) + +export const createMessage = ( + messageRoomId: number, + params: CreateMessageReq +) => + http.post( + `/msgrooms/${messageRoomId}/msgs`, + params + ) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index b9342542..a9e15a11 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -1,6 +1,6 @@ -import { useQuery } from '@tanstack/react-query' -import { getMessageRooms, getMessage } from './apis' -import type { GetMessageReq } from './types' +import { useMutation, useQuery } from '@tanstack/react-query' +import { getMessageRooms, getMessage, createMessage } from './apis' +import type { CreateMessageReq, GetMessageReq } from './types' export const useGetMessageRooms = (page?: number) => useQuery({ @@ -18,3 +18,9 @@ export const useGetMessageQuery = ({ msgRoomId, ...res }: GetMessageReq) => }), enabled: Boolean(msgRoomId) }) + +export const useCreateMessageMutation = (messageRoomId: number) => + useMutation({ + mutationFn: (params: CreateMessageReq) => + createMessage(messageRoomId, params) + }) diff --git a/src/apis/message/types.ts b/src/apis/message/types.ts index 8b54e077..cc1558a5 100644 --- a/src/apis/message/types.ts +++ b/src/apis/message/types.ts @@ -17,7 +17,6 @@ export type GetMessageReq = { export type GetMessageRes = MessageInfo[] export type CreateMessageReq = { - msgRoomId: number content: string } export type CreateMessageRes = CommonCreation From 06e1b5a8ecffaa3984327554cfac8e2899c330d0 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 18:59:19 +0900 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../messagebox/ChattingRoom/index.tsx | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index cd0bcecf..4fee6c56 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -1,9 +1,11 @@ import { Image, IconButton, Input } from '@offer-ui/react' +import { useEffect, useRef, useState } from 'react' import { Styled } from './styled' import type { ChattingRoomProps } from './types' import { Chatting } from '../Chatting' +import type { ChattingProps } from '../Chatting/types' import { toLocaleCurrency } from '@utils/format' -import { useGetMessageQuery } from '@apis' +import { useCreateMessageMutation, useGetMessageQuery } from '@apis' import { useAuth } from '@hooks' // TODO: messageRoom 정보조회 api 붙이고 제거 @@ -17,16 +19,47 @@ const POST_MOCK = { } export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - const messageQuery = useGetMessageQuery({ + const getMessageQuery = useGetMessageQuery({ msgRoomId: id, page: 0 }) + const createMessageMutation = useCreateMessageMutation(id) + const [messages, setMessages] = useState([]) const { user } = useAuth() + const inputRef = useRef(null) + const senderInfo = { + id: user.id, + nickname: user.nickname, + imageUrl: user.profileImageUrl + } const handleCloseRoom = () => { onClose?.(id) } + const handleSubmitMessage = async (message: string) => { + const res = await createMessageMutation.mutateAsync({ + content: message + }) + + setMessages(prev => [ + ...prev, + { + member: senderInfo, + content: message, + sendTime: res.createdAt + } + ]) + + if (inputRef.current) { + inputRef.current.value = '' + } + } + + useEffect(() => { + setMessages(getMessageQuery.data || []) + }, [getMessageQuery.data]) + return ( @@ -59,10 +92,10 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - + - + ) From fbcbd7621c205ecf8a0a53377b4e425485b01915 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 22:51:53 +0900 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EC=8B=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=ED=95=98=EB=8B=A8=EC=97=90=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95,=20=EC=8B=9C=EA=B0=84=20=EB=8B=A4=EB=A5=B8?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=8B=9C=EA=B0=84=20=EB=B3=B4=EC=9D=B4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/messagebox/Chatting/index.tsx | 84 ++++++++++--------- .../messagebox/ChattingRoom/index.tsx | 15 +++- 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/components/messagebox/Chatting/index.tsx b/src/components/messagebox/Chatting/index.tsx index 85c6944e..61ed6db1 100644 --- a/src/components/messagebox/Chatting/index.tsx +++ b/src/components/messagebox/Chatting/index.tsx @@ -5,6 +5,7 @@ import type { ChattingProps } from './types' import { formatDate } from '@utils/format' export const getDate = (sendTime = '') => sendTime.split('T')[0] +export const getTime = (sendTime = '') => formatDate(sendTime, 'A H:m') // TODO: 상품 정보 버블 추가 export const Chatting = ({ @@ -12,47 +13,50 @@ export const Chatting = ({ messages, receiverImageUrl }: ChattingProps) => { - return ( - - {messages.map(({ content, member, sendTime }, idx, list) => { - const prevMessage = list.at(idx - 1) - const nextMessage = list.at(idx + 1) - const isSender = member.id === userId + const renderChattingItem = () => + messages.map(({ content, member, sendTime }, idx, list) => { + const prevMessage = list.at(idx - 1) + const nextMessage = list.at(idx + 1) + const isSender = member.id === userId - const currentDate = getDate(sendTime) - const prevDate = getDate(prevMessage?.sendTime) - const nextDate = getDate(nextMessage?.sendTime) - const isPrevDateChanged = prevDate !== currentDate - const isNextDateChanged = nextDate !== currentDate + const currentDate = getDate(sendTime) + const prevDate = getDate(prevMessage?.sendTime) + const nextDate = getDate(nextMessage?.sendTime) + const isPrevDateChanged = prevDate !== currentDate + const isNextDateChanged = nextDate !== currentDate + const currentTime = getTime(sendTime) + const nextTime = getTime(nextMessage?.sendTime) - const commonProps = { - time: formatDate(sendTime, 'A H:m'), - isSectionStart: - member.id !== prevMessage?.member.id || isPrevDateChanged, - isSectionLast: - member.id !== nextMessage?.member.id || isNextDateChanged - } + const commonProps = { + time: formatDate(sendTime, 'A H:m'), + isSectionStart: + member.id !== prevMessage?.member.id || isPrevDateChanged, + isSectionLast: + member.id !== nextMessage?.member.id || + isNextDateChanged || + currentTime !== nextTime + } - return ( - // TODO: 메세지 키값 내려줄 수 있는지 확인하기 -
- {isPrevDateChanged && ( - - - {formatDate(sendTime, 'YYYY년 M월 D일 dddd')} - - - )} - {isSender ? ( - {content} - ) : ( - - {content} - - )} -
- ) - })} -
- ) + return ( + // TODO: 메세지 키값 내려줄 수 있는지 확인하기 +
+ {isPrevDateChanged && ( + + + {formatDate(sendTime, 'YYYY년 M월 D일 dddd')} + + + )} + {isSender ? ( + {content} + ) : ( + + {content} + + )} +
+ ) + }) + + return {renderChattingItem()} } diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index 4fee6c56..318f59f8 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -25,14 +25,21 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { }) const createMessageMutation = useCreateMessageMutation(id) const [messages, setMessages] = useState([]) - const { user } = useAuth() + const chattingBoxRef = useRef(null) const inputRef = useRef(null) + const { user } = useAuth() const senderInfo = { id: user.id, nickname: user.nickname, imageUrl: user.profileImageUrl } + const scrollToBottom = () => { + if (chattingBoxRef.current) { + chattingBoxRef.current.scrollTop = chattingBoxRef.current.scrollHeight + } + } + const handleCloseRoom = () => { onClose?.(id) } @@ -60,6 +67,10 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { setMessages(getMessageQuery.data || []) }, [getMessageQuery.data]) + useEffect(() => { + scrollToBottom() + }, [messages]) + return ( @@ -91,7 +102,7 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { - + From 9a8a44db69c4250e6c8184cd83633e89750a2953 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 23:41:06 +0900 Subject: [PATCH 09/20] =?UTF-8?q?feat:=20=EC=AA=BD=EC=A7=80=ED=95=A8=20?= =?UTF-8?q?=EB=82=98=EA=B0=80=EA=B8=B0=20api=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/apis.ts | 3 +++ src/apis/message/queries.ts | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/apis/message/apis.ts b/src/apis/message/apis.ts index 5d440911..a680911a 100644 --- a/src/apis/message/apis.ts +++ b/src/apis/message/apis.ts @@ -25,3 +25,6 @@ export const createMessage = ( `/msgrooms/${messageRoomId}/msgs`, params ) + +export const deleteMessageRoom = (messageRoomId: number) => + http.delete(`/msgrooms/${messageRoomId}`) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index a9e15a11..349bbe60 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -1,5 +1,10 @@ import { useMutation, useQuery } from '@tanstack/react-query' -import { getMessageRooms, getMessage, createMessage } from './apis' +import { + getMessageRooms, + getMessage, + createMessage, + deleteMessageRoom +} from './apis' import type { CreateMessageReq, GetMessageReq } from './types' export const useGetMessageRooms = (page?: number) => @@ -24,3 +29,8 @@ export const useCreateMessageMutation = (messageRoomId: number) => mutationFn: (params: CreateMessageReq) => createMessage(messageRoomId, params) }) + +export const useDeleteMessageRoomMutation = (messageRoomId: number) => + useMutation({ + mutationFn: () => deleteMessageRoom(messageRoomId) + }) From 847db70deea47aae001576e2f6994b2fecc4297b Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 23:52:44 +0900 Subject: [PATCH 10/20] =?UTF-8?q?feat:=20Sidebar=20=EC=AA=BD=EC=A7=80?= =?UTF-8?q?=ED=95=A8=20=EB=A7=81=ED=81=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Header/SideBar/index.tsx | 25 ++++++++++++------- .../common/Header/SideBar/styled.ts | 2 ++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/common/Header/SideBar/index.tsx b/src/components/common/Header/SideBar/index.tsx index 11ec4478..49e3f681 100644 --- a/src/components/common/Header/SideBar/index.tsx +++ b/src/components/common/Header/SideBar/index.tsx @@ -1,5 +1,4 @@ import { Avatar, Divider, Icon, Badge } from '@offer-ui/react' -import Link from 'next/link' import { useRouter } from 'next/router' import type { ReactElement } from 'react' import React from 'react' @@ -21,7 +20,7 @@ const NAV_DATA: NavDataType = [ }, { content: '쪽지함', - url: '/message', + url: '/messagebox', iconType: 'message' } ] @@ -32,11 +31,19 @@ export const SideBar = ({ isOpen, onClose }: SideBarProps): ReactElement => { const handleClickLogin = () => { router.replace(OAUTH_URL.KAKAO) + + onClose() + } + + const handleClickButton = (url: string) => { + router.push(url) + onClose() } const handleClickLogout = () => { handleLogout() + onClose() } @@ -64,14 +71,14 @@ export const SideBar = ({ isOpen, onClose }: SideBarProps): ReactElement => { )} - {NAV_DATA.map((item, index) => { + {NAV_DATA.map(({ iconType, content, url }) => { return ( - - - - {item.content} - - + handleClickButton(url)}> + + {content} + ) })} diff --git a/src/components/common/Header/SideBar/styled.ts b/src/components/common/Header/SideBar/styled.ts index 660cce07..d6f22879 100644 --- a/src/components/common/Header/SideBar/styled.ts +++ b/src/components/common/Header/SideBar/styled.ts @@ -78,6 +78,8 @@ const SidebarMenu = styled.li` align-items: center; ${({ theme }): string => theme.fonts.body01B}; color: ${({ theme }): string => theme.colors.grayScale90}; + + cursor: pointer; ` const SidebarLogoutButton = styled.button` From e5e5f498be6422d554367911b5c8b07e729aa224 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 23:55:35 +0900 Subject: [PATCH 11/20] =?UTF-8?q?feat:=20=EC=AA=BD=EC=A7=80=ED=95=A8=20?= =?UTF-8?q?=EB=82=98=EA=B0=80=EA=B8=B0=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChattingRoom/ChattingRoom.stories.tsx | 2 +- .../messagebox/ChattingRoom/index.tsx | 44 +++++++++++++++---- .../messagebox/ChattingRoom/styled.ts | 14 ++++++ .../messagebox/ChattingRoom/types.ts | 2 +- src/pages/messagebox/index.tsx | 9 ++-- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/components/messagebox/ChattingRoom/ChattingRoom.stories.tsx b/src/components/messagebox/ChattingRoom/ChattingRoom.stories.tsx index f8f53e50..24acc76c 100644 --- a/src/components/messagebox/ChattingRoom/ChattingRoom.stories.tsx +++ b/src/components/messagebox/ChattingRoom/ChattingRoom.stories.tsx @@ -11,6 +11,6 @@ const meta: Meta = { export default meta export const Default: StoryObj = { - args: { id: 1 }, + args: { roomId: 1 }, render: args => } diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index 318f59f8..c473875e 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -4,9 +4,14 @@ import { Styled } from './styled' import type { ChattingRoomProps } from './types' import { Chatting } from '../Chatting' import type { ChattingProps } from '../Chatting/types' +import { Dialog } from '@components/common' import { toLocaleCurrency } from '@utils/format' -import { useCreateMessageMutation, useGetMessageQuery } from '@apis' -import { useAuth } from '@hooks' +import { + useCreateMessageMutation, + useDeleteMessageRoomMutation, + useGetMessageQuery +} from '@apis' +import { useAuth, useModal } from '@hooks' // TODO: messageRoom 정보조회 api 붙이고 제거 const POST_MOCK = { @@ -18,15 +23,17 @@ const POST_MOCK = { } } -export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { +export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { const getMessageQuery = useGetMessageQuery({ - msgRoomId: id, + msgRoomId: roomId, page: 0 }) - const createMessageMutation = useCreateMessageMutation(id) + const createMessageMutation = useCreateMessageMutation(roomId) + const deleteMessageRoomMutation = useDeleteMessageRoomMutation(roomId) const [messages, setMessages] = useState([]) const chattingBoxRef = useRef(null) const inputRef = useRef(null) + const { isOpen, openModal, closeModal } = useModal() const { user } = useAuth() const senderInfo = { id: user.id, @@ -36,12 +43,19 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { const scrollToBottom = () => { if (chattingBoxRef.current) { - chattingBoxRef.current.scrollTop = chattingBoxRef.current.scrollHeight + chattingBoxRef.current.scrollTop = + chattingBoxRef.current.scrollHeight + 40 } } const handleCloseRoom = () => { - onClose?.(id) + onClose?.(roomId) + } + + const handleDeleteRoom = async () => { + await deleteMessageRoomMutation.mutateAsync() + + handleCloseRoom() } const handleSubmitMessage = async (message: string) => { @@ -78,7 +92,21 @@ export const ChattingRoom = ({ id, onClose }: ChattingRoomProps) => { {user.nickname} - + + + {isOpen && ( + + + 쪽지함 나가기 + + + )} + diff --git a/src/components/messagebox/ChattingRoom/styled.ts b/src/components/messagebox/ChattingRoom/styled.ts index 60bf7e83..f1cf228c 100644 --- a/src/components/messagebox/ChattingRoom/styled.ts +++ b/src/components/messagebox/ChattingRoom/styled.ts @@ -34,6 +34,18 @@ const IconButtonContainer = styled.div` gap: 20px; ` +const MoreButtonWrapper = styled.div` + position: relative; +` + +const DeleteButton = styled.button` + border: none; + + background-color: transparent; + + cursor: pointer; +` + const ProductInfo = styled.div` display: flex; gap: 8px; @@ -106,6 +118,8 @@ export const Styled = { Header, Nickname, IconButtonContainer, + MoreButtonWrapper, + DeleteButton, ProductInfo, ProductTextContainer, ProductName, diff --git a/src/components/messagebox/ChattingRoom/types.ts b/src/components/messagebox/ChattingRoom/types.ts index 9080221b..a059f55c 100644 --- a/src/components/messagebox/ChattingRoom/types.ts +++ b/src/components/messagebox/ChattingRoom/types.ts @@ -1,4 +1,4 @@ export type ChattingRoomProps = { - id: number + roomId: number onClose?(id: number): void } diff --git a/src/pages/messagebox/index.tsx b/src/pages/messagebox/index.tsx index 6e201ac3..ec9c7dad 100644 --- a/src/pages/messagebox/index.tsx +++ b/src/pages/messagebox/index.tsx @@ -40,13 +40,13 @@ export const getServerSideProps: GetServerSideProps = async ({ }) const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { - const messageRoomsQuery = useGetMessageRooms() + const getMessageRoomsQuery = useGetMessageRooms() const [tab, setTab] = useState('all') const [roomId, setRoomId] = useState(defaultRoomId) const router = useRouter() const { isOpen, openModal, closeModal } = useModal() const { desktop, mobile, tablet } = useMedia() - const messageList = messageRoomsQuery.data || [] + const messageList = getMessageRoomsQuery.data || [] const messageCount = messageList.length const handleChangeTab = (currentIndex: number, nextIndex: number) => { @@ -72,6 +72,7 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { const handleCloseRoom = () => { setRoomId(null) + getMessageRoomsQuery.refetch() router.push(`/messagebox`) if (!desktop) { @@ -138,7 +139,7 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { {roomId ? ( - + ) : ( { {roomId && ( - + )} From 51c21e2c18c7c6f8a4a840d718be0bc7f1ab6edb Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Tue, 9 Jan 2024 23:58:00 +0900 Subject: [PATCH 12/20] =?UTF-8?q?feat:=20=EC=AA=BD=EC=A7=80=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20refresh=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/messagebox/ChattingRoom/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index c473875e..edf80a50 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -58,6 +58,10 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { handleCloseRoom() } + const handleClickRefresh = async () => { + await getMessageQuery.refetch() + } + const handleSubmitMessage = async (message: string) => { const res = await createMessageMutation.mutateAsync({ content: message @@ -91,7 +95,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { {user.nickname} - + {isOpen && ( From 0108540618ba4da0f82ef0ff292ca8158816f93a Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 10 Jan 2024 00:09:29 +0900 Subject: [PATCH 13/20] =?UTF-8?q?design:=20=EC=AA=BD=EC=A7=80=ED=95=A8=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/messagebox/Chatting/index.tsx | 4 ++-- src/utils/format/index.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/messagebox/Chatting/index.tsx b/src/components/messagebox/Chatting/index.tsx index 61ed6db1..0910dee4 100644 --- a/src/components/messagebox/Chatting/index.tsx +++ b/src/components/messagebox/Chatting/index.tsx @@ -5,7 +5,7 @@ import type { ChattingProps } from './types' import { formatDate } from '@utils/format' export const getDate = (sendTime = '') => sendTime.split('T')[0] -export const getTime = (sendTime = '') => formatDate(sendTime, 'A H:m') +export const getTime = (sendTime = '') => formatDate(sendTime, 'A H:mm') // TODO: 상품 정보 버블 추가 export const Chatting = ({ @@ -28,7 +28,7 @@ export const Chatting = ({ const nextTime = getTime(nextMessage?.sendTime) const commonProps = { - time: formatDate(sendTime, 'A H:m'), + time: formatDate(sendTime, 'A H:mm'), isSectionStart: member.id !== prevMessage?.member.id || isPrevDateChanged, isSectionLast: diff --git a/src/utils/format/index.ts b/src/utils/format/index.ts index 9279eb2d..3c37b714 100644 --- a/src/utils/format/index.ts +++ b/src/utils/format/index.ts @@ -5,7 +5,7 @@ dayjs.locale('ko') const DATE_FORMAT = { 'YYYY년 M월 D일 dddd': 'YYYY년 M월 D일 dddd', - 'A H:m': 'A H:m' + 'A H:mm': 'A H:mm' } export const formatDate = ( From fdb7333e01ffa11c2b5e34f05214ab47d1c404a5 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 10 Jan 2024 19:37:10 +0900 Subject: [PATCH 14/20] =?UTF-8?q?feat:=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20sort=20=ED=95=AD=EB=AA=A9=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/queries.ts | 10 +++++++--- src/apis/message/types.ts | 8 +++++++- src/constants/app.ts | 12 ++++++++++++ src/pages/messagebox/index.tsx | 30 ++++++++++++------------------ src/types/service.ts | 9 ++++++++- 5 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index 349bbe60..a5f11387 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -5,12 +5,16 @@ import { createMessage, deleteMessageRoom } from './apis' -import type { CreateMessageReq, GetMessageReq } from './types' +import type { + CreateMessageReq, + GetMessageReq, + GetMessageRoomsReq +} from './types' -export const useGetMessageRooms = (page?: number) => +export const useGetMessageRooms = (params: GetMessageRoomsReq) => useQuery({ queryKey: ['getMessageRooms'], - queryFn: () => getMessageRooms({ page: page || 0 }) + queryFn: () => getMessageRooms(params) }) export const useGetMessageQuery = ({ msgRoomId, ...res }: GetMessageReq) => diff --git a/src/apis/message/types.ts b/src/apis/message/types.ts index cc1558a5..1a65f1bf 100644 --- a/src/apis/message/types.ts +++ b/src/apis/message/types.ts @@ -1,6 +1,12 @@ -import type { CommonCreation, MessageRoomInfo, MessageInfo } from '@types' +import type { + CommonCreation, + MessageRoomInfo, + MessageInfo, + MessageSortTypeCodes +} from '@types' export type GetMessageRoomsReq = { + sort: MessageSortTypeCodes page: number } export type GetMessageRoomsRes = MessageRoomInfo[] diff --git a/src/constants/app.ts b/src/constants/app.ts index 875fccc1..f69922df 100644 --- a/src/constants/app.ts +++ b/src/constants/app.ts @@ -34,6 +34,18 @@ export const TRADE_TYPES = [ } ] as const +export const MESSAGE_SORT_OPTIONS = [ + { code: 'ALL', name: '전체' }, + { + code: 'BUY', + name: '구매' + }, + { + code: 'SELL', + name: '판매' + } +] + export const TRADE_STATUS = [ { code: 'SELLING', diff --git a/src/pages/messagebox/index.tsx b/src/pages/messagebox/index.tsx index ec9c7dad..44c5a677 100644 --- a/src/pages/messagebox/index.tsx +++ b/src/pages/messagebox/index.tsx @@ -13,24 +13,15 @@ import { ChattingRoom, MessageBoxPlaceholder } from '@components' -import { IMAGE } from '@constants' +import { IMAGE, MESSAGE_SORT_OPTIONS } from '@constants' import { useModal } from '@hooks' +import type { MessageSortTypeCodes } from '@types' -type TabType = 'all' | 'buy' | 'sell' type RoomId = number | null type Props = { roomId: RoomId } -const TABS = { - all: '전체', - buy: '구매', - sell: '판매' -} as const - -const TabKeys = Object.keys(TABS) as TabType[] -const TabEntries = Object.entries>(TABS) - export const getServerSideProps: GetServerSideProps = async ({ query }) => ({ @@ -40,8 +31,11 @@ export const getServerSideProps: GetServerSideProps = async ({ }) const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { - const getMessageRoomsQuery = useGetMessageRooms() - const [tab, setTab] = useState('all') + const [tab, setTab] = useState('ALL') + const getMessageRoomsQuery = useGetMessageRooms({ + page: 0, + sort: tab + }) const [roomId, setRoomId] = useState(defaultRoomId) const router = useRouter() const { isOpen, openModal, closeModal } = useModal() @@ -50,9 +44,9 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { const messageCount = messageList.length const handleChangeTab = (currentIndex: number, nextIndex: number) => { - const nextTab = TabKeys[nextIndex] + const { code } = MESSAGE_SORT_OPTIONS[nextIndex] - setTab(nextTab) + setTab(code) } const handleSelectRoom = (id: number) => { @@ -104,9 +98,9 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => {
- {TabEntries.map(([key, value]) => ( - - {value} + {MESSAGE_SORT_OPTIONS.map(({ code, name }) => ( + + {name} ))} diff --git a/src/types/service.ts b/src/types/service.ts index 90b5791b..20d0109a 100644 --- a/src/types/service.ts +++ b/src/types/service.ts @@ -4,7 +4,8 @@ import type { SORT_TYPES, TRADE_TYPES, TRADE_STATUS, - PRODUCT_CONDITIONS + PRODUCT_CONDITIONS, + MESSAGE_SORT_OPTIONS } from '@constants' /** 정렬 옵션 */ @@ -19,6 +20,12 @@ export type SortType = ValueOf export type SortTypeCodes = SortType['code'] export type SortTypeNames = SortType['name'] +/** 정렬 타입 - 메세지 */ +export type MessageSortTypes = typeof MESSAGE_SORT_OPTIONS +export type MessageSortType = ValueOf +export type MessageSortTypeCodes = MessageSortType['code'] +export type MessageSortTypeNames = MessageSortType['name'] + /** 거래 방식 */ export type TradeTypes = typeof TRADE_TYPES export type TradeType = ValueOf From bf234d096608ceafcee1252e0dcc71f17d8ac5d6 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 10 Jan 2024 20:55:30 +0900 Subject: [PATCH 15/20] =?UTF-8?q?design:=20pc=20=EC=B1=84=ED=8C=85?= =?UTF-8?q?=EC=B0=BD=20=EC=B5=9C=ED=95=98=EB=8B=A8=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EA=B0=80=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=9D=B4=EC=8A=88=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../messagebox/ChattingRoom/index.tsx | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index edf80a50..41b86205 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -1,4 +1,4 @@ -import { Image, IconButton, Input } from '@offer-ui/react' +import { Image, IconButton, Input, useMedia } from '@offer-ui/react' import { useEffect, useRef, useState } from 'react' import { Styled } from './styled' import type { ChattingRoomProps } from './types' @@ -30,9 +30,10 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { }) const createMessageMutation = useCreateMessageMutation(roomId) const deleteMessageRoomMutation = useDeleteMessageRoomMutation(roomId) - const [messages, setMessages] = useState([]) const chattingBoxRef = useRef(null) const inputRef = useRef(null) + const { desktop, tablet, mobile } = useMedia() + const [messages, setMessages] = useState([]) const { isOpen, openModal, closeModal } = useModal() const { user } = useAuth() const senderInfo = { @@ -42,9 +43,12 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { } const scrollToBottom = () => { - if (chattingBoxRef.current) { - chattingBoxRef.current.scrollTop = - chattingBoxRef.current.scrollHeight + 40 + if (!chattingBoxRef.current) { + return + } + + if (chattingBoxRef.current.scrollHeight > 0) { + chattingBoxRef.current.scrollTop = chattingBoxRef.current.scrollHeight } } @@ -58,7 +62,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { handleCloseRoom() } - const handleClickRefresh = async () => { + const refetchMessage = async () => { await getMessageQuery.refetch() } @@ -67,6 +71,10 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { content: message }) + if (inputRef.current) { + inputRef.current.value = '' + } + setMessages(prev => [ ...prev, { @@ -75,10 +83,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { sendTime: res.createdAt } ]) - - if (inputRef.current) { - inputRef.current.value = '' - } + await refetchMessage() } useEffect(() => { @@ -87,7 +92,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { useEffect(() => { scrollToBottom() - }, [messages]) + }, [messages, desktop, tablet, mobile, chattingBoxRef.current?.scrollHeight]) return ( @@ -95,7 +100,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { {user.nickname} - + {isOpen && ( From e1845a44cc77d55a1ba18c2a8686ee12e8afff56 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 10 Jan 2024 21:02:50 +0900 Subject: [PATCH 16/20] =?UTF-8?q?feat:=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20dto=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MessagePreview/MessagePreview.stories.tsx | 3 ++- .../messagebox/MessagePreview/index.tsx | 2 +- .../messagebox/MessagePreview/types.ts | 18 +++--------------- src/types/scheme.ts | 3 +-- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx b/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx index 88a1ec2a..1ae96898 100644 --- a/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx +++ b/src/components/messagebox/MessagePreview/MessagePreview.stories.tsx @@ -19,7 +19,8 @@ export const Default: StoryObj = { }, post: { id: 1, - imageUrl: '' + price: 10000, + thumbnailImageUrl: '' }, offerPrice: 123, lastContent: diff --git a/src/components/messagebox/MessagePreview/index.tsx b/src/components/messagebox/MessagePreview/index.tsx index 1d8c4c25..8bbda187 100644 --- a/src/components/messagebox/MessagePreview/index.tsx +++ b/src/components/messagebox/MessagePreview/index.tsx @@ -46,7 +46,7 @@ export const MessagePreview = ({ alt="product" fallbackSrc={IMAGE.CHECKBOARD} height="40px" - src={post.imageUrl || ''} + src={post.thumbnailImageUrl || ''} width="40px" /> diff --git a/src/components/messagebox/MessagePreview/types.ts b/src/components/messagebox/MessagePreview/types.ts index f7d029b9..8dde04a6 100644 --- a/src/components/messagebox/MessagePreview/types.ts +++ b/src/components/messagebox/MessagePreview/types.ts @@ -1,18 +1,6 @@ -export type MessagePreviewProps = { - id: number - partner: { - id: number - nickname: string - imageUrl: string - } - post: { - id: number - imageUrl?: string - } - offerPrice: number - lastContent: string - lastSendTime: string +import type { MessageRoomInfo } from '@types' + +export type MessagePreviewProps = MessageRoomInfo & { isSelected?: boolean - notReadCnt: number onClick?(id: number): void } diff --git a/src/types/scheme.ts b/src/types/scheme.ts index 4f7fda45..a364f61f 100644 --- a/src/types/scheme.ts +++ b/src/types/scheme.ts @@ -154,8 +154,7 @@ export type OfferSummary = { export type MessageRoomInfo = { id: number partner: PartnerBrief - // dto 변경되면 수정 예정 - post: Pick & { imageUrl: string } + post: Pick offerPrice: number lastContent: string notReadCnt: number From c334aa356693e396051ebe90551f92c71661cf30 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Fri, 12 Jan 2024 23:50:40 +0900 Subject: [PATCH 17/20] =?UTF-8?q?chore:=20Res=EC=97=90=20messageId=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EC=BD=94=EB=93=9C=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=97=AC=EB=B0=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/apis.ts | 7 ++--- src/apis/message/queries.ts | 9 +++---- src/apis/message/types.ts | 1 + .../messagebox/ChattingRoom/index.tsx | 26 +++++++++++-------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/apis/message/apis.ts b/src/apis/message/apis.ts index a680911a..93759916 100644 --- a/src/apis/message/apis.ts +++ b/src/apis/message/apis.ts @@ -17,11 +17,8 @@ export const getMessage = (params: GetMessageReq) => params ) -export const createMessage = ( - messageRoomId: number, - params: CreateMessageReq -) => - http.post( +export const createMessage = ({ messageRoomId, ...params }: CreateMessageReq) => + http.post, CreateMessageRes>( `/msgrooms/${messageRoomId}/msgs`, params ) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index a5f11387..cd3fe513 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -11,7 +11,7 @@ import type { GetMessageRoomsReq } from './types' -export const useGetMessageRooms = (params: GetMessageRoomsReq) => +export const useGetMessageRoomsQuery = (params: GetMessageRoomsReq) => useQuery({ queryKey: ['getMessageRooms'], queryFn: () => getMessageRooms(params) @@ -25,13 +25,12 @@ export const useGetMessageQuery = ({ msgRoomId, ...res }: GetMessageReq) => msgRoomId, ...res }), - enabled: Boolean(msgRoomId) + enabled: typeof msgRoomId === 'number' }) -export const useCreateMessageMutation = (messageRoomId: number) => +export const useCreateMessageMutation = () => useMutation({ - mutationFn: (params: CreateMessageReq) => - createMessage(messageRoomId, params) + mutationFn: (params: CreateMessageReq) => createMessage(params) }) export const useDeleteMessageRoomMutation = (messageRoomId: number) => diff --git a/src/apis/message/types.ts b/src/apis/message/types.ts index 1a65f1bf..18d8611a 100644 --- a/src/apis/message/types.ts +++ b/src/apis/message/types.ts @@ -23,6 +23,7 @@ export type GetMessageReq = { export type GetMessageRes = MessageInfo[] export type CreateMessageReq = { + messageRoomId: number content: string } export type CreateMessageRes = CommonCreation diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index 41b86205..98cfbe5f 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -28,14 +28,17 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { msgRoomId: roomId, page: 0 }) - const createMessageMutation = useCreateMessageMutation(roomId) + const createMessageMutation = useCreateMessageMutation() const deleteMessageRoomMutation = useDeleteMessageRoomMutation(roomId) + const chattingBoxRef = useRef(null) const inputRef = useRef(null) - const { desktop, tablet, mobile } = useMedia() + const [messages, setMessages] = useState([]) + const { desktop, tablet, mobile } = useMedia() const { isOpen, openModal, closeModal } = useModal() const { user } = useAuth() + const senderInfo = { id: user.id, nickname: user.nickname, @@ -62,13 +65,10 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { handleCloseRoom() } - const refetchMessage = async () => { - await getMessageQuery.refetch() - } - - const handleSubmitMessage = async (message: string) => { + const handleSubmitMessage = async (content: string) => { const res = await createMessageMutation.mutateAsync({ - content: message + messageRoomId: roomId, + content }) if (inputRef.current) { @@ -79,11 +79,11 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { ...prev, { member: senderInfo, - content: message, + content, sendTime: res.createdAt } ]) - await refetchMessage() + await getMessageQuery.refetch() } useEffect(() => { @@ -100,7 +100,11 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { {user.nickname} - + await getMessageQuery.refetch()} + /> {isOpen && ( From d0fb4bb7b5177f6042d31d2e6486d65b49fac2c7 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Fri, 12 Jan 2024 23:51:42 +0900 Subject: [PATCH 18/20] =?UTF-8?q?chore:=20=EC=BD=94=EB=93=9C=20=EA=B0=80?= =?UTF-8?q?=EB=8F=85=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95,=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/messagebox/Chatting/index.tsx | 33 ++++++++++---------- src/pages/messagebox/index.tsx | 27 +++++++++------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/components/messagebox/Chatting/index.tsx b/src/components/messagebox/Chatting/index.tsx index 0910dee4..58bf4142 100644 --- a/src/components/messagebox/Chatting/index.tsx +++ b/src/components/messagebox/Chatting/index.tsx @@ -4,31 +4,34 @@ import { Styled } from './styled' import type { ChattingProps } from './types' import { formatDate } from '@utils/format' -export const getDate = (sendTime = '') => sendTime.split('T')[0] -export const getTime = (sendTime = '') => formatDate(sendTime, 'A H:mm') - // TODO: 상품 정보 버블 추가 export const Chatting = ({ userId, messages, receiverImageUrl }: ChattingProps) => { - const renderChattingItem = () => + const renderChattingList = () => messages.map(({ content, member, sendTime }, idx, list) => { const prevMessage = list.at(idx - 1) const nextMessage = list.at(idx + 1) const isSender = member.id === userId - const currentDate = getDate(sendTime) - const prevDate = getDate(prevMessage?.sendTime) - const nextDate = getDate(nextMessage?.sendTime) + const currentDate = formatDate(sendTime, 'YYYY년 M월 D일 dddd') + const prevDate = formatDate( + prevMessage?.sendTime || '', + 'YYYY년 M월 D일 dddd' + ) + const nextDate = formatDate( + nextMessage?.sendTime || '', + 'YYYY년 M월 D일 dddd' + ) const isPrevDateChanged = prevDate !== currentDate const isNextDateChanged = nextDate !== currentDate - const currentTime = getTime(sendTime) - const nextTime = getTime(nextMessage?.sendTime) + const currentTime = formatDate(sendTime, 'A H:mm') + const nextTime = formatDate(nextMessage?.sendTime || '', 'A H:mm') const commonProps = { - time: formatDate(sendTime, 'A H:mm'), + time: currentDate, isSectionStart: member.id !== prevMessage?.member.id || isPrevDateChanged, isSectionLast: @@ -39,12 +42,10 @@ export const Chatting = ({ return ( // TODO: 메세지 키값 내려줄 수 있는지 확인하기 -
+
{isPrevDateChanged && ( - - - {formatDate(sendTime, 'YYYY년 M월 D일 dddd')} - + + {currentDate} )} {isSender ? ( @@ -58,5 +59,5 @@ export const Chatting = ({ ) }) - return {renderChattingItem()} + return {renderChattingList()} } diff --git a/src/pages/messagebox/index.tsx b/src/pages/messagebox/index.tsx index 44c5a677..f7de2583 100644 --- a/src/pages/messagebox/index.tsx +++ b/src/pages/messagebox/index.tsx @@ -5,7 +5,7 @@ import type { GetServerSideProps } from 'next' import { useRouter } from 'next/router' import { useState, type ReactElement, useEffect } from 'react' import { toQueryString } from '@utils/format' -import { useGetMessageRooms } from '@apis' +import { useGetMessageRoomsQuery } from '@apis' import { MessagePreview, Tabs, @@ -31,22 +31,24 @@ export const getServerSideProps: GetServerSideProps = async ({ }) const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { - const [tab, setTab] = useState('ALL') - const getMessageRoomsQuery = useGetMessageRooms({ + const [sortType, setSortType] = useState('ALL') + const getMessageRoomsQuery = useGetMessageRoomsQuery({ page: 0, - sort: tab + sort: sortType }) + const [roomId, setRoomId] = useState(defaultRoomId) const router = useRouter() const { isOpen, openModal, closeModal } = useModal() const { desktop, mobile, tablet } = useMedia() + const messageList = getMessageRoomsQuery.data || [] - const messageCount = messageList.length + const messagesCount = messageList.length - const handleChangeTab = (currentIndex: number, nextIndex: number) => { + const handleChangeSortType = (currentIndex: number, nextIndex: number) => { const { code } = MESSAGE_SORT_OPTIONS[nextIndex] - setTab(code) + setSortType(code) } const handleSelectRoom = (id: number) => { @@ -77,7 +79,6 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { useEffect(() => { if (desktop) { closeModal() - return } @@ -93,14 +94,16 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => { - 내 쪽지함 {messageCount} + 내 쪽지함 {messagesCount}
- + {MESSAGE_SORT_OPTIONS.map(({ code, name }) => ( - {name} + + {name} + ))} @@ -108,7 +111,7 @@ const MessageBoxPage = ({ roomId: defaultRoomId }: Props): ReactElement => {
- {messageCount > 0 ? ( + {messagesCount > 0 ? ( messageList.map(({ id, post, ...resInfo }) => ( Date: Fri, 12 Jan 2024 23:58:05 +0900 Subject: [PATCH 19/20] =?UTF-8?q?chore:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/queries.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index cd3fe513..3b8b1c38 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -17,15 +17,11 @@ export const useGetMessageRoomsQuery = (params: GetMessageRoomsReq) => queryFn: () => getMessageRooms(params) }) -export const useGetMessageQuery = ({ msgRoomId, ...res }: GetMessageReq) => +export const useGetMessageQuery = (params: GetMessageReq) => useQuery({ - queryKey: ['getMessage', msgRoomId], - queryFn: () => - getMessage({ - msgRoomId, - ...res - }), - enabled: typeof msgRoomId === 'number' + queryKey: ['getMessage', params], + queryFn: () => getMessage(params), + enabled: typeof params.msgRoomId === 'number' }) export const useCreateMessageMutation = () => From cd910468f471f328bef8a5281af6182ca20cec16 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sun, 21 Jan 2024 17:02:02 +0900 Subject: [PATCH 20/20] =?UTF-8?q?feat:=20useGetMessageRoomsQuery=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/message/queries.ts | 2 +- src/components/messagebox/ChattingRoom/index.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apis/message/queries.ts b/src/apis/message/queries.ts index ff9a12fd..e126d5e0 100644 --- a/src/apis/message/queries.ts +++ b/src/apis/message/queries.ts @@ -15,7 +15,7 @@ import type { export const useGetMessageRoomsQuery = (params: GetMessageRoomsReq) => useQuery({ - queryKey: ['getMessageRooms'], + queryKey: ['getMessageRooms', params], queryFn: () => getMessageRooms(params) }) diff --git a/src/components/messagebox/ChattingRoom/index.tsx b/src/components/messagebox/ChattingRoom/index.tsx index 98cfbe5f..a1474991 100644 --- a/src/components/messagebox/ChattingRoom/index.tsx +++ b/src/components/messagebox/ChattingRoom/index.tsx @@ -92,7 +92,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { useEffect(() => { scrollToBottom() - }, [messages, desktop, tablet, mobile, chattingBoxRef.current?.scrollHeight]) + }, [messages, desktop, tablet, mobile]) return ( @@ -103,7 +103,7 @@ export const ChattingRoom = ({ roomId, onClose }: ChattingRoomProps) => { await getMessageQuery.refetch()} + onClick={() => getMessageQuery.refetch()} />