diff --git a/main/_front/dist/add-edit.html b/main/_front/dist/add-edit.html new file mode 100644 index 0000000..b0dad57 --- /dev/null +++ b/main/_front/dist/add-edit.html @@ -0,0 +1,294 @@ + + + + + + + Document + + + + + +
+
+ +
+
+
+
+

Добавление/Редактирование

+
+
+
+
+
+
+

Выберите
тип продукта

+
+ + + + + + + + +
+
+ +
+
+ +
Введите название продукта
+
+ + Название +
+
+
Введите цену:
+
+ + Цена +
+
+
+

Количество:

+
+ +
1
+ +
+
+
Дополнительные характеристики + (появляются после добавления)
+
+ +
+
+ +
+ +
+
Выберите обязательные поля
+
+
+
Сокет (разъем на плате)
+
+ + + + + + +
+
+
+
Количество слотов ОЗУ
+
+ + +
+
+ + +
+
Тип памяти
+
+ + +
+
+
+
Добавьте еще несколько характеристик
+
+ + Название хар-ки +
+
+ + Характеристика +
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/main/_front/dist/components-admin.html b/main/_front/dist/components-admin.html new file mode 100644 index 0000000..dbf1033 --- /dev/null +++ b/main/_front/dist/components-admin.html @@ -0,0 +1,304 @@ + + + + + + + Document + + + + + + +
+
+ +
+
+
+
+

Комплектующие

+
+
+
+
+
+
+
+ + + + + + + + +
+ + + +
+
+
+
Сортировка:
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
ЦП AMD Ryzen 7 2700
+
8 500 ₽
+ +
+
+
+ +
+
ЦП AMD Ryzen 7 2700
+
8 500 ₽
+ +
+
+
+ +
+
ЦП AMD Ryzen 7 2700
+
8 500 ₽
+ +
+
+
+ +
+
ЦП AMD Ryzen 7 2700
+
8 500 ₽
+ +
+
+
+ +
+
ЦП AMD Ryzen 7 2700
+
8 500 ₽
+ +
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/main/_front/dist/components.html b/main/_front/dist/components.html new file mode 100644 index 0000000..b332393 --- /dev/null +++ b/main/_front/dist/components.html @@ -0,0 +1,264 @@ + + + + + + + Document + + + + + + +
+
+ +
+
+
+
+

Комплектующие

+
+
+
+
+
+
+
+ + + + + + + + +
+ + +
+
+
+
Сортировка:
+
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/main/_front/dist/css/style.css b/main/_front/dist/css/style.css new file mode 100644 index 0000000..8c4ba2f --- /dev/null +++ b/main/_front/dist/css/style.css @@ -0,0 +1,685 @@ +/* Reset and base styles */ +* { + padding: 0; + margin: 0; + border: none; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Links */ +a, a:link, a:visited { + text-decoration: none; +} + +a:hover { + text-decoration: none; +} + +/* Common */ +aside, nav, footer, header, section, main { + display: block; +} + +h1, h2, h3, h4, h5, h6, p { + font-size: inherit; + font-weight: inherit; +} + +ul, ul li { + list-style: none; +} + +img { + vertical-align: top; +} + +img, svg { + max-width: 100%; + height: auto; +} + +address { + font-style: normal; +} + +/* Form */ +input, textarea, button, select { + font-family: inherit; + font-size: inherit; + color: inherit; + background-color: transparent; +} + +input::-ms-clear { + display: none; +} + +button, input[type=submit] { + display: inline-block; + box-shadow: none; + background-color: transparent; + background: none; + cursor: pointer; +} + +input:focus, input:active, +button:focus, button:active { + outline: none; +} + +button::-moz-focus-inner { + padding: 0; + border: 0; +} + +label { + cursor: pointer; +} + +legend { + display: block; +} + +body { + font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-size: 16px; +} + +.container { + width: 100%; + max-width: 1170px; + margin: 0 auto; + padding: 0 15px; +} + +.grey_background { + border: 1px solid #d8d8d8; + background-color: #F8F8F8; + border-radius: 10px; +} + +.btn { + display: inline-block; + background: #712CF9; + font-size: 18px; + line-height: 21px; + color: white; + font-weight: bold; + text-decoration: none; + border-radius: 8px; + min-width: 190px; + border: 1px solid #712CF9; + padding: 12px; + transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease; +} +.btn-big { + min-width: 275px; + font-size: 24px; + line-height: 28px; +} +.btn:hover { + background-color: #fff; + color: #712CF9; +} +.btn:disabled { + background: #712CF9; + color: white; + opacity: 0.4; + cursor: not-allowed; +} + +.checkbox-group { + display: flex; + flex-direction: column; + gap: 6px; +} + +.checkbox-group__title { + font-size: 18px; + margin-bottom: 6px; + font-weight: 500; +} + +.checkbox { + display: flex; + align-items: center; + font-size: 18px; + width: 100%; + user-select: none; +} +.checkbox label { + height: 28px; + width: 100%; +} + +.checkbox-real { + width: 0; + height: 0; + opacity: 0; + position: absolute; + z-index: -1; +} + +.checkbox-real:focus + .checkbox-custom { + box-shadow: 0 0 4px 1px #D0D0D0; +} + +.checkbox-custom { + display: inline-block; + width: 24px; + height: 24px; + background-color: #fff; + border: 1px solid #D0D0D0; + border-radius: 4px; + margin-right: 10px; + vertical-align: sub; + transition: background-color 0.2s ease, border 0.2s ease; + position: relative; +} + +.checkbox-custom::before { + content: ""; + display: inline-block; + width: 20px; + height: 20px; + background-image: url("../../img/tick.svg"); + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +.checkbox-real:checked + .checkbox-custom { + background-color: #712CF9; + border-color: #712CF9; +} + +.choice { + display: flex; + gap: 10px; +} +.choice-grid { + flex-wrap: wrap; + justify-content: space-between; +} + +.choice__elem { + min-width: 110px; + font-size: 16px; + font-weight: 500; + line-height: 35px; + border-radius: 10px; + padding: 0 8px; + background-color: #ededed; + transition: background-color 0.2s ease, color 0.2s ease; +} +.choice__elem-wide { + min-width: 150px; +} +.choice__elem:hover { + background-color: #D0D0D0; +} +.choice__elem.active { + background-color: #712CF9; + color: #fff; +} +.choice__elem.active:hover { + background-color: #8245fa; +} +.choice__elem-with_img { + display: flex; + align-items: center; + column-gap: 15px; + font-size: 18px; + padding: 15px; + min-width: 236px; + text-align: start; + line-height: 21px; + min-height: 72px; +} +.choice__elem-with_img svg { + min-width: 40px; + min-height: 40px; + fill: #000; + transition: fill 0.2s ease; +} +.choice__elem-with_img.active svg { + fill: #fff; +} +.choice__elem-text_sm { + font-size: 16px; + line-height: 19px; +} + +.header { + padding: 15px 0; + border-bottom: 1px solid #D0D0D0; +} + +.header__inner { + display: flex; + justify-content: space-between; + align-items: center; +} + +.header__logo { + display: flex; + column-gap: 30px; + align-items: center; + cursor: pointer; +} +.header__logo img { + width: 50px; + height: 50px; +} + +.header__title { + font-size: 28px; + color: #712CF9; +} + +.header__nav { + display: flex; + column-gap: 20px; + align-items: center; +} + +.header__link { + font-size: 18px; + color: #636363; + transition: color 0.2s ease; +} +.header__link:hover, .header__link.active { + color: #712CF9; +} +.header__link:hover svg, .header__link.active svg { + fill: #712CF9; +} +.header__link svg { + fill: #636363; + transition: fill 0.2s ease; +} + +.input { + position: relative; + background-color: #fff; +} + +.input__text { + width: 100%; + padding: 16px 15px; + border: 2px solid #D0D0D0; + background: transparent; + border-radius: 10px; + outline: none; + line-height: 24px; + color: #000; + transition: border 0.3s ease; + font-size: 18px; +} + +.input span { + position: absolute; + left: 0; + top: 0; + line-height: 24px; + margin: 17px 3px; + padding: 0 12px; + pointer-events: none; + font-size: 18px; + color: #555555; + font-weight: 400; + border-radius: 6px; + transition: 0.2s ease; +} + +.input__text:not(:placeholder-shown) ~ span, +.input__text:focus ~ span { + transform: translate(19px, -7px); + font-size: 14px; + line-height: 18px; + padding: 0 8px; + border-radius: 4px; + font-weight: 400; + letter-spacing: 0.04em; + margin: 0; + color: #fff; +} + +.input__text:not(:placeholder-shown) ~ span { + background: #878787; +} + +.input__text:focus ~ span { + background: #712CF9; +} + +.input__text:not(:placeholder-shown) { + border: 2px solid #878787; +} + +.input__text:focus { + border: 2px solid #712CF9; +} + +.property { + justify-content: space-between; + align-items: center; + text-align: left; + background-color: #EDEDED; + border-radius: 10px; +} +.property-with-delete { + display: flex; +} + +.property__text { + padding: 10px 15px; +} + +.property__name { + font-size: 16px; + line-height: 19px; + color: #555; + margin-bottom: 5px; +} + +.property__value { + font-size: 18px; + line-height: 21px; + font-weight: 500; +} + +.property__btn { + padding: 10px; + border-radius: 10px; + background-color: #DC3545; + cursor: pointer; + transition: background-color 0.2s ease; +} +.property__btn:hover { + background-color: #d32535; +} + +.stepper { + display: inline-flex; + align-items: center; + border-radius: 8px; + overflow: hidden; + border: 2px solid #712CF9; +} + +.stepper__minus, .stepper__plus { + background-color: #712CF9; + padding: 4px 6px; + width: 41px; + height: 36px; + transition: background-color 0.2s ease, opacity 0.2s ease; +} +.stepper__minus svg, .stepper__plus svg { + fill: #fff; + transition: fill 0.2s ease; +} +.stepper__minus:hover, .stepper__plus:hover { + background-color: #fff; +} +.stepper__minus:hover svg, .stepper__plus:hover svg { + fill: #712CF9; +} +.stepper__minus:disabled, .stepper__plus:disabled { + opacity: 0.4; + cursor: not-allowed; + background-color: #712CF9; +} +.stepper__minus:disabled svg, .stepper__plus:disabled svg { + fill: #fff; +} + +.stepper__minus { + border-right: 2px solid #712CF9; +} + +.stepper__plus { + border-left: 2px solid #712CF9; +} + +.stepper__value { + font-size: 22px; + width: 44px; + line-height: 36px; + text-align: center; +} + +.add-center { + width: 468px; + padding: 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + flex: 1; +} + +.add-center__input { + width: 100%; +} + +.add-center__price { + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; +} + +.add-center__count { + display: flex; + align-items: center; + column-gap: 50px; +} + +.add-center__properties { + width: 100%; + display: flex; + flex-direction: column; + row-gap: 10px; + max-height: 385px; + overflow-y: auto; +} + +.add-edit { + margin-bottom: 20px; +} + +.add-edit__inner { + display: flex; + justify-content: space-between; +} + +.add-edit__choice { + width: 276px; + padding: 20px; +} + +.add-edit__choice-subtitle { + margin-bottom: 20px; +} + +.add-edit__center { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + row-gap: 20px; +} + +.add-right { + width: 276px; + padding: 20px 10px; + display: flex; + flex-direction: column; + align-items: center; + row-gap: 20px; +} + +.add-right__choices { + display: flex; + flex-direction: column; + align-items: center; + row-gap: 20px; + max-height: 330px; + overflow-y: auto; +} + +.add-right__choice-title { + font-size: 18px; + line-height: 21px; + margin-bottom: 10px; +} + +.add-right__choice { + width: 100%; +} + +.cards { + display: flex; + gap: 20px; + flex-wrap: wrap; +} + +.card { + width: 268px; + background-color: #fff; + box-shadow: 0 2px 10px 4px rgba(114, 114, 114, 0.25); + border-radius: 10px; + padding: 34px 16px 16px; + display: flex; + flex-direction: column; + align-items: center; +} + +.card__description { + display: flex; + flex-direction: column; + align-items: center; +} + +.card__name { + font-size: 16px; + text-align: center; + font-weight: 400; + line-height: 19px; + height: 65px; + margin: 8px 0 16px; +} + +.card__price { + font-size: 24px; + font-weight: 500; + margin-bottom: 16px; +} + +.components__inner { + display: flex; + justify-content: space-between; + align-items: flex-start; + column-gap: 20px; +} + +.components__choice { + width: 276px; + padding: 20px; + display: flex; + flex-direction: column; + gap: 15px; +} + +.components__choice-title { + font-size: 24px; + line-height: 28px; + font-weight: 700; + text-align: center; +} + +.components__main { + flex: 1; +} + +.components__sort { + margin-bottom: 20px; +} + +.form { + width: 100%; + height: calc(100vh - 326px); + display: flex; + justify-content: center; + align-items: center; +} + +.form__inner { + width: 400px; + padding: 20px; + display: flex; + flex-direction: column; + align-items: center; + row-gap: 20px; +} + +.form__title { + font-size: 24px; + line-height: 28px; + font-weight: 700; +} + +.form__input { + width: 100%; +} + +.section { + margin-top: 30px; +} + +.sort { + display: flex; + align-items: center; + width: 100%; + padding: 13px 20px; +} + +.sort__text { + font-size: 18px; + color: #000; + margin-right: 20px; + font-weight: 500; +} + +.sort__block { + display: flex; + justify-content: space-between; + width: 100%; +} + +.subtitle { + font-size: 24px; + line-height: 28px; + text-align: center; + font-weight: 700; +} + +.title { + margin: 15px 0 20px; +} + +.title__text { + font-size: 30px; + font-weight: 700; + line-height: 47px; +} \ No newline at end of file diff --git a/main/_front/dist/font/Roboto-Regular.woff2 b/main/_front/dist/font/Roboto-Regular.woff2 new file mode 100644 index 0000000..41fcd19 Binary files /dev/null and b/main/_front/dist/font/Roboto-Regular.woff2 differ diff --git a/main/_front/dist/img/components/case.svg b/main/_front/dist/img/components/case.svg new file mode 100644 index 0000000..ed82684 --- /dev/null +++ b/main/_front/dist/img/components/case.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/main/_front/dist/img/components/cooler.svg b/main/_front/dist/img/components/cooler.svg new file mode 100644 index 0000000..53cb007 --- /dev/null +++ b/main/_front/dist/img/components/cooler.svg @@ -0,0 +1,20 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + diff --git a/main/_front/dist/img/components/cpu.svg b/main/_front/dist/img/components/cpu.svg new file mode 100644 index 0000000..d6a786e --- /dev/null +++ b/main/_front/dist/img/components/cpu.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/main/_front/dist/img/components/gpu.svg b/main/_front/dist/img/components/gpu.svg new file mode 100644 index 0000000..29e2cd1 --- /dev/null +++ b/main/_front/dist/img/components/gpu.svg @@ -0,0 +1,23 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + diff --git a/main/_front/dist/img/components/motherboard.svg b/main/_front/dist/img/components/motherboard.svg new file mode 100644 index 0000000..c2a46d6 --- /dev/null +++ b/main/_front/dist/img/components/motherboard.svg @@ -0,0 +1,25 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + diff --git a/main/_front/dist/img/components/power_unit.svg b/main/_front/dist/img/components/power_unit.svg new file mode 100644 index 0000000..fdec73f --- /dev/null +++ b/main/_front/dist/img/components/power_unit.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/main/_front/dist/img/components/ram.svg b/main/_front/dist/img/components/ram.svg new file mode 100644 index 0000000..9bb24af --- /dev/null +++ b/main/_front/dist/img/components/ram.svg @@ -0,0 +1,46 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/main/_front/dist/img/components/rom.svg b/main/_front/dist/img/components/rom.svg new file mode 100644 index 0000000..4c36aab --- /dev/null +++ b/main/_front/dist/img/components/rom.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/main/_front/dist/img/javascript.svg b/main/_front/dist/img/javascript.svg new file mode 100644 index 0000000..f9abb2b --- /dev/null +++ b/main/_front/dist/img/javascript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/main/_front/dist/img/logo.svg b/main/_front/dist/img/logo.svg new file mode 100644 index 0000000..309e9ab --- /dev/null +++ b/main/_front/dist/img/logo.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/main/_front/dist/img/tick.svg b/main/_front/dist/img/tick.svg new file mode 100644 index 0000000..3cbdb2e --- /dev/null +++ b/main/_front/dist/img/tick.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/main/_front/dist/img/trash.svg b/main/_front/dist/img/trash.svg new file mode 100644 index 0000000..a38d8f5 --- /dev/null +++ b/main/_front/dist/img/trash.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/main/_front/src/html/index.html b/main/_front/dist/index.html similarity index 77% rename from main/_front/src/html/index.html rename to main/_front/dist/index.html index e06b2d1..a36cc85 100644 --- a/main/_front/src/html/index.html +++ b/main/_front/dist/index.html @@ -6,8 +6,8 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> Document - - + +

Hello, world!

diff --git a/main/_front/dist/js/components.js b/main/_front/dist/js/components.js new file mode 100644 index 0000000..55a5f23 --- /dev/null +++ b/main/_front/dist/js/components.js @@ -0,0 +1,46 @@ +const choiceLists = document.querySelectorAll(".choice"); + +choiceLists.forEach((choiceList) => { + const choiceItems = choiceList.querySelectorAll(".choice__elem"); + choiceItems.forEach((choice) => { + if (choice.classList.contains("active")) { + choiceList.dataset.value = choice.dataset.value; + // console.log(choice.dataset.value); + } + choice.addEventListener("click", (e) => { + choiceItems.forEach((choice) => { + if (choice === e.target) { + choiceList.dataset.value = choice.dataset.value; + choice.classList.add("active"); + console.log(choice.dataset.value); + }else { + choice.classList.remove("active"); + } + }); + }); + }); +}) + +const cards_place = document.querySelector("#cards_place"); + +const addCards = () => { + fetch("http://localhost:4444/components") + .then(res => res.json()) + .then(data => { + data.forEach((item) => { + cards_place.insertAdjacentHTML("beforeend", ` +
+ +
+
${item.name}
+
${item.price} ₽
+ +
+
+ `) + }) + }) +} + +addCards(); + \ No newline at end of file diff --git a/main/_front/src/js/add-edit.js b/main/_front/dist/js/elems/add-edit.js similarity index 100% rename from main/_front/src/js/add-edit.js rename to main/_front/dist/js/elems/add-edit.js diff --git a/main/_front/src/js/checkbox.js b/main/_front/dist/js/elems/checkbox.js similarity index 100% rename from main/_front/src/js/checkbox.js rename to main/_front/dist/js/elems/checkbox.js diff --git a/main/_front/src/js/choice.js b/main/_front/dist/js/elems/choice.js similarity index 100% rename from main/_front/src/js/choice.js rename to main/_front/dist/js/elems/choice.js diff --git a/main/_front/src/js/stepper.js b/main/_front/dist/js/elems/stepper.js similarity index 100% rename from main/_front/src/js/stepper.js rename to main/_front/dist/js/elems/stepper.js diff --git a/main/_front/dist/js/main.js b/main/_front/dist/js/main.js new file mode 100644 index 0000000..e69de29 diff --git a/main/_front/dist/login.html b/main/_front/dist/login.html new file mode 100644 index 0000000..af08e29 --- /dev/null +++ b/main/_front/dist/login.html @@ -0,0 +1,79 @@ + + + + + + + Document + + + + +
+
+ +
+
+
+
+

Вход в панель администратора

+
+
+
+
+

Вход

+
+ + Почта +
+
+ + Пароль +
+ +
+
+ + \ No newline at end of file diff --git a/main/_front/gulpfile.js b/main/_front/gulpfile.js index 7424528..0a0514b 100644 --- a/main/_front/gulpfile.js +++ b/main/_front/gulpfile.js @@ -6,12 +6,15 @@ import * as dartSass from 'sass'; import gulpSass from 'gulp-sass'; const sass = gulpSass(dartSass); -const publicPath = "_public/"; const srcPath = "src/"; import sassGlob from 'gulp-sass-glob'; import newer from "gulp-newer"; import {deleteAsync} from "del"; +const isProduction = false; + +const publicPath = isProduction? "dist/" : "_public/"; + const path = { build: { html: publicPath, @@ -95,4 +98,9 @@ const dev = gulp.series( gulp.parallel(watch, server) ) -export default dev; \ No newline at end of file +const production = gulp.series( + clear, + gulp.parallel(html, scss, js, img, font) +) + +export default isProduction? production : dev; \ No newline at end of file diff --git a/main/_front/src/html/add-edit.html b/main/_front/src/html/add-edit.html index 9590b23..5f0c8b8 100644 --- a/main/_front/src/html/add-edit.html +++ b/main/_front/src/html/add-edit.html @@ -8,7 +8,7 @@ Document - + @@ -20,7 +20,7 @@

Пора Cобрать ПК

- Комплектующие + Комплектующие Конфигуратор Готовые сборки @@ -41,7 +41,7 @@

Пора Cобрать ПК

- + Пора Cобрать ПК
- Комплектующие + Комплектующие Конфигуратор Готовые сборки @@ -42,7 +42,7 @@

Пора Cобрать ПК

- + - +
@@ -21,7 +21,7 @@

Пора Cобрать ПК

- Комплектующие + Комплектующие Конфигуратор Готовые сборки @@ -40,7 +42,7 @@

Пора Cобрать ПК

- + Вход в панель администратора

Вход

-
+
Почта
-
+
Пароль
- +
diff --git a/main/_front/src/js/elems/add-edit.js b/main/_front/src/js/elems/add-edit.js new file mode 100644 index 0000000..abe6c29 --- /dev/null +++ b/main/_front/src/js/elems/add-edit.js @@ -0,0 +1,118 @@ +const choiceLists = document.querySelectorAll(".choice"); + +choiceLists.forEach((choiceList) => { + const choiceItems = choiceList.querySelectorAll(".choice__elem"); + choiceItems.forEach((choice) => { + if (choice.classList.contains("active")) { + choiceList.dataset.value = choice.dataset.value; + // console.log(choice.dataset.value); + } + choice.addEventListener("click", (e) => { + choiceItems.forEach((choice) => { + if (choice === e.target) { + choiceList.dataset.value = choice.dataset.value; + choice.classList.add("active"); + console.log(choice.dataset.value); + }else { + choice.classList.remove("active"); + } + }); + }); + }); +}) + +const steppers = document.querySelectorAll('.stepper'); +const checkMinDisabled = (element) => { + return Number(element.textContent) <= 1; +} +const checkMaxDisabled = (element, maxValue) => { + return Number(element.textContent) >= Number(maxValue); +} +const writeDataValue = (element, value) => { + element.dataset.value = value; +} + +steppers.forEach(stepper => { + + + const minus_btn = stepper.querySelector('.stepper__minus'); + const plus_btn = stepper.querySelector('.stepper__plus'); + const value = stepper.querySelector('.stepper__value'); + if (value.textContent) writeDataValue(stepper, value.textContent); + + const max = stepper.dataset.max; + + if (checkMinDisabled(value)){ + minus_btn.disabled = true; + value.textContent = "1"; + } + if (checkMaxDisabled(value, max)){ + plus_btn.disabled = true; + value.textContent = max; + } + + minus_btn.addEventListener('click', (e) => { + let count = Number(value.textContent); + if (count > 1) { + count--; + value.textContent = count; + plus_btn.disabled = false; + writeDataValue(stepper, value.textContent); + if (checkMinDisabled(value)){ + minus_btn.disabled = true; + value.textContent = "1"; + } + } + }) + + plus_btn.addEventListener('click', (e) => { + let count = Number(value.textContent); + if (count < max) { + count++; + value.textContent = count; + minus_btn.disabled = false; + writeDataValue(stepper, value.textContent); + if (checkMaxDisabled(value, max)){ + plus_btn.disabled = true; + value.textContent = max; + } + } + }) +}) + +// Начало файла, считай (все выше - скопировано из других для удобства разработки) + +const input_property_name = document.querySelector("#property_name>input"); +const input_property_value = document.querySelector("#property_value>input"); + +const properties_list = document.querySelector("#properties_list") + +const handleDelete = (e) => { + e.currentTarget.parentElement.remove(); +} + +const property_btn = document.querySelector("#property_btn"); +property_btn.addEventListener('click', (e) => { + const name = input_property_name.value; + const value = input_property_value.value; + if (name !== "" && value !== "") { + properties_list.insertAdjacentHTML('beforeend', ` +
+
+
${name}
+
${value}
+
+ +
+ `) + properties_list.querySelectorAll(".property .property__btn").forEach(button => { + button.removeEventListener("click", handleDelete); + button.addEventListener("click", handleDelete); + }) + input_property_name.value = ""; + input_property_value.value = ""; + } +}) + diff --git a/main/_front/src/js/elems/checkbox.js b/main/_front/src/js/elems/checkbox.js new file mode 100644 index 0000000..dc9f3bd --- /dev/null +++ b/main/_front/src/js/elems/checkbox.js @@ -0,0 +1,28 @@ +const socket = document.querySelector("#socket"); +const ram_count = document.querySelector("#ram_count"); + +const getCheckboxValues = (element) => { + const checkboxes = element.querySelectorAll(".checkbox"); + const values = []; + checkboxes.forEach(checkbox => { + const input = checkbox.querySelector("input"); + // console.log(input); + // console.log(input.checked); + input.checked? values.push(checkbox.dataset.value) : undefined; + }) + return values; +} + +const getValues = (elemsArray) => { + const object = {} + elemsArray.forEach(elem => { + object[elem.dataset.value] = getCheckboxValues(elem); + }) + return object; +} + +const button = document.querySelector("#checkbox_btn"); + +button.addEventListener("click", (e) => { + console.log(getValues([socket, ram_count])) +}) \ No newline at end of file diff --git a/main/_front/src/js/elems/choice.js b/main/_front/src/js/elems/choice.js new file mode 100644 index 0000000..aa6e57a --- /dev/null +++ b/main/_front/src/js/elems/choice.js @@ -0,0 +1,24 @@ +const choiceLists = document.querySelectorAll(".choice"); + +choiceLists.forEach((choiceList) => { + const choiceItems = choiceList.querySelectorAll(".choice__elem"); + choiceItems.forEach((choice) => { + if (choice.classList.contains("active")) { + choiceList.dataset.value = choice.dataset.value; + // console.log(choice.dataset.value); + } + choice.addEventListener("click", (e) => { + choiceItems.forEach((choice) => { + if (choice === e.target) { + choiceList.dataset.value = choice.dataset.value; + choice.classList.add("active"); + console.log(choice.dataset.value); + }else { + choice.classList.remove("active"); + } + }); + }); + }); +}) + + diff --git a/main/_front/src/js/elems/stepper.js b/main/_front/src/js/elems/stepper.js new file mode 100644 index 0000000..49ef2ec --- /dev/null +++ b/main/_front/src/js/elems/stepper.js @@ -0,0 +1,58 @@ +const steppers = document.querySelectorAll('.stepper'); +const checkMinDisabled = (element) => { + return Number(element.textContent) <= 1; +} +const checkMaxDisabled = (element, maxValue) => { + return Number(element.textContent) >= Number(maxValue); +} +const writeDataValue = (element, value) => { + element.dataset.value = value; +} + +steppers.forEach(stepper => { + + + const minus_btn = stepper.querySelector('.stepper__minus'); + const plus_btn = stepper.querySelector('.stepper__plus'); + const value = stepper.querySelector('.stepper__value'); + if (value.textContent) writeDataValue(stepper, value.textContent); + + const max = stepper.dataset.max; + + if (checkMinDisabled(value)){ + minus_btn.disabled = true; + value.textContent = "1"; + } + if (checkMaxDisabled(value, max)){ + plus_btn.disabled = true; + value.textContent = max; + } + + minus_btn.addEventListener('click', (e) => { + let count = Number(value.textContent); + if (count > 1) { + count--; + value.textContent = count; + plus_btn.disabled = false; + writeDataValue(stepper, value.textContent); + if (checkMinDisabled(value)){ + minus_btn.disabled = true; + value.textContent = "1"; + } + } + }) + + plus_btn.addEventListener('click', (e) => { + let count = Number(value.textContent); + if (count < max) { + count++; + value.textContent = count; + minus_btn.disabled = false; + writeDataValue(stepper, value.textContent); + if (checkMaxDisabled(value, max)){ + plus_btn.disabled = true; + value.textContent = max; + } + } + }) +}) \ No newline at end of file diff --git a/main/_front/src/js/login.js b/main/_front/src/js/login.js new file mode 100644 index 0000000..b5e7abd --- /dev/null +++ b/main/_front/src/js/login.js @@ -0,0 +1,9 @@ +// const login = document.querySelector('#login input'); +// const password = document.querySelector('#password input'); +// +// const btn_submit = document.querySelector('#submit'); +// btn_submit.addEventListener('click', (e) => { +// fetch( 'http://localhost:5000/auth/login', { +// +// }) +// }) \ No newline at end of file diff --git a/main/controllers/PageController.js b/main/controllers/PageController.js new file mode 100644 index 0000000..3272290 --- /dev/null +++ b/main/controllers/PageController.js @@ -0,0 +1,3 @@ +export const mainPage = async (req, res) => { + +} \ No newline at end of file diff --git a/main/index.js b/main/index.js index 33d5d71..88350e8 100644 --- a/main/index.js +++ b/main/index.js @@ -4,22 +4,36 @@ import cors from "cors"; import {login, register} from "./controllers/AdminController.js"; import checkAuth from "./utils/checkAuth.js"; import {addComponent, getAll, getOne} from "./controllers/ComponentsController.js"; +import path from 'path'; const app = express(); +const isProduction = false; +const folder = isProduction? "dist": "_public"; + const PORT = 4444; const __dirname = import.meta.dirname; - mongoose.connect("mongodb://127.0.0.1:27017/build_pc") .then(() => console.log('DB ok')) .catch((err) => console.warn('DB error: ', err)); app.use(cors()) app.use(express.json()); -app.use(express.static(__dirname + '/_front')); +app.use((req, res, next) => { + if (req.path.endsWith('.html')){ + return res.status(404).send('404 Not Found'); + } + next(); +}) +app.use(express.static(__dirname + `/_front/${folder}`)); app.get('/', (req, res) => { - res.send("Hello world!"); + console.log(path.join(__dirname + `/_front/${folder}/components.html`)); + res.sendFile(path.join(__dirname + `/_front/${folder}/components.html`)); +}); + +app.get('/login', (req, res) => { + res.sendFile(path.join(__dirname + `/_front/${folder}/login.html`)); }); app.post('/auth/register', register);