diff --git a/.gitignore b/.gitignore index a547bf36..0949766f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ dist-ssr *.njsproj *.sln *.sw? + + + +.env diff --git a/package-lock.json b/package-lock.json index 9046ff7c..103c8b19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "axios": "^1.11.0", + "lodash": "^4.17.21", "react": "^19.1.0", "react-dom": "^19.1.0", "react-helmet": "^6.1.0", @@ -3133,6 +3134,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", diff --git a/package.json b/package.json index ce8ad815..84880f73 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "axios": "^1.11.0", + "lodash": "^4.17.21", "react": "^19.1.0", "react-dom": "^19.1.0", "react-helmet": "^6.1.0", diff --git a/src/api/axios_instance.js b/src/api/axios_instance.js new file mode 100644 index 00000000..a08c7ef6 --- /dev/null +++ b/src/api/axios_instance.js @@ -0,0 +1,9 @@ +//axios instance + +import axios from "axios"; +const BASE_URL=import.meta.env.VITE_PRODUCT_BASE_URL; +const instance=axios.create({ + baseURL: BASE_URL, +}); + +export default instance; \ No newline at end of file diff --git a/src/api/productApi.jsx b/src/api/productApi.jsx index ffaea698..ae5b266c 100644 --- a/src/api/productApi.jsx +++ b/src/api/productApi.jsx @@ -1,11 +1,21 @@ -import axios from "axios"; +import instance from "./axios_instance"; //베스트 상품 -const BASE_URL = "https://panda-market-api.vercel.app/products?page="; -export async function getProductBest({ pageSize = 4 }) { +const BASE_URL = import.meta.env.VITE_PRODUCT_BASE_URL; +function createParams({ page, pageSize, orderBy }) { + return new URLSearchParams({ + page: page.toString(), + pageSize: pageSize.toString(), + orderBy: orderBy, + }); +} + + +export async function getProductBest({ page, pageSize, orderBy }) { try { - const response = await axios.get( - `${BASE_URL}1&pageSize=${pageSize}&orderBy=favorite` + const params=createParams({page, pageSize,orderBy}); + const response = await instance.get( + `/products?${params.toString()}` ); return response.data; } catch (error) { @@ -16,8 +26,9 @@ export async function getProductBest({ pageSize = 4 }) { //리스트 export async function getProductList({ page, pageSize, orderBy }) { try { - const response = await axios.get( - `${BASE_URL}${page}&pageSize=${pageSize}&orderBy=${orderBy}` + const params=createParams({page, pageSize,orderBy}); + const response = await instance.get( + `/products?${params.toString()}` ); return response.data; } catch (error) { diff --git a/src/assets/css/common.css b/src/assets/css/common.css index 428fba87..8258397a 100644 --- a/src/assets/css/common.css +++ b/src/assets/css/common.css @@ -2,7 +2,7 @@ @import url("../css/reset.css"); @import url("../css/variable.css"); body { - width: 100%; + width: calc(100vw - (100vw - 100%)); font-family: "Pretendard-Regular"; font-size: var(--common); } @@ -46,7 +46,8 @@ body { display: inline-flex; justify-content: center; align-items: center; - padding: 1.2rem 2.3rem; + padding: 1.3rem 2.229rem; + line-height: 1; font-size: var(--common); font-weight: 600; color: var(--white100); @@ -58,14 +59,48 @@ body { -o-border-radius: 9999px; white-space: nowrap; } +.button[disabled] { + background-color: var(--gray400); + cursor: default; +} .medium-button { height: 4.8rem; } +.small-round { + border-radius: 1.2rem; + -webkit-border-radius: 1.2rem; + -moz-border-radius: 1.2rem; + -ms-border-radius: 1.2rem; + -o-border-radius: 1.2rem; +} + +.sectionTitleWrap { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 0 1.2rem; + position: relative; + z-index: 100; + margin-bottom: 1.6rem; + width: 100%; + min-height: 3.2rem; +} +.sectionTitleWrap .sectionTitle { + position: absolute; + left: 0; + font-size: var(--sectionTitle); +} + @media all and (max-width: 47.9375rem) { .inner { - padding: 0 2rem; + padding: 0 1.5rem; width: 100%; } + .sectionTitleWrap { + flex-wrap: wrap; + gap: 0.8rem 1.4rem; + align-items: flex-start; + } }/*# sourceMappingURL=common.css.map */ \ No newline at end of file diff --git a/src/assets/css/common.css.map b/src/assets/css/common.css.map index a364f6f1..feb76b0e 100644 --- a/src/assets/css/common.css.map +++ b/src/assets/css/common.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/common.scss","../scss/_variables.scss"],"names":[],"mappings":"AAAQ;AACA;AACA;AAGR;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;ACTA;EDaA;IACE;IACA","file":"common.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/common.scss","../scss/_variables.scss"],"names":[],"mappings":"AAAQ;AACA;AACA;AAGR;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EChEE,eDiEe;EChEf,uBDgEe;EC/Df,oBD+De;EC9Df,mBD8De;EC7Df,kBD6De;;;AAGjB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;ACpCF;EDyCA;IACE;IACA;;EAGF;IACE;IACA;IACA","file":"common.css"} \ No newline at end of file diff --git a/src/assets/css/form.module.css b/src/assets/css/form.module.css new file mode 100644 index 00000000..31ae4b6b --- /dev/null +++ b/src/assets/css/form.module.css @@ -0,0 +1,154 @@ +.formWrap { + display: flex; + flex-direction: column; + gap: 2.4rem 0; + padding: 1rem 0; + width: 100%; +} + +.inputGroup { + display: flex; + flex-direction: column; + gap: 1.6rem 0; + padding-bottom: 0.8rem; +} + +.inputTitle { + font-size: var(--medium); +} + +.inputBox { + display: flex; + align-items: center; + position: relative; + width: 100%; + height: fit-content; + background-color: var(--gray100); + border: 1px solid var(--gray50); + border-radius: 1.2rem; + -webkit-border-radius: 1.2rem; + -moz-border-radius: 1.2rem; + -ms-border-radius: 1.2rem; + -o-border-radius: 1.2rem; +} +.inputBox input:not([type=checkbox]) { + padding: 1.6rem 2.4rem 1.4rem; + flex: 1 1 0; + height: 5.6rem; + font-size: var(--common); + font-weight: 400; + outline: 0 none; +} +.inputBox input:not([type=checkbox]).err { + border: 1px solid var(--red) !important; +} +.inputBox input:not([type=checkbox]).focus { + border: 1px solid var(--blue200); +} +.inputBox input:not([type=checkbox])::placeholder { + font-size: inherit; + font-weight: 400; + color: var(--gray400); +} +.inputBox textarea { + padding: 1.6rem 2.4rem 1.4rem; + width: 100%; + height: 28.2rem; + line-height: 1.7; + font-size: var(--common); + font-weight: 400; + outline: 0 none; +} +.inputBox textarea::placeholder { + font-size: inherit; + font-weight: 400; + color: var(--gray400); +} + +.imageFileGroup { + display: flex; + flex-wrap: wrap; + gap: 1.6rem 2.4rem; +} +.imageFileGroup .box { + overflow: hidden; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + gap: 1.2rem 0; + position: relative; + width: 28.2rem; + height: 28.2rem; + font-weight: 400; + color: var(--gray400); + background-color: var(--gray100); + border-radius: 1.6rem; + -webkit-border-radius: 1.6rem; + -moz-border-radius: 1.6rem; + -ms-border-radius: 1.6rem; + -o-border-radius: 1.6rem; + cursor: pointer; +} +.imageFileGroup .box input { + display: none; + position: absolute; +} +.imageFileGroup .errorMessage { + width: 100%; + font-weight: 400; + color: var(--red); +} + +input[type=file] { + overflow: hidden; + margin: -1px; + width: 0; + height: 0; +} +input[type=file]::file-selector-button { + display: none; +} + +.imagePreview img { + width: auto; + height: 100%; + object-fit: cover; +} +.imagePreview .deleteButton { + z-index: 10; + position: absolute; + top: 1rem; + right: 1rem; + padding: 1rem; + font-size: var(--large); + color: var(--withe100); +} + +@media all and (max-width: 74.9375rem) { + .imageFileGroup { + gap: 1.6rem 1rem; + } + .imageFileGroup .box { + width: 16.8rem; + height: 16.8rem; + } + .imagePreview .deleteButton { + top: 0.5rem; + right: 0.5rem; + } +} +@media all and (max-width: 47.9375rem) { + .imageFileGroup { + gap: 1.6rem 1rem; + } + .imageFileGroup .box { + width: calc(50% - 0.5rem); + max-width: 16.8rem; + } +} +.tagWrap { + display: flex; + flex-direction: column; + gap: 1.4rem 0; +}/*# sourceMappingURL=form.module.css.map */ \ No newline at end of file diff --git a/src/assets/css/form.module.css.map b/src/assets/css/form.module.css.map new file mode 100644 index 00000000..cc73894a --- /dev/null +++ b/src/assets/css/form.module.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../scss/form.module.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;;AAKN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EChFF,eDiFiB;EChFjB,uBDgFiB;EC/EjB,oBD+EiB;EC9EjB,mBD8EiB;EC7EjB,kBD6EiB;EACf;;AACA;EACE;EACA;;AAGJ;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AACA;EACE;;;AAKF;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AC9EF;EDmFA;IACE;;EAEA;IACE;IACA;;EAIF;IACE;IACA;;;ACxFJ;ED8FA;IACE;;EAEA;IACE;IACA;;;AAKN;EACE;EACA;EACA","file":"form.module.css"} \ No newline at end of file diff --git a/src/assets/css/header.module.css b/src/assets/css/header.module.css index 9757df03..45c9af10 100644 --- a/src/assets/css/header.module.css +++ b/src/assets/css/header.module.css @@ -3,7 +3,7 @@ position: fixed; top: 0; padding: 1rem 0 0.9rem; - width: 100%; + width: 100vw; height: 7rem; background-color: var(--white100); border-bottom: 1px solid var(--line); @@ -38,11 +38,26 @@ } .nav a { display: block; + position: relative; height: fit-content; padding: 1rem 1rem; } -.nav a.active { - border-bottom: 2px solid #3692ff; +.nav a::after { + position: absolute; + left: 0; + bottom: 0; + width: 0; + height: 2px; + background-color: #3692ff; + content: ""; +} +.nav a.active::after { + width: 100%; + transition: width 0.3s 0.1s; + -webkit-transition: width 0.3s 0.1s; + -moz-transition: width 0.3s 0.1s; + -ms-transition: width 0.3s 0.1s; + -o-transition: width 0.3s 0.1s; } @media all and (max-width: 47.9375rem) { diff --git a/src/assets/css/header.module.css.map b/src/assets/css/header.module.css.map index 78414d64..2a886039 100644 --- a/src/assets/css/header.module.css.map +++ b/src/assets/css/header.module.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/header.module.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AACA;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AACA;EACE;;;ACSJ;EDDA;IACE;IACA;;EAGA;IACE;;EAIF;IACE;;EACA;IACE","file":"header.module.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/header.module.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AACA;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;EChBN;EACA;EACA;EACA;EACA;;;AAUA;EDUA;IACE;IACA;;EAGA;IACE;;EAIF;IACE;;EACA;IACE","file":"header.module.css"} \ No newline at end of file diff --git a/src/assets/css/itemsList.module.css b/src/assets/css/itemsList.module.css index 7a5287f3..b576e090 100644 --- a/src/assets/css/itemsList.module.css +++ b/src/assets/css/itemsList.module.css @@ -1,20 +1,3 @@ -.sectionTitleWrap { - display: flex; - justify-content: flex-end; - align-items: center; - gap: 0 1.2rem; - position: relative; - z-index: 100; - margin-bottom: 1.6rem; - width: 100%; - min-height: 3.2rem; -} -.sectionTitleWrap .sectionTitle { - position: absolute; - left: 0; - font-size: var(--sectionTitle); -} - .formWrap { width: 40%; max-width: 32.5rem; @@ -40,11 +23,6 @@ } @media all and (max-width: 47.9375rem) { - .sectionTitleWrap { - flex-wrap: wrap; - gap: 0.8rem 1.4rem; - align-items: flex-start; - } .formWrap { order: 3; width: 100%; diff --git a/src/assets/css/itemsList.module.css.map b/src/assets/css/itemsList.module.css.map index b66e4a47..e5960a4d 100644 --- a/src/assets/css/itemsList.module.css.map +++ b/src/assets/css/itemsList.module.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/itemsList.module.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EC1BE;EACA;EACA;ED0BA;EACA;EACA;EACA;ECzBA,eADmB;EAEnB,uBAFmB;EAGnB,oBAHmB;EAInB,mBAJmB;EAKnB,kBALmB;;;AA+CnB;EDhBA;IACE;IACA;IACA;;EAEF;IACE;IACA;IACA;;EAGF;IACE;;EAGF;IC7CA,eD8CiB;IC7CjB,uBD6CiB;IC5CjB,oBD4CiB;IC3CjB,mBD2CiB;IC1CjB,kBD0CiB","file":"itemsList.module.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/itemsList.module.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA;EACE;EACA;;;AAGF;EACE;;;AAGF;ECRE;EACA;EACA;EDQA;EACA;EACA;EACA;ECPA,eADmB;EAEnB,uBAFmB;EAGnB,oBAHmB;EAInB,mBAJmB;EAKnB,kBALmB;;;AA+CnB;EDlCA;IACE;IACA;IACA;;EAGF;IACE;;EAGF;ICtBA,eDuBiB;ICtBjB,uBDsBiB;ICrBjB,oBDqBiB;ICpBjB,mBDoBiB;ICnBjB,kBDmBiB","file":"itemsList.module.css"} \ No newline at end of file diff --git a/src/assets/css/reset.css b/src/assets/css/reset.css index 79673f9d..8a63cffa 100644 --- a/src/assets/css/reset.css +++ b/src/assets/css/reset.css @@ -252,6 +252,17 @@ address { font-style: normal; } +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox용 */ +input[type=number] { + -moz-appearance: textfield; +} + @media (prefers-reduced-motion: reduce) { * { diff --git a/src/assets/css/tagGroup.module.css b/src/assets/css/tagGroup.module.css new file mode 100644 index 00000000..3d3a7c3f --- /dev/null +++ b/src/assets/css/tagGroup.module.css @@ -0,0 +1,20 @@ +.tagGroup { + display: flex; + flex-wrap: wrap; + gap: 1.2rem; + width: 100%; +} + +.tag { + display: flex; + align-items: center; + gap: 0 0.8rem; + padding: 0.5rem 1.2rem 0.5rem 1.6rem; + width: fit-content; + background-color: var(--gray100); + border-radius: 1.8rem; + -webkit-border-radius: 1.8rem; + -moz-border-radius: 1.8rem; + -ms-border-radius: 1.8rem; + -o-border-radius: 1.8rem; +}/*# sourceMappingURL=tagGroup.module.css.map */ \ No newline at end of file diff --git a/src/assets/css/tagGroup.module.css.map b/src/assets/css/tagGroup.module.css.map new file mode 100644 index 00000000..c4bab68e --- /dev/null +++ b/src/assets/css/tagGroup.module.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../scss/tagGroup.module.scss","../scss/_variables.scss"],"names":[],"mappings":"AAEA;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;ECNA,eDOe;ECNf,uBDMe;ECLf,oBDKe;ECJf,mBDIe;ECHf,kBDGe","file":"tagGroup.module.css"} \ No newline at end of file diff --git a/src/assets/images/ic_plus.svg b/src/assets/images/ic_plus.svg new file mode 100644 index 00000000..5bb9abf5 --- /dev/null +++ b/src/assets/images/ic_plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/selfDelete.svg b/src/assets/images/selfDelete.svg new file mode 100644 index 00000000..87a00547 --- /dev/null +++ b/src/assets/images/selfDelete.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/scss/common.scss b/src/assets/scss/common.scss index 37fe4da1..27ec1273 100644 --- a/src/assets/scss/common.scss +++ b/src/assets/scss/common.scss @@ -4,7 +4,7 @@ @import "./_variables"; body { - width: 100%; + width: calc(100vw - calc(100vw - 100%)); font-family: "Pretendard-Regular"; font-size: var(--common); } @@ -48,7 +48,8 @@ body { display: inline-flex; justify-content: center; align-items: center; - padding: 1.2rem 2.3rem; + padding: 1.3rem 2.229rem; + line-height: 1; font-size: var(--common); font-weight: 600; color: var(--white100); @@ -59,15 +60,48 @@ body { -ms-border-radius: 9999px; -o-border-radius: 9999px; white-space: nowrap; + + &[disabled] { + background-color: var(--gray400); + cursor: default; + } } .medium-button { height: 4.8rem; } +.small-round { + @include round(1.2rem); +} + +.sectionTitleWrap { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 0 1.2rem; + position: relative; + z-index: 100; + margin-bottom: 1.6rem; + width: 100%; + min-height: 3.2rem; + + .sectionTitle { + position: absolute; + left: 0; + font-size: var(--sectionTitle); + } +} + @include mobile { .inner { - padding: 0 2rem; + padding: 0 1.5rem; width: 100%; } + + .sectionTitleWrap { + flex-wrap: wrap; + gap: 0.8rem 1.4rem; + align-items: flex-start; + } } diff --git a/src/assets/scss/form.module.scss b/src/assets/scss/form.module.scss new file mode 100644 index 00000000..009e2776 --- /dev/null +++ b/src/assets/scss/form.module.scss @@ -0,0 +1,164 @@ +@import "./_variables"; + +.formWrap { + display: flex; + flex-direction: column; + gap: 2.4rem 0; + padding: 1rem 0; + width: 100%; +} + +.inputGroup { + display: flex; + flex-direction: column; + gap: 1.6rem 0; + padding-bottom: 0.8rem; +} + +.inputTitle { + font-size: var(--medium); +} + +.inputBox { + display: flex; + align-items: center; + position: relative; + width: 100%; + height: fit-content; + background-color: var(--gray100); + border: 1px solid var(--gray50); + border-radius: 1.2rem; + -webkit-border-radius: 1.2rem; + -moz-border-radius: 1.2rem; + -ms-border-radius: 1.2rem; + -o-border-radius: 1.2rem; + + input:not([type="checkbox"]) { + padding: 1.6rem 2.4rem 1.4rem; + flex: 1 1 0; + height: 5.6rem; + font-size: var(--common); + font-weight: 400; + outline: 0 none; + &.err { + border: 1px solid var(--red) !important; + } + &.focus { + border: 1px solid var(--blue200); + } + + &::placeholder { + font-size: inherit; + font-weight: 400; + color: var(--gray400); + } + } + + textarea { + padding: 1.6rem 2.4rem 1.4rem; + width: 100%; + height: 28.2rem; + line-height: 1.7; + font-size: var(--common); + font-weight: 400; + outline: 0 none; + &::placeholder { + font-size: inherit; + font-weight: 400; + color: var(--gray400); + } + } +} + +.imageFileGroup { + display: flex; + flex-wrap: wrap; + gap: 1.6rem 2.4rem; + + .box { + overflow: hidden; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + gap: 1.2rem 0; + position: relative; + width: 28.2rem; + height: 28.2rem; + font-weight: 400; + color: var(--gray400); + background-color: var(--gray100); + @include round(1.6rem); + cursor: pointer; + input { + display: none; + position: absolute; + } + } + .errorMessage { + width: 100%; + font-weight: 400; + color: var(--red); + } +} + +input[type="file"] { + overflow: hidden; + margin: -1px; + width: 0; + height: 0; + &::file-selector-button { + display: none; + } +} + +.imagePreview { + img { + width: auto; + height: 100%; + object-fit: cover; + } + .deleteButton { + z-index: 10; + position: absolute; + top: 1rem; + right: 1rem; + padding: 1rem; + font-size: var(--large); + color: var(--withe100); + } +} + +@include tablet { + .imageFileGroup { + gap: 1.6rem 1rem; + + .box { + width: 16.8rem; + height: 16.8rem; + } + } + .imagePreview { + .deleteButton { + top: 0.5rem; + right: 0.5rem; + } + } +} + +@include mobile { + .imageFileGroup { + gap: 1.6rem 1rem; + + .box { + width: calc(calc(100% / 2) - 0.5rem); + max-width: 16.8rem; + } + } +} + +.tagWrap { + display: flex; + flex-direction: column; + gap: 1.4rem 0; +} diff --git a/src/assets/scss/header.module.scss b/src/assets/scss/header.module.scss index a1835da2..0882a513 100644 --- a/src/assets/scss/header.module.scss +++ b/src/assets/scss/header.module.scss @@ -5,7 +5,7 @@ position: fixed; top: 0; padding: 1rem 0 0.9rem; - width: 100%; + width: 100vw; height: 7rem; background-color: var(--white100); border-bottom: 1px solid var(--line); @@ -41,16 +41,27 @@ a { display: block; + position: relative; height: fit-content; padding: 1rem 1rem; + &::after { + position: absolute; + left: 0; + bottom: 0; + width: 0; + height: 2px; + background-color: #3692ff; + content: ""; + } &.active { - border-bottom: 2px solid #3692ff; + &::after { + width: 100%; + @include transition(width, 0.3s, 0.1s); + } } } } - - @include mobile { .container { padding: 0 1.6rem; diff --git a/src/assets/scss/itemsList.module.scss b/src/assets/scss/itemsList.module.scss index fea89b75..563c8f11 100644 --- a/src/assets/scss/itemsList.module.scss +++ b/src/assets/scss/itemsList.module.scss @@ -1,23 +1,5 @@ @import "./_variables"; -.sectionTitleWrap { - display: flex; - justify-content: flex-end; - align-items: center; - gap: 0 1.2rem; - position: relative; - z-index: 100; - margin-bottom: 1.6rem; - width: 100%; - min-height: 3.2rem; - - .sectionTitle { - position: absolute; - left: 0; - font-size: var(--sectionTitle); - } -} - .formWrap { width: 40%; max-width: 32.5rem; @@ -37,11 +19,6 @@ } @include mobile { - .sectionTitleWrap { - flex-wrap: wrap; - gap: 0.8rem 1.4rem; - align-items: flex-start; - } .formWrap { order: 3; width: 100%; diff --git a/src/assets/scss/tagGroup.module.scss b/src/assets/scss/tagGroup.module.scss new file mode 100644 index 00000000..e983ae68 --- /dev/null +++ b/src/assets/scss/tagGroup.module.scss @@ -0,0 +1,18 @@ +@import "./_variables"; + +.tagGroup { + display: flex; + flex-wrap: wrap; + gap: 1.2rem; + width: 100%; +} + +.tag { + display: flex; + align-items: center; + gap: 0 0.8rem; + padding: 0.5rem 1.2rem 0.5rem 1.6rem; + width: fit-content; + background-color: var(--gray100); + @include round(1.8rem); +} diff --git a/src/components/Button.jsx b/src/components/Button.jsx new file mode 100644 index 00000000..754e8ec5 --- /dev/null +++ b/src/components/Button.jsx @@ -0,0 +1,12 @@ +const Button = ({ children, className, isDisabled = false, type, onClick }) => ( + +); + +export default Button; diff --git a/src/components/Container.jsx b/src/components/Container.jsx deleted file mode 100644 index d974544c..00000000 --- a/src/components/Container.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import classNames from 'classnames'; -import styles from '../Container.module.scss'; - -function Container({ className, children }) { - return ( -
{children}
- ); -} - -export default Container; diff --git a/src/components/Pagination.jsx b/src/components/Pagination.jsx index e15a354f..ca11b1a2 100644 --- a/src/components/Pagination.jsx +++ b/src/components/Pagination.jsx @@ -3,23 +3,22 @@ import leftArrowIcon from "../assets/images/left_arrow.svg"; import rightArrowIcon from "../assets/images/right_arrow.svg"; import wrap from "../assets/scss/pagination.module.scss"; -function Pagination({ onPageLoad, totalCount, itemListLength }) { +//페이지네이션 최대 생성 갯수 +const LIST_MAX = 5; +const paginationArr = (startPage, maxPages) => { + const pages = []; + for (let i = 0; i < maxPages; i++) { + pages.push(startPage + i); + } + return pages; +}; - //페이지네이션 최대 생성 갯수 - const LIST_MAX = 5; +function Pagination({ onPageLoad, totalCount, itemListLength }) { const ITEM_LENGTH = itemListLength; const [currentPage, setCurrentPage] = useState(1); //현재 페이지 const [pages, setPages] = useState([]); //페이지네이션 배열 const [hasNext, setHasNext] = useState(true); - const paginationArr = (startPage, maxPages) => { - const pages = []; - for (let i = 0; i < maxPages; i++) { - pages.push(startPage + i); - } - return pages; - }; - // 페이지네이션 상태 업데이트 함수 useEffect(() => { const totalPages = Math.ceil(totalCount / ITEM_LENGTH); @@ -42,7 +41,7 @@ function Pagination({ onPageLoad, totalCount, itemListLength }) { setPages(newPages); } - }, [currentPage,totalCount,itemListLength]); + }, [currentPage, totalCount, itemListLength]); // 이전 페이지 버튼 클릭 const handlePrevClick = () => { @@ -60,22 +59,6 @@ function Pagination({ onPageLoad, totalCount, itemListLength }) { onPageLoad(nextPage); }; - // 페이지네이션 렌더링 - const renderPages = () => { - return pages.map((number) => ( -
  • - -
  • - )); - }; - //페이지 클릭 const handlePageClick = (number) => { setCurrentPage(number); //현재 페이지 변경 @@ -87,7 +70,13 @@ function Pagination({ onPageLoad, totalCount, itemListLength }) { - + {hasNext && ( + + )); +} + export default Pagination; diff --git a/src/components/ProductList.jsx b/src/components/ProductList.jsx index 5c8ccae8..f2a0a29e 100644 --- a/src/components/ProductList.jsx +++ b/src/components/ProductList.jsx @@ -9,19 +9,19 @@ import "react-loading-skeleton/dist/skeleton.css"; //베스트 아이템 function BestProduct({ items, col, setNumberComma, isBestLoading }) { return ( - + ); } diff --git a/src/components/TagGroup.jsx b/src/components/TagGroup.jsx new file mode 100644 index 00000000..8faa1e1b --- /dev/null +++ b/src/components/TagGroup.jsx @@ -0,0 +1,30 @@ +import Button from "./Button"; +import tagGroup from "../assets/scss/tagGroup.module.scss"; +import selfDelete from "../assets/images/selfDelete.svg"; + +function TagGroup({ tagArr, deleteTag }) { + const handleDeleteTag = (e) => { + const targetParent = e.target.closest("fieldset"); + const targetInput = targetParent.querySelector("input"); + const value = targetInput.value; + deleteTag(value); + }; + + return ( +
    + {tagArr.map((item, index) => { + return ( +
    + + {"#" + item} + +
    + ); + })} +
    + ); +} + +export default TagGroup; diff --git a/src/components/UserMenu.jsx b/src/components/UserMenu.jsx index bbf721fc..71215ae8 100644 --- a/src/components/UserMenu.jsx +++ b/src/components/UserMenu.jsx @@ -1,7 +1,8 @@ import { Link } from "react-router-dom"; import userMenu from "../assets/scss/userMenu.module.scss"; import userProFile from "../assets/images/UserButton.svg"; -import { useState } from "react"; +import Button from "./Button"; +import { Children, useState } from "react"; function UserMenu({ isLogin }) { return ( @@ -14,7 +15,9 @@ function UserMenu({ isLogin }) { diff --git a/src/components/header.jsx b/src/components/header.jsx index 58b5d5a6..f0e7d8aa 100644 --- a/src/components/header.jsx +++ b/src/components/header.jsx @@ -16,7 +16,7 @@ function Header({ isLogin }) {