diff --git a/src/features/reviews/api/review.ts b/src/features/reviews/api/review.ts index 57650bf2..6304cf7f 100644 --- a/src/features/reviews/api/review.ts +++ b/src/features/reviews/api/review.ts @@ -22,6 +22,13 @@ export interface UserEvaluation { score: number; } +export type AttractionType = + | "STORY" + | "CHARACTER" + | "DRAWING" + | "VOICE_ACTOR" + | "MUSIC"; + export default class ReviewApi { /** @description 리뷰 작성 요청 */ async addReview(review: AddReviewDto): Promise { @@ -106,4 +113,29 @@ export default class ReviewApi { async getEvaluation(animeId: number) { return get(`/ratings/${animeId}`); } + + // 입덕 포인트 + + /** @description 입덕 포인트 남기기 */ + async addAttractionPoint( + animeId: number, + attractionElements: AttractionType[], + ) { + return post(`/attraction-points`, { + animeId, + attractionElements, + }); + } + + /** @description 입덕 포인트 존재 여부 조회 */ + async getUserAttractionPointStatus(animeId: number) { + return get<{ isAttractionPoint: boolean }>(`/attraction-points/${animeId}`); + } + + /** @description 리뷰 수정 시 입덕 포인트 조회 */ + async getUserAttractionPoint(animeId: number, name: string) { + return get(`/short-reviews/attraction-points`, { + params: { animeId, name }, + }); + } } diff --git a/src/features/reviews/api/reviewDev.ts b/src/features/reviews/api/reviewDev.ts index eccb84a8..861476ec 100644 --- a/src/features/reviews/api/reviewDev.ts +++ b/src/features/reviews/api/reviewDev.ts @@ -10,7 +10,12 @@ import recentReviewMock1 from "./mock/recentReview1.json"; import recentReviewMock2 from "./mock/recentReview2.json"; import recentReviewMock3 from "./mock/recentReview3.json"; import recentReviewOnlyOneMock from "./mock/recentReviewOnlyOne.json"; -import { AddReviewDto, ReviewInfo, UserEvaluation } from "./review"; +import { + AddReviewDto, + AttractionType, + ReviewInfo, + UserEvaluation, +} from "./review"; export default class ReviewDevApi { /** @description 리뷰 작성 요청*/ @@ -71,4 +76,27 @@ export default class ReviewDevApi { async getEvaluation(animeId: number) { return get(`/ratings/${animeId}`); } + + /** @description 입덕 포인트 남기기 */ + async addAttractionPoint( + animeId: number, + attractionElements: AttractionType[], + ) { + return post(`/attraction-points`, { + animeId, + attractionElements, + }); + } + + /** @description 입덕 포인트 존재 여부 조회 */ + async getUserAttractionPointStatus(animeId: number) { + return get<{ isAttractionPoint: boolean }>(`/attraction-points/${animeId}`); + } + + /** @description 리뷰 수정 시 입덕 포인트 조회 */ + async getUserAttractionPoint(animeId: number, name: string) { + return get(`/short-reviews/attraction-points`, { + params: { animeId, name }, + }); + } } diff --git a/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx b/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx index db6ca630..934a1b96 100644 --- a/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx +++ b/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx @@ -9,6 +9,7 @@ import useSnackBar from "@/components/SnackBar/useSnackBar"; import useToast from "@/components/Toast/useToast"; import DropDownModal from "@/features/users/components/DropDownModal"; import useDropDownModal from "@/features/users/components/DropDownModal/useDropDownModal"; +import useDebounce from "@/hooks/useDebounce"; import useEvaluation from "../../hook/useEvaluation"; import ShortReviewModal from "../ReviewRating/ShortReviewModal"; @@ -19,15 +20,6 @@ import { RatingContainer, } from "./ReviewMoreButton.style"; -// TODO: 서버에서 가져오기 -const USER_MOCK_ATTRACTION = { - character: true, - art: true, - story: false, - voiceActing: false, - sound: true, -}; - interface ReviewMoreButtonProps { isMine: boolean; reviewId: number; @@ -37,6 +29,8 @@ interface ReviewMoreButtonProps { score: number; } +const DEBOUNCE_DELAY = 200; + export default function ReviewMoreButton({ isMine, reviewId, @@ -62,7 +56,7 @@ export default function ReviewMoreButton({ handleReviewModalToggle(); }; - const handleRate = (value: number) => { + const handleRate = useDebounce((value: number) => { evaluationMutation.mutate( { score: value }, { @@ -71,8 +65,7 @@ export default function ReviewMoreButton({ }, }, ); - console.log(value); - }; + }, DEBOUNCE_DELAY); const handleReviewDeleteClick = () => console.log("리뷰삭제"); @@ -150,7 +143,6 @@ export default function ReviewMoreButton({ animeId, content, isSpoiler, - ...USER_MOCK_ATTRACTION, }} > 내 별점 diff --git a/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx b/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx index 9a8843dc..d4352c57 100644 --- a/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx +++ b/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx @@ -1,8 +1,10 @@ import { PropsWithChildren } from "react"; +import DeferredComponent from "@/components/DeferredComponent"; import Modal from "@/components/Modal"; import Textarea from "@/components/TextArea"; +import { ReviewInfo } from "../../api/review"; import useReviewForm from "../../hook/useReviewForm"; import AttractionPoint from "../AttractionPoint"; @@ -15,23 +17,16 @@ import { } from "./ShortReviewModal.style"; import SpoilerCheckBox from "./SpoilerCheckBox"; -export interface MOCK_USER_REVIEW_DATA { - reviewId: number; - animeId: number; - content: string; - isSpoiler: boolean; - character: boolean; - art: boolean; - story: boolean; - voiceActing: boolean; - sound: boolean; -} +export type UserReview = Pick< + ReviewInfo, + "reviewId" | "animeId" | "content" | "isSpoiler" +>; interface ShortReviewModalProps { onClose: () => void; onReview: () => void; showBackdrop?: boolean; - userReviewData?: MOCK_USER_REVIEW_DATA; + userReviewData?: UserReview; } export default function ShortReviewModal({ @@ -60,14 +55,14 @@ export default function ShortReviewModal({ isChecked: form.character, }, { - name: "art", + name: "drawing", content: ( <> 현실 찢고 들어간듯한/이쁜 그림체 ), - isChecked: form.art, + isChecked: form.drawing, }, { name: "story", @@ -80,84 +75,91 @@ export default function ShortReviewModal({ isChecked: form.story, }, { - name: "voiceActing", + name: "voiceActor", content: ( <> 성우들의 미친 연기력 ), - isChecked: form.voiceActing, + isChecked: form.voiceActor, }, { - name: "sound", + name: "music", content: ( <> 가슴이 옹졸해지는 음악 ), - isChecked: form.sound, + isChecked: form.music, }, ]; return ( - - - 한 줄 리뷰 모달 - {children} - - -