mirror of
https://github.com/sergeyyarkov/digital-store.git
synced 2026-10-11 10:19:15 +03:00
component categories
This commit is contained in:
parent
d8adf40c5c
commit
a4a7f14146
@ -97,6 +97,9 @@ function getItemsRoute(req, res, dbo) {
|
||||
? res.send(result)
|
||||
: res.send({error: 'На сайте нету категорий'});
|
||||
});
|
||||
} else if (req.query.icons === 'all') {
|
||||
const icons = fs.readdirSync('dist/public/img/service-icons');
|
||||
res.send(icons);
|
||||
} else if (req.query.category) {
|
||||
dbo.collection('categories').find({title: req.query.category}).toArray((err, result) => {
|
||||
res.send(result);
|
||||
@ -228,10 +231,9 @@ function controlPanelDatabaseRoute(req, res) {
|
||||
|
||||
function controlPanelAddCategory(req, res, db) {
|
||||
try {
|
||||
const filedata = req.file;
|
||||
const data = {
|
||||
title: req.body.title.toLowerCase().trim(),
|
||||
img: filedata.filename,
|
||||
img: req.body.img,
|
||||
type: req.body.type,
|
||||
format: req.body.format
|
||||
}
|
||||
@ -246,14 +248,46 @@ function controlPanelDellCategory(req, res, db) {
|
||||
try {
|
||||
const data = JSON.parse(req.body.category);
|
||||
db.collection('categories').deleteOne({"_id": ObjectID(data.id)});
|
||||
|
||||
// Удаляем иконку
|
||||
const path = `./dist/public/img/service-icons/${data.img}`
|
||||
try {
|
||||
fs.unlinkSync(path);
|
||||
res.redirect('/control-panel/categories');
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.render('main/404');
|
||||
}
|
||||
}
|
||||
|
||||
function controlPanelUpdCategory(req, res, db) {
|
||||
try {
|
||||
const data = {
|
||||
id: req.body.id,
|
||||
title: req.body.title.toLowerCase().trim(),
|
||||
originalTitle: req.body.originalTitle.toLowerCase().trim(),
|
||||
img: req.body.img,
|
||||
type: req.body.type,
|
||||
format: req.body.format
|
||||
}
|
||||
db.collection('categories').updateOne({"_id": ObjectID(data.id)}, {$set: {title: data.title, img: data.img, type: data.type, format: data.format}});
|
||||
db.collection('items').updateMany({"category": data.originalTitle}, {$set: {category: data.title}});
|
||||
res.redirect('/control-panel/categories');
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.render('main/404');
|
||||
}
|
||||
}
|
||||
|
||||
function controlPanelAddIcon(req, res, db) {
|
||||
try {
|
||||
res.redirect('/control-panel/categories');
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.render('main/404');
|
||||
}
|
||||
}
|
||||
|
||||
function controlPanelDellIcon(req, res, db) {
|
||||
const path = `./dist/public/img/service-icons/${req.body.img}`
|
||||
try {
|
||||
fs.unlinkSync(path);
|
||||
res.redirect('/control-panel/categories');
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@ -278,4 +312,7 @@ module.exports = function (server, db) {
|
||||
|
||||
server.post('/control-panel/categories/create', checkAuthenticated, (req, res) => controlPanelAddCategory(req, res, db));
|
||||
server.post('/control-panel/categories/delete', checkAuthenticated, (req, res) => controlPanelDellCategory(req, res, db));
|
||||
server.post('/control-panel/categories/update', checkAuthenticated, (req, res) => controlPanelUpdCategory(req, res, db));
|
||||
server.post('/control-panel/categories/addicon', checkAuthenticated, (req, res) => controlPanelAddIcon(req, res, db));
|
||||
server.post('/control-panel/categories/dellicon', checkAuthenticated, (req, res) => controlPanelDellIcon(req, res, db));
|
||||
}
|
||||
|
||||
21
dist/public/css/style.css
vendored
21
dist/public/css/style.css
vendored
@ -123,16 +123,14 @@ hr {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.cart,
|
||||
.pay {
|
||||
.c_modal {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.cart-wrap,
|
||||
.pay-wrap {
|
||||
.c_modal-wrap {
|
||||
position: fixed;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
top: 0;
|
||||
@ -143,14 +141,16 @@ hr {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.cart-content,
|
||||
.pay-content {
|
||||
.c_modal-content {
|
||||
background-color: #fff;
|
||||
margin-top: 7rem;
|
||||
padding: 25px;
|
||||
width: 460px;
|
||||
min-height: 230px;
|
||||
}
|
||||
.c_modal-content.editCategory {
|
||||
width: 760px;
|
||||
}
|
||||
|
||||
.modal-content__header .small-title {
|
||||
color: #404751;
|
||||
@ -163,13 +163,11 @@ hr {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.cart-close,
|
||||
.pay-close {
|
||||
.modal-close {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cart-close i,
|
||||
.pay-close i {
|
||||
.modal-close i {
|
||||
color: #8d8d8d;
|
||||
}
|
||||
|
||||
@ -682,6 +680,9 @@ footer.main-footer {
|
||||
.admin-main {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.admin-main p {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.admin-main h2 {
|
||||
margin: 23px 0px 20px 0px;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 675 B After Width: | Height: | Size: 675 B |
36
dist/views/admin/assets/templates/modals/edit_category.pug
vendored
Normal file
36
dist/views/admin/assets/templates/modals/edit_category.pug
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Edit Category
|
||||
#editCategory.c_modal-wrap.hide
|
||||
.container
|
||||
.row
|
||||
.c_modal
|
||||
.c_modal-content.editCategory
|
||||
.modal-content
|
||||
.modal-content__header(style="margin-bottom: 1rem;")
|
||||
h4.small-title Редактирование категории
|
||||
span#editCategoryClose.modal-close
|
||||
i.material-icons close
|
||||
.modal-content__form
|
||||
form(action="/control-panel/categories/update" method="POST")
|
||||
.input-field.id
|
||||
input(style="color: gray;" type="text" name="id" required readonly)
|
||||
label ID категории
|
||||
.input-field.originalTitle
|
||||
input(style="color: gray;" type="text" name="originalTitle" required readonly)
|
||||
label Старое название категории
|
||||
.input-field.title
|
||||
input(type="text" name="title" required)
|
||||
label Новое название категории
|
||||
.input-field.type
|
||||
input(type="text" name="type" required)
|
||||
label Тип аккаунтов
|
||||
.input-field.img
|
||||
select(name="img" id="img" required)
|
||||
option(value="" disabled selected)
|
||||
| Выберите иконку
|
||||
label(for="img") Иконка
|
||||
.input-field.format
|
||||
input(type="text" name="format" required)
|
||||
label Формат аккаунтов
|
||||
.edit_success
|
||||
button(type="submit" class="btn green waves-effect" style="width: 100%;height:50px") Редактировать
|
||||
// Edit Category END
|
||||
0
dist/views/admin/assets/templates/modals/edit_item.pug
vendored
Normal file
0
dist/views/admin/assets/templates/modals/edit_item.pug
vendored
Normal file
47
dist/views/admin/categories.pug
vendored
47
dist/views/admin/categories.pug
vendored
@ -6,6 +6,13 @@ body.has-fixed-sidenav
|
||||
.row
|
||||
.col.s12
|
||||
h2 Редактирование категорий
|
||||
p На этой странице есть возможность добавлять новые категории, удалять старые и редактировать существующие.
|
||||
.col.s12
|
||||
.card
|
||||
.card-content
|
||||
span.card-title Кол-во категорий
|
||||
.divider
|
||||
h3#categoriesCount 0
|
||||
.col.s12
|
||||
#categories.card
|
||||
.card-content
|
||||
@ -14,14 +21,13 @@ body.has-fixed-sidenav
|
||||
.row
|
||||
form(id="categoryAdd" action="/control-panel/categories/create" method="POST" enctype="multipart/form-data")
|
||||
.input-field.col.l6.s12
|
||||
input(id="title" name="title" type="text" data-length="20" required)
|
||||
input(id="title" name="title" type="text" required)
|
||||
label(for="title") Название категории
|
||||
.file-field.input-field.col.l6.s12
|
||||
.btn.orange
|
||||
span Иконка
|
||||
input(type="file" name="img" required)
|
||||
.file-path-wrapper
|
||||
input(type="text" class="file-path" placeholder="Загрузите иконку в формате .svg")
|
||||
#img.input-field.col.l6.s12
|
||||
select(name="img" id="img" required)
|
||||
option(value="" disabled selected)
|
||||
| Выберите иконку
|
||||
label(for="img") Иконка
|
||||
.input-field.col.l6.s12
|
||||
textarea(class="materialize-textarea" type="text" id="type" name="type" required)
|
||||
label(for="type") Тип аккаунтов
|
||||
@ -29,9 +35,20 @@ body.has-fixed-sidenav
|
||||
input(type="text" id="format" name="format" required)
|
||||
label(for="format") Формат аккаунтов
|
||||
.col.s12
|
||||
button(type="submit" class="btn green") Добавить категорию
|
||||
button(type="submit" class="btn") Добавить категорию
|
||||
.divider
|
||||
.under-block
|
||||
.icon-add
|
||||
h5 Добавить иконку
|
||||
.row
|
||||
form(id="iconAdd" 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
|
||||
#edit.input-field.col.s12
|
||||
@ -39,6 +56,16 @@ body.has-fixed-sidenav
|
||||
option(value="" disabled selected)
|
||||
| Выберите категорию для редактирования
|
||||
label Редактирование
|
||||
.icon-dell
|
||||
.row
|
||||
form(id="iconDell" action="/control-panel/categories/dellicon" method="POST")
|
||||
#imgDell.input-field.col.s12
|
||||
select(name="img")
|
||||
option(value="" disabled selected)
|
||||
| Выберите иконку для удаления
|
||||
label Удаление иконки
|
||||
.col.s12
|
||||
button(type="submit" class="btn red ") Удалить
|
||||
.category-delete
|
||||
.row
|
||||
form(id="categoryDelete" action="/control-panel/categories/delete" method="POST")
|
||||
@ -47,9 +74,9 @@ body.has-fixed-sidenav
|
||||
option(value="" disabled selected)
|
||||
| Выберите категорию для удаления
|
||||
label Удаление
|
||||
.col.s6
|
||||
.col.s12
|
||||
button(type="submit" class="btn red ") Удалить
|
||||
|
||||
|
||||
include ./assets/templates/modals/edit_category.pug
|
||||
include ./assets/templates/footer.pug
|
||||
include ./assets/scripts.pug
|
||||
@ -1,13 +1,13 @@
|
||||
// Cart Modal
|
||||
#cart.cart-wrap.hide
|
||||
#cart.c_modal-wrap.hide
|
||||
.container
|
||||
.row
|
||||
.cart
|
||||
.cart-content
|
||||
.c_modal
|
||||
.c_modal-content
|
||||
.modal-content
|
||||
.modal-content__header
|
||||
h4.small-title Корзина
|
||||
span#cartClose.cart-close
|
||||
span#cartClose.modal-close
|
||||
i.material-icons close
|
||||
#modalList.modal-content__items
|
||||
.modal-content__info
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
// Pay Modal
|
||||
#pay.pay-wrap.hide
|
||||
#pay.c_modal-wrap.hide
|
||||
.container
|
||||
.row
|
||||
.pay
|
||||
.pay-content
|
||||
.c_modal
|
||||
.c_modal-content
|
||||
.modal-content
|
||||
.modal-content__header
|
||||
h4.small-title Оплатить товар
|
||||
span#payClose.cart-close
|
||||
span#payClose.modal-close
|
||||
i.material-icons close
|
||||
form(action='#')
|
||||
.modal-content__fields
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Component } from "../core/component";
|
||||
import { apiService } from "../services/api.service";
|
||||
import { renderCategories } from "../templates/categories.template";
|
||||
import { renderIcons } from "../templates/icons.template";
|
||||
|
||||
export class CategoriesComponent extends Component {
|
||||
constructor(id) {
|
||||
@ -8,9 +9,14 @@ export class CategoriesComponent extends Component {
|
||||
if (this.$el) {
|
||||
this.$editSelect = this.$el.querySelector('#edit select');
|
||||
this.$deleteSelect = this.$el.querySelector('#delete select');
|
||||
this.$iconsSelect = this.$el.querySelector('#img select');
|
||||
this.$dellIconsSelect = this.$el.querySelector('#imgDell select');
|
||||
|
||||
this.$dellIconFrom = this.$el.querySelector('#iconDell');
|
||||
this.$addForm = this.$el.querySelector('#categoryAdd');
|
||||
this.$deleteForm = this.$el.querySelector('#categoryDelete');
|
||||
|
||||
this.$dellIconFrom.addEventListener('submit', this.dellIcon.bind(this));
|
||||
this.$addForm.addEventListener('submit', this.addCategory.bind(this));
|
||||
this.$deleteForm.addEventListener('submit', this.deleteCategory.bind(this));
|
||||
this.$editSelect.addEventListener('change', this.insertData);
|
||||
@ -19,10 +25,16 @@ export class CategoriesComponent extends Component {
|
||||
|
||||
async init() {
|
||||
const categories = await apiService.getCategories();
|
||||
const icons = await apiService.getIcons();
|
||||
|
||||
const icons_html = renderIcons(icons);
|
||||
const html = renderCategories(categories);
|
||||
|
||||
document.querySelector('#categoriesCount').textContent = categories.length;
|
||||
this.$editSelect.insertAdjacentHTML('beforeend', html);
|
||||
this.$deleteSelect.insertAdjacentHTML('beforeend', html);
|
||||
this.$iconsSelect.insertAdjacentHTML('beforeend', icons_html);
|
||||
this.$dellIconsSelect.insertAdjacentHTML('beforeend', icons_html);
|
||||
M.FormSelect.init(document.querySelectorAll('select')); // Инициализируем все селекты только после их рендера!
|
||||
}
|
||||
|
||||
@ -39,6 +51,14 @@ export class CategoriesComponent extends Component {
|
||||
const categories = await apiService.getCategories();
|
||||
const title = this.$deleteForm.elements[0].value.toLowerCase().trim();
|
||||
const index = categories.map((category) => {return category.title}).indexOf(title);
|
||||
index != -1 ? this.$deleteForm.submit() : alert('Выберите категорию.');
|
||||
index != -1 ? this.$deleteForm.submit() : alert('Выберите категорию для удаления.');
|
||||
}
|
||||
|
||||
async dellIcon(e) {
|
||||
e.preventDefault();
|
||||
const icons = await apiService.getIcons();
|
||||
const currIcon = e.target.elements[0].value;
|
||||
const index = icons.indexOf(currIcon);
|
||||
index != -1 ? e.target.submit() : alert('Выберите иконку для удаления.');
|
||||
}
|
||||
}
|
||||
@ -3,15 +3,12 @@ export class Modal {
|
||||
this.$el = document.getElementById(id);
|
||||
this.open = document.getElementById(open);
|
||||
this.close = document.getElementById(close);
|
||||
this.open ? this.close.addEventListener('click', this.hide.bind(this)) : false;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.open != null) {
|
||||
this.open.addEventListener('click', openHandler.bind(this));
|
||||
this.close.addEventListener('click', closeHandler.bind(this));
|
||||
}
|
||||
}
|
||||
init() {}
|
||||
|
||||
show() {
|
||||
this.$el.classList.remove('hide');
|
||||
@ -23,11 +20,3 @@ export class Modal {
|
||||
document.body.style.overflowY = '';
|
||||
}
|
||||
}
|
||||
|
||||
function openHandler() {
|
||||
this.show();
|
||||
}
|
||||
|
||||
function closeHandler() {
|
||||
this.hide();
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
import { MaterializeConfig } from "./config/materialize.config.js";
|
||||
import { CategoriesComponent } from "./components/categories.component.js";
|
||||
import { editCategoryModal } from "./modals/editCategory.modal.js";
|
||||
|
||||
const categories = new CategoriesComponent('categories');
|
||||
const editCategory = new editCategoryModal('editCategory', 'edit', 'editCategoryClose');
|
||||
const materialize = new MaterializeConfig();
|
||||
console.log('Control-Panel v1.0.0');
|
||||
38
src/admin/modals/editCategory.modal.js
Normal file
38
src/admin/modals/editCategory.modal.js
Normal file
@ -0,0 +1,38 @@
|
||||
import { Modal } from "../core/modal";
|
||||
import { apiService } from "../services/api.service";
|
||||
import { renderIcons } from "../templates/icons.template";
|
||||
|
||||
export class editCategoryModal extends Modal {
|
||||
constructor(id, open, close) {
|
||||
super(id, open, close);
|
||||
if (this.open) {
|
||||
this.open.addEventListener('change', this.openHandler.bind(this));
|
||||
this.$el.querySelector('form').addEventListener('submit', this.updateCategory.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
async openHandler(e) {
|
||||
this.show();
|
||||
const data = JSON.parse(e.target.value);
|
||||
this.$el.querySelector('form .id input').value = data.id;
|
||||
this.$el.querySelector('form .originalTitle input').value = data.title[0].toUpperCase() + data.title.slice(1);
|
||||
this.$el.querySelector('form .title input').value = data.title[0].toUpperCase() + data.title.slice(1);
|
||||
this.$el.querySelector('form .type input').value = data.type;
|
||||
this.$el.querySelector('form .format input').value = data.format;
|
||||
|
||||
const icons = await apiService.getIcons();
|
||||
const icons_html = renderIcons(icons);
|
||||
this.$el.querySelector('form .img select').insertAdjacentHTML('beforeend', icons_html);
|
||||
M.FormSelect.init(this.$el.querySelector('form .img select'));
|
||||
M.updateTextFields();
|
||||
}
|
||||
|
||||
async updateCategory(e) {
|
||||
e.preventDefault();
|
||||
const form = this.$el.querySelector('form');
|
||||
const categories = await apiService.getCategories();
|
||||
const id = form.elements[0].value.toLowerCase().trim();
|
||||
const index = categories.map((category) => {return category._id}).indexOf(id);
|
||||
index != -1 ? form.submit() : alert('Категории с таким ID не существует.');
|
||||
}
|
||||
}
|
||||
@ -52,6 +52,15 @@ class ApiService {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
async getIcons() {
|
||||
try {
|
||||
const request = `${this.url}api?token=${API_TOKEN}&icons=all`;
|
||||
return useRequest(request);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function useRequest(request) {
|
||||
|
||||
7
src/admin/templates/icons.template.js
Normal file
7
src/admin/templates/icons.template.js
Normal file
@ -0,0 +1,7 @@
|
||||
export function renderIcons(icons) {
|
||||
let html = '';
|
||||
icons.forEach(icon => {
|
||||
html += `<option value='${icon}' data-icon="../img/service-icons/${icon}">${icon}</option>`;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user