Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 쪽지함 api 연결 #196

Merged
merged 26 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ac3c285
feat: message list query 구현
Dec 16, 2023
45a1d42
feat: message list api 연결
Dec 16, 2023
feb4077
feat: message 내용 조회 query 추가
Dec 16, 2023
365321e
feat: message 내용 api 연결
Dec 16, 2023
fd0149d
Merge branch 'develop' into feat/#195_messagebox-api
Jan 2, 2024
21adf89
Merge branch 'feat/api-changes' into feat/#195_messagebox-api
Jan 4, 2024
76e2a7c
Merge branch 'develop' into feat/#195_messagebox-api
Jan 5, 2024
bb80733
feat: roomId가 있는 경우 해당 메세지룸 열기
Jan 9, 2024
5903515
feat: message 보내기 api 작성
Jan 9, 2024
1e6059e
Merge branch 'develop' into feat/#195_messagebox-api
Jan 9, 2024
06e1b5a
feat: 메세지 전송 api 연결
Jan 9, 2024
fbcbd76
feat: 채팅시 스크롤 하단에 고정, 시간 다른경우 시간 보이기
Jan 9, 2024
9a8a44d
feat: 쪽지함 나가기 api 작성
Jan 9, 2024
847db70
feat: Sidebar 쪽지함 링크 수정
Jan 9, 2024
e5e5f49
feat: 쪽지함 나가기 api 연결
Jan 9, 2024
51c21e2
feat: 쪽지내용 refresh 기능 추가
Jan 9, 2024
0108540
design: 쪽지함 시간 보여주는 스타일 변경
Jan 9, 2024
fdb7333
feat: 메세지 리스트 sort 항목 추가
Jan 10, 2024
bf234d0
design: pc 채팅창 최하단으로 가지 않는 이슈 수정
Jan 10, 2024
e1845a4
feat: 메세지 리스트 dto 변경 반영
Jan 10, 2024
c334aa3
chore: Res에 messageId 추가, 코드 가독성을 위한 여백 추가
Jan 12, 2024
d0fb4bb
chore: 코드 가독성을 위한 변수명 수정, 불필요한 코드 제거
Jan 12, 2024
32e7e96
chore: 가독성을 위한 변수명 수정
Jan 12, 2024
ddacbb1
Merge branch 'develop' into feat/#195_messagebox-api
Jan 15, 2024
cd91046
feat: useGetMessageRoomsQuery 의존성 변경
Jan 21, 2024
2776145
Merge branch 'develop' into feat/#195_messagebox-api
shinhyojeong Jan 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion src/apis/message/apis.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
import type { CreateMessageRoomReq, CreateMessageRoomRes } from './types'
import type {
GetMessageRoomsReq,
GetMessageRoomsRes,
GetMessageReq,
GetMessageRes,
CreateMessageReq,
CreateMessageRes,
CreateMessageRoomReq,
CreateMessageRoomRes
} from './types'
import { http } from '@utils/http'

export const getMessageRooms = (params: GetMessageRoomsReq) =>
http.get<GetMessageRoomsReq, GetMessageRoomsRes>('/msgrooms', params)

export const getMessage = (params: GetMessageReq) =>
http.get<GetMessageReq, GetMessageRes>(
`/msgrooms/${params.msgRoomId}/msgs`,
params
)

export const createMessage = ({ messageRoomId, ...params }: CreateMessageReq) =>
http.post<Omit<CreateMessageReq, 'messageRoomId'>, CreateMessageRes>(
`/msgrooms/${messageRoomId}/msgs`,
params
)

export const deleteMessageRoom = (messageRoomId: number) =>
http.delete<null>(`/msgrooms/${messageRoomId}`)
sonsurim marked this conversation as resolved.
Show resolved Hide resolved

export const createMessageRoom = (params: CreateMessageRoomReq) =>
http.post<CreateMessageRoomReq, CreateMessageRoomRes>('/msgrooms', params)
40 changes: 37 additions & 3 deletions src/apis/message/queries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
import { useMutation } from '@tanstack/react-query'
import { createMessageRoom } from './apis'
import type { CreateMessageRoomReq } from './types'
import { useMutation, useQuery } from '@tanstack/react-query'
import {
getMessageRooms,
getMessage,
createMessage,
deleteMessageRoom,
createMessageRoom
} from './apis'
import type {
CreateMessageReq,
GetMessageReq,
GetMessageRoomsReq,
CreateMessageRoomReq
} from './types'

export const useGetMessageRoomsQuery = (params: GetMessageRoomsReq) =>
useQuery({
queryKey: ['getMessageRooms', params],
queryFn: () => getMessageRooms(params)
})

export const useGetMessageQuery = (params: GetMessageReq) =>
useQuery({
queryKey: ['getMessage', params],
queryFn: () => getMessage(params),
enabled: typeof params.msgRoomId === 'number'
})

export const useCreateMessageMutation = () =>
useMutation({
sonsurim marked this conversation as resolved.
Show resolved Hide resolved
mutationFn: (params: CreateMessageReq) => createMessage(params)
})

export const useDeleteMessageRoomMutation = (messageRoomId: number) =>
useMutation({
mutationFn: () => deleteMessageRoom(messageRoomId)
})

export const useCreateMessageRoomMutation = () =>
useMutation({
Expand Down
10 changes: 8 additions & 2 deletions src/apis/message/types.ts
Original file line number Diff line number Diff line change
@@ -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[]
Expand All @@ -17,7 +23,7 @@ export type GetMessageReq = {
export type GetMessageRes = MessageInfo[]

export type CreateMessageReq = {
msgRoomId: number
messageRoomId: number
content: string
}
export type CreateMessageRes = CommonCreation
25 changes: 16 additions & 9 deletions src/components/common/Header/SideBar/index.tsx
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -21,7 +20,7 @@ const NAV_DATA: NavDataType = [
},
{
content: '쪽지함',
url: '/message',
url: '/messagebox',
iconType: 'message'
}
]
Expand All @@ -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()
}

Expand Down Expand Up @@ -64,14 +71,14 @@ export const SideBar = ({ isOpen, onClose }: SideBarProps): ReactElement => {
)}
<Divider direction="horizontal" gap={16} length="259px" />
<Styled.SidebarMenuSection>
{NAV_DATA.map((item, index) => {
{NAV_DATA.map(({ iconType, content, url }) => {
return (
<Link key={index} href={item.url}>
<Styled.SidebarMenu>
<Icon size={16} type={item.iconType} />
{item.content}
</Styled.SidebarMenu>
</Link>
<Styled.SidebarMenu
key={content}
onClick={() => handleClickButton(url)}>
<Icon size={16} type={iconType} />
{content}
</Styled.SidebarMenu>
)
})}
</Styled.SidebarMenuSection>
Expand Down
2 changes: 2 additions & 0 deletions src/components/common/Header/SideBar/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
71 changes: 42 additions & 29 deletions src/components/messagebox/Chatting/Chatting.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: '수림',
sonsurim marked this conversation as resolved.
Show resolved Hide resolved
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<Chatting> = {
args: {
userId: 1,
receiverImageUrl: 'https://picsum.photos/id/237/200/300',
messages: MESSAGES_MOCK
},
render: args => <ChattingComponent {...args} />
Expand Down
87 changes: 47 additions & 40 deletions src/components/messagebox/Chatting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,60 @@ import { Styled } from './styled'
import type { ChattingProps } from './types'
import { formatDate } from '@utils/format'

export const getDate = (createdDate = '') => createdDate.split('T')[0]

// TODO: 상품 정보 버블 추가
export const Chatting = ({
userId,
messages,
receiverImageUrl
}: ChattingProps) => {
return (
<Styled.Container>
{messages.map(({ id, content, senderId, createdDate }, idx, list) => {
const prevMessage = list.at(idx - 1)
const nextMessage = list.at(idx + 1)
const isSender = senderId === userId
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 = 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 = formatDate(sendTime, 'A H:mm')
const nextTime = formatDate(nextMessage?.sendTime || '', 'A H:mm')

const currentDate = getDate(createdDate)
const prevDate = getDate(prevMessage?.createdDate)
const nextDate = getDate(nextMessage?.createdDate)
const isPrevDateChanged = prevDate !== currentDate
const isNextDateChanged = nextDate !== currentDate
const commonProps = {
time: currentDate,
isSectionStart:
member.id !== prevMessage?.member.id || isPrevDateChanged,
isSectionLast:
member.id !== nextMessage?.member.id ||
isNextDateChanged ||
currentTime !== nextTime
}

const commonProps = {
time: formatDate(createdDate, 'A H:m'),
isSectionStart:
senderId !== prevMessage?.senderId || isPrevDateChanged,
isSectionLast: senderId !== nextMessage?.senderId || isNextDateChanged
}
return (
// TODO: 메세지 키값 내려줄 수 있는지 확인하기
<div key={`${member.nickname}-${currentDate}`}>
{isPrevDateChanged && (
<Styled.DateWrapper key={currentDate}>
<Styled.ChattingDate>{currentDate}</Styled.ChattingDate>
</Styled.DateWrapper>
)}
{isSender ? (
<Send {...commonProps}>{content}</Send>
) : (
<Receive avatarUrl={receiverImageUrl} {...commonProps}>
{content}
</Receive>
)}
</div>
)
})

return (
<div key={id}>
{isPrevDateChanged && (
<Styled.DateWrapper key={createdDate}>
<Styled.ChattingDate>
{formatDate(createdDate, 'YYYY년 M월 D일 dddd')}
</Styled.ChattingDate>
</Styled.DateWrapper>
)}
{isSender ? (
<Send {...commonProps}>{content}</Send>
) : (
<Receive avatarUrl={receiverImageUrl} {...commonProps}>
{content}
</Receive>
)}
</div>
)
})}
</Styled.Container>
)
return <Styled.Container>{renderChattingList()}</Styled.Container>
}
10 changes: 6 additions & 4 deletions src/components/messagebox/Chatting/types.ts
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ const meta: Meta<ChattingRoom> = {
export default meta

export const Default: StoryObj<ChattingRoom> = {
args: { id: 1 },
args: { roomId: 1 },
render: args => <ChattingRoomComponent {...args} />
}
Loading