Skip to content

Commit

Permalink
Merge pull request #101 from SOPT-all/develop
Browse files Browse the repository at this point in the history
merge to main
  • Loading branch information
seong-hui authored Nov 29, 2024
2 parents 06f2dfb + e3be852 commit df17a55
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 79 deletions.
11 changes: 11 additions & 0 deletions src/apis/productPage/order/orderProduct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import instance from '@apis/instance';

const fetchOrderProduct = async (productId: number) => {
const response = await instance.post(`/api/order`, {
productId,
});

return response.data;
};

export default fetchOrderProduct;
15 changes: 15 additions & 0 deletions src/apis/productPage/order/orderQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import fetchOrderProduct from '@apis/productPage/order/orderProduct';
import { useMutation, useQueryClient } from '@tanstack/react-query';

const useOrderProduct = () => {
const queryClient = useQueryClient();

const mutation = useMutation({
mutationFn: (productId: number) => fetchOrderProduct(productId),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['order'] }),
});

return { mutate: mutation.mutate };
};

export default useOrderProduct;
36 changes: 36 additions & 0 deletions src/apis/productPage/review/getReview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import instance from '@apis/instance';
import { AxiosError } from 'axios';

export interface Review {
reviewId: number;
username: string;
rating: number;
isMonth: boolean;
contentKorean: string;
contentOriginal: string;
reviewImage: string;
usefulCount: number;
recommendCount: number;
likeCount: number;
}

export interface GetReviewResponse {
success: boolean;
data: {
goodReviews: Review[];
badReviews: Review[];
};
error: null | string;
}

export const getReview = async (productId: number): Promise<GetReviewResponse> => {
try {
const response = await instance.get<GetReviewResponse>(`/api/products/${productId}/reviews`);
return response.data;
} catch (error) {
if (error instanceof AxiosError) {
throw error.response?.data || new Error('An error occurred');
}
throw error;
}
};
18 changes: 18 additions & 0 deletions src/apis/productPage/review/reviewQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useQuery } from '@tanstack/react-query';

import { getReview, GetReviewResponse } from './getReview';

const useReviewQueries = ({ productId }: { productId: number }) => {
const QUERY_KEY = {
PRODUCT_REVIEW: 'review',
};

const { data, error } = useQuery<GetReviewResponse>({
queryKey: [QUERY_KEY.PRODUCT_REVIEW, productId],
queryFn: () => getReview(productId),
});

return { data, error };
};

export default useReviewQueries;
3 changes: 3 additions & 0 deletions src/assets/icons/ic_dot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@ export { default as ImgLine } from '../images/Line 18.svg';
export { default as ImgVector7192 } from '../images/Vector 7192.svg';
export { default as ImgProfile30 } from '../images/img_profile_30.svg';
export { default as ImgGraph } from '@assets/images/img_graph.svg';
export { default as IcDot } from './ic_dot.svg';
10 changes: 8 additions & 2 deletions src/components/ProductInfo/ProductInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IcInfoGray14, IcWarningBrandYellow16 } from '@assets/icons';
import { IcInfoGray14, IcWarningBrandYellow16, IcDot } from '@assets/icons';
import bannerRewordImg from '@assets/images/img_banner_reward.png';
import productSubImg1 from '@assets/images/img_product_sub1.png';
import { productOptionImages, productSubImages } from '@assets/images/productDetailImages';
import StarBtn from '@components/button/starBtn/StarBtn';
import {
productInfoContainerStyle,
proudctImgLayoutStyle,
Expand All @@ -25,6 +26,7 @@ import {
endSaleTiemStyle,
reviewBoxStyle,
columnflexStyle,
reivewBoxStyle,
} from '@components/ProductInfo/ProductInfoStyle';

const ProductInfo = () => (
Expand Down Expand Up @@ -55,7 +57,11 @@ const ProductInfo = () => (
67W
</div>
</div>
<div css={reviewBoxStyle}>5,000+개 판매</div>
<div css={reivewBoxStyle}>
<StarBtn rating={4.8} reviewCount={123} />
<IcDot />
<div css={reviewBoxStyle}>5,000+개 판매</div>
</div>
<div css={mediumDividerStyle} />
<div css={optionStyle}>색상: 검정</div>
<section css={optionImgStyle}>
Expand Down
10 changes: 10 additions & 0 deletions src/components/ProductInfo/ProductInfoStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export const productNameStyle = (theme: Theme) => css`
`;

export const reviewBoxStyle = (theme: Theme) => css`
display: flex;
align-items: center;
width: 100%;
height: 2rem;
Expand Down Expand Up @@ -170,3 +172,11 @@ export const columnflexStyle = css`
display: flex;
flex-direction: column;
`;

export const reivewBoxStyle = css`
display: flex;
gap: 0.6rem;
align-items: center;
height: 2rem;
`;

10 changes: 8 additions & 2 deletions src/components/button/starBtn/StarBtnStyle.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { css, Theme } from '@emotion/react';

export const starBtnContainerStyle = css`
const flexBoxStyle = css`
display: flex;
align-items: center;
width: 11.5rem;
height: 2rem;
`;

export const starBtnContainerStyle = css`
width: 11.5rem;
background-color: transparent;
border: none;
${flexBoxStyle}
`;

export const startIconBoxStyle = css`
Expand All @@ -20,10 +24,12 @@ export const ratingStyle = (theme: Theme) => css`
margin-left: 0.6rem;
${theme.fonts.eng.captionBold11};
${flexBoxStyle}
`;

export const reviewCountSTyle = (theme: Theme) => css`
margin-left: 0.4rem;
${flexBoxStyle}
${theme.fonts.eng.captionMedium12};
`;
132 changes: 77 additions & 55 deletions src/components/orderBox/OrderBox.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useOrderProduct from '@apis/productPage/order/orderQuery';
import {
IcMapBlackStorke18,
IcDeliveryBlack20,
Expand Down Expand Up @@ -31,69 +32,90 @@ import {
engCaptionBoldStyle,
orderBtnWrapperStyle,
emojiBtnWrapperStyle,
freeDeliveryText,
} from '@components/orderBox/OrderboxStyle';
import FreeTag from '@components/product/FreeTag';
import { useNavigate } from 'react-router-dom';

const OrderBox = () => (
<article css={orderBoxContinerStyle}>
<section css={orderInfoLayoutStyle}>
<div css={orderTitleWrapperStyle}>
<p css={korTitleStyle}>배송지:</p>
<div css={adressStyle}>
<IcMapBlackStorke18 />
<p>Gangnam-gu, Seoul, Korea</p>
const OrderBox = () => {
const navigate = useNavigate();
const { mutate: orderProduct } = useOrderProduct();

const handleOrderBtnClick = (productId: number) => {
orderProduct(productId, {
onSuccess: (response) => {
if (response.success) {
navigate('/order');
}
},
onError: (error) => {
console.error(error);
},
});
};

return (
<article css={orderBoxContinerStyle}>
<section css={orderInfoLayoutStyle}>
<div css={orderTitleWrapperStyle}>
<p css={korTitleStyle}>배송지:</p>
<div css={adressStyle}>
<IcMapBlackStorke18 />
<p>Gangnam-gu, Seoul, Korea</p>
</div>
</div>
</div>
<div css={dividerStyle} />
<section css={orderInfoLayouttyle}>
<div>
<div css={freeOrderInfoWrapperStyle}>
<div css={flexBoxStyle}>
<IcDeliveryBlack20 />
<span css={korTitleStyle}>무료 배송</span>
{/* 영경이가 만든 무료 반품 버튼 넣기 */}
<div css={dividerStyle} />
<section css={orderInfoLayouttyle}>
<div>
<div css={freeOrderInfoWrapperStyle}>
<div css={flexBoxStyle}>
<IcDeliveryBlack20 />
<span css={freeDeliveryText}>무료 배송</span>
<FreeTag text="무료 반품" color="gray" />
</div>
<IcArrowrightSBlack24 />
</div>
<div css={arrivalDateWrapperStyle}>
<span css={arriveTitleStyle}>도착일:</span>
<span css={engTitleStyle}>11 월 19 일-26 일</span>
</div>
<IcArrowrightSBlack24 />
</div>
<div css={arrivalDateWrapperStyle}>
<span css={arriveTitleStyle}>도착일:</span>
<span css={engTitleStyle}>11 월 19 일-26 일</span>
<div css={privacyInfoLayoutStyle}>
<div css={privacyTitleBoxStyle}>
<IcShieldBlack20 />
<span css={korTitleStyle}>개인 정보 보호</span>
</div>
<div css={descriptionBoxStyle}>
<p>안심 결제: 카드 정보는 안전하게 보호되며 유출되지 않습니다.</p>
<p>개인정보 보호: 개인정보 보안을 최우선으로 생각합니다.</p>
</div>
</div>
</div>
<div css={privacyInfoLayoutStyle}>
<div css={privacyTitleBoxStyle}>
<IcShieldBlack20 />
<span css={korTitleStyle}>개인 정보 보호</span>
</section>
</section>
<div css={dividerStyle} />
<section css={orderButtonsLayoutStyle}>
<div css={korTitleStyle}>수량</div>
<section css={countButtonsStyle}>
<div css={iconWrapperStyle}>
<IcCountdownGray18 />
</div>
<div css={descriptionBoxStyle}>
<p>안심 결제: 카드 정보는 안전하게 보호되며 유출되지 않습니다.</p>
<p>개인정보 보호: 개인정보 보안을 최우선으로 생각합니다.</p>
<p css={engCaptionBoldStyle}>1</p>
<div css={iconWrapperStyle}>
<IcCountupGray18 />
</div>
</div>
</section>
</section>
<div css={dividerStyle} />
<section css={orderButtonsLayoutStyle}>
<div css={korTitleStyle}>수량</div>
<section css={countButtonsStyle}>
<div css={iconWrapperStyle}>
<IcCountdownGray18 />
</div>
<p css={engCaptionBoldStyle}>1</p>
<div css={iconWrapperStyle}>
<IcCountupGray18 />
</div>
</section>
<section css={orderBtnWrapperStyle}>
<TextBtn btnText="바로 구매" color="red" size="large" />
<TextBtn btnText="장바구니 담기" color="black" size="large" />
<div css={emojiBtnWrapperStyle}>
<EmojiBtn type="seller" />
<EmojiBtn type="share" />
<LikeBtn />
</div>
</section>
<section css={orderBtnWrapperStyle}>
<TextBtn btnText="바로 구매" color="red" size="large" onClick={() => handleOrderBtnClick(1)} />
<TextBtn btnText="장바구니 담기" color="black" size="large" />
<div css={emojiBtnWrapperStyle}>
<EmojiBtn type="seller" />
<EmojiBtn type="share" />
<LikeBtn />
</div>
</section>
</section>
</section>
</article>
);
</article>
);
};

export default OrderBox;
7 changes: 6 additions & 1 deletion src/components/orderBox/OrderboxStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export const korTitleStyle = (theme: Theme) => css`
${theme.fonts.kor.captionBold12}
`;

export const freeDeliveryText = (theme: Theme) => css`
margin-right: 0.6rem;
${theme.fonts.kor.captionBold12}
`;

export const engTitleStyle = (theme: Theme) => css`
${theme.fonts.eng.captionMedium12}
`;
Expand Down Expand Up @@ -70,7 +75,7 @@ export const freeOrderInfoWrapperStyle = css`
export const flexBoxStyle = css`
display: flex;
align-items: center;
height: 100%;
height: 2rem;
`;

export const arrivalDateWrapperStyle = css`
Expand Down
Loading

0 comments on commit df17a55

Please sign in to comment.