From 8d2134b0987690e6f61457133cbb35d49afdc8a0 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Wed, 5 Apr 2023 16:17:08 +0900 Subject: [PATCH 1/9] =?UTF-8?q?:sparkles:=20feat:=20interface=20InfiniteQu?= =?UTF-8?q?eryPromise=EC=9D=98=20data=20=ED=83=80=EC=9E=85=20=EC=A0=9C?= =?UTF-8?q?=EB=84=A4=EB=A6=AD=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20#29?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/apis/itemApis.ts | 9 +++++---- client/src/types/itemList.type.ts | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/client/src/apis/itemApis.ts b/client/src/apis/itemApis.ts index fe676fe0..0881e7f8 100644 --- a/client/src/apis/itemApis.ts +++ b/client/src/apis/itemApis.ts @@ -2,16 +2,17 @@ import { FetchCathgoryItems, FetchSearchItems, InfiniteQueryPromise, + Item, } from '../types/itemList.type'; import axiosInstance from '../utils/axiosInstance'; -import { FetchOrderListsProps } from '../types/order.type'; +import { FetchOrderListsProps, OrderListData } from '../types/order.type'; export const fetchCathgoryItems = async ({ category, path, query, pageParam, -}: FetchCathgoryItems): Promise => { +}: FetchCathgoryItems): Promise> => { const res = await axiosInstance.get( `/category${path}?categoryName=${category}${query}&page=${pageParam}&size=12`, ); @@ -30,7 +31,7 @@ export const fetchSearchItems = async ({ path, query, pageParam, -}: FetchSearchItems): Promise => { +}: FetchSearchItems): Promise> => { const res = await axiosInstance.get( `/search${path}?keyword=${keyword}${query}&page=${pageParam}&size=12`, ); @@ -48,7 +49,7 @@ export const fetchSearchItems = async ({ export const fetchOrderLists = async ({ pageParam, isSub, -}: FetchOrderListsProps): Promise => { +}: FetchOrderListsProps): Promise> => { const res = await axiosInstance.get( `/orders?subscription=${isSub}&page=${pageParam}&size=7`, ); diff --git a/client/src/types/itemList.type.ts b/client/src/types/itemList.type.ts index 63500d02..ba6bc3d3 100644 --- a/client/src/types/itemList.type.ts +++ b/client/src/types/itemList.type.ts @@ -33,8 +33,8 @@ export interface FetchSearchItems extends GetList { keyword: string; } -export interface InfiniteQueryPromise { - data: Item[]; +export interface InfiniteQueryPromise { + data: T; nextPage: number; isLast: boolean; } From 6d966ecd2471959684a85803b15a12cd2f6c9094 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Wed, 5 Apr 2023 16:18:20 +0900 Subject: [PATCH 2/9] =?UTF-8?q?:recycle:=20refactor:=20=EC=A3=BC=EB=AC=B8?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=ED=8E=98=EC=9D=B4=EC=A7=80=20(=EC=9D=BC?= =?UTF-8?q?=EB=B0=98)=20=ED=83=80=EC=9E=85=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=81=EC=9A=A9=20#293?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MyPageLists/{OrderList.js => OrderList.tsx} | 7 +++---- .../MyPages/{NormalOrder.js => NormalOrder.tsx} | 2 +- client/src/types/order.type.ts | 13 +++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) rename client/src/components/Lists/MyPageLists/{OrderList.js => OrderList.tsx} (95%) rename client/src/pages/MyPages/{NormalOrder.js => NormalOrder.tsx} (98%) diff --git a/client/src/components/Lists/MyPageLists/OrderList.js b/client/src/components/Lists/MyPageLists/OrderList.tsx similarity index 95% rename from client/src/components/Lists/MyPageLists/OrderList.js rename to client/src/components/Lists/MyPageLists/OrderList.tsx index def13b2b..0a73410d 100644 --- a/client/src/components/Lists/MyPageLists/OrderList.js +++ b/client/src/components/Lists/MyPageLists/OrderList.tsx @@ -8,13 +8,12 @@ import { DotDate } from '../../Etc/ListDate'; import Price from '../../Etc/Price'; import CancelModal from '../../Modals/CancelModal'; import { useDelete } from '../../../hooks/useFetch'; +import { OrderListData } from '../../../types/order.type'; -function OrderList({ list }) { +function OrderList({ list }: { list: OrderListData }) { const navigate = useNavigate(); const [openCancel, setOpenCancel] = useState(false); - const { mutate, isLoading, isError, error, response } = useDelete( - `/orders/${list.orderId}`, - ); + const { mutate } = useDelete(`/orders/${list.orderId}`); const handlePageMove = useCallback(() => { navigate(`/detail/${list.item.itemId}`); diff --git a/client/src/pages/MyPages/NormalOrder.js b/client/src/pages/MyPages/NormalOrder.tsx similarity index 98% rename from client/src/pages/MyPages/NormalOrder.js rename to client/src/pages/MyPages/NormalOrder.tsx index a1cbc5b9..92dfdd28 100644 --- a/client/src/pages/MyPages/NormalOrder.js +++ b/client/src/pages/MyPages/NormalOrder.tsx @@ -42,7 +42,7 @@ function NormalOrder() { return ( <> - {data.pages[0].data.length === 0 ? ( + {data?.pages[0].data.length === 0 ? ( {NO_ORDER_HISTORY} ) : ( data?.pages.map((page, i) => ( diff --git a/client/src/types/order.type.ts b/client/src/types/order.type.ts index b0d1f20c..d5aaa709 100644 --- a/client/src/types/order.type.ts +++ b/client/src/types/order.type.ts @@ -1,3 +1,5 @@ +import { ItemShortcutData } from './item.type'; + export interface UseGetOrderListProps { pathname: string; isSub: boolean; @@ -7,3 +9,14 @@ export interface FetchOrderListsProps { pageParam: number; isSub: boolean; } + +export interface OrderListData { + createdAt: Date; + expectPrice: number; + item: ItemShortcutData; + orderId: number; + orderStatus: string; + subscription: boolean; + totalItems: number; + updatedAt: Date; +} From db1c00d47bb31773577721e89905b7c1f9f4f771 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Wed, 5 Apr 2023 16:20:49 +0900 Subject: [PATCH 3/9] =?UTF-8?q?:recycle:=20refactor:=20=EC=A3=BC=EB=AC=B8?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=ED=8E=98=EC=9D=B4=EC=A7=80(=EC=A0=95?= =?UTF-8?q?=EA=B8=B0)=20=ED=83=80=EC=9E=85=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=81=EC=9A=A9=20#293?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MyPages/{SubscriptionOrder.js => SubscriptionOrder.tsx} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename client/src/pages/MyPages/{SubscriptionOrder.js => SubscriptionOrder.tsx} (94%) diff --git a/client/src/pages/MyPages/SubscriptionOrder.js b/client/src/pages/MyPages/SubscriptionOrder.tsx similarity index 94% rename from client/src/pages/MyPages/SubscriptionOrder.js rename to client/src/pages/MyPages/SubscriptionOrder.tsx index ac8e04c0..d8455150 100644 --- a/client/src/pages/MyPages/SubscriptionOrder.js +++ b/client/src/pages/MyPages/SubscriptionOrder.tsx @@ -43,13 +43,13 @@ function SubscriptionOrder() { return ( <> - {data.pages[0].data.length === 0 ? ( + {data?.pages[0].data.length === 0 ? ( {NO_ORDER_HISTORY} ) : ( data?.pages.map((page, i) => ( {page.data.map((list) => ( - + ))} )) From 3ca3fed7c10f21f542c3003152f06813eb43bb1d Mon Sep 17 00:00:00 2001 From: uxolrv Date: Thu, 6 Apr 2023 00:07:38 +0900 Subject: [PATCH 4/9] =?UTF-8?q?:recycle:=20refactor:=20=EC=A3=BC=EB=AC=B8?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=EC=83=81=EC=84=B8=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=83=80=EC=9E=85=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=A0=81=EC=9A=A9=20#293?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...OrderDetailList.js => OrderDetailList.tsx} | 42 ++++---- .../{OrderDetail.js => OrderDetail.tsx} | 98 ++++++++++--------- client/src/types/order.type.ts | 22 +++++ 3 files changed, 92 insertions(+), 70 deletions(-) rename client/src/components/Lists/MyPageLists/{OrderDetailList.js => OrderDetailList.tsx} (82%) rename client/src/pages/MyPages/{OrderDetail.js => OrderDetail.tsx} (52%) diff --git a/client/src/components/Lists/MyPageLists/OrderDetailList.js b/client/src/components/Lists/MyPageLists/OrderDetailList.tsx similarity index 82% rename from client/src/components/Lists/MyPageLists/OrderDetailList.js rename to client/src/components/Lists/MyPageLists/OrderDetailList.tsx index daa66a33..491ada8d 100644 --- a/client/src/components/Lists/MyPageLists/OrderDetailList.js +++ b/client/src/components/Lists/MyPageLists/OrderDetailList.tsx @@ -7,6 +7,7 @@ import { useNavigate } from 'react-router-dom'; import { LetterButtonColor } from '../../Buttons/LetterButton'; import Price from '../../Etc/Price'; import ReviewModal from '../../Modals/ReviewModal'; +import { OrderDetailListProps } from '../../../types/order.type'; function OrderDetailList({ inModal, @@ -16,14 +17,14 @@ function OrderDetailList({ nowPrice, beforePrice, discountRate, - itemOrderId, // 주문내역 속 개별아이템 주문id! + itemOrderId, // 주문내역 속 개별아이템 주문id capacity, quantity, period, subscription, orderStatus, itemId, -}) { +}: OrderDetailListProps) { const [modalIsOpen, setIsOpen] = useState(false); const navigate = useNavigate(); @@ -51,12 +52,12 @@ function OrderDetailList({ }; return ( - + 상품 이미지 - + {brand} {`${title}${ capacity && `, ${capacity}정` @@ -69,8 +70,8 @@ function OrderDetailList({ {quantity && {quantity}개 / } 리뷰 쓰기 @@ -101,17 +102,15 @@ function OrderDetailList({ ); } -const Box = styled.div` +const Box = styled.div<{ inModal?: boolean }>` border-bottom: 1px solid rgb(235, 235, 235); background-color: white; width: 450px; height: 180px; display: flex; align-items: center; - padding: 19px; - &.in-modal { - width: 100%; - } + padding: 18px 10px 18px 18px; + width: ${({ inModal }) => (inModal ? '100%' : '450px')}; `; const Wrap = styled.div` @@ -119,7 +118,7 @@ const Wrap = styled.div` flex-direction: column; margin-left: 20px; width: 100%; - position: relative; + margin-top: 2px; `; const ImageContainer = styled.div` @@ -135,11 +134,8 @@ const Image = styled.img` align-items: center; `; -const InformationForm = styled.div` - margin-bottom: 23px; - &.subscription { - margin-bottom: 12px; - } +const InformationForm = styled.div<{ subscription: boolean }>` + margin-bottom: ${({ subscription }) => (subscription ? '14px' : '23px')}; `; const Brand = styled.div` @@ -164,14 +160,12 @@ const BottomContainer = styled.div` const Total = styled.div` display: flex; font-weight: var(--bold); + align-items: center; `; const Period = styled.div` color: var(--purple-200); - /* position: relative; */ - margin-bottom: 4px; - /* top: -15px; */ - /* right: 0; */ + margin-bottom: 5px; font-size: 12px; `; @@ -184,9 +178,7 @@ const ReviewContainer = styled.div` align-items: center; cursor: pointer; align-self: end; - position: absolute; - bottom: -25px; - right: -12px; + margin-top: 4px; * { color: var(--gray-500); } diff --git a/client/src/pages/MyPages/OrderDetail.js b/client/src/pages/MyPages/OrderDetail.tsx similarity index 52% rename from client/src/pages/MyPages/OrderDetail.js rename to client/src/pages/MyPages/OrderDetail.tsx index a65dfdd8..76a18974 100644 --- a/client/src/pages/MyPages/OrderDetail.js +++ b/client/src/pages/MyPages/OrderDetail.tsx @@ -8,61 +8,60 @@ import CustomerInformation from '../../components/Etc/CustomerInformation'; import PaymentSummary from '../../components/Etc/PaymentSummary'; import { useGet } from '../../hooks/useFetch'; import { LoadingSpinner } from '../../components/Etc/LoadingSpinner'; +import { ERROR_INFORMATION } from '../../components/Etc/Constants'; +import { OrderDetailData } from '../../types/order.type'; // 주문내역 상세조회 function OrderDetail() { const { pathname } = useLocation(); const { id } = useParams(); - const { isLoading, isError, data, error } = useGet(`/orders/${id}`, pathname); + const { isLoading, isError, data, error } = useGet( + `/orders/${id}`, + pathname, + ); + + const lists = !isLoading && data?.data?.data.itemOrders.data; + const info = !isLoading && data?.data?.data; - if (isLoading) { + if (isLoading || !lists || !info) { return ; } - if (isError) { - return
Error: {error.message}
; + if (isError && error instanceof Error) { + return
{ERROR_INFORMATION}
; } - const lists = !isLoading && data.data.data.itemOrders.data; - const info = !isLoading && data.data.data; - - const payData = { - totalPrice: info.totalPrice, - totalDiscountPrice: info.totalDiscountPrice, - expectPrice: info.expectPrice, - }; - return ( - + 주문 상세 내역 - {data && - lists.map((list) => ( - - ))} + + {data && + lists.map((list) => ( + + ))} + ); @@ -93,32 +92,41 @@ const LeftContainer = styled.section` `; const RightContainer = styled(LeftContainer)` + padding: 0px 0px 40px 0px; +`; + +const ListContainer = styled.div` align-items: center; display: flex; + flex-direction: column; justify-content: flex-start; position: relative; padding: 0px; overflow-x: visible; - width: 510px; padding-bottom: 30px; - overflow-y: scroll; + overflow-y: auto; + scroll-behavior: smooth; + ::-webkit-scrollbar { - display: none; + width: 11px; + } + + ::-webkit-scrollbar-thumb { + background-color: rgb(235, 235, 235); + border-radius: 10px; + background-clip: padding-box; + border: 2px solid transparent; } `; const Title = styled.h1` font-size: 20px; font-weight: var(--bold); - align-self: flex-start; - position: sticky; + border-radius: 10px; width: 100%; - top: 0px; - padding: 70px 0 20px 0; + padding: 70px 0 16px 0; background-color: white; - &.order { - padding-left: 50px; - } + padding-left: 50px; `; export default React.memo(OrderDetail); diff --git a/client/src/types/order.type.ts b/client/src/types/order.type.ts index d5aaa709..3039dd5c 100644 --- a/client/src/types/order.type.ts +++ b/client/src/types/order.type.ts @@ -1,4 +1,5 @@ import { ItemShortcutData } from './item.type'; +import { PayData } from './payment.type'; export interface UseGetOrderListProps { pathname: string; @@ -20,3 +21,24 @@ export interface OrderListData { totalItems: number; updatedAt: Date; } + +export interface OrderDetailListProps { + inModal?: boolean; + itemOrderId: number; + itemId: number; + brand: string; + thumbnail: string; + title: string; + quantity: number; + nowPrice: number; + discountRate: number; + beforePrice: number; + period: number; + subscription: boolean; + capacity: number; + orderStatus: string; +} + +export interface OrderDetailData { + data: PayData; +} From 67f1025cd33cf04c129036363857a4394cc868bc Mon Sep 17 00:00:00 2001 From: uxolrv Date: Fri, 7 Apr 2023 01:51:09 +0900 Subject: [PATCH 5/9] =?UTF-8?q?:bug:=20fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EC=95=98=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=EC=9D=98=20=EC=A0=84=EC=B2=B4=20=EC=9C=84?= =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EB=A7=89=EA=B8=B0=20#299?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ItemSummary/ItemSummary.tsx | 8 +++-- client/src/hooks/useGetWishes.ts | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 client/src/hooks/useGetWishes.ts diff --git a/client/src/components/ItemSummary/ItemSummary.tsx b/client/src/components/ItemSummary/ItemSummary.tsx index 6d82ce11..5196ff7c 100644 --- a/client/src/components/ItemSummary/ItemSummary.tsx +++ b/client/src/components/ItemSummary/ItemSummary.tsx @@ -10,7 +10,8 @@ import { PeriodChoiceTab } from '../Tabs/ToggleTabs'; import { LongTextStar } from '../Stars/TextStar'; import Price, { SummaryPrice } from '../Etc/Price'; import CartModal from '../Modals/CartModal'; -import { usePost, useGet } from '../../hooks/useFetch'; +import useGetWishes from '../../hooks/useGetWishes'; +import { usePost } from '../../hooks/useFetch'; import usePurchase from '../../hooks/usePurchase'; interface ItemSummaryProps { @@ -51,7 +52,10 @@ function ItemSummary({ subscription: false, }); - const { data: WishData } = useGet('/wishes/item', `detail/wishs`); + const { data: WishData } = useGetWishes<{ data: number[] }>( + '/wishes/item', + `detail/wishs`, + ); const [isCheckedWish, setIsCheckedWish] = useState( WishData?.data?.data.includes(itemId) ? 1 : 0, ); diff --git a/client/src/hooks/useGetWishes.ts b/client/src/hooks/useGetWishes.ts new file mode 100644 index 00000000..882a56f5 --- /dev/null +++ b/client/src/hooks/useGetWishes.ts @@ -0,0 +1,29 @@ +import { AxiosResponse, AxiosError } from 'axios'; +import { useState } from 'react'; +import { useQuery } from 'react-query'; +import axiosInstance from '../utils/axiosInstance'; + +// 상세페이지 - 유저의 전체 위시리스트 조회 +export default function useGetWishes(url: string, keyValue: string) { + const token = localStorage.getItem('accessToken'); + // 상태 코드가 403이면 토큰 만료, 재로그인해야 함 (선택사항) + const [errorStatus, setErrorStatus] = useState(0); + + // 로그인이 되어있지 않을 때 wishlist 조회 요청 x + if (!token) { + return { errorStatus }; + } + + const { isLoading, isError, isSuccess, data, error, refetch } = useQuery< + AxiosResponse + >([keyValue], () => axiosInstance.get(url), { + onError: async (errRes) => { + const { response } = errRes as AxiosError; + if (response) { + setErrorStatus(response.status); + } + }, + }); + + return { isLoading, isError, isSuccess, data, error, errorStatus, refetch }; +} From 17a222812c240bfb492928758138981c3b81ee18 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Fri, 7 Apr 2023 01:55:11 +0900 Subject: [PATCH 6/9] =?UTF-8?q?:sparkles:=20feat:=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=A0=91=EA=B7=BC=20=EC=8B=9C=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EB=9D=84=EC=9A=B0=EA=B8=B0=20#298?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Buttons/WishlistButton.tsx | 12 ++++++--- .../components/ItemSummary/ItemSummary.tsx | 26 +++++++++---------- client/src/types/button.type.ts | 3 ++- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/client/src/components/Buttons/WishlistButton.tsx b/client/src/components/Buttons/WishlistButton.tsx index ccba1c3d..7b0070d8 100644 --- a/client/src/components/Buttons/WishlistButton.tsx +++ b/client/src/components/Buttons/WishlistButton.tsx @@ -1,18 +1,22 @@ import styled from 'styled-components'; import { FaHeart } from 'react-icons/fa'; import { useCallback, useState } from 'react'; -import { toast } from 'react-toastify'; import { usePost } from '../../hooks/useFetch'; import { WishlistBtnProps } from '../../types/button.type'; -function WishlistButton({ isChecked, itemId, setIsChecked }: WishlistBtnProps) { +function WishlistButton({ + isChecked, + itemId, + setIsChecked, + setOpenLoginModal, +}: WishlistBtnProps) { const [request, setRequest] = useState(isChecked ? 0 : 1); const token = localStorage.getItem('accessToken'); const { mutate } = usePost(`/wishes/${itemId}?wish=${request}`); const handleHeartClick = useCallback(() => { - if (!token) { - toast.error('로그인이 필요한 서비스입니다.'); + if (!token && setOpenLoginModal) { + setOpenLoginModal(true); return; } mutate(); diff --git a/client/src/components/ItemSummary/ItemSummary.tsx b/client/src/components/ItemSummary/ItemSummary.tsx index 5196ff7c..92159cb2 100644 --- a/client/src/components/ItemSummary/ItemSummary.tsx +++ b/client/src/components/ItemSummary/ItemSummary.tsx @@ -1,7 +1,6 @@ import styled, { keyframes } from 'styled-components'; import { useCallback, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { toast } from 'react-toastify'; import WishlistButton from '../Buttons/WishlistButton'; import Tag from '../Etc/Tag'; import { BlackButton, WhiteButton } from '../Buttons/BlackButton'; @@ -13,6 +12,7 @@ import CartModal from '../Modals/CartModal'; import useGetWishes from '../../hooks/useGetWishes'; import { usePost } from '../../hooks/useFetch'; import usePurchase from '../../hooks/usePurchase'; +import LoginModal from '../Modals/LoginModal'; interface ItemSummaryProps { name: string; @@ -45,6 +45,7 @@ function ItemSummary({ const [path, setPath] = useState(''); // 바로결제하기 클릭 시, 이동할 페이지 const [showOptions, setShowOptions] = useState(false); const [openCartModal, setOpenCartModal] = useState(false); + const [openLoginModal, setOpenLoginModal] = useState(false); const token = localStorage.getItem('accessToken'); const [orderList, setOrdertList] = useState({ quantity: 1, @@ -117,7 +118,7 @@ function ItemSummary({ if (token) { purMu({ ...orderList, itemId }); } else { - toast.error('로그인이 필요한 서비스입니다.'); + setOpenLoginModal(true); } }, [orderList]); @@ -127,7 +128,7 @@ function ItemSummary({ cartMu({ ...orderList }); setOpenCartModal(true); } else { - toast.error('로그인이 필요한 서비스입니다.'); + setOpenLoginModal(true); } }, [orderList]); @@ -140,17 +141,10 @@ function ItemSummary({ } }, [orderList]); - // // 로그인 모달을 띄우는 함수 - // const handleOpenLoginModal = () => { - // if (!token) { - // setOpenLoginModal(true); - // } - // }; - // 로그인 모달 속, 로그인 페이지로 가는 함수 - // const handleLoginMove = useCallback(() => { - // navigate('/login'); - // }, []); + const handleLoginMove = useCallback(() => { + navigate('/login'); + }, []); return ( @@ -159,6 +153,7 @@ function ItemSummary({

{brand}

+
); } diff --git a/client/src/types/button.type.ts b/client/src/types/button.type.ts index 275506bc..81ea1fbe 100644 --- a/client/src/types/button.type.ts +++ b/client/src/types/button.type.ts @@ -37,5 +37,6 @@ export interface PriceButtonProps { export interface WishlistBtnProps { isChecked: boolean | number; itemId: number; - setIsChecked?: (isChecked: number) => void; + setIsChecked?: React.Dispatch>; + setOpenLoginModal?: React.Dispatch>; } From 07b3998a395d3b9e24ab65176c1fdc7b88751c63 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Fri, 7 Apr 2023 02:21:09 +0900 Subject: [PATCH 7/9] =?UTF-8?q?:recycle:=20refactor:=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=83=81=ED=92=88=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20useGet=20hook=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#296?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/Detail.tsx | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/client/src/pages/Detail.tsx b/client/src/pages/Detail.tsx index d05d897f..714a4df5 100644 --- a/client/src/pages/Detail.tsx +++ b/client/src/pages/Detail.tsx @@ -1,22 +1,19 @@ import styled, { keyframes, css } from 'styled-components'; import { useLocation, useParams } from 'react-router-dom'; import { useCallback, useState, useRef, Fragment } from 'react'; -import { useQuery } from 'react-query'; -import { AxiosResponse } from 'axios'; import { toast } from 'react-toastify'; import { IoIosArrowBack } from 'react-icons/io'; import ItemSummary from '../components/ItemSummary/ItemSummary'; import DetailReviewList from '../components/Lists/DetailReviewList'; import DetailTalkList from '../components/Lists/DetailTalkList'; import TalkForm from '../components/Forms/TalkForm'; -import { usePost } from '../hooks/useFetch'; +import { useGet, usePost } from '../hooks/useFetch'; import { DeliveryInfo, ReturnInfo, ProductInfo, } from '../components/Etc/Constants'; import { LoadingSpinner } from '../components/Etc/LoadingSpinner'; -import axiosInstance from '../utils/axiosInstance'; import { DetailReviewsData, DetailTalksData } from '../types/note.type'; import { NutritionFact, ItemShortcutData } from '../types/item.type'; @@ -66,10 +63,10 @@ function Detail() { }; // 상품 상세 조회 - const { isLoading, isError, data, error } = useQuery< - AxiosResponse - >([pathname], () => axiosInstance.get(`/items/${id}`)); - // const { isLoading, isError, data, error } = useGet(`/items/${id}`, pathname); + const { isLoading, isError, data, error } = useGet( + `/items/${id}`, + pathname, + ); // 토크 작성 const { mutate: talkMu } = usePost(`/talks/${id}`); @@ -84,7 +81,6 @@ function Detail() { setContent(''); setIsTalkOpen(false); setIsDelay(true); - // setTimeout(() => setIsTalkOpen(false), 300); }, [content]); // 토크 컨텐츠 상태 From f586438a42c30d7ff6046ada33a57ccc4cf9b458 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Fri, 7 Apr 2023 02:23:23 +0900 Subject: [PATCH 8/9] =?UTF-8?q?:sparkles:=20feat:=20toast=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=ED=99=94=EB=A9=B4=20=EB=B0=96=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=ED=8F=AC=EC=BB=A4=EC=8A=A4=20=EC=9D=B4=EB=8F=99=ED=96=88?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EC=A0=95=EC=A7=80=EB=90=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/App.tsx b/client/src/App.tsx index f8510b52..cfb4ca4d 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -30,6 +30,7 @@ function App() { position="top-center" autoClose={3000} theme="colored" + pauseOnFocusLoss={false} /> From 1fc40e6f4eb5d2464378fa91bc50add7ff146ce8 Mon Sep 17 00:00:00 2001 From: uxolrv Date: Fri, 7 Apr 2023 19:03:31 +0900 Subject: [PATCH 9/9] =?UTF-8?q?:bug:=20fix:=20=EC=B0=9C=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=202=ED=9A=8C=20=EC=9D=B4=EC=83=81=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20=EC=9A=94=EC=B2=AD=EC=9D=B4=20=EC=A0=9C?= =?UTF-8?q?=EB=8C=80=EB=A1=9C=20=EA=B0=80=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95=20#301?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Buttons/WishlistButton.tsx | 31 ++++++++++++------- .../components/ItemSummary/ItemSummary.tsx | 15 +++------ client/src/types/button.type.ts | 4 +-- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/client/src/components/Buttons/WishlistButton.tsx b/client/src/components/Buttons/WishlistButton.tsx index 7b0070d8..a3e77f90 100644 --- a/client/src/components/Buttons/WishlistButton.tsx +++ b/client/src/components/Buttons/WishlistButton.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components'; import { FaHeart } from 'react-icons/fa'; -import { useCallback, useState } from 'react'; +import { useEffect, useState } from 'react'; import { usePost } from '../../hooks/useFetch'; import { WishlistBtnProps } from '../../types/button.type'; @@ -14,15 +14,21 @@ function WishlistButton({ const token = localStorage.getItem('accessToken'); const { mutate } = usePost(`/wishes/${itemId}?wish=${request}`); - const handleHeartClick = useCallback(() => { + const handleHeartClick = () => { if (!token && setOpenLoginModal) { setOpenLoginModal(true); return; } + mutate(); + if (setIsChecked) { - setIsChecked(isChecked ? 0 : 1); + setIsChecked(!isChecked); } + }; + + useEffect(() => { + setRequest(isChecked ? 0 : 1); }, [isChecked]); return ( @@ -37,16 +43,11 @@ function WishlistButton({ const WishBox = styled.div` display: inline-flex; - z-index: 99; - .red-heart { - path { - color: #ff555f; - opacity: 100%; - stroke-width: 0; - } - } + z-index: 2; + & > svg { font-size: 18px; + path { cursor: pointer; stroke: var(--gray-300); @@ -55,6 +56,14 @@ const WishBox = styled.div` opacity: 30%; } } + + .red-heart { + path { + color: #ff555f; + opacity: 100%; + stroke-width: 0; + } + } `; export default WishlistButton; diff --git a/client/src/components/ItemSummary/ItemSummary.tsx b/client/src/components/ItemSummary/ItemSummary.tsx index 92159cb2..cf3d24c2 100644 --- a/client/src/components/ItemSummary/ItemSummary.tsx +++ b/client/src/components/ItemSummary/ItemSummary.tsx @@ -1,5 +1,5 @@ import styled, { keyframes } from 'styled-components'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import WishlistButton from '../Buttons/WishlistButton'; import Tag from '../Etc/Tag'; @@ -57,17 +57,14 @@ function ItemSummary({ '/wishes/item', `detail/wishs`, ); + const [isCheckedWish, setIsCheckedWish] = useState( - WishData?.data?.data.includes(itemId) ? 1 : 0, + !!WishData?.data?.data.includes(itemId), ); useEffect(() => { - if (WishData?.data?.data.includes(itemId)) { - setIsCheckedWish(1); - } else { - setIsCheckedWish(0); - } - }, []); + setIsCheckedWish(!!WishData?.data?.data.includes(itemId)); + }, [WishData]); const { mutate: cartMu } = usePost(`/carts/${itemId}`); const { mutate: purMu } = usePurchase('/orders/single', path); @@ -301,7 +298,6 @@ const TagsBox = styled.div` const RateBox = styled.div` display: flex; justify-content: space-between; - /* align-items: center; */ width: 100%; margin-bottom: 10px; `; @@ -309,7 +305,6 @@ const RateBox = styled.div` const ButtonBox = styled.div` display: flex; justify-content: space-between; - /* width: 100%; */ `; const slide = keyframes` diff --git a/client/src/types/button.type.ts b/client/src/types/button.type.ts index 81ea1fbe..3f8d2fa7 100644 --- a/client/src/types/button.type.ts +++ b/client/src/types/button.type.ts @@ -35,8 +35,8 @@ export interface PriceButtonProps { } export interface WishlistBtnProps { - isChecked: boolean | number; + isChecked: boolean; itemId: number; - setIsChecked?: React.Dispatch>; + setIsChecked?: React.Dispatch>; setOpenLoginModal?: React.Dispatch>; }