diff --git a/src/app/(route)/(withLayout)/items/[itemId]/_utils/validation.ts b/src/app/(route)/(withLayout)/items/[itemId]/_utils/validation.ts
index bad713ee..60135022 100644
--- a/src/app/(route)/(withLayout)/items/[itemId]/_utils/validation.ts
+++ b/src/app/(route)/(withLayout)/items/[itemId]/_utils/validation.ts
@@ -1,6 +1,7 @@
import renderToast from '@/app/_utils/toast'
const MAX_CONTENT_LENGTH = 11
+const MIN_COUNT = 0
/* 아이템 등록 - 이미지 별점 선택 검증 */
export const validateForm = ({
@@ -21,7 +22,7 @@ export const validateForm = ({
return false
}
- if (rating === 0) {
+ if (rating === MIN_COUNT) {
renderToast({
type: 'error',
message: '별점을 선택해 주세요!',
@@ -30,7 +31,7 @@ export const validateForm = ({
return false
}
- if (multipartReviewImages.length === 0) {
+ if (multipartReviewImages.length === MIN_COUNT) {
renderToast({
type: 'error',
message: '리뷰 사진을 첨부해 주세요.',
@@ -42,26 +43,35 @@ export const validateForm = ({
return true
}
-/* 이미지 갯수 검증 */
+/* 이미지 개수 검증 */
export const validateImage = ({
existingImages,
multipartReviewImages,
- content,
+ filesArray,
}: {
existingImages: string[]
multipartReviewImages: File[]
- content: string
+ filesArray?: File[]
}) => {
- if (content.trim().length < MAX_CONTENT_LENGTH) {
+ const MAX_IMAGE_COUNT = 5
+
+ const files = filesArray || []
+
+ const totalImagesCount =
+ existingImages.length + multipartReviewImages.length + files.length
+
+ /** 최대 이미지 개수 */
+ if (totalImagesCount > MAX_IMAGE_COUNT) {
renderToast({
type: 'error',
- message: '리뷰 내용을 최소 10자 이상 작성해 주세요..',
+ message: '최대 5장까지 등록 가능합니다.',
})
return false
}
- if (existingImages.length + multipartReviewImages.length === 0) {
+ /** 최소 이미지 개수 */
+ if (totalImagesCount < MIN_COUNT) {
renderToast({
type: 'error',
message: '이미지를 등록해 주세요.',
@@ -72,3 +82,23 @@ export const validateImage = ({
return true
}
+
+/** 이미지 용량 */
+export const validateImageSize = (filesArray: File[]) => {
+ const MAX_IMAGE_SIZE = 5 * 1024 * 1024
+
+ const isExceedingSize = filesArray.some(
+ (file: File) => file.size > MAX_IMAGE_SIZE,
+ )
+
+ if (isExceedingSize) {
+ renderToast({
+ type: 'error',
+ message: '이미지 파일 크기는 5MB를 초과할 수 없습니다.',
+ })
+
+ return false
+ }
+
+ return true
+}
diff --git a/src/app/(route)/(withLayout)/items/add-item/page.tsx b/src/app/(route)/(withLayout)/items/add-item/page.tsx
index ecddcf65..5edca148 100644
--- a/src/app/(route)/(withLayout)/items/add-item/page.tsx
+++ b/src/app/(route)/(withLayout)/items/add-item/page.tsx
@@ -1,4 +1,3 @@
-import RQProvider from '@/app/_components/RQProvider'
import { cn } from '@/app/_utils/twMerge'
import PostForm from './_component/PostForm'
@@ -10,9 +9,7 @@ export default function AddItemPage() {
아이템 생성
-
-
-
+
)
}
diff --git a/src/app/_hook/api/reviews/useAddReview.ts b/src/app/_hook/api/reviews/useAddReview.ts
index aa9bf92e..ae58f947 100644
--- a/src/app/_hook/api/reviews/useAddReview.ts
+++ b/src/app/_hook/api/reviews/useAddReview.ts
@@ -3,6 +3,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'
import renderToast from '@/app/_utils/toast'
import { getCookie } from 'cookies-next'
import { reviewKeys } from '.'
+import { itemKeys } from '../items'
interface AddReviewRequest {
itemId: number
@@ -43,6 +44,7 @@ export default function useAddReview() {
queryClient.invalidateQueries({
queryKey: reviewKeys.reviewList._def,
})
+ queryClient.invalidateQueries({ queryKey: itemKeys.itemDetail._def })
},
onError: (error) => {
renderToast({
diff --git a/src/app/_hook/api/votes/useFavoritesList.ts b/src/app/_hook/api/votes/useFavoritesList.ts
index bd268831..a3b66a84 100644
--- a/src/app/_hook/api/votes/useFavoritesList.ts
+++ b/src/app/_hook/api/votes/useFavoritesList.ts
@@ -1,18 +1,14 @@
import { useQuery } from '@tanstack/react-query'
-import { useCookies } from 'next-client-cookies'
+import { getCookie } from 'cookies-next'
import { voteKeys } from '.'
interface RequestInfo {
type: 'folder' | 'item'
folderId?: number | null
- accessToken: string
}
-export async function fetchFavoriteList({
- type,
- folderId,
- accessToken,
-}: RequestInfo) {
+export async function fetchFavoriteList({ type, folderId }: RequestInfo) {
+ const accessToken = getCookie('accessToken')
let url = `${process.env.NEXT_PUBLIC_BASE_URL}/api/favorites?favoriteTypeCondition=${type}`
if (type === 'item' && folderId) {
@@ -40,16 +36,13 @@ export const useFavoritesList = (
type: 'folder' | 'item',
folderId?: number | null,
) => {
- const cookies = useCookies()
- const accessToken = cookies.get('accessToken') ?? ''
-
const {
data: itemList,
isError,
isSuccess,
} = useQuery({
queryKey: voteKeys.favorites(folderId as number).queryKey,
- queryFn: () => fetchFavoriteList({ type, folderId, accessToken }),
+ queryFn: () => fetchFavoriteList({ type, folderId }),
staleTime: 1000 * 60,
})
diff --git a/src/app/_hook/api/votes/useParticipationVote.ts b/src/app/_hook/api/votes/useParticipationVote.ts
index 7a054f8e..18fd8491 100644
--- a/src/app/_hook/api/votes/useParticipationVote.ts
+++ b/src/app/_hook/api/votes/useParticipationVote.ts
@@ -41,7 +41,7 @@ export const useParticipationVote = () => {
onSuccess: () => {
renderToast({
type: 'success',
- message: '투표 취소 성공!',
+ message: '투표 성공!',
})
queryClient.invalidateQueries({
diff --git a/src/app/_hook/api/votes/useVoteListData.ts b/src/app/_hook/api/votes/useVoteListData.ts
index fb168325..99066afe 100644
--- a/src/app/_hook/api/votes/useVoteListData.ts
+++ b/src/app/_hook/api/votes/useVoteListData.ts
@@ -9,23 +9,26 @@ interface VoteQueryParams {
sortOption: string
}
+const VOTE_FETCH_SIZE = 6
+
async function fetchVoteData({
pageParam,
hobby,
sortOption,
}: VoteQueryParams) {
- const SIZE = 6
-
- const res = await fetch(
- `${process.env.NEXT_PUBLIC_BASE_URL}/api/votes?hobby=${hobby}&cursorId=${pageParam}&size=${SIZE}&sort=${sortOption}`,
- {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
- cache: 'no-store',
+ let URL = `${process.env.NEXT_PUBLIC_BASE_URL}/api/votes?hobby=${hobby}&size=${VOTE_FETCH_SIZE}&sort=${sortOption}`
+
+ if (pageParam) {
+ URL += `&cursorId=${pageParam}`
+ }
+
+ const res = await fetch(URL, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
},
- )
+ cache: 'no-store',
+ })
const data = await res.json()
@@ -44,6 +47,10 @@ export const useVoteListData = (hobby: string, sortOption: string) => {
fetchVoteData({ pageParam, sortOption, hobby }),
initialPageParam: null,
getNextPageParam: (lastPage: PagesResponse) => {
+ if (lastPage.totalCount < VOTE_FETCH_SIZE) {
+ return null
+ }
+
return lastPage.nextCursorId
},
staleTime: 1000 * 60,
diff --git a/src/app/_utils/dateFormatter.ts b/src/app/_utils/dateFormatter.ts
index 4ad771c4..f142948b 100644
--- a/src/app/_utils/dateFormatter.ts
+++ b/src/app/_utils/dateFormatter.ts
@@ -27,6 +27,6 @@ export function detailDateFormatter(dateString: string): string {
const formattedDate = new Intl.DateTimeFormat('ko-KR', options).format(date)
return formattedDate
- .replace(/(\d{4})\. (\d{2})\. (\d{2})\. (\d{2}):(\d{2})/, '$1.$2.$3.$4.$5')
+ .replace(/(\d{4})\. (\d{2})\. (\d{2})\. (\d{2}):(\d{2})/, '$1.$2.$3 $4:$5')
.trim()
}