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

상세페이지 QA 보완 #72

Merged
merged 11 commits into from
Jan 6, 2024
52 changes: 52 additions & 0 deletions package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"react-kakao-maps-sdk": "^1.1.24",
"react-modal": "^3.16.1",
"react-router-dom": "^6.21.1",
"react-scroll": "^1.9.0",
"recoil": "^0.7.7",
"styled-components": "^6.1.3",
"uuid": "^9.0.1"
Expand All @@ -34,8 +35,9 @@
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@types/react-infinite-scroller": "^1.2.5",
"@types/uuid": "^9.0.7",
"@types/react-modal": "^3.16.3",
"@types/react-scroll": "^1.8.10",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitejs/plugin-react": "^4.2.1",
Expand Down
30 changes: 30 additions & 0 deletions src/api/tours.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,36 @@ export const getDetailTours = async (tourItemId: number) => {
}
};

// 관심 여행지 등록
export const postLikedTours = async (options: { id: number }) => {
try {
const { id } = options;

let query = `/liked/${id}`;

const res = await client.post(query);

return res;
} catch (e) {
console.error(e);
}
};

// 관심 여행지 삭제
export const deleteLikedTours = async (options: { id: number }) => {
try {
const { id } = options;

let query = `/liked/${id}`;

const res = await client.delete(query);

return res;
} catch (e) {
console.error(e);
}
};

// 여행 상품 리뷰 조회
export const getToursReviews = async (tourItemId: number) => {
const res = await client.get(`tours/${tourItemId}/reviews`);
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 @@ -75,7 +75,7 @@ export default function DetailReviews({ reviewData }: reviewProps) {

return (
<>
<div className="mb-4 mt-2 text-lg font-bold">
<div className="mb-4 mt-2 text-lg font-bold" id="scrollToReview">
리뷰<span className="pl-1 text-gray4">{reviewDataLength}</span>
</div>
{reviewDataLength > 0 && (
Expand Down
54 changes: 44 additions & 10 deletions src/components/DetailSectionTop/DetailToursInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,47 @@
import { HeartIcon } from '@components/common/icons/Icons';
import { postLikedTours, deleteLikedTours } from '@api/tours';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';

interface DetailToursInfoProps {
infoData: tourDetail;
}

export default function DetailToursInfo({ infoData }: DetailToursInfoProps) {
const { title, liked, originalThumbnailUrl } = infoData;
const { title, liked, originalThumbnailUrl, id } = infoData;

const navigate = useNavigate();
const queryClient = useQueryClient();

const { mutate: likeMutate } = useMutation({
mutationFn: (id: number) => postLikedTours({ id }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['details'] });
},
onError: () => console.log('error'),
});

const { mutate: unlikeMutate } = useMutation({
mutationFn: (id: number) => deleteLikedTours({ id }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['details'] });
},
onError: () => console.log('error'),
});

const onClickLikeButton = () => {
const token = localStorage.getItem('accessToken');
if (!token) {
// 비로그인 알람창 처리 필요
navigate('/signin');
} else {
if (liked === false) {
likeMutate(id);
} else {
unlikeMutate(id);
}
}
};

return (
<>
Expand All @@ -20,15 +56,13 @@ export default function DetailToursInfo({ infoData }: DetailToursInfoProps) {
<h1 className="font-['Pretendard'] text-2xl font-bold text-black ">
{title}
</h1>
{liked ? (
<div className="top-75 h-[24px] w-[24px] cursor-pointer">
<HeartIcon fill="#FF2167" color="none" />
</div>
) : (
<div className="top-75 h-[24px] w-[24px] cursor-pointer">
<HeartIcon fill="#D7D7D7" color="none" />
</div>
)}
<div className="top-75 h-[24px] w-[24px] cursor-pointer">
<HeartIcon
fill={liked ? '#FF2167' : '#D7D7D7'}
color="none"
onClick={onClickLikeButton}
/>
</div>
</div>
</>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/DetailSectionTop/DetailToursMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export default function DetailToursMap({ mapData }: DetailToursMapProps) {
)}
</div>

<CheckIcon onClick={closeMap} size={17} className="cursor-pointer" />
<div className="cursor-pointer">
<CheckIcon onClick={closeMap} size={17} />
</div>
</div>
<div className="flex justify-center">
<Map
Expand Down
66 changes: 34 additions & 32 deletions src/components/DetailSectionTop/DetailToursRating.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';

import { Link } from 'react-scroll';
interface ReviewData {
ratingAverage: number;
reviewTotalCount: number;
Expand Down Expand Up @@ -35,38 +35,40 @@ export default function DetailToursRating({
}, []);

return (
<div className="flex w-full items-center ">
{STAR_IDX_ARR.map((item, idx) => {
return (
<span key={`${item}+${idx}`}>
<svg
width="16"
height="15"
viewBox="0 0 16 15"
fill="#EDEDED"
xmlns="http://www.w3.org/2000/svg">
<clipPath id={`${item}StarClip`}>
<rect width={`${ratedStarArr[idx]}`} height="15" />
</clipPath>
<path
id={`${item}star`}
d="M7.46447 0.974901C7.76382 0.0535908 9.06723 0.0535913 9.36658 0.974902L10.4362 4.2667C10.57 4.67872 10.954 4.95768 11.3872 4.95768H14.8484C15.8171 4.95768 16.2199 6.1973 15.4362 6.7667L12.636 8.80114C12.2855 9.05578 12.1389 9.50715 12.2728 9.91917L13.3423 13.211C13.6417 14.1323 12.5872 14.8984 11.8035 14.329L9.00331 12.2946C8.65283 12.0399 8.17823 12.0399 7.82774 12.2946L5.02757 14.329C4.24386 14.8984 3.18938 14.1323 3.48873 13.211L4.5583 9.91917C4.69217 9.50715 4.54552 9.05578 4.19503 8.80114L1.39486 6.7667C0.611146 6.1973 1.01392 4.95768 1.98265 4.95768H5.44385C5.87707 4.95768 6.26103 4.67872 6.3949 4.2667L7.46447 0.974901Z"
/>
<use
clipPath={`url(#${item}StarClip)`}
href={`#${item}star`}
fill="#FFEC3E"
/>
</svg>
</span>
);
})}
<Link to="scrollToReview" spy={true} smooth={true}>
<div className="flex w-full cursor-pointer items-center">
{STAR_IDX_ARR.map((item, idx) => {
return (
<span key={`${item}+${idx}`}>
<svg
width="16"
height="15"
viewBox="0 0 16 15"
fill="#EDEDED"
xmlns="http://www.w3.org/2000/svg">
<clipPath id={`${item}StarClip`}>
<rect width={`${ratedStarArr[idx]}`} height="15" />
</clipPath>
<path
id={`${item}star`}
d="M7.46447 0.974901C7.76382 0.0535908 9.06723 0.0535913 9.36658 0.974902L10.4362 4.2667C10.57 4.67872 10.954 4.95768 11.3872 4.95768H14.8484C15.8171 4.95768 16.2199 6.1973 15.4362 6.7667L12.636 8.80114C12.2855 9.05578 12.1389 9.50715 12.2728 9.91917L13.3423 13.211C13.6417 14.1323 12.5872 14.8984 11.8035 14.329L9.00331 12.2946C8.65283 12.0399 8.17823 12.0399 7.82774 12.2946L5.02757 14.329C4.24386 14.8984 3.18938 14.1323 3.48873 13.211L4.5583 9.91917C4.69217 9.50715 4.54552 9.05578 4.19503 8.80114L1.39486 6.7667C0.611146 6.1973 1.01392 4.95768 1.98265 4.95768H5.44385C5.87707 4.95768 6.26103 4.67872 6.3949 4.2667L7.46447 0.974901Z"
/>
<use
clipPath={`url(#${item}StarClip)`}
href={`#${item}star`}
fill="#FFEC3E"
/>
</svg>
</span>
);
})}

<div className="h-3 pl-1">
<p className="text-xs font-normal leading-4 text-gray4 ">
{reviewTotalCount}
</p>
<div className="h-3 pl-1">
<p className="text-xs font-normal leading-4 text-gray4 ">
({reviewTotalCount})
</p>
</div>
</div>
</div>
</Link>
);
}
1 change: 0 additions & 1 deletion src/components/DetailSectionTop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import DetailToursRating from './DetailToursRating';
import DetailToursMap from './DetailToursMap';
import DetailToursButtons from './DetailToursButtons';


export {
DetailToursInfo,
DetailToursRating,
Expand Down
4 changes: 3 additions & 1 deletion src/components/common/icons/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ export const HeartIcon: React.FC<IconProps> = ({
size = 25,
color = 'black',
fill = 'none',
onClick,
}) => {
return (
<svg
onClick={onClick}
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
Expand Down Expand Up @@ -470,7 +472,7 @@ export const ChatIcon: React.FC<IconProps> = ({
xmlns="http://www.w3.org/2000/svg">
<g
id="mail-chat-bubble-typing-oval--messages-message-bubble-typing-chat"
clip-path="url(#clip0_447_1104)">
clipPath="url(#clip0_447_1104)">
<g id="Group">
<path
id="Vector"
Expand Down