diff --git a/main/_front/dist/add-edit.html b/main/_front/dist/add-edit.html index b0dad57..496c7ab 100644 --- a/main/_front/dist/add-edit.html +++ b/main/_front/dist/add-edit.html @@ -20,7 +20,7 @@

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

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

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

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

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

-
+
- +
-
Выберите обязательные поля
-
-
+
Выберите обязательные поля
+
+
Сокет (разъем на плате)
@@ -258,16 +258,14 @@

Количество:

-
+
Количество слотов ОЗУ
- - -
+
Тип памяти
diff --git a/main/_front/dist/components-admin.html b/main/_front/dist/components-admin.html index dbf1033..5fb1bb3 100644 --- a/main/_front/dist/components-admin.html +++ b/main/_front/dist/components-admin.html @@ -21,7 +21,7 @@

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

diff --git a/main/_front/dist/css/style.css b/main/_front/dist/css/style.css index 8c4ba2f..ffb8dce 100644 --- a/main/_front/dist/css/style.css +++ b/main/_front/dist/css/style.css @@ -103,18 +103,23 @@ body { border-radius: 10px; } +.hide { + display: none !important; +} + .btn { display: inline-block; background: #712CF9; font-size: 18px; line-height: 21px; - color: white; + color: #fff; font-weight: bold; text-decoration: none; border-radius: 8px; min-width: 190px; border: 1px solid #712CF9; padding: 12px; + text-align: center; transition: background-color 0.2s ease, color 0.2s ease, opacity 0.2s ease; } .btn-big { @@ -128,10 +133,22 @@ body { } .btn:disabled { background: #712CF9; - color: white; + color: #fff; opacity: 0.4; cursor: not-allowed; } +.btn-red { + background-color: #DC3545; + border: 1px solid #DC3545; +} +.btn-red:hover { + background-color: #fff; + color: #DC3545; +} +.btn-red:disabled { + background-color: #DC3545; + color: #fff; +} .checkbox-group { display: flex; @@ -643,6 +660,12 @@ body { width: 100%; } +.form__not_true { + color: #DC3545; + font-size: 18px; + font-weight: 500; +} + .section { margin-top: 30px; } diff --git a/main/_front/dist/index.html b/main/_front/dist/index.html deleted file mode 100644 index a36cc85..0000000 --- a/main/_front/dist/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Document - - - - -

Hello, world!

- - \ No newline at end of file diff --git a/main/_front/dist/js/add-edit.js b/main/_front/dist/js/add-edit.js new file mode 100644 index 0000000..fa8495d --- /dev/null +++ b/main/_front/dist/js/add-edit.js @@ -0,0 +1,249 @@ +const main_properties_tilte = document.querySelector("#main_properties_title"); +const name = document.querySelector('#name input'); +const price = document.querySelector('#price input'); +const count = document.querySelector('#count .stepper__value'); +const type = document.querySelector('#type'); +const main_properties = document.querySelector('#main_properties'); +const other_properties = document.querySelector('#properties_list'); +const btn_submit = document.querySelector('#submit'); +const socket = document.querySelector('#socket'); +const ram_count= document.querySelector('#ram_count'); +const ram_type = document.querySelector('#ram_type'); + +const choiceLists = document.querySelectorAll(".choice"); + +choiceLists.forEach((choiceList) => { + const isType = choiceList.id === "type"; + 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"); + } + }); + if (isType){ + if (choiceList.dataset.value === "cpu") { + main_properties_tilte.classList.remove('hide'); + socket.classList.remove('hide'); + ram_count.classList.add('hide'); + ram_type.classList.add('hide'); + }else if (choiceList.dataset.value === "motherboard"){ + main_properties_tilte.classList.remove('hide'); + socket.classList.remove('hide'); + ram_count.classList.remove('hide'); + ram_type.classList.remove('hide'); + }else if (choiceList.dataset.value === "ram"){ + main_properties_tilte.classList.remove('hide'); + socket.classList.add('hide'); + ram_count.classList.add('hide'); + ram_type.classList.remove('hide'); + }else { + main_properties_tilte.classList.add('hide'); + socket.classList.add('hide'); + ram_count.classList.add('hide'); + ram_type.classList.add('hide'); + } + } + }); + }); + if (isType){ + if (choiceList.dataset.value === "cpu") { + main_properties_tilte.classList.remove('hide'); + socket.classList.remove('hide'); + ram_count.classList.add('hide'); + ram_type.classList.add('hide'); + }else if (choiceList.dataset.value === "motherboard"){ + main_properties_tilte.classList.remove('hide'); + socket.classList.remove('hide'); + ram_count.classList.remove('hide'); + ram_type.classList.remove('hide'); + }else if (choiceList.dataset.value === "ram"){ + main_properties_tilte.classList.remove('hide'); + socket.classList.add('hide'); + ram_count.classList.add('hide'); + ram_type.classList.remove('hide'); + }else { + main_properties_tilte.classList.add('hide'); + socket.classList.add('hide'); + ram_count.classList.add('hide'); + ram_type.classList.add('hide'); + } + } +}) + +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 input_name = input_property_name.value; + const input_value = input_property_value.value; + if (input_name !== "" && input_value !== "") { + properties_list.insertAdjacentHTML('beforeend', ` +
+
+
${input_name}
+
${input_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 = ""; + } +}) + +document.addEventListener("DOMContentLoaded", function() { + fetch('http://localhost:4444/auth/authorized', { + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('authToken'), + 'Content-Type': 'application/json' + } + }) + .then(res => res.json()) + .then(data => { + if (data.message === true) { + + }else { + window.location.href = 'login' + } + }) +}) + + + +btn_submit.addEventListener('click', (e) => { + // console.log(name.value); + // console.log(price.value); + // console.log(Number(count.textContent)); + // console.log(type.dataset.value); + // console.log(main_properties); + // console.log(); + let otherPropertiesArray = [] + other_properties.querySelectorAll(".property").forEach(property => { + // console.log(property); + otherPropertiesArray.push({ + name: property.querySelector(".property__name").textContent, + value: property.querySelector(".property__value").textContent, + }) + }) + let mainPropertiesArray = [] + main_properties.querySelectorAll(".add-right__choice").forEach(property => { + if (property.classList.contains('hide')){ + return; + } + mainPropertiesArray.push({ + name: property.querySelector(".add-right__choice-title").textContent, + value: property.querySelector(".choice").dataset.value + }) + }) + // console.log(mainPropertiesArray); + // console.log(otherPropertiesArray); + const object = { + name: name.value, + type: type.dataset.value, + price: price.value, + count: Number(count.textContent), + main_properties: mainPropertiesArray, + other_properties: otherPropertiesArray + } + if (name.value !== "" && type.dataset.value !== "" && String(price.value)!== "" && count.textContent!== ""){ + fetch('http://localhost:4444/components', { + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('authToken'), + 'Content-Type': 'application/json' + }, + body: JSON.stringify(object) + }) + .then(res => res.json()) + .then(data => { + if (!data.message){ + window.location.href = '/' + } + }) + } +}) \ No newline at end of file diff --git a/main/_front/dist/js/components.js b/main/_front/dist/js/components.js index 55a5f23..6457d39 100644 --- a/main/_front/dist/js/components.js +++ b/main/_front/dist/js/components.js @@ -22,7 +22,9 @@ choiceLists.forEach((choiceList) => { }) const cards_place = document.querySelector("#cards_place"); - + +let isAdmin = false; + const addCards = () => { fetch("http://localhost:4444/components") .then(res => res.json()) @@ -34,13 +36,31 @@ const addCards = () => {
${item.name}
${item.price} ₽
- + + ${isAdmin ? ``: ''}
`) }) }) } - -addCards(); - \ No newline at end of file +const btn_add = document.querySelector("#add"); + +document.addEventListener("DOMContentLoaded", function() { + fetch('http://localhost:4444/auth/authorized', { + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('authToken'), + 'Content-Type': 'application/json' + } + }) + .then(res => res.json()) + .then(data => { + if (data.message === true) { + isAdmin = true; + btn_add.parentElement.classList.remove('hide'); + } + addCards(); + }) +}) + diff --git a/main/_front/dist/js/elems/add-edit.js b/main/_front/dist/js/elems/add-edit.js deleted file mode 100644 index abe6c29..0000000 --- a/main/_front/dist/js/elems/add-edit.js +++ /dev/null @@ -1,118 +0,0 @@ -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/dist/js/login.js b/main/_front/dist/js/login.js new file mode 100644 index 0000000..cb4d0bf --- /dev/null +++ b/main/_front/dist/js/login.js @@ -0,0 +1,57 @@ +const login = document.querySelector('#login input'); +const password = document.querySelector('#password input'); + +const title = document.querySelector('#title'); +const btn_submit = document.querySelector('#submit'); +const btn_logout = document.querySelector('#logout'); +const form_not_true = document.querySelector('#form-not-true'); + +btn_submit.addEventListener('click', (e) => { + if (login.value !== "" && password.value !== "") { + fetch('http://localhost:4444/auth/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + "login": String(login.value), + "password": String(password.value) + }) + }) + .then(res => res.json()) + .then(data => { + console.log(data); + if (data.token){ + localStorage.setItem('authToken', data.token); + window.location.href = '/' + }else { + form_not_true.classList.remove('hide'); + } + }) + } +}) + +document.addEventListener("DOMContentLoaded", function() { + fetch('http://localhost:4444/auth/authorized', { + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + localStorage.getItem('authToken'), + 'Content-Type': 'application/json' + } + }) + .then(res => res.json()) + .then(data => { + if (data.message === true) { + title.textContent = "Вы уже вошли в панель администратора" + login.parentElement.classList.add('hide'); + password.parentElement.classList.add('hide'); + btn_submit.classList.add('hide'); + btn_logout.classList.remove('hide'); + btn_logout.addEventListener('click', (e) => { + localStorage.removeItem('authToken'); + window.location.reload() + }) + } + document.querySelector('.form').classList.remove('hide'); + }) +}) \ No newline at end of file diff --git a/main/_front/dist/login.html b/main/_front/dist/login.html index af08e29..6a50c19 100644 --- a/main/_front/dist/login.html +++ b/main/_front/dist/login.html @@ -8,6 +8,8 @@ Document + + @@ -19,7 +21,7 @@

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

-
+
-

Вход

-
+

Вход

+
Почта
-
+
Пароль
- +
Неверный логин или пароль
+ +
diff --git a/main/_front/gulpfile.js b/main/_front/gulpfile.js index 0a0514b..5a80285 100644 --- a/main/_front/gulpfile.js +++ b/main/_front/gulpfile.js @@ -11,7 +11,7 @@ import sassGlob from 'gulp-sass-glob'; import newer from "gulp-newer"; import {deleteAsync} from "del"; -const isProduction = false; +const isProduction = true; const publicPath = isProduction? "dist/" : "_public/"; @@ -62,7 +62,7 @@ export const js = () => { } export const clear = () => { - return deleteAsync("./_public"); + return deleteAsync(isProduction ? "dist" : "./_public"); } export const img = () => { diff --git a/main/_front/src/js/login.js b/main/_front/src/js/login.js index 5f3f944..cb4d0bf 100644 --- a/main/_front/src/js/login.js +++ b/main/_front/src/js/login.js @@ -41,7 +41,7 @@ document.addEventListener("DOMContentLoaded", function() { }) .then(res => res.json()) .then(data => { - if (data.message === "Вы авторизованы") { + if (data.message === true) { title.textContent = "Вы уже вошли в панель администратора" login.parentElement.classList.add('hide'); password.parentElement.classList.add('hide'); diff --git a/main/index.js b/main/index.js index 4a3a9e2..235d1eb 100644 --- a/main/index.js +++ b/main/index.js @@ -7,7 +7,7 @@ import {addComponent, getAll, getOne} from "./controllers/ComponentsController.j import path from 'path'; const app = express(); -const isProduction = false; +const isProduction = true; const folder = isProduction? "dist": "_public"; const PORT = 4444; @@ -28,7 +28,6 @@ app.use(express.static(__dirname + `/_front/${folder}`)); app.get('/', (req, res) => { - console.log(path.join(__dirname + `/_front/${folder}/components.html`)); res.sendFile(path.join(__dirname + `/_front/${folder}/components.html`)); }); @@ -49,7 +48,7 @@ app.get('/components', getAll) app.get('/components/:id', getOne); app.get('/auth/authorized', checkAuth, (req, res) => { res.json({ - message: "Вы авторизованы" + message: true }) });