Skip to content

Commit 1549d49

Browse files
authored
feat: 쪽지함 api 연결 (#196)
2 parents 3f3fd53 + 2776145 commit 1549d49

File tree

20 files changed

+440
-419
lines changed

20 files changed

+440
-419
lines changed

src/apis/message/apis.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
1-
import type { CreateMessageRoomReq, CreateMessageRoomRes } from './types'
1+
import type {
2+
GetMessageRoomsReq,
3+
GetMessageRoomsRes,
4+
GetMessageReq,
5+
GetMessageRes,
6+
CreateMessageReq,
7+
CreateMessageRes,
8+
CreateMessageRoomReq,
9+
CreateMessageRoomRes
10+
} from './types'
211
import { http } from '@utils/http'
312

13+
export const getMessageRooms = (params: GetMessageRoomsReq) =>
14+
http.get<GetMessageRoomsReq, GetMessageRoomsRes>('/msgrooms', params)
15+
16+
export const getMessage = (params: GetMessageReq) =>
17+
http.get<GetMessageReq, GetMessageRes>(
18+
`/msgrooms/${params.msgRoomId}/msgs`,
19+
params
20+
)
21+
22+
export const createMessage = ({ messageRoomId, ...params }: CreateMessageReq) =>
23+
http.post<Omit<CreateMessageReq, 'messageRoomId'>, CreateMessageRes>(
24+
`/msgrooms/${messageRoomId}/msgs`,
25+
params
26+
)
27+
28+
export const deleteMessageRoom = (messageRoomId: number) =>
29+
http.delete<null>(`/msgrooms/${messageRoomId}`)
30+
431
export const createMessageRoom = (params: CreateMessageRoomReq) =>
532
http.post<CreateMessageRoomReq, CreateMessageRoomRes>('/msgrooms', params)

src/apis/message/queries.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,40 @@
1-
import { useMutation } from '@tanstack/react-query'
2-
import { createMessageRoom } from './apis'
3-
import type { CreateMessageRoomReq } from './types'
1+
import { useMutation, useQuery } from '@tanstack/react-query'
2+
import {
3+
getMessageRooms,
4+
getMessage,
5+
createMessage,
6+
deleteMessageRoom,
7+
createMessageRoom
8+
} from './apis'
9+
import type {
10+
CreateMessageReq,
11+
GetMessageReq,
12+
GetMessageRoomsReq,
13+
CreateMessageRoomReq
14+
} from './types'
15+
16+
export const useGetMessageRoomsQuery = (params: GetMessageRoomsReq) =>
17+
useQuery({
18+
queryKey: ['getMessageRooms', params],
19+
queryFn: () => getMessageRooms(params)
20+
})
21+
22+
export const useGetMessageQuery = (params: GetMessageReq) =>
23+
useQuery({
24+
queryKey: ['getMessage', params],
25+
queryFn: () => getMessage(params),
26+
enabled: typeof params.msgRoomId === 'number'
27+
})
28+
29+
export const useCreateMessageMutation = () =>
30+
useMutation({
31+
mutationFn: (params: CreateMessageReq) => createMessage(params)
32+
})
33+
34+
export const useDeleteMessageRoomMutation = (messageRoomId: number) =>
35+
useMutation({
36+
mutationFn: () => deleteMessageRoom(messageRoomId)
37+
})
438

539
export const useCreateMessageRoomMutation = () =>
640
useMutation({

src/apis/message/types.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
import type { CommonCreation, MessageRoomInfo, MessageInfo } from '@types'
1+
import type {
2+
CommonCreation,
3+
MessageRoomInfo,
4+
MessageInfo,
5+
MessageSortTypeCodes
6+
} from '@types'
27

38
export type GetMessageRoomsReq = {
9+
sort: MessageSortTypeCodes
410
page: number
511
}
612
export type GetMessageRoomsRes = MessageRoomInfo[]
@@ -17,7 +23,7 @@ export type GetMessageReq = {
1723
export type GetMessageRes = MessageInfo[]
1824

1925
export type CreateMessageReq = {
20-
msgRoomId: number
26+
messageRoomId: number
2127
content: string
2228
}
2329
export type CreateMessageRes = CommonCreation

src/components/common/Header/SideBar/index.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Avatar, Divider, Icon, Badge } from '@offer-ui/react'
2-
import Link from 'next/link'
32
import { useRouter } from 'next/router'
43
import type { ReactElement } from 'react'
54
import React from 'react'
@@ -21,7 +20,7 @@ const NAV_DATA: NavDataType = [
2120
},
2221
{
2322
content: '쪽지함',
24-
url: '/message',
23+
url: '/messagebox',
2524
iconType: 'message'
2625
}
2726
]
@@ -32,11 +31,19 @@ export const SideBar = ({ isOpen, onClose }: SideBarProps): ReactElement => {
3231

3332
const handleClickLogin = () => {
3433
router.replace(OAUTH_URL.KAKAO)
34+
35+
onClose()
36+
}
37+
38+
const handleClickButton = (url: string) => {
39+
router.push(url)
40+
3541
onClose()
3642
}
3743

3844
const handleClickLogout = () => {
3945
handleLogout()
46+
4047
onClose()
4148
}
4249

@@ -64,14 +71,14 @@ export const SideBar = ({ isOpen, onClose }: SideBarProps): ReactElement => {
6471
)}
6572
<Divider direction="horizontal" gap={16} length="259px" />
6673
<Styled.SidebarMenuSection>
67-
{NAV_DATA.map((item, index) => {
74+
{NAV_DATA.map(({ iconType, content, url }) => {
6875
return (
69-
<Link key={index} href={item.url}>
70-
<Styled.SidebarMenu>
71-
<Icon size={16} type={item.iconType} />
72-
{item.content}
73-
</Styled.SidebarMenu>
74-
</Link>
76+
<Styled.SidebarMenu
77+
key={content}
78+
onClick={() => handleClickButton(url)}>
79+
<Icon size={16} type={iconType} />
80+
{content}
81+
</Styled.SidebarMenu>
7582
)
7683
})}
7784
</Styled.SidebarMenuSection>

src/components/common/Header/SideBar/styled.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ const SidebarMenu = styled.li`
7878
align-items: center;
7979
${({ theme }): string => theme.fonts.body01B};
8080
color: ${({ theme }): string => theme.colors.grayScale90};
81+
82+
cursor: pointer;
8183
`
8284

8385
const SidebarLogoutButton = styled.button`

src/components/messagebox/Chatting/Chatting.stories.tsx

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,61 +12,74 @@ export default meta
1212

1313
const MESSAGES_MOCK = [
1414
{
15-
id: 10,
1615
content: 'offer 쪽지1',
17-
receiverId: 1,
18-
senderId: 2,
19-
createdDate: '2021-11-11T00:12:43'
16+
member: {
17+
id: 1,
18+
nickname: '주영',
19+
imageUrl: ''
20+
},
21+
sendTime: '2021-11-11T00:12:43'
2022
},
2123
{
22-
id: 8,
2324
content: 'offer 쪽지2',
24-
receiverId: 1,
25-
senderId: 2,
26-
createdDate: '2021-12-15T00:13:49'
25+
member: {
26+
id: 2,
27+
nickname: '수림',
28+
imageUrl: ''
29+
},
30+
sendTime: '2021-12-15T00:13:49'
2731
},
2832
{
29-
id: 6,
3033
content:
3134
' 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',
32-
receiverId: 1,
33-
senderId: 2,
34-
createdDate: '2021-12-15T00:25:31'
35+
member: {
36+
id: 1,
37+
nickname: '주영',
38+
imageUrl: ''
39+
},
40+
sendTime: '2021-12-15T00:25:31'
3541
},
3642
{
37-
id: 61,
3843
content: 'offer 쪽지3',
39-
receiverId: 2,
40-
senderId: 1,
41-
createdDate: '2021-12-15T01:45:41'
44+
member: {
45+
id: 2,
46+
nickname: '수림',
47+
imageUrl: ''
48+
},
49+
sendTime: '2021-12-15T01:45:41'
4250
},
4351
{
44-
id: 62,
4552
content: 'offer 쪽지3',
46-
receiverId: 2,
47-
senderId: 1,
48-
createdDate: '2021-12-15T01:45:41'
53+
member: {
54+
id: 1,
55+
nickname: '주영',
56+
imageUrl: ''
57+
},
58+
sendTime: '2021-12-15T01:45:41'
4959
},
5060
{
51-
id: 63,
5261
content: 'offer 쪽지3',
53-
receiverId: 2,
54-
senderId: 1,
55-
createdDate: '2021-12-15T01:45:41'
62+
member: {
63+
id: 1,
64+
nickname: '주영',
65+
imageUrl: ''
66+
},
67+
sendTime: '2021-12-15T01:45:41'
5668
},
5769
{
58-
id: 64,
5970
content: 'offer 쪽지3',
60-
receiverId: 2,
61-
senderId: 1,
62-
createdDate: '2021-12-15T01:45:41'
71+
member: {
72+
id: 1,
73+
nickname: '주영',
74+
imageUrl: ''
75+
},
76+
sendTime: '2021-12-15T01:45:41'
6377
}
6478
]
6579

6680
export const Default: StoryObj<Chatting> = {
6781
args: {
6882
userId: 1,
69-
receiverImageUrl: 'https://picsum.photos/id/237/200/300',
7083
messages: MESSAGES_MOCK
7184
},
7285
render: args => <ChattingComponent {...args} />

src/components/messagebox/Chatting/index.tsx

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,60 @@ import { Styled } from './styled'
44
import type { ChattingProps } from './types'
55
import { formatDate } from '@utils/format'
66

7-
export const getDate = (createdDate = '') => createdDate.split('T')[0]
8-
97
// TODO: 상품 정보 버블 추가
108
export const Chatting = ({
119
userId,
1210
messages,
1311
receiverImageUrl
1412
}: ChattingProps) => {
15-
return (
16-
<Styled.Container>
17-
{messages.map(({ id, content, senderId, createdDate }, idx, list) => {
18-
const prevMessage = list.at(idx - 1)
19-
const nextMessage = list.at(idx + 1)
20-
const isSender = senderId === userId
13+
const renderChattingList = () =>
14+
messages.map(({ content, member, sendTime }, idx, list) => {
15+
const prevMessage = list.at(idx - 1)
16+
const nextMessage = list.at(idx + 1)
17+
const isSender = member.id === userId
18+
19+
const currentDate = formatDate(sendTime, 'YYYY년 M월 D일 dddd')
20+
const prevDate = formatDate(
21+
prevMessage?.sendTime || '',
22+
'YYYY년 M월 D일 dddd'
23+
)
24+
const nextDate = formatDate(
25+
nextMessage?.sendTime || '',
26+
'YYYY년 M월 D일 dddd'
27+
)
28+
const isPrevDateChanged = prevDate !== currentDate
29+
const isNextDateChanged = nextDate !== currentDate
30+
const currentTime = formatDate(sendTime, 'A H:mm')
31+
const nextTime = formatDate(nextMessage?.sendTime || '', 'A H:mm')
2132

22-
const currentDate = getDate(createdDate)
23-
const prevDate = getDate(prevMessage?.createdDate)
24-
const nextDate = getDate(nextMessage?.createdDate)
25-
const isPrevDateChanged = prevDate !== currentDate
26-
const isNextDateChanged = nextDate !== currentDate
33+
const commonProps = {
34+
time: currentDate,
35+
isSectionStart:
36+
member.id !== prevMessage?.member.id || isPrevDateChanged,
37+
isSectionLast:
38+
member.id !== nextMessage?.member.id ||
39+
isNextDateChanged ||
40+
currentTime !== nextTime
41+
}
2742

28-
const commonProps = {
29-
time: formatDate(createdDate, 'A H:m'),
30-
isSectionStart:
31-
senderId !== prevMessage?.senderId || isPrevDateChanged,
32-
isSectionLast: senderId !== nextMessage?.senderId || isNextDateChanged
33-
}
43+
return (
44+
// TODO: 메세지 키값 내려줄 수 있는지 확인하기
45+
<div key={`${member.nickname}-${currentDate}`}>
46+
{isPrevDateChanged && (
47+
<Styled.DateWrapper key={currentDate}>
48+
<Styled.ChattingDate>{currentDate}</Styled.ChattingDate>
49+
</Styled.DateWrapper>
50+
)}
51+
{isSender ? (
52+
<Send {...commonProps}>{content}</Send>
53+
) : (
54+
<Receive avatarUrl={receiverImageUrl} {...commonProps}>
55+
{content}
56+
</Receive>
57+
)}
58+
</div>
59+
)
60+
})
3461

35-
return (
36-
<div key={id}>
37-
{isPrevDateChanged && (
38-
<Styled.DateWrapper key={createdDate}>
39-
<Styled.ChattingDate>
40-
{formatDate(createdDate, 'YYYY년 M월 D일 dddd')}
41-
</Styled.ChattingDate>
42-
</Styled.DateWrapper>
43-
)}
44-
{isSender ? (
45-
<Send {...commonProps}>{content}</Send>
46-
) : (
47-
<Receive avatarUrl={receiverImageUrl} {...commonProps}>
48-
{content}
49-
</Receive>
50-
)}
51-
</div>
52-
)
53-
})}
54-
</Styled.Container>
55-
)
62+
return <Styled.Container>{renderChattingList()}</Styled.Container>
5663
}

src/components/messagebox/Chatting/types.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
type Message = {
2-
id: number
2+
member: {
3+
id: number
4+
nickname: string
5+
imageUrl: string
6+
}
37
content: string
4-
receiverId: number
5-
senderId: number
6-
createdDate: string
8+
sendTime: string
79
}
810

911
export type SendProps = {

src/components/messagebox/ChattingRoom/ChattingRoom.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ const meta: Meta<ChattingRoom> = {
1111
export default meta
1212

1313
export const Default: StoryObj<ChattingRoom> = {
14-
args: { id: 1 },
14+
args: { roomId: 1 },
1515
render: args => <ChattingRoomComponent {...args} />
1616
}

0 commit comments

Comments
 (0)