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

리뷰/댓글 3차 QA 반영 #106

Merged
merged 13 commits into from
Jan 10, 2024
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@pnpm-monorepo/shared": "^1.0.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-icons": "^1.3.0",
Expand Down
32 changes: 32 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 49 additions & 6 deletions src/api/trips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import client from './client';

// 여정 관련 API

// 나의 여정 목록조회
export const getTrips = async (page: number, size: number) => {
const res = await client.get(`trips?page=${page}&size=${size}`);
// 여정 상세조회
export const getTrips = async (tripId: number) => {
const res = await client.get(`trips/${tripId}`);
return res;
};

// 여정 생성
export const postTrips = async (tripsData: TripRequest) => {
const res = await client.post(`trips`, tripsData);
// 여정 기본정보 수정
export const putTrips = async (tripId: number, tripsData: TripRequest) => {
const res = await client.put(`trips/${tripId}`, tripsData);
return res;
};

Expand All @@ -19,3 +19,46 @@ export const deleteTrips = async (tripId: number) => {
const res = await client.delete(`trips/${tripId}`);
return res;
};

// 여정 생성
export const postTrips = async (tripsData: TripRequest) => {
const res = await client.post(`trips`, tripsData);
return res;
};

// 우리의 관심목록 조회
export const getTripsLike = async (
tripId: number,
category: number,
page: number,
size: number,
) => {
const res = await client.get(
`trips/${tripId}/tripLikedTours?category=${category}&page=${page}$size=${size}`,
);
return res;
};

// 우리의 관심 여행지 등록
export const postTripsLike = async (tripId: number, tourItemIds: number[]) => {
const res = await client.post(`trips/${tripId}/tripLikedTours`, tourItemIds);
return res;
};

// 우리의 관심 여행지 좋아요/싫어요
export const postTripsLikeHate = async (
tripId: number,
tourId: number,
prefer: boolean,
) => {
const res = await client.post(
`trips/${tripId}/tripLikedTours/${tourId}?prefer=${prefer}`,
);
return res;
};

// 우리의 여행취향 조회
export const getTripsSurvey = async (tripId: number) => {
const res = await client.get(`trips/${tripId}/survey`);
return res;
};
12 changes: 5 additions & 7 deletions src/components/DetailSectionBottom/DetailReviewStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ const DetailReviewStats = () => {
backgroundColor: getColor(data.keywordCount),
}}
/>
<div className="absolute left-[14.5px] top-[12.23px] flex items-center justify-start gap-[137.5px]">
<div className="flex items-start justify-start gap-2.5">
<p className="w-4">{getEmoji(data.content)}</p>
<p className="h-[15.55px] w-[166px] font-bold text-gray6">
{data.content}
</p>
<div className="absolute left-[14.5px] top-[12.23px] flex w-[90%] items-center justify-start">
<div className="flex flex-grow items-start justify-start gap-2.5">
<p>{getEmoji(data.content)}</p>
<p className="font-bold text-gray6">{data.content}</p>
</div>
<p className=" font-bold text-gray5">{data.keywordCount}</p>
<p className="font-bold text-gray5">{data.keywordCount}</p>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/DetailSectionBottom/DetailReviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export default function DetailReviews({ reviewData }: reviewProps) {
noun: '',
verb: '',
}));
}, 2000);
}, 3500);
return () => clearTimeout(timer);
}
}, [alert]);
Expand Down
8 changes: 7 additions & 1 deletion src/components/DetailSectionBottom/ReviewItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,13 @@ const Item: React.FC<ItemProps> = (props: ItemProps) => {
{showMoreKeywords &&
Array.from({ length: Math.ceil(keywords.length / 2) }).map(
(_, lineIdx) => (
<div key={lineIdx} className="mb-3 flex gap-2">
<div
key={lineIdx}
className={`flex gap-2 ${
lineIdx === Math.ceil(keywords.length / 2) - 1
? ''
: ' mb-3'
}`}>
{keywords
.slice(lineIdx * 2, lineIdx * 2 + 2)
.map((keyword, idx) => (
Expand Down
5 changes: 5 additions & 0 deletions src/components/DetailSectionTop/DetailToursButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@

import { useSetRecoilState } from 'recoil';
import { isModifyingReviewState } from '@recoil/review';
import { PenIcon } from '@components/common/icons/Icons';
import { useNavigate, useParams } from 'react-router-dom';
import { useEffect } from 'react';
Expand All @@ -12,8 +15,10 @@ export default function DetailTourButtons({ reviewData }: reviewProps) {
const params = useParams();
const tourItemId = Number(params.id);
const navigate = useNavigate();
const setIsModifyingReview = useSetRecoilState(isModifyingReviewState);

const handlePostingReivew = () => {
setIsModifyingReview(false);
navigate(`/reviewPosting/${tourItemId}`, {
state: { title, contentTypeId },
});
Expand Down
25 changes: 25 additions & 0 deletions src/components/common/accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as accordion from '@radix-ui/react-accordion';
import { CheckIcon } from '../icons/Icons';

interface AccordionProps {
title: React.ReactNode;
content: React.ReactNode;
}

const Accordion: React.FC<AccordionProps> = ({ title, content }) => {
return (
<accordion.Root type="single" collapsible>
<accordion.Item value="item-1">
<accordion.Header className="flex">
{title}
<accordion.Trigger className="ml-auto">
<CheckIcon size={17} className="rotate-on-open" />
</accordion.Trigger>
</accordion.Header>
<accordion.Content>{content}</accordion.Content>
</accordion.Item>
</accordion.Root>
);
};

export default Accordion;
2 changes: 1 addition & 1 deletion src/components/common/button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const ButtonPrimary: React.FC<ButtonProps> = ({
return (
<button
onClick={onClick}
className={`btn-base bg-primary text-xs font-bold text-white disabled:cursor-not-allowed disabled:bg-gray3 ${className}`}
className={`btn-base bg-primary text-lg font-bold text-white disabled:cursor-not-allowed disabled:bg-gray3 ${className}`}
disabled={disabled}>
{children}
</button>
Expand Down
2 changes: 2 additions & 0 deletions src/components/common/icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@ export const CheckIcon: React.FC<IconProps> = ({
fill = 'none',
onClick,
cursor = 'pointer',
className,
}) => {
return (
<svg
onClick={onClick}
cursor={cursor}
className={className}
width={size}
height={size}
viewBox="0 0 17 17"
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const getModalStyles = (modalChildren: string) => {
bottom: '0',
marginRight: '-50%',
transform: 'translate(-50%, 0)',
width: '375px',
width: '415px', // 375px + padding 40 (20 20)
height: '186px',
borderTopLeftRadius: '2rem',
borderTopRightRadius: '2rem',
Expand Down
18 changes: 14 additions & 4 deletions src/components/common/modal/children/DeleteAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,28 @@ import {
} from '@recoil/review';
import { useNavigate } from 'react-router-dom';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useMutation, useQueryClient } from '@tanstack/react-query';

const DeleteAlert = ({}) => {
const navigate = useNavigate();
const tourItemId = useRecoilValue(tourItemIdState);
const targetReviewId = useRecoilValue(targetReviewIdState);
const setIsModalOpen = useSetRecoilState(isModalOpenState);
const setToastPopUp = useSetRecoilState(toastPopUpState);
const queryClient = useQueryClient();

const { mutate: deleteReviewMutate } = useMutation({
mutationFn: (targetReviewId: number) => deleteReview(targetReviewId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['toursReviews'] });
},
onError: () => console.log('error'),
});

const handleDeleteButton = async () => {
await deleteReview(targetReviewId);
await deleteReviewMutate(targetReviewId);
setIsModalOpen(false);
navigate(`/detail/${tourItemId}`);
window.location.reload();
setToastPopUp(() => ({
isPopUp: true,
noun: '리뷰',
Expand All @@ -38,10 +48,10 @@ const DeleteAlert = ({}) => {
onClick={() => {
setIsModalOpen(false);
}}
className="text-xs">
className="text-sm">
취소
</ButtonWhite>
<ButtonPrimary onClick={handleDeleteButton} className="text-xs">
<ButtonPrimary onClick={handleDeleteButton} className="text-sm">
삭제
</ButtonPrimary>
</div>
Expand Down
17 changes: 15 additions & 2 deletions src/components/common/modal/children/EditDelete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { commentState } from '@recoil/review';

const EditDelete: React.FC = () => {
const rating = useRecoilValue(ratingState);
Expand All @@ -34,6 +36,9 @@ const EditDelete: React.FC = () => {
const navigate = useNavigate();
const setIsModalOpen = useSetRecoilState(isModalOpenState);
const setModalChildren = useSetRecoilState(modalChildrenState);
const setComment = useSetRecoilState(commentState);

const queryClient = useQueryClient();

const handleEdit = () => {
if (title == '내 리뷰') {
Expand All @@ -55,13 +60,21 @@ const EditDelete: React.FC = () => {
}
};

const { mutate: deleteCommentMutate } = useMutation({
mutationFn: (targetCommentId: number) => deleteComments(targetCommentId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['reviewComments'] });
},
onError: () => console.log('error'),
});

const handleDelete = async () => {
if (title === '내 리뷰') {
setModalChildren('DeleteAlert');
} else if (title === '내 댓글') {
await deleteComments(targetCommentId);
await deleteCommentMutate(targetCommentId);
setIsModalOpen(false);
window.location.reload();
setComment('');
}
};

Expand Down
33 changes: 29 additions & 4 deletions src/components/common/nav/InputComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ import { commentState } from '@recoil/review';
import { useRecoilState, useRecoilValue } from 'recoil';
import { putComments } from '@api/comments';
import { isModifyingCommentState, targetCommentIdState } from '@recoil/review';
import { useMutation, useQueryClient } from '@tanstack/react-query';

interface InputCommentProps {
classNameName?: string;
}

interface PostCommentMutationParams {
comment: string;
reviewId: number;
}
interface EditCommentMutationParams {
comment: string;
targetCommentId: number;
}
export const InputComment: React.FC<InputCommentProps> = () => {
const [comment, setComment] = useRecoilState(commentState);
const params = useParams();
Expand All @@ -18,6 +26,24 @@ export const InputComment: React.FC<InputCommentProps> = () => {
isModifyingCommentState,
);
const targetCommentId = useRecoilValue(targetCommentIdState);
const queryClient = useQueryClient();

const { mutate: postCommentMutate } = useMutation({
mutationFn: ({ comment, reviewId }: PostCommentMutationParams) =>
postComments(comment, reviewId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['reviewComments'] });
},
onError: () => console.log('error'),
});
const { mutate: editCommentMutate } = useMutation({
mutationFn: ({ comment, targetCommentId }: EditCommentMutationParams) =>
putComments(comment, targetCommentId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['reviewComments'] });
},
onError: () => console.log('error'),
});

const handleTextChange = (event: ChangeEvent<HTMLInputElement>) => {
const inputText = event.target.value;
Expand All @@ -26,13 +52,12 @@ export const InputComment: React.FC<InputCommentProps> = () => {

const handleSubmit = async () => {
if (isModifyingComment) {
await putComments(comment, targetCommentId);
await editCommentMutate({ comment, targetCommentId });
setIsModifyingComment(false);
} else {
await postComments(comment, reviewId);
await postCommentMutate({ comment, reviewId });
}
setComment('');
window.location.reload();
};
const handleKeyPress = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
Expand Down
Loading