+
);
})}
diff --git a/src/components/App.js b/src/components/App.js
index 6b55f1e83..628c823cc 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -9,6 +9,7 @@ import "../css/reset.css";
import "../css/style.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import NotFoundPage from "./NotFoundPage";
+import ProductDetail from "./ProductDetail";
function App() {
return (
@@ -20,7 +21,10 @@ function App() {
} />
diff --git a/src/components/BestProduct.js b/src/components/BestProduct.js
index 1302d01ba..a6467b213 100644
--- a/src/components/BestProduct.js
+++ b/src/components/BestProduct.js
@@ -1,3 +1,4 @@
+import { Link } from "react-router-dom";
import { getProducts } from "../api.js";
import { useEffect, useState } from "react";
@@ -51,21 +52,23 @@ function BestProduct() {
.replace(/\B(?
-
-
{product.name}
-
{productPrice}원
-
-
-
{product.favoriteCount}
+
+
+
+
-
-
+
+
{product.name}
+
{productPrice}원
+
+
+
{product.favoriteCount}
+
+
+
+
);
})}
diff --git a/src/components/Header.js b/src/components/Header.js
index 10f94e732..bed423e48 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -24,8 +24,8 @@ function Header() {
{
- let { list } = await getProducts(options);
- setProducts(list);
- };
-
- useEffect(() => {
- handleLoad({ pageSize, order });
- }, []);
-
return (
<>
>
);
diff --git a/src/components/ProductDetail.js b/src/components/ProductDetail.js
new file mode 100644
index 000000000..b157b6900
--- /dev/null
+++ b/src/components/ProductDetail.js
@@ -0,0 +1,194 @@
+import { Link, Navigate, useParams } from "react-router-dom";
+import { getProducts } from "../api.js";
+import { getComments } from "../api.js";
+import { useEffect, useState } from "react";
+
+function ProductDetail() {
+ const { productId } = useParams();
+ const [products, setProducts] = useState([]);
+ const [comments, setComments] = useState([]);
+ const [commentLimit, setCommentLimit] = useState(3);
+ const [loading, setLoading] = useState(true);
+ const [inquiryTxt, setInquiryTxt] = useState("");
+ const [inquiryBtn, setInquiryBtn] = useState({
+ disabled: "true",
+ btnClass: "",
+ });
+
+ const productIdFind = (id) => {
+ return products.find((product) => product.id === id);
+ };
+
+ const foundProduct = productIdFind(Number(productId));
+
+ const validInquiry = () => {
+ return inquiryTxt.trim() !== "";
+ };
+
+ // 상품 가져오기
+ useEffect(() => {
+ const handleLoad = async () => {
+ try {
+ const { list } = await getProducts(1);
+ setProducts(list);
+ } catch (error) {
+ console.log("Error message:", error);
+ } finally {
+ setLoading(false); // 로딩 완료
+ }
+ };
+
+ handleLoad();
+ }, []);
+
+ // 상품 댓글 가져오기
+ useEffect(() => {
+ const handleLoad = async (option) => {
+ try {
+ const { list } = await getComments(option);
+ setComments(list);
+ } catch (error) {
+ console.log("Error message:", error);
+ } finally {
+ setLoading(false); // 로딩 완료
+ }
+ };
+
+ handleLoad({ productId, commentLimit });
+ }, [commentLimit]);
+
+ // 문의하기 유효성 검사
+ useEffect(() => {
+ if (validInquiry()) {
+ setInquiryBtn({
+ disabled: "false",
+ btnClass: "on",
+ });
+ } else {
+ setInquiryBtn({
+ disabled: "true",
+ btnClass: "",
+ });
+ }
+ }, [inquiryTxt]);
+
+ // 로딩중
+ if (loading) {
+ return (
+
+
상품 정보를 찾고 있습니다.
+
+ );
+ }
+
+ // 상품을 찾지 못했을 경우
+ if (!foundProduct) {
+ return (
+
+
상품을 찾지 못했습니다.
+ 중고마켓 페이지로 가기
+
+ );
+ }
+
+ // 상품 이미지 경로 확인후 잘못된 이미지면 기본 이미지로 적용
+ const imgChk = foundProduct.images.join("").includes("jpeg"); // 이미지 경로에 jpeg가 있는지 확인
+ const imgUrl = imgChk ? foundProduct.images : "/images/card01-small.png";
+
+ return (
+
+
+
+
+
+
+
+
+
{foundProduct.name}
+
+
+
+
{foundProduct.price.toLocaleString("ko-KR")}원
+
+
+ 상품소개
+ {foundProduct.description}
+
+
상품 태그
+
+ {foundProduct.tags.map((tag, i) => {
+ return - # {tag}
;
+ })}
+
+
+
+
+
+
+
+
+
+
+
+ {comments.map((comment) => {
+ const updateTime = new Date(comment.updatedAt);
+ const currentTime = new Date();
+
+ const timeDiff = currentTime.getTime() - updateTime.getTime();
+ const resultTime = Math.round(timeDiff / (1000 * 60 * 60));
+ return (
+
+
+
{comment.content}
+
+
+
+
+
+ {comment.writer.nickname}
+ {resultTime}시간 전
+
+
+
+ );
+ })}
+
+
+
+
+
+ 목록으로 돌아가기
+
+
+
+
+ );
+}
+
+export default ProductDetail;
diff --git a/src/css/style.css b/src/css/style.css
index a8a997294..62f39d534 100644
--- a/src/css/style.css
+++ b/src/css/style.css
@@ -28,6 +28,33 @@
max-width: 1200px;
}
+.loading {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: calc(100vh - (70px + 160px));
+ background-color: var(--gray100-color);
+}
+
+.loading h2 {
+ font-size: 40px;
+ margin: 40px 0;
+}
+
+.loading a {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 50px;
+ padding: 0 20px;
+ border-radius: 10px;
+ font-size: 18px;
+ color: #ffffff;
+ background-color: var(--blue-color);
+}
+
.login-btn {
display: flex;
align-items: center;
@@ -790,6 +817,269 @@ main .main-wrap .banner .banner-wrap h2 {
}
/* //상품 등록하기 */
+/* 상품 상세 페이지 */
+.product-detail-wrap {
+ padding-top: 40px;
+ margin: 0 auto 170px;
+}
+
+.product-detail-wrap .list-btn-area {
+ display: flex;
+ justify-content: center;
+ width: 100%;
+ margin-top: 40px;
+}
+
+.product-detail-wrap .list-btn-area a {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ width: 100%;
+ max-width: 240px;
+ height: 48px;
+ border-radius: 40px;
+ font-size: 18px;
+ font-weight: 600;
+ color: #ffffff;
+ background-color: var(--blue-color);
+}
+
+.product-detail-wrap .middle-line {
+ border: 1px solid var(--gray200-color);
+ margin: 32px 0;
+}
+
+.product-detail-wrap .product-detail-top {
+ display: flex;
+ gap: 24px;
+}
+
+.product-detail-wrap .product-detail-top .detail-img {
+ flex: 1;
+ max-width: 486px;
+ border-radius: 16px;
+ overflow: hidden;
+}
+
+.product-detail-wrap .product-detail-top .detail-img img {
+ width: 100%;
+ aspect-ratio: 1 / 1;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ flex: 1;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap .detail-txt-title {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 16px;
+}
+
+.product-detail-wrap
+ .product-detail-top
+ .detail-txt-wrap
+ .detail-txt-title
+ button {
+ background-color: #ffffff;
+ border: none;
+ cursor: pointer;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap h2 {
+ font-size: 24px;
+ font-weight: 600;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap h3 {
+ font-size: 40px;
+ font-weight: 600;
+ margin-bottom: 16px;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap hr {
+ border: 1px solid var(--gray200-color);
+ margin-bottom: 16px;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap .detail-txt {
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 1.2;
+ margin-bottom: 23px;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap span {
+ display: block;
+ margin-bottom: 8px;
+ font-size: 14px;
+ font-weight: 500;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap .detail-tag {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 30px;
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap .detail-tag li {
+ height: 36px;
+ line-height: 36px;
+ padding: 0 16px;
+ border-radius: 26px;
+ background-color: var(--gray100-color);
+}
+
+.product-detail-wrap .product-detail-top .detail-txt-wrap .detail-like-btn {
+ display: flex;
+ align-items: center;
+ gap: 7px;
+ height: 40px;
+ padding: 0 12px;
+ border-radius: 35px;
+ border: 1px solid var(--gray200-color);
+ background-color: #ffffff;
+ cursor: pointer;
+}
+
+.product-detail-wrap .detail-inquiry-wrap .detail-inquiry {
+ margin-bottom: 24px;
+}
+
+.product-detail-wrap .detail-inquiry-wrap .detail-inquiry label {
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--gray900-color);
+}
+
+.product-detail-wrap .detail-inquiry-wrap .detail-inquiry textarea {
+ display: block;
+ width: 100%;
+ height: 100px;
+ margin: 16px 0;
+ font-size: 16px;
+ font-weight: 400;
+ padding: 16px 24px;
+ border-radius: 12px;
+ border: none;
+ background-color: var(--gray100-color);
+ resize: none;
+}
+
+.product-detail-wrap .detail-inquiry-wrap .detail-inquiry .inquiry-btn {
+ text-align: right;
+}
+
+.product-detail-wrap .detail-inquiry-wrap .detail-inquiry .inquiry-btn button {
+ padding: 0 23px;
+ height: 42px;
+ font-size: 16px;
+ font-weight: 600;
+ border: none;
+ border-radius: 8px;
+ color: #ffffff;
+ background-color: var(--gray400-color);
+ cursor: pointer;
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry
+ .inquiry-btn
+ button.on {
+ background-color: var(--blue-color);
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt {
+ padding-bottom: 24px;
+ margin-bottom: 24px;
+ border-bottom: 1px solid var(--gray200-color);
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ .comment-title {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 24px;
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ .comment-title
+ button {
+ border: none;
+ background-color: #ffffff;
+ cursor: pointer;
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ p {
+ font-size: 16px;
+ font-weight: 400;
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ .inquiry-list-profile {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ .inquiry-list-profile
+ img {
+ max-width: 40px;
+ max-height: 40px;
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ .inquiry-list-profile
+ span {
+ display: block;
+ font-size: 12px;
+ font-weight: 400;
+ color: var(--gray400-color);
+}
+
+.product-detail-wrap
+ .detail-inquiry-wrap
+ .detail-inquiry-list
+ .inquiry-list-txt
+ .inquiry-list-profile
+ span:first-child {
+ margin-bottom: 5px;
+ font-size: 14px;
+ color: var(--gray600-color);
+}
+/* //상품 상세 페이지 */
+
footer {
height: 160px;
padding: 32px 24px 0 24px;
@@ -1003,6 +1293,17 @@ footer .footer-wrap ul.sns {
}
/* //상품 등록하기 */
+ /* 상품 상세 페이지 */
+ .product-detail-wrap {
+ padding-left: 24px;
+ padding-right: 24px;
+ }
+
+ .product-detail-wrap .product-detail-top .detail-img {
+ max-width: 340px;
+ }
+ /* //상품 상세 페이지 */
+
footer {
padding: 32px 104px 0 104px;
}
@@ -1162,6 +1463,24 @@ footer .footer-wrap ul.sns {
}
/* //상품 등록하기 */
+ /* 상품 상세 페이지 */
+ .product-detail-wrap .product-detail-top {
+ flex-direction: column;
+ }
+
+ .product-detail-wrap .product-detail-top .detail-img {
+ max-width: 100%;
+ }
+
+ .product-detail-wrap .product-detail-top .detail-txt-wrap h2 {
+ font-size: 16px;
+ }
+
+ .product-detail-wrap .product-detail-top .detail-txt-wrap h3 {
+ font-size: 24px;
+ }
+ /* 상품 상세 페이지 */
+
footer {
padding: 32px;
}