Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions src/app/reviews/_components/CompletedReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,23 @@ const CompletedReview = ({ review, offSeparator }: CompletedReviewProps) => {
<div className="flex justify-between">
<div className="flex items-center gap-2.5">
{menuImageErrors[review.reviewId] || !review.menuImage ? (
<div className="mt-1 flex size-[72px] items-center justify-center rounded-sm bg-primary/15 text-xl font-extrabold text-primary">
<div className="mt-1 flex size-[80px] items-center justify-center rounded-sm bg-primary/15 text-xl font-extrabold text-primary">
{review.storeName.slice(0, 3)}
</div>
) : (
<Image
src={review.menuImage}
alt="pending-review "
width={72}
height={72}
className="mt-1 size-[72px] rounded-sm"
width={80}
height={80}
className="mt-1 size-[80px] rounded-sm"
onError={() => {
setMenuImageErrors((prev) => ({ ...prev, [review.reviewId]: true }))
}}
/>
)}
<div className="flex flex-col gap-1">
<div>{review.menuName}</div>
<div className="text-base font-medium">{review.menuName}</div>
<TotalRating score={review.totalScore} />
<div className="flex gap-2.5">
<div className="flex gap-1 text-xs font-extrabold">
Expand Down Expand Up @@ -154,7 +154,7 @@ const CompletedReview = ({ review, offSeparator }: CompletedReviewProps) => {
)}
</div>
{/* 리뷰 내용 */}
<div className="whitespace-pre-line">{review.clientReviewContent}</div>
<div className="whitespace-pre-line text-base">{review.clientReviewContent}</div>
{/* 리뷰 수정 기간 */}
{isEditable && (
<>
Expand Down
2 changes: 1 addition & 1 deletion src/app/reviews/_components/NoWritableReview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Icon from '@/components/Icon'

const NoWritableReview = () => (
<div className="flex h-[calc(100vh-190px)] flex-col items-center justify-center gap-6">
<div className="flex h-full flex-col items-center justify-center gap-6">
<Icon name="UtensilsCrossed" size="96px" className="text-gray-400" />
<div className="font-medium text-gray-400">주문 후 리뷰를 작성해주세요!</div>
</div>
Expand Down
42 changes: 26 additions & 16 deletions src/app/reviews/_components/Review.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,24 @@ import WritableReview from '@/app/reviews/_components/WritableReview'
import WritableReviewSkeleton from '@/app/reviews/_components/WritableReviewSkeleton'
import { useInfiniteScroll } from '@/hooks/useInfiniteScroll'
import { motion } from 'motion/react'
import { useState } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import { useRef, useState } from 'react'

export type ReviewTabType = '작성가능' | '작성완료'

const Review = () => {
const [tab, setTab] = useState<ReviewTabType>('작성가능')
const searchParams = useSearchParams()
const [tab, setTab] = useState<ReviewTabType>(
searchParams.get('tab')
? searchParams.get('tab') === '1'
? '작성가능'
: '작성완료'
: '작성가능'
)
const router = useRouter()

const { data: writableReviews, isLoading } = useGetWritableReviews()
const scrollRef = useRef<HTMLDivElement>(null)

const {
data: completedReviews,
Expand All @@ -32,10 +42,11 @@ const Review = () => {

const handleChangeTab = (tab: ReviewTabType) => {
setTab(tab)
router.push(`/reviews?tab=${tab === '작성가능' ? '1' : '2'}`)
}

return (
<section>
<section className="pt-4">
<div className="px-mobile_safe">
<ReviewTab
tab={tab}
Expand All @@ -44,23 +55,24 @@ const Review = () => {
completedReviewsCount={completedReviewsCount ?? 0}
/>
</div>
<div className="relative mt-2">
<div
ref={scrollRef}
className="relative mt-2 h-[calc(100dvh-40px-85px-56px-1rem-0.75rem-0.5rem)] w-dvw overflow-hidden"
>
<motion.div
initial={{ x: 0 }}
animate={{
x: tab === '작성가능' ? 0 : '-110%',
x: tab === '작성가능' ? 0 : -window.innerWidth,
}}
transition={{ duration: 0.3 }}
transition={{ type: 'spring', stiffness: 300, damping: 30 }}
className="absolute w-full overflow-y-auto overflow-x-hidden"
style={{
height: 'calc(100vh - 190px)',
}}
style={{ height: '100%' }}
>
{isLoading ? (
Array.from({ length: 5 }).map((_, i) => (
<WritableReviewSkeleton key={i} offSeparator={i === 4} />
))
) : writableReviews ? (
) : writableReviews && writableReviews.length > 0 ? (
writableReviews.map((review, index) => (
<WritableReview
key={review.orderId}
Expand All @@ -74,15 +86,13 @@ const Review = () => {
</motion.div>

<motion.div
initial={{ x: '110%' }}
initial={{ x: window.innerWidth }}
animate={{
x: tab === '작성가능' ? '110%' : 0,
x: tab === '작성가능' ? window.innerWidth : 0,
}}
transition={{ duration: 0.3 }}
transition={{ type: 'spring', stiffness: 300, damping: 30 }}
className="absolute w-full overflow-y-auto overflow-x-hidden"
style={{
height: 'calc(100vh - 190px)',
}}
style={{ height: '100%' }}
>
{completedReviews?.map((review, index) => (
<CompletedReview
Expand Down
12 changes: 11 additions & 1 deletion src/app/reviews/_components/ReviewEditorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import Loading from '@/components/Loading'
import { useToast } from '@/hooks/useToast'
import { cn } from '@/lib/utils'
import { modalStore } from '@/store/modal'
import { ROUTE_PATHS } from '@/utils/routes'
import { useQueryClient } from '@tanstack/react-query'
import Image from 'next/image'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { useForm } from 'react-hook-form'

Expand Down Expand Up @@ -51,7 +54,7 @@ const ReviewEditorModal = ({
content: prevData?.clientReviewContent || '',
deliveryQuality: prevData?.deliveryQuality || '',
image: null,
imagePreview: prevData?.representativeImageUri + `?v=${Date.now()}` || null,
imagePreview: prevData?.representativeImageUri,
isImageChanged: false,
},
})
Expand All @@ -71,6 +74,9 @@ const ReviewEditorModal = ({
(deliveryQuality === 'GOOD' || deliveryQuality === 'BAD')
const [isContentValid, setIsContentValid] = useState(true)

const router = useRouter()
const queryClient = useQueryClient()

const handleBlurContent = () => {
if (content.length < 5) {
setIsContentValid(false)
Expand Down Expand Up @@ -110,7 +116,10 @@ const ReviewEditorModal = ({
},
{
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['completed-reviews'] })
hideModal()
router.push(`${ROUTE_PATHS.REVIEW}?tab=2`)

toast({
title: '리뷰가 등록되었어요.',
position: 'center',
Expand Down Expand Up @@ -141,6 +150,7 @@ const ReviewEditorModal = ({
},
{
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['completed-reviews'] })
hideModal()
toast({
title: '리뷰가 수정되었어요.',
Expand Down
8 changes: 4 additions & 4 deletions src/app/reviews/_components/ReviewTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ const ReviewTab = ({
}

return (
<div className="relative flex h-10 justify-center rounded-sm bg-primary/15 text-sm font-medium">
<div className="relative flex h-12 justify-center rounded-sm bg-primary/15 text-base font-medium">
<button
onClick={handleClickTab}
value="작성가능"
className={`z-10 w-1/2 ${tab === '작성가능' ? 'text-white' : 'text-gray-700'}`}
className={`z-10 h-full w-1/2 ${tab === '작성가능' ? 'text-white' : 'text-gray-700'}`}
>
{`작성 가능한 리뷰 (${writableReviewsCount})`}
</button>
<button
onClick={handleClickTab}
value="작성완료"
className={`z-10 w-1/2 ${tab === '작성완료' ? 'text-white' : 'text-gray-700'}`}
className={`z-10 h-full w-1/2 ${tab === '작성완료' ? 'text-white' : 'text-gray-700'}`}
>
{`작성한 리뷰 (${completedReviewsCount})`}
</button>
<motion.div
className="absolute left-1 top-1 z-0 h-[32px] w-[calc(50%-4px)] rounded-sm bg-primary"
className="absolute left-1 top-1 z-0 h-10 w-[calc(50%-4px)] rounded-lg bg-primary"
animate={{
x: tab === '작성가능' ? '0%' : '100%',
}}
Expand Down
35 changes: 19 additions & 16 deletions src/app/reviews/_components/WritableReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const WritableReview = ({ review, offSeparator = false }: WritableReviewProps) =
const { showModal } = modalStore()
const [imageErrors, setImageErrors] = useState<Record<string, boolean>>({})
const handleClickReviewButton = () => {
console.log(review)
showModal({
content: (
<ReviewEditorModal
Expand All @@ -32,35 +33,37 @@ const WritableReview = ({ review, offSeparator = false }: WritableReviewProps) =
<>
<div className="flex gap-3 px-mobile_safe py-5">
{imageErrors[review.orderId] || !review.storeImageThumbnail ? (
<div className="mt-1 flex size-[72px] items-center justify-center rounded-sm bg-primary/15 text-xl font-extrabold text-primary">
<div className="mt-1 flex size-[80px] items-center justify-center rounded-sm bg-primary/15 text-xl font-extrabold text-primary">
{review.storeName.slice(0, 3)}
</div>
) : (
<Image
src={review.storeImageThumbnail}
alt="pending-review "
width={72}
height={72}
className="mt-1 size-[72px] rounded-sm"
width={80}
height={80}
className="mt-1 size-[80px] rounded-sm"
onError={() => {
setImageErrors((prev) => ({ ...prev, [review.orderId]: true }))
}}
/>
)}

<div className="flex flex-col justify-between py-0.5 text-sm">
<div>
<div className="font-semibold">{review.storeName}</div>
<ul className="whitespace-pre-wrap">{review.orderSummary}</ul>
<div className="flex flex-col justify-between gap-2">
<div className="flex flex-col gap-1">
<div className="text-base font-bold">{review.storeName}</div>
<ul className="whitespace-pre-wrap text-sm text-gray-700">{review.orderSummary}</ul>
</div>
<div className="flex flex-1">
<Button
variant="primaryFit"
size="s"
className="h-full w-fit rounded-sm"
onClick={handleClickReviewButton}
>
리뷰 쓰기
</Button>
</div>
<Button
variant="primaryFit"
size="s"
className="size-fit py-0.5"
onClick={handleClickReviewButton}
>
리뷰 작성
</Button>
</div>
</div>
{!offSeparator && <Separator ignoreMobileSafe className="h-2" />}
Expand Down
3 changes: 0 additions & 3 deletions src/constants/navigationProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ const NAVIGATION_PROPS: Record<string, NavigationProps> = {
[ROUTE_PATHS.ORDERS]: {
title: '주문내역',
},
[ROUTE_PATHS.ORDERS_DETAIL]: {
title: '주문상세',
},
[ROUTE_PATHS.FAVORITES]: {
title: '찜',
},
Expand Down