diff --git a/package-lock.json b/package-lock.json index 3801cda6..c100f3a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", "react-scripts": "5.0.1", + "styled-components": "^6.1.13", "web-vitals": "^2.1.4" } }, @@ -2380,6 +2381,27 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -4782,6 +4804,12 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "license": "MIT" }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.9", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", @@ -6375,6 +6403,15 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -6848,6 +6885,15 @@ "postcss": "^8.4" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", @@ -6997,6 +7043,17 @@ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", "license": "MIT" }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -17159,6 +17216,12 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -17775,6 +17838,68 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-components": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", + "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.38", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -17791,6 +17916,12 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", diff --git a/package.json b/package.json index 96059456..1ab9a905 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", "react-scripts": "5.0.1", + "styled-components": "^6.1.13", "web-vitals": "^2.1.4" }, "scripts": { diff --git a/src/assets/images/ic_sort.png b/src/assets/images/ic_sort.png new file mode 100644 index 00000000..9292d758 Binary files /dev/null and b/src/assets/images/ic_sort.png differ diff --git a/src/assets/images/user_profile.png b/src/assets/images/user_profile.png new file mode 100644 index 00000000..c58d418f Binary files /dev/null and b/src/assets/images/user_profile.png differ diff --git a/src/components/Footer/Footer.module.css b/src/components/Footer/Footer.module.css index 01480cba..8a53223e 100644 --- a/src/components/Footer/Footer.module.css +++ b/src/components/Footer/Footer.module.css @@ -13,15 +13,31 @@ line-height: 19.09px; display: flex; justify-content: space-between; + position: relative; + /* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ + @media (min-width: 744px) and (max-width: 1199.98px) { + padding: 0 24px; + } + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + padding: 0 24px; + } } .copy { - color: #9CA3AF; + color: #9ca3af; + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + padding: 0 24px; + position: absolute; + left: 0; + bottom: -33px; + } } .info { width: 145px; - color: #E5E7EB; + color: #e5e7eb; display: flex; justify-content: space-between; } @@ -38,4 +54,4 @@ .sns > span { cursor: pointer; -} \ No newline at end of file +} diff --git a/src/components/Main/Main.module.css b/src/components/Main/Main.module.css index 6edeb266..41949043 100644 --- a/src/components/Main/Main.module.css +++ b/src/components/Main/Main.module.css @@ -1,17 +1,31 @@ .main { - padding: 26px 200px; + /* padding: 26px 200px; */ + padding: 26px 0; color: #111827; } .container { margin: 0 auto; - width: 1118px; -} -.bestItem { + /* PC 스타일: 1200px 이상 */ + @media (min-width: 1200px) { + width: 1118px; + } + + /* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ + @media (min-width: 744px) and (max-width: 1199.98px) { + width: 696px; + } + + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + width: 100%; + max-width: 344px; + } } .title { + white-space: nowrap; font-weight: 700; font-size: 2rem; margin-bottom: 16px; @@ -25,6 +39,8 @@ display: flex; justify-content: space-between; margin-bottom: 24px; + flex-wrap: wrap; + position: relative; } .toolBox { @@ -46,6 +62,16 @@ font-weight: 400; font-size: 1.6rem; padding: 0 39px 0 13px; + /* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ + @media (min-width: 744px) and (max-width: 1199.98px) { + width: 242px; + font-size: 1.4rem; + } + + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + max-width: 288px; + } } .searchLogo { @@ -68,6 +94,12 @@ border-radius: 8px; font-size: 1.6rem; cursor: pointer; + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + position: absolute; + top: 0; + right: 45px; + } } .select { @@ -76,4 +108,14 @@ border-radius: 8px; padding: 0 20px; font-size: 1.6rem; + + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + width: 42px; + border-radius: 12px; + -webkit-appearance: none; /* Safari와 Chrome */ + -moz-appearance: none; /* Firefox */ + appearance: none; /* 나머지 브라우저 */ + background: url(../../assets/images/ic_sort.png) no-repeat center / 24px; + } } diff --git a/src/components/Nav/Nav.js b/src/components/Nav/Nav.js index d9ff2c8d..0c8b0733 100644 --- a/src/components/Nav/Nav.js +++ b/src/components/Nav/Nav.js @@ -1,19 +1,30 @@ import React from 'react'; import styles from './Nav.module.css' import logo from '../../assets/images/logo.png' +import avatar from '../../assets/images/user_profile.png' function Nav() { + const isLoggedIn = false; // true 또는 false로 각각 바꿔보며 확인 + return (
+
로고 -
판다마켓
+
판다마켓
+ {isLoggedIn ? ( +
+ 유저 프로필 +
+ ) : (
로그인
+ )} +
); } diff --git a/src/components/Nav/Nav.module.css b/src/components/Nav/Nav.module.css index b2c8b06e..3338fa3f 100644 --- a/src/components/Nav/Nav.module.css +++ b/src/components/Nav/Nav.module.css @@ -1,11 +1,41 @@ +/* PC 스타일: 1200px 이상 */ +@media (min-width: 1200px) { +} + +/* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ +@media (min-width: 744px) and (max-width: 1199.98px) { +} + +/* Mobile 스타일: 375px 이상 ~ 743px 이하 */ +@media (min-width: 375px) and (max-width: 743.98px) { +} + .nav { height: 70px; background: #fff; + border-bottom: 1px solid #dfdfdf; +} + +.gnb { + height: 69px; padding: 0 200px; display: flex; justify-content: space-between; align-items: center; - border-bottom: 1px solid #dfdfdf; + /* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ + @media (min-width: 744px) and (max-width: 1199.98px) { + margin: 0 auto; + /* max-width: 696px; */ + width: 100%; + padding: 0 15px; + } + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + margin: 0 auto; + /* max-width: 344px; */ + width: 100%; + padding: 0 15px; + } } .logo { @@ -19,6 +49,10 @@ width: 40px; position: relative; margin-right: 8px; + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + display: none; + } } .logoTitle { @@ -28,6 +62,10 @@ font-size: 2.56rem; color: #3692ff; display: inline-block; + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + font-size: 2rem; + } } .ul { @@ -48,6 +86,12 @@ color: #4b5563; padding: 0 15px; cursor: pointer; + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + padding: 0; + width: 74px; + font-size: 1.6rem; + } } .li:hover { @@ -67,3 +111,13 @@ font-size: 1.6rem; cursor: pointer; } + +.avatar { + width: 40px; + height: 40px; +} + +.avatar img { + width: 40px; + object-fit: cover; +} diff --git a/src/components/Pagination/Pagination_copy.js b/src/components/Pagination/Pagination_copy.js deleted file mode 100644 index 9fdda26c..00000000 --- a/src/components/Pagination/Pagination_copy.js +++ /dev/null @@ -1,53 +0,0 @@ -import React, { useState } from 'react'; -import styles from './Pagination.module.css'; - -const Pagination = ({ currentPage, totalPages, onPageChange }) => { - const [currentGroup, setCurrentGroup] = useState(0); // 현재 페이지 그룹 - - const pagesPerGroup = 5; // 한 그룹당 표시할 페이지 수 - - const handlePreviousGroup = () => { - if (currentGroup > 0) { - setCurrentGroup(currentGroup - 1); - } - }; - - const handleNextGroup = () => { - if ((currentGroup + 1) * pagesPerGroup < totalPages) { - setCurrentGroup(currentGroup + 1); - } - }; - - const handlePageClick = (pageNumber) => { - onPageChange(pageNumber); - }; - - const renderPageNumbers = () => { - const startPage = currentGroup * pagesPerGroup + 1; - const endPage = Math.min(startPage + pagesPerGroup - 1, totalPages); // 총 페이지 수에 맞게 마지막 페이지 설정 - - const pages = []; - for (let i = startPage; i <= endPage; i++) { - pages.push( - - ); - } - return pages; - }; - - return ( -
- - {renderPageNumbers()} - -
- ); -}; - -export default Pagination; \ No newline at end of file diff --git a/src/components/ProductCard/ProductCard.module.css b/src/components/ProductCard/ProductCard.module.css index b7bbe8b5..2eba1e4c 100644 --- a/src/components/ProductCard/ProductCard.module.css +++ b/src/components/ProductCard/ProductCard.module.css @@ -1,22 +1,42 @@ +@media (min-width: 1200px) { + .card { + --card-width: 261px; /* 데스크탑 크기 */ + --card-height: 370px; + } +} + +@media (min-width: 375px) and (max-width: 1199.98px) { + .card { + --card-width: 343px; /* 태블릿 & 모바일 크기 */ + --card-height: 434px; + } +} + .card { - width: 261px; - height: 370px; + width: var(--card-width); + height: var(--card-height); } .image { - width: 261px; - height: 261px; + width: var(--card-width); + height: var(--card-width); object-fit: cover; margin-bottom: 16px; } -.details { -} - .name { font-size: 1.4rem; line-height: 2.4rem; font-weight: 500; + /* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ + @media (min-width: 744px) and (max-width: 1199.98px) { + line-height: 2rem; + } + + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + line-height: 2rem; + } } .price { @@ -24,6 +44,15 @@ font-size: 1.6rem; line-height: 4.1rem; font-family: Pretendard; + /* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ + @media (min-width: 744px) and (max-width: 1199.98px) { + line-height: 3.5rem; + } + + /* Mobile 스타일: 375px 이상 ~ 743px 이하 */ + @media (min-width: 375px) and (max-width: 743.98px) { + line-height: 3.5rem; + } } .likes { diff --git a/src/components/ProductList/BestProductList.js b/src/components/ProductList/BestProductList.js index 3ebe4c91..4a9e77d2 100644 --- a/src/components/ProductList/BestProductList.js +++ b/src/components/ProductList/BestProductList.js @@ -9,12 +9,16 @@ const BestProductList = () => { // 화면 크기에 따른 열 개수 및 pageSize 설정 const isDesktop = useMediaQuery('(min-width:1200px)'); - const isTablet = useMediaQuery('(min-width:768px) and (max-width:1199px)'); - const isMobile = useMediaQuery('(max-width:767px)'); + const isTablet = useMediaQuery('(min-width:744px) and (max-width:1199.98px)'); + const isMobile = useMediaQuery('(max-width:743px)'); const columns = isDesktop ? 4 : isTablet ? 2 : 1; const pageSize = columns; // 화면 크기에 맞춰 pageSize를 columns와 동일하게 설정 + console.log('Desktop:', isDesktop); + console.log('Tablet:', isTablet); + console.log('Mobile:', isMobile); + useEffect(() => { // API에서 데이터 가져오기 - pageSize를 동적으로 전달 getProductList(1, pageSize, 'favorite', '') diff --git a/src/components/ProductList/BestProductList.module.css b/src/components/ProductList/BestProductList.module.css index 7e210dc9..eb6bfc13 100644 --- a/src/components/ProductList/BestProductList.module.css +++ b/src/components/ProductList/BestProductList.module.css @@ -1,5 +1,7 @@ .productList { + width: 100%; display: flex; - flex-wrap: wrap; - gap: 24px; + /* flex-wrap: wrap; */ + justify-content: space-between; + /* gap: 24px; */ } diff --git a/src/components/ProductList/onSalesProductList.js b/src/components/ProductList/onSalesProductList.js index 0f195c28..1de1dbdb 100644 --- a/src/components/ProductList/onSalesProductList.js +++ b/src/components/ProductList/onSalesProductList.js @@ -13,8 +13,8 @@ const OnSalesProductList = ({ orderBy = 'recent', keyword }) => { // 화면 크기에 따른 열 개수 및 pageSize 설정 const isDesktop = useMediaQuery('(min-width:1200px)'); - const isTablet = useMediaQuery('(min-width:768px) and (max-width:1199px)'); - const isMobile = useMediaQuery('(max-width:767px)'); + const isTablet = useMediaQuery('(min-width:744px) and (max-width:1199.98px)'); + const isMobile = useMediaQuery('(max-width:743px)'); const columns = isDesktop ? 5 : isTablet ? 3 : 2; const pageSize = columns * 2; // 화면 크기에 맞춰 pageSize를 columns와 동일하게 설정 diff --git a/src/components/ProductList/onSalesProductList.module.css b/src/components/ProductList/onSalesProductList.module.css index cb531863..2fcde204 100644 --- a/src/components/ProductList/onSalesProductList.module.css +++ b/src/components/ProductList/onSalesProductList.module.css @@ -1,7 +1,8 @@ .productList { display: flex; + justify-content: space-between; flex-wrap: wrap; - gap: 10px; + /* gap: 10px; */ } /* .productList > div { diff --git a/src/media_query.css b/src/media_query.css deleted file mode 100644 index 09e379ff..00000000 --- a/src/media_query.css +++ /dev/null @@ -1,21 +0,0 @@ -/* 스프린트 미션4 까지 사용했던 미디어 쿼리 기준 -미션5에 미디어 쿼리 적용을 아직완성하지 못하고 파일만 만들어 둠 */ - -/* PC 스타일: 1200px 이상 */ -@media (min-width: 1200px) and (max-width: 1440px) { -} - -/* Tablet 스타일: 744px 이상 ~ 1199px 이하 */ -@media (min-width: 744px) and (max-width: 1199px) { -} - -/* Mobile 스타일: 375px 이상 ~ 743px 이하 */ -@media (min-width: 375px) and (max-width: 743px) { -} - -@media (max-width: 500px) { -} - -/* 375px 미만에 대한 스타일은 고려하지 않음 */ -@media (max-width: 374px) { -}