From 634677504a842210bf69fe79067858a1c6fd3f26 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:15:32 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20chakra=20ui=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=EB=B0=8F=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 31 ++++++++++++------------------- package.json | 6 +++--- src/App.tsx | 4 ++++ src/index.tsx | 13 ++++++++----- tsconfig.json | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5f34e945..7dc6a907 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@emotion/styled": "^11.11.5", "@tanstack/react-query": "^5.24.1", "axios": "^1.6.7", - "framer-motion": "^11.3.2", + "framer-motion": "^11.3.6", "react": "^18.2.0", "react-dom": "^18.2.0", "react-intersection-observer": "^9.8.1", @@ -36,8 +36,8 @@ "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", "@types/node": "^16.18.82", - "@types/react": "^18.2.57", - "@types/react-dom": "^18.2.19", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "eslint": "^8.56.0", @@ -11774,20 +11774,19 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.58", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.58.tgz", - "integrity": "sha512-TaGvMNhxvG2Q0K0aYxiKfNDS5m5ZsoIBBbtfUorxdH4NGSXIlYvZxLJI+9Dd3KjeB3780bciLyAb7ylO8pLhPw==", + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", "devOptional": true, "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.2.19", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.19.tgz", - "integrity": "sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", "dev": true, "dependencies": { "@types/react": "*" @@ -11805,12 +11804,6 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "devOptional": true - }, "node_modules/@types/semver": { "version": "7.5.7", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", @@ -19934,9 +19927,9 @@ } }, "node_modules/framer-motion": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.2.tgz", - "integrity": "sha512-RgjSzrNFZmedWcvmW4MMc84A7UcoY37jocadE3Mbg3o+UMofodfyeNnYD/HR15UhP22/bb5KOebNhYOj4mYkpQ==", + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.6.tgz", + "integrity": "sha512-olpX48qfoSIDjhw0RbolhOGBQmdMAXHHpSI0PFdTj5LeXChcf5F4ApShs0mQ6FPEPOj7dnEvSyB07UgRK5G9Jw==", "dependencies": { "tslib": "^2.4.0" }, diff --git a/package.json b/package.json index 892ae758..a0a3a6ee 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@emotion/styled": "^11.11.5", "@tanstack/react-query": "^5.24.1", "axios": "^1.6.7", - "framer-motion": "^11.3.2", + "framer-motion": "^11.3.6", "react": "^18.2.0", "react-dom": "^18.2.0", "react-intersection-observer": "^9.8.1", @@ -52,8 +52,8 @@ "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", "@types/node": "^16.18.82", - "@types/react": "^18.2.57", - "@types/react-dom": "^18.2.19", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "eslint": "^8.56.0", diff --git a/src/App.tsx b/src/App.tsx index ec6c4562..ef845b2f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,8 @@ import { MainLayout } from '@/components/Layout/MainLayout'; import LoginPage from '@/pages/LoginPage'; import MainPage from '@/pages/MainPage'; import MyAccountPage from '@/pages/MyAccountPage'; +import OrderPage from '@/pages/OrderPage'; +import ProductDetailPage from '@/pages/ProductDetailPage'; import ThemePage from '@/pages/ThemePage'; import { ResetStyles } from '@/styles/reset'; @@ -34,6 +36,8 @@ const App = () => { } /> } />; + } />; + } />; diff --git a/src/index.tsx b/src/index.tsx index 276cd2d8..d5cd5b60 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,3 +1,4 @@ +import { ChakraProvider } from '@chakra-ui/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import React from 'react'; import ReactDOM from 'react-dom/client'; @@ -10,10 +11,12 @@ const queryClient = new QueryClient(); const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render( - - - - - + + + + + + + , ); diff --git a/tsconfig.json b/tsconfig.json index 78fe2033..0965cc7c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,7 @@ "sourceMap": true, "noUnusedLocals": true, "noUnusedParameters": true, - "jsxImportSource": "@emotion/react", + "types": ["@emotion/react/types/css-prop"], "incremental": true, "baseUrl": ".", "paths": { From 3b1fd846370143b363be1d26e6592f8cac9d9d8e Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:15:57 +0900 Subject: [PATCH 02/18] =?UTF-8?q?feat:=20ProductDetailPage=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/OrderPage.tsx | 3 ++ src/pages/ProductDetailPage.tsx | 62 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/pages/OrderPage.tsx create mode 100644 src/pages/ProductDetailPage.tsx diff --git a/src/pages/OrderPage.tsx b/src/pages/OrderPage.tsx new file mode 100644 index 00000000..f3f0740a --- /dev/null +++ b/src/pages/OrderPage.tsx @@ -0,0 +1,3 @@ +export default function OrderPage() { + return <>; +} diff --git a/src/pages/ProductDetailPage.tsx b/src/pages/ProductDetailPage.tsx new file mode 100644 index 00000000..70904715 --- /dev/null +++ b/src/pages/ProductDetailPage.tsx @@ -0,0 +1,62 @@ +import styled from '@emotion/styled'; +import { Navigate, useParams } from 'react-router-dom'; + +import { Loading } from '@/components/common/Handle'; +import { Container } from '@/components/common/Layout/Container'; +import { DetailSection } from '@/components/ProductDetail/DetailSection'; +import { OptionSection } from '@/components/ProductDetail/OptionSection'; +import { useProductDetail } from '@/services/useProductDetail'; + +export default function ProductDetailPage() { + const { productId = '' } = useParams<{ productId: string }>(); + const { isPending, isError, error, data } = useProductDetail(productId); + + if (isPending) { + return ; + } + if (isError) { + console.error(error); + return ; + } + + return ( + + + + + + + + + + + + + ); +} +const ProductDetailPageWrapper = styled.div` + width: 100%; +`; +const Inner = styled.div` + width: 100%; + display: flex; + justify-content: flex-start; + align-items: flex-start; + position: relative; +`; +const Left = styled.div` + width: 100%; + max-width: 900px; +`; +const Right = styled.div` + display: none; + position: sticky; + top: 54px; + width: 100%; + max-width: 360px; + height: calc(100vh - 54px); + + @media screen and (min-width: 768px) { + display: block; + } +`; From d6f11b4abbe03a378f96bc9ecf239c3437b99f32 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:16:35 +0900 Subject: [PATCH 03/18] =?UTF-8?q?feat:=20DetailSection=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductDetail/DetailSection.tsx | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/components/ProductDetail/DetailSection.tsx diff --git a/src/components/ProductDetail/DetailSection.tsx b/src/components/ProductDetail/DetailSection.tsx new file mode 100644 index 00000000..339140e1 --- /dev/null +++ b/src/components/ProductDetail/DetailSection.tsx @@ -0,0 +1,66 @@ +import { Divider } from '@chakra-ui/react'; +import styled from '@emotion/styled'; + +import { Image } from '../common/Image'; + +import type { ProductDetailResponse } from '@/services/types'; + +export const DetailSection = ({ data }: { data: ProductDetailResponse }) => { + return ( + + + + {data.detail.name} + {data.detail.price.basicPrice}원 + + 카톡 친구가 아니어도 선물 코드로 선물 할 수 있어요! + + + + ); +}; +const DetailSectionWrapper = styled.div` + width: 100%; + display: flex; + flex-direction: column; + + @media screen and (min-width: 768px) { + flex-direction: row; + padding: 32px 32px 80px; + } +`; +const CustomImage = styled(Image)` + width: 100%; + max-width: 450px; +`; +const DetailWrapper = styled.div` + width: 100%; + + @media screen and (min-width: 768px) { + padding-left: 20px; + } +`; +const Title = styled.h2` + padding-top: 24px; + font-size: 24px; + line-height: 33px; + color: #111; + font-weight: 400; + word-break: break-all; +`; +const Price = styled.p` + width: 100%; + min-height: 120px; + padding-top: 16px; + font-size: 30px; + font-weight: 400; + line-height: 52px; + color: #222; +`; +const Text = styled.p` + padding: 24px 12px; + font-size: 14px; + font-weight: 700; + line-height: 23px; + color: #111; +`; From 810610f656ecd668e57346f81760dd30c015870f Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:16:49 +0900 Subject: [PATCH 04/18] =?UTF-8?q?feat:=20detail=20response=20type=20?= =?UTF-8?q?=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/types.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/services/types.ts b/src/services/types.ts index 6b8583e3..596938d9 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -28,3 +28,32 @@ export interface ProductWithPageData { totalResults: number; }; } +export interface ProductDetailResponse { + detail: { + id: number; + name: string; + imageURL: string; + wish: { + isWished: boolean; + wishCount: number; + }; + price: { + basicPrice: number; + discountRate: number; + sellingPrice: number; + }; + brandInfo: { + id: number; + name: string; + imageURL: string; + }; + isAccessableProductPage: boolean; + review: { + averageRating: number; + totalReviewCount: number; + }; + productDescription: { + displayImage: string; + }; + }; +} From 84afd42b070064cf4991e983656eb3ee38f628c2 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:17:13 +0900 Subject: [PATCH 05/18] =?UTF-8?q?feat:=20item=EA=B3=BC=20detail=20page=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Theme/ItmeList.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/Theme/ItmeList.tsx b/src/components/Theme/ItmeList.tsx index f0825198..984dc522 100644 --- a/src/components/Theme/ItmeList.tsx +++ b/src/components/Theme/ItmeList.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled'; import { useEffect } from 'react'; import { useInView } from 'react-intersection-observer'; +import { Link } from 'react-router-dom'; import { GoodsItem } from '@/components/common/GoodsItem'; import { HandleBox, Loading } from '@/components/common/Handle'; @@ -35,14 +36,16 @@ export const ItemListWithInfiniteScroll = ({ themeKey }: { themeKey: string }) = - {products.map((item, index) => ( - + {products.map((item) => ( + + + ))}
From 2afd9df281d8f587dc4d6d73bffb1270fbde0c86 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:18:04 +0900 Subject: [PATCH 06/18] =?UTF-8?q?feat:=20OptionSection=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ProductDetail/CountOption.tsx | 54 ++++++++++++++ .../ProductDetail/OptionSection.tsx | 72 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/components/ProductDetail/CountOption.tsx create mode 100644 src/components/ProductDetail/OptionSection.tsx diff --git a/src/components/ProductDetail/CountOption.tsx b/src/components/ProductDetail/CountOption.tsx new file mode 100644 index 00000000..1685f6b0 --- /dev/null +++ b/src/components/ProductDetail/CountOption.tsx @@ -0,0 +1,54 @@ +import { Button, Input, useNumberInput } from '@chakra-ui/react'; +import styled from '@emotion/styled'; + +interface Props { + name?: string; + count: string; + setCount: (value: string) => void; +} + +export const CountOption = ({ name, count, setCount }: Props) => { + const { getInputProps, getIncrementButtonProps, getDecrementButtonProps } = useNumberInput({ + step: 1, + defaultValue: count, + min: 1, + max: 1000, + onChange: (num) => { + setCount(num); + }, + }); + const inc = getIncrementButtonProps(); + const dec = getDecrementButtonProps(); + const input = getInputProps(); + + return ( + + {name} + + + + + + + ); +}; + +const CountWrapper = styled.div` + width: 100%; + padding: 12px 14px 16px; + border: 1px solid #ededed; + border-radius: 2px; +`; +const Name = styled.p` + font-weight: 700; + line-height: 22px; + color: #111; + word-wrap: break-word; + word-break: break-all; +`; +const Wrapper = styled.div` + display: flex; + justify-content: center; + padding-top: 8px; + gap: 8px; +`; diff --git a/src/components/ProductDetail/OptionSection.tsx b/src/components/ProductDetail/OptionSection.tsx new file mode 100644 index 00000000..ed76eda5 --- /dev/null +++ b/src/components/ProductDetail/OptionSection.tsx @@ -0,0 +1,72 @@ +import styled from '@emotion/styled'; +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { Button } from '../common/Button'; +import { CountOption } from './CountOption'; + +import { useAuth } from '@/hooks/useAuth'; +import { useOrderHistory } from '@/hooks/useOrderHistory'; +import type { ProductDetailResponse } from '@/services/types'; + +export const OptionSection = ({ productId, data }: { productId: string; data: ProductDetailResponse }) => { + const [count, setCount] = useState('1'); + const navigate = useNavigate(); + const sessionStorage = window.sessionStorage; + const { authToken } = useAuth(); + const { setOrderHistoryToken } = useOrderHistory(); + + const totalPrice = data.detail.price.basicPrice * Number(count); + const handleClick = () => { + if (!authToken) { + if (!window.confirm('로그인이 필요한 메뉴입니다.\n로그인 페이지로 이동하시겠습니까?')) return null; + return navigate('/login'); + } + sessionStorage.setItem('orderHistory', JSON.stringify({ id: parseInt(productId), count: parseInt(count) })); + setOrderHistoryToken({ id: parseInt(productId), count: parseInt(count) }); + navigate('/order'); + }; + + return ( + + + + + 총 결제 금액{totalPrice}원 + + + + + ); +}; +const OptionSectionWrapper = styled.div` + width: 100%; + padding: 30px 12px 30px 30px; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; +`; +const ResultWrapper = styled.div` + padding: 12px 0 0; +`; +const FinallyPrice = styled.div` + margin-bottom: 20px; + padding: 18px 20px; + border-radius: 4px; + background-color: #f5f5f5; + display: flex; + justify-content: space-between; + + font-size: 14px; + font-weight: 700; + line-height: 14px; + color: #111; + + & span { + font-size: 20px; + letter-spacing: -0.02em; + } +`; From f6ae0176ec7b56c108b94692368e4b25433eb3a8 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:18:33 +0900 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20useOrderHistory=20context=20API?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useOrderHistory.tsx | 7 +++++++ src/store/OrderHistoryProvider.tsx | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/hooks/useOrderHistory.tsx create mode 100644 src/store/OrderHistoryProvider.tsx diff --git a/src/hooks/useOrderHistory.tsx b/src/hooks/useOrderHistory.tsx new file mode 100644 index 00000000..7e153336 --- /dev/null +++ b/src/hooks/useOrderHistory.tsx @@ -0,0 +1,7 @@ +import { useContext } from 'react'; + +import { OrderHistoryContext } from '@/store/OrderHistoryProvider'; + +export const useOrderHistory = () => { + return useContext(OrderHistoryContext); +}; diff --git a/src/store/OrderHistoryProvider.tsx b/src/store/OrderHistoryProvider.tsx new file mode 100644 index 00000000..49c99355 --- /dev/null +++ b/src/store/OrderHistoryProvider.tsx @@ -0,0 +1,29 @@ +import { createContext, useEffect, useState } from 'react'; +export interface OrderHistoryToken { + id: number; + count: number; +} +interface OrderHistoryContextType { + orderHistoryToken: OrderHistoryToken; + setOrderHistoryToken: (orderHistoryToken: OrderHistoryToken) => void; +} +export const OrderHistoryContext = createContext({ + orderHistoryToken: { id: 0, count: 0 }, + setOrderHistoryToken: () => {}, +}); + +export function OrderHistoryProvider({ children }: { children: React.ReactNode }) { + const token = sessionStorage.getItem('orderHistory'); + const [orderHistoryToken, setOrderHistoryToken] = useState({ id: 0, count: 0 }); + + useEffect(() => { + if (token) { + setOrderHistoryToken(JSON.parse(token)); + } + }, [token]); + return ( + + {children} + + ); +} From 9c858e1733cdb76e33ba283325cc9fba02a2b655 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:18:45 +0900 Subject: [PATCH 08/18] =?UTF-8?q?feat:=20useProductDetail=20API=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/useProductDetail.tsx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/services/useProductDetail.tsx diff --git a/src/services/useProductDetail.tsx b/src/services/useProductDetail.tsx new file mode 100644 index 00000000..c7cf03a8 --- /dev/null +++ b/src/services/useProductDetail.tsx @@ -0,0 +1,29 @@ +import { useQuery } from '@tanstack/react-query'; +import { AxiosError } from 'axios'; + +import { axiosInstance } from '.'; +import type { ProductDetailResponse } from './types'; + +export const useProductDetail = (productId: string) => + useQuery({ + queryKey: ['productDetail', productId], + queryFn: async () => { + try { + const response = await axiosInstance.get(`v1/products/${productId}/detail`); + return response.data; + } catch (error) { + if (error instanceof AxiosError) { + if (error.response?.status === 404) { + console.error('해당하는 상품이 없습니다:', error); + throw new Error('해당하는 상품이 없습니다.'); + } else { + console.error('데이터를 불러오는 중에 문제가 발생했습니다:', error); + throw new Error('데이터를 불러오는 중에 문제가 발생했습니다.'); + } + } else { + console.error('Unexpected error occurred:', error); + throw new Error('Unexpected error occurred'); + } + } + }, + }); From e46fcedbcb70684920dfd030902df21dda0d9eb4 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:19:41 +0900 Subject: [PATCH 09/18] =?UTF-8?q?feat:=20orderHistoryProvider=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index ef845b2f..cc6d8f43 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import { Navigate, Route, Routes } from 'react-router-dom'; import { useAuth } from './hooks/useAuth'; import { AuthProvider } from './store/AuthProvider'; +import { OrderHistoryProvider } from './store/OrderHistoryProvider'; import { MainLayout } from '@/components/Layout/MainLayout'; import LoginPage from '@/pages/LoginPage'; @@ -23,23 +24,25 @@ const App = () => { <> - - } /> - }> - } /> - - - - } - /> - } />; - } />; - } />; - - + + + } /> + }> + } /> + + + + } + /> + } />; + } />; + } />; + + + ); From 6855ae965455c68e3bc5b6501635431ef9d3bda5 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:23:14 +0900 Subject: [PATCH 10/18] =?UTF-8?q?feat:=20OrderPage=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/OrderPage.tsx | 54 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/pages/OrderPage.tsx b/src/pages/OrderPage.tsx index f3f0740a..784e15ee 100644 --- a/src/pages/OrderPage.tsx +++ b/src/pages/OrderPage.tsx @@ -1,3 +1,55 @@ +import styled from '@emotion/styled'; + +import { Container } from '@/components/common/Layout/Container'; +import { GiftMessageSection } from '@/components/Order/GiftMessageSection'; +import { PaymentSection } from '@/components/Order/PaymentSection'; +import { useOrderHistory } from '@/hooks/useOrderHistory'; + export default function OrderPage() { - return <>; + const { orderHistoryToken } = useOrderHistory(); + return ( + + + + + + + + + + + + + ); } +const OrderPageWrapper = styled.div` + width: 100%; +`; +const Inner = styled.div` + width: 100%; + display: flex; + justify-content: flex-start; + align-items: flex-start; + position: relative; +`; +const Left = styled.div` + width: 100%; + max-width: 900px; + border: 1px solid #ededed; + border-top: none; + border-bottom: none; + height: calc(100vh - 54px); +`; +const Right = styled.div` + display: none; + position: sticky; + top: 54px; + width: 100%; + max-width: 360px; + height: calc(100vh - 54px); + border-right: 1px solid #ededed; + + @media screen and (min-width: 768px) { + display: block; + } +`; From a5bcb629a3e1f2dd3f23b5f7481fda4e90ba6745 Mon Sep 17 00:00:00 2001 From: Hyoeunkh Date: Thu, 18 Jul 2024 16:24:07 +0900 Subject: [PATCH 11/18] =?UTF-8?q?feat:=20GiftMessageSection=EC=9D=98=20?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=B9=B4=EB=93=9C=EC=99=80=20?= =?UTF-8?q?=EC=84=A0=EB=AC=BC=EB=82=B4=EC=97=AD=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Order/GiftHistory.tsx | 76 +++++++++++++++++++++ src/components/Order/GiftMessageSection.tsx | 23 +++++++ src/components/Order/MessageCard.tsx | 40 +++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/components/Order/GiftHistory.tsx create mode 100644 src/components/Order/GiftMessageSection.tsx create mode 100644 src/components/Order/MessageCard.tsx diff --git a/src/components/Order/GiftHistory.tsx b/src/components/Order/GiftHistory.tsx new file mode 100644 index 00000000..21d927b7 --- /dev/null +++ b/src/components/Order/GiftHistory.tsx @@ -0,0 +1,76 @@ +import styled from '@emotion/styled'; + +import { HandleBox, Loading } from '../common/Handle'; +import { Image } from '../common/Image'; + +import { useProductDetail } from '@/services/useProductDetail'; + +export const GiftHistory = ({ orderHistory }: { orderHistory: { id: number; count: number } }) => { + const { isPending, isError, error, data } = useProductDetail(orderHistory.id.toString()); + if (isPending) { + return ; + } + if (isError) { + return {error.message}; + } + return ( + + 선물내역 + + + + {data.detail.brandInfo.name} + + {data.detail.name} + X {orderHistory.count}개 + + + + + ); +}; +const OptionSectionWrapper = styled.div` + width: 100%; + padding: 16px; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; +`; +const Title = styled.h2` + padding: 12px 0px; + font-size: 16px; + font-weight: 700; + line-height: 23px; + color: #111; +`; +const GoodsWrapper = styled.div` + display: flex; + width: 100%; + padding: 18px; + border: 1px solid #ededed; + border-radius: 10px; +`; +const CustomImage = styled(Image)` + width: 86px; + margin-right: 10px; +`; +const GoodsInfo = styled.div` + display: flex; + flex-direction: column; +`; +const Brand = styled.p` + font-size: 13px; + line-height: 14px; + color: #888; + font-weight: 400; +`; +const Name = styled.p` + font-size: 14px; + line-height: 18px; + font-weight: 400; + margin-top: 3px; + color: #222; + overflow: hidden; + font-weight: 400; +`; diff --git a/src/components/Order/GiftMessageSection.tsx b/src/components/Order/GiftMessageSection.tsx new file mode 100644 index 00000000..ebd179f7 --- /dev/null +++ b/src/components/Order/GiftMessageSection.tsx @@ -0,0 +1,23 @@ +import styled from '@emotion/styled'; + +import { GiftHistory } from './GiftHistory'; +import { MessageCard } from './MessageCard'; + +export const GiftMessageSection = ({ orderHistory }: { orderHistory: { id: number; count: number } }) => { + return ( + + + + + + ); +}; +const GiftMessageSectionWrapper = styled.div` + width: 100%; + display: flex; + flex-direction: column; +`; +const CustomDivider = styled.div` + height: 8px; + background-color: #ededed; +`; diff --git a/src/components/Order/MessageCard.tsx b/src/components/Order/MessageCard.tsx new file mode 100644 index 00000000..5a755890 --- /dev/null +++ b/src/components/Order/MessageCard.tsx @@ -0,0 +1,40 @@ +import { Textarea } from '@chakra-ui/react'; +import styled from '@emotion/styled'; + +export const MessageCard = () => { + return ( + + 나에게 주는 선물 + +