Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#206_image-modal
Browse files Browse the repository at this point in the history
  • Loading branch information
shinhyojeong committed Jan 12, 2024
2 parents 8a7a014 + a20c429 commit 01e5097
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 112 deletions.
5 changes: 5 additions & 0 deletions src/apis/message/apis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { CreateMessageRoomReq, CreateMessageRoomRes } from './types'
import { http } from '@utils/http'

export const createMessageRoom = (params: CreateMessageRoomReq) =>
http.post<CreateMessageRoomReq, CreateMessageRoomRes>('/msgrooms', params)
1 change: 1 addition & 0 deletions src/apis/message/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './types'
export * from './queries'
8 changes: 8 additions & 0 deletions src/apis/message/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useMutation } from '@tanstack/react-query'
import { createMessageRoom } from './apis'
import type { CreateMessageRoomReq } from './types'

export const useCreateMessageRoomMutation = () =>
useMutation({
mutationFn: (params: CreateMessageRoomReq) => createMessageRoom(params)
})
123 changes: 85 additions & 38 deletions src/components/post/PriceOfferCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { Divider, SelectBox, Text, Icon } from '@offer-ui/react'
import type { ReactElement } from 'react'
import { Divider, SelectBox, Text, Icon, Radio } from '@offer-ui/react'
import { useRouter } from 'next/router'
import type { ChangeEvent, ReactElement } from 'react'
import { useEffect, useState } from 'react'
import { Styled } from './styled'
import type { PriceOfferCardProps } from './types'
import { PriceOfferModal } from '../PriceOfferModal'
import type { OfferForm } from '../PriceOfferModal/types'
import { UserProfile } from '../UserProfile'
import { getTimeDiffText, toLocaleCurrency } from '@utils/format'
import {
getTimeDiffText,
localeCurrencyToNumber,
toLocaleCurrency,
toQueryString
} from '@utils/format'
import {
useUpdateLikeStatusMutation,
useGetPostQuery,
useGetPostOffersQuery,
useCreateOfferMutation
useCreateOfferMutation,
useCreateMessageRoomMutation
} from '@apis'
import { SORT_OPTIONS } from '@constants'
import { useModal } from '@hooks'
Expand All @@ -24,29 +31,33 @@ const PriceOfferCard = ({
const [sortOptionCode, setSortOptionCode] = useState<SortOptionCodes>(
SORT_OPTIONS[0].code
)
const offerModal = useModal()
const [selectedOffer, setSelectedOffer] = useState<number | null>(null)
const [likePost, setLikePost] = useState({
status: false,
count: 0
})

const postOffersQuery = useGetPostOffersQuery({
const router = useRouter()
const offerModal = useModal()

const getPostOffersQuery = useGetPostOffersQuery({
postId,
sort: sortOptionCode
})
const postQuery = useGetPostQuery(postId)
const likeStatusMutation = useUpdateLikeStatusMutation()
const offerMutation = useCreateOfferMutation()
const getPostQuery = useGetPostQuery(postId)
const createMessageRoomMutation = useCreateMessageRoomMutation()
const updateLikeStatusMutation = useUpdateLikeStatusMutation()
const createOfferMutation = useCreateOfferMutation()

useEffect(() => {
setLikePost({
status: Boolean(postQuery.data?.liked),
count: postQuery.data?.totalLikeCount || 0
status: Boolean(getPostQuery.data?.liked),
count: getPostQuery.data?.totalLikeCount || 0
})
}, [postQuery])
}, [getPostQuery.data])

const offers =
postOffersQuery.data?.offers.map(({ offerer, createdAt, ...offer }) => ({
getPostOffersQuery.data?.offers.map(({ offerer, createdAt, ...offer }) => ({
...offerer,
level: Number(offerer.level),
date: createdAt,
Expand All @@ -65,7 +76,13 @@ const PriceOfferCard = ({
count: status ? count - 1 : count + 1
}))

await likeStatusMutation.mutateAsync(postId)
await updateLikeStatusMutation.mutateAsync(postId)
}

const handleChangeOffer = (e: ChangeEvent<HTMLFormElement>) => {
const offerId = Number(e.target.value)

setSelectedOffer(offerId)
}

const handleClickOffer = async ({
Expand All @@ -75,16 +92,29 @@ const PriceOfferCard = ({
}: OfferForm) => {
const offerInfo = {
postId,
// TODO: post 보내기 merge 후 number로 변환하는 유틸 적용
price: Number(price) ?? 0,
price: localeCurrencyToNumber(price || '0'),
tradeType: tradeType ?? '',
location: `${tradeArea?.city} ${tradeArea?.county} ${tradeArea?.town}`
}

offerModal.closeModal()

await offerMutation.mutateAsync(offerInfo)
postOffersQuery.refetch()
await createOfferMutation.mutateAsync(offerInfo)
getPostOffersQuery.refetch()
}

const handleClickStartMessage = async () => {
if (selectedOffer) {
const res = await createMessageRoomMutation.mutateAsync({
offerId: selectedOffer
})

router.push(
`/messagebox${toQueryString({
roomId: res.id
})}`
)
}
}

return (
Expand Down Expand Up @@ -112,7 +142,10 @@ const PriceOfferCard = ({
<Styled.Divider />
{hasOffer ? (
<Styled.CardBody>
<Styled.OfferListBox>
<Styled.OfferListBox
direction="vertical"
formName="offer"
onChange={handleChangeOffer}>
{offers.map(
({
id,
Expand All @@ -123,20 +156,33 @@ const PriceOfferCard = ({
profileImageUrl,
tradeType,
price
}) => (
<Styled.Offer key={id}>
<UserProfile
date={getTimeDiffText(date)}
image={profileImageUrl}
level={level}
location={location}
nickName={nickname}
tradeType={tradeType.name}
type="offer"
/>
<Text styleType="body01B">{toLocaleCurrency(price)}</Text>
</Styled.Offer>
)
}) => {
const isSelected = selectedOffer === id

return (
<Styled.Offer key={id} isSelected={isSelected}>
<Radio.Input
checked={isSelected}
formName="offer"
value={String(id)}
/>
<Styled.OfferContent>
<UserProfile
date={getTimeDiffText(date)}
image={profileImageUrl}
level={level}
location={location}
nickName={nickname}
tradeType={tradeType.name}
type="offer"
/>
<Text styleType="body01B">
{toLocaleCurrency(price)}
</Text>
</Styled.OfferContent>
</Styled.Offer>
)
}
)}
</Styled.OfferListBox>
</Styled.CardBody>
Expand All @@ -159,21 +205,22 @@ const PriceOfferCard = ({
</Styled.LikeButton>
{isSeller ? (
<Styled.MessageButton
disabled={!postOffersQuery.data?.totalSize}
size="large">
disabled={!selectedOffer}
size="large"
onClick={handleClickStartMessage}>
쪽지하기
</Styled.MessageButton>
) : (
<Styled.MessageButton
disabled={
postOffersQuery.data?.offerCountOfCurrentMember ===
postOffersQuery.data?.maximumOfferCount
getPostOffersQuery.data?.offerCountOfCurrentMember ===
getPostOffersQuery.data?.maximumOfferCount
}
size="large"
onClick={() => {
offerModal.openModal()
}}>{`가격 제안하기(${
postOffersQuery.data?.offerCountOfCurrentMember || 0
getPostOffersQuery.data?.offerCountOfCurrentMember || 0
}/2)`}</Styled.MessageButton>
)}
</Styled.CardFooter>
Expand Down
27 changes: 21 additions & 6 deletions src/components/post/PriceOfferCard/styled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { css } from '@emotion/react'
import styled from '@emotion/styled'
import { Button, Divider as DividerComponent, Text } from '@offer-ui/react'
import {
Button,
Divider as DividerComponent,
Radio,
Text
} from '@offer-ui/react'

const OfferPriceCardWrapper = styled.div`
${({ theme }) => {
Expand Down Expand Up @@ -29,7 +34,7 @@ const OfferPriceCardWrapper = styled.div`
}}
`

const OfferListBox = styled.div`
const OfferListBox = styled(Radio)`
display: flex;
flex-direction: column;
gap: 8px;
Expand Down Expand Up @@ -88,16 +93,17 @@ const BlankCard = styled.div`
height: 120px;
padding: 20px 0;
`
const Offer = styled.div`
const Offer = styled(Radio.Label)<{ isSelected: boolean }>`
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px;
border: ${({ theme }): string => `solid 1px ${theme.colors.grayScale10}`};
border-radius: ${({ theme }): string => theme.radius.round6};
${({ theme }): string => `
${({ theme, isSelected }) => css`
border: solid 1px
${isSelected ? theme.colors.brandPrimary : theme.colors.grayScale10};
${theme.mediaQuery.tablet} {
padding: 16px;
border: none;
Expand All @@ -110,6 +116,14 @@ const Offer = styled.div`
`}
`

const OfferContent = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
`

const CardBody = styled.div`
height: 564px;
padding: 20px 16px;
Expand Down Expand Up @@ -191,6 +205,7 @@ export const Styled = {
Divider,
BlankCard,
Offer,
OfferContent,
CardBody,
CardFooter,
MessageButton,
Expand Down
Loading

0 comments on commit 01e5097

Please sign in to comment.