From 292f8cadb6fdd1e675ad096c6bc3058ffaf0e2b6 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Mon, 30 Dec 2019 14:02:57 +0300 Subject: [PATCH] icons component --- config/routes/control-panel.js | 66 +++++++++++++++---- dist/public/css/style.css | 10 ++- dist/views/admin/assets/templates/header.pug | 4 ++ .../assets/templates/modals/edit_item.pug | 2 +- dist/views/admin/categories.pug | 21 ------ dist/views/admin/icons.pug | 35 ++++++++++ dist/views/admin/items.pug | 24 +++++++ src/admin/components/categories.component.js | 25 ++----- src/admin/components/icons.component.js | 31 +++++++++ src/admin/components/items.component.js | 11 +++- src/admin/components/pagination.component.js | 4 -- src/admin/index.js | 2 + src/admin/modals/deleteItem.modal.js | 4 +- 13 files changed, 177 insertions(+), 62 deletions(-) create mode 100644 dist/views/admin/icons.pug create mode 100644 src/admin/components/icons.component.js diff --git a/config/routes/control-panel.js b/config/routes/control-panel.js index 67ead64..340e03c 100644 --- a/config/routes/control-panel.js +++ b/config/routes/control-panel.js @@ -52,6 +52,19 @@ module.exports = function(server, db) { res.render('main/404'); } }); + server.get('/control-panel/icons', checkAuthenticated, async (req, res) => { + try { + res.render('admin/icons', { + name: req.user.name, + email: req.user.email, + title: 'Digital-Store | Категории', + host: req.headers.host, + pageName: ['Иконки', 'icons'] + }); + } catch (error) { + res.render('main/404'); + } + }); server.get('/control-panel/content', checkAuthenticated, (req, res) => { try { res.render('admin/content', { @@ -114,6 +127,7 @@ module.exports = function(server, db) { db.collection('categories').deleteOne({"_id": ObjectID(data.id)}); res.redirect('/control-panel/categories'); } catch (error) { + console.log(error); res.render('main/404'); } }); @@ -134,24 +148,60 @@ module.exports = function(server, db) { res.render('main/404'); } }); - server.post('/control-panel/categories/addicon', checkAuthenticated, (req, res) => { + + // иконки + server.post('/control-panel/icons/create', checkAuthenticated, (req, res) => { try { - res.redirect('/control-panel/categories'); + res.redirect('/control-panel/icons'); } catch (error) { res.render('main/404'); } }); - server.post('/control-panel/categories/dellicon', checkAuthenticated, (req, res) => { + server.post('/control-panel/icons/delete', checkAuthenticated, (req, res) => { const path = `./dist/public/img/service-icons/${req.body.img}` try { fs.unlinkSync(path); - res.redirect('/control-panel/categories'); + res.redirect('/control-panel/icons'); } catch (error) { res.render('main/404'); } }); // товары + server.post('/control-panel/items/create', checkAuthenticated, (req, res) => { + try { + // документ с информацией товара для отдачи клиенту + const item = { + _id: new ObjectID(), + title: req.body.title, + count: req.body.data.split(',').length, + price: parseFloat(req.body.price), + category: JSON.parse(req.body.category).title, + description: req.body.description, + date: new Date() + } + // документ куда мы записываем данные товара + const info = { + _id: item._id, + title: item.title, + data: req.body.data.split(',') + } + + db.collection('info').insertOne(info); + db.collection('items').insertOne(item); + res.redirect('/control-panel/items'); + } catch (error) { + res.render('main/404'); + } + }); + server.post('/control-panel/items/delete', checkAuthenticated, (req, res) => { + try { + db.collection('items').deleteOne({"_id": ObjectID(req.body.id)}); + res.redirect('/control-panel/items'); + } catch (error) { + res.render('main/404'); + } + }); server.post('/control-panel/items/update', checkAuthenticated, (req, res) => { try { const data = { @@ -167,12 +217,4 @@ module.exports = function(server, db) { res.render('main/404'); } }); - server.post('/control-panel/items/delete', checkAuthenticated, (req, res) => { - try { - db.collection('items').deleteOne({"_id": ObjectID(req.body.id)}); - res.redirect('/control-panel/items'); - } catch (error) { - res.render('main/404'); - } - }); } \ No newline at end of file diff --git a/dist/public/css/style.css b/dist/public/css/style.css index 083a5b0..fd820be 100644 --- a/dist/public/css/style.css +++ b/dist/public/css/style.css @@ -697,6 +697,12 @@ footer.main-footer { .admin-header nav.navbar { padding-left: 10px; } +.card .card-content { + padding: 0; +} +.card { + padding: 24px; +} .card .card-content .card-title { font-size: 16px; } @@ -761,9 +767,9 @@ div.table > table > tbody > tr > td:nth-child(7) > button.btn.orange { .sidenav .collapsible-body>ul:not(.collapsible)>li.active a, .sidenav.sidenav-fixed .collapsible-body>ul:not(.collapsible)>li.active a, .sidenav.sidenav-fixed .collapsible-body>ul:not(.collapsible)>li.active i { color: #f6f6f6; } -.category-add h5, .category-delete h5 { +.card h5 { margin-top: 2rem; - margin-bottom: 1rem; + margin-bottom: 2rem; } .select-dropdown { max-height: 200px; diff --git a/dist/views/admin/assets/templates/header.pug b/dist/views/admin/assets/templates/header.pug index 48dbc94..438a6f5 100644 --- a/dist/views/admin/assets/templates/header.pug +++ b/dist/views/admin/assets/templates/header.pug @@ -47,6 +47,10 @@ header.admin-header a(href='http://'+host+'/control-panel/categories') i.material-icons category | Категории + li(data-page="icons") + a(href='http://'+host+'/control-panel/icons') + i.material-icons add_photo_alternate + | Иконки li(data-page="content") a(href='http://'+host+'/control-panel/content') i.material-icons visibility diff --git a/dist/views/admin/assets/templates/modals/edit_item.pug b/dist/views/admin/assets/templates/modals/edit_item.pug index 40db312..39b28df 100644 --- a/dist/views/admin/assets/templates/modals/edit_item.pug +++ b/dist/views/admin/assets/templates/modals/edit_item.pug @@ -19,7 +19,7 @@ label(for="title") Новое название товара .input-field input.price(id="price" type="text" name="price" required) - label(for="price") Цена + label(for="price") Цена товара ₽ .input-field textarea.description(id="description" class="materialize-textarea" type="text" name="description") label(for="description") Описание товара diff --git a/dist/views/admin/categories.pug b/dist/views/admin/categories.pug index 3d225e9..30c3bf1 100644 --- a/dist/views/admin/categories.pug +++ b/dist/views/admin/categories.pug @@ -38,17 +38,6 @@ body.has-fixed-sidenav button(type="submit" class="btn") Добавить категорию .divider .under-block - .icon-add - h5 Добавить иконку - .row - form(action="/control-panel/categories/addicon" method="POST" enctype="multipart/form-data") - .file-field.input-field.col.s12 - .btn.orange - span Иконка - input(type="file" name="img" required) - .file-path-wrapper - input(type="text" class="file-path" placeholder="Загрузите иконку в формате .svg") - button(type="submit" class="btn right" style="margin-right: 10px;") Добавить .category-edit .row .input-field.col.s12 @@ -56,16 +45,6 @@ body.has-fixed-sidenav option(value="" disabled selected) | Выберите категорию для редактирования label Редактирование категории - .icon-dell - .row - form(id="dellIcon" action="/control-panel/categories/dellicon" method="POST") - .input-field.col.s12 - select#dellIcon_select(name="img") - option(value="" disabled selected) - | Выберите иконку для удаления - label Удаление иконки - .col.s12 - button(type="submit" class="btn red ") Удалить .category-delete .row form(id="dellCategory" action="/control-panel/categories/delete" method="POST") diff --git a/dist/views/admin/icons.pug b/dist/views/admin/icons.pug new file mode 100644 index 0000000..f464ea5 --- /dev/null +++ b/dist/views/admin/icons.pug @@ -0,0 +1,35 @@ +include ./assets/head.pug +body.has-fixed-sidenav + include ./assets/templates/header.pug + main.admin-main + .container + .row + .col.s12 + h2 Редактирование иконок + .col.s12 + #icons.card + .card-content + .icon-add + h5 Добавить иконку + .row + form(action="/control-panel/icons/create" method="POST" enctype="multipart/form-data") + .file-field.input-field.col.s12 + .btn.orange + span Иконка + input(type="file" name="img" required) + .file-path-wrapper + input(type="text" class="file-path" placeholder="Загрузите иконку в формате .svg") + button(type="submit" class="btn right" style="margin-right: 10px;") Добавить + .icon-dell + h5 Удалить иконку + .row + form(id="dellIcon" action="/control-panel/icons/delete" method="POST") + .input-field.col.s12 + select#selectIcons(name="img") + option(value="" disabled selected) + | Выберите иконку для удаления + .col.s12 + button(type="submit" class="btn red right") Удалить + + include ./assets/templates/footer.pug + include ./assets/scripts.pug \ No newline at end of file diff --git a/dist/views/admin/items.pug b/dist/views/admin/items.pug index ef1deaa..b2846d1 100644 --- a/dist/views/admin/items.pug +++ b/dist/views/admin/items.pug @@ -34,6 +34,30 @@ body.has-fixed-sidenav #loader.progress .indeterminate ul#pagination.pagination.center(data-page="1") + .divider + .items-add + h5 Добавить новый товар + .row + form(action="/control-panel/items/create" method="POST") + .input-field.col.l6.s12 + input(id="title" type="text" name="title") + label(for="title") Название товара + .input-field.col.l6.s12 + input(id="price" type="text" name="price") + label(for="price") Цена товара ₽ + .input-field.col.l6.s12 + textarea(id="description" class="materialize-textarea" type="text" name="description") + label(for="description") Описание товара + .input-field.col.l6.s12 + select#selectCategories(name="category") + option(value="" disabled selected) + | Выберите категорию + label Категория товара + .input-field.col.s12 + textarea(class="materialize-textarea" type="text" placeholder="Пречеслите аккаунты в вашем формате через запятую." name="data") + label Данные товара + .col.s12 + button(type="submit" class="btn") Добавить товар include ./assets/templates/modals/delete_item.pug include ./assets/templates/modals/edit_item.pug diff --git a/src/admin/components/categories.component.js b/src/admin/components/categories.component.js index efed22d..62d1ccc 100644 --- a/src/admin/components/categories.component.js +++ b/src/admin/components/categories.component.js @@ -13,30 +13,24 @@ export class CategoriesComponent extends Component { this.$editSelect = this.$el.querySelector('#editCategory_select'); // редактирование категории this.$dellSelect = this.$el.querySelector('#delete_select'); // удаление категории this.$iconsSelect = this.$el.querySelector('#icons_select'); // выбор иконки - this.$dellIconsSelect = this.$el.querySelector('#dellIcon_select'); // удаление иконки // обработка форм - this.$dellIconFrom = this.$el.querySelector('#dellIcon'); // удаление иконки this.$addForm = this.$el.querySelector('#addCategory'); // добавление категории this.$dellForm = this.$el.querySelector('#dellCategory'); // удаление категории // добавим ивенты на наши формы - this.$dellIconFrom.addEventListener('submit', this.dellIcon.bind(this)); this.$addForm.addEventListener('submit', this.addCategory.bind(this)); this.$dellForm.addEventListener('submit', this.deleteCategory.bind(this)); } async init() { const categories = await apiService.getCategories(), - icons = await apiService.getIcons(), - icons_html = renderIcons(icons), - categories_html = renderCategories(categories); + icons = await apiService.getIcons(); - this.$editSelect.insertAdjacentHTML('beforeend', categories_html); - this.$dellSelect.insertAdjacentHTML('beforeend', categories_html); - this.$iconsSelect.insertAdjacentHTML('beforeend', icons_html); - this.$dellIconsSelect.insertAdjacentHTML('beforeend', icons_html); - M.FormSelect.init(document.querySelectorAll('select')); // Инициализируем все селекты только после их рендера! + this.$editSelect.insertAdjacentHTML('beforeend', renderCategories(categories)); + this.$dellSelect.insertAdjacentHTML('beforeend', renderCategories(categories)); + this.$iconsSelect.insertAdjacentHTML('beforeend', renderIcons(icons)); + M.FormSelect.init(document.querySelectorAll('select')); } async addCategory(e) { @@ -56,13 +50,4 @@ export class CategoriesComponent extends Component { index != -1 ? this.$dellForm.submit() : alert('Выберите категорию для удаления.'); } - - async dellIcon(e) { - e.preventDefault(); - const icons = await apiService.getIcons(), - currIcon = e.target.elements[0].value, - index = icons.indexOf(currIcon); - - index != -1 ? e.target.submit() : alert('Выберите иконку для удаления.'); - } } \ No newline at end of file diff --git a/src/admin/components/icons.component.js b/src/admin/components/icons.component.js new file mode 100644 index 0000000..1eaefd8 --- /dev/null +++ b/src/admin/components/icons.component.js @@ -0,0 +1,31 @@ +import { Component } from "../core/component"; +import { apiService } from "../services/api.service"; +import { renderIcons } from "../templates/icons.template"; + +export class IconsComponent extends Component { + constructor(id) { + super(id); + } + + setElems() { + this.$icons = this.$el.querySelector('#selectIcons'); + this.$delete = this.$el.querySelector('#dellIcon'); + this.$delete.addEventListener('submit', this.dellIcon.bind(this)); + } + + async init() { + const icons = await apiService.getIcons(); + + this.$icons.insertAdjacentHTML('beforeend', renderIcons(icons)); + M.FormSelect.init(this.$icons); + } + + async dellIcon(e) { + e.preventDefault(); + const icons = await apiService.getIcons(), + currIcon = e.target.elements[0].value, + index = icons.indexOf(currIcon); + + index != -1 ? e.target.submit() : alert('Выберите иконку для удаления.'); + } +} \ No newline at end of file diff --git a/src/admin/components/items.component.js b/src/admin/components/items.component.js index fdb90dd..767b8c4 100644 --- a/src/admin/components/items.component.js +++ b/src/admin/components/items.component.js @@ -1,6 +1,7 @@ import { Component } from "../core/component"; import { apiService } from "../services/api.service"; import { renderItems } from "../templates/items.template"; +import { renderCategories } from "../templates/categories.template"; export class ItemsComponent extends Component { constructor(id, {pagination}, {search}) { @@ -9,11 +10,19 @@ export class ItemsComponent extends Component { this.search = search; } + setElems() { + this.$categories = this.$el.querySelector('#selectCategories'); + } + async init() { - const items = await apiService.getItems(); + const items = await apiService.getItems(), + categories = await apiService.getCategories(); + this.$table = this.$el.querySelector('table tbody'); this.search.initialize(this.$table, this.getItemsByText); this.pagination.initialize(items.length, this.$table, this.getItemsByPage); + this.$categories.insertAdjacentHTML('beforeend', renderCategories(categories)); + M.FormSelect.init(this.$categories); } async getItemsByText(text) { diff --git a/src/admin/components/pagination.component.js b/src/admin/components/pagination.component.js index b477cc5..1ba9aa7 100644 --- a/src/admin/components/pagination.component.js +++ b/src/admin/components/pagination.component.js @@ -90,8 +90,4 @@ export class PaginationComponent extends Component { html += '
  • chevron_right
  • '; this.$el.insertAdjacentHTML('afterbegin', html); } - - hide() { - this.$el.classList.add('hide'); - } } \ No newline at end of file diff --git a/src/admin/index.js b/src/admin/index.js index 53e6e9e..fc73055 100644 --- a/src/admin/index.js +++ b/src/admin/index.js @@ -7,11 +7,13 @@ import { PaginationComponent } from "./components/pagination.component.js"; import { editItemModal } from "./modals/editItem.modal.js"; import { deleteItemModal } from "./modals/deleteItem.modal.js"; import { SearchComponent } from "./components/search.component.js"; +import { IconsComponent } from "./components/icons.component.js"; const loader = new LoaderComponent('loader'); const pagination = new PaginationComponent('pagination', {loader}); const search = new SearchComponent('search', {loader}); const categories = new CategoriesComponent('categories'); +const icons = new IconsComponent('icons'); const items = new ItemsComponent('items', {pagination}, {search}); const editCategory = new editCategoryModal('editCategoryModal', 'editCategory_select', 'editCategoryClose'); diff --git a/src/admin/modals/deleteItem.modal.js b/src/admin/modals/deleteItem.modal.js index 0fb7155..996bf34 100644 --- a/src/admin/modals/deleteItem.modal.js +++ b/src/admin/modals/deleteItem.modal.js @@ -16,16 +16,18 @@ export class deleteItemModal extends Modal { setElems() { this.$content = this.$el.querySelector('.modal-content__form p'); + this.$button = this.$el.querySelector('.delete-item'); } openHandler(e) { const data = JSON.parse(e.target.parentNode.parentNode.dataset.info); this.$content.innerHTML = `Вы действительно хотите удалить товар:
    "${data.title}"?`; - this.$el.querySelector('.delete-item').onclick = this.deleteHandler.bind(this, data.id); + this.$button.onclick = this.deleteHandler.bind(this, data.id); } async deleteHandler(id) { try { + this.$button.classList.add('hide'); this.$content.innerHTML = '
    ' await axios.post('/control-panel/items/delete', {id}); alert('Товар был успешно удален.');