mirror of
https://github.com/sergeyyarkov/digital-store.git
synced 2026-10-11 18:29:11 +03:00
icons component
This commit is contained in:
parent
2fa5c40bd3
commit
292f8cadb6
@ -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');
|
||||
}
|
||||
});
|
||||
}
|
||||
10
dist/public/css/style.css
vendored
10
dist/public/css/style.css
vendored
@ -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;
|
||||
|
||||
4
dist/views/admin/assets/templates/header.pug
vendored
4
dist/views/admin/assets/templates/header.pug
vendored
@ -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
|
||||
|
||||
@ -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") Описание товара
|
||||
|
||||
21
dist/views/admin/categories.pug
vendored
21
dist/views/admin/categories.pug
vendored
@ -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")
|
||||
|
||||
35
dist/views/admin/icons.pug
vendored
Normal file
35
dist/views/admin/icons.pug
vendored
Normal file
@ -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
|
||||
24
dist/views/admin/items.pug
vendored
24
dist/views/admin/items.pug
vendored
@ -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
|
||||
|
||||
@ -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('Выберите иконку для удаления.');
|
||||
}
|
||||
}
|
||||
31
src/admin/components/icons.component.js
Normal file
31
src/admin/components/icons.component.js
Normal file
@ -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('Выберите иконку для удаления.');
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -90,8 +90,4 @@ export class PaginationComponent extends Component {
|
||||
html += '<li><a class="disabled" href="#" data-type="next"><i class="material-icons">chevron_right</i></a></li>';
|
||||
this.$el.insertAdjacentHTML('afterbegin', html);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.$el.classList.add('hide');
|
||||
}
|
||||
}
|
||||
@ -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');
|
||||
|
||||
@ -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 = `Вы действительно хотите удалить товар: <br> "${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 = '<div class="progress"><div class="indeterminate"></div></div>'
|
||||
await axios.post('/control-panel/items/delete', {id});
|
||||
alert('Товар был успешно удален.');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user