|
|
@@ -3,717 +3,529 @@ div(class="admin-products")
|
|
|
h1(class="admin-products__title") Управление товарами
|
|
|
div(class="admin-products__actions")
|
|
|
button(
|
|
|
- @click="showProductModal = true"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
+ @click="createProduct"
|
|
|
+ class="admin-products__button admin-products__button--primary"
|
|
|
) Добавить товар
|
|
|
button(
|
|
|
@click="showImportModal = true"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
) Импорт из CSV
|
|
|
button(
|
|
|
- @click="showCategoriesModal = true"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
+ @click="showCategoriesManager"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
) Управление категориями
|
|
|
button(
|
|
|
+ v-if="selectedProducts.length > 0"
|
|
|
@click="showMassActionsModal = true"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Массовые действия
|
|
|
+ class="admin-products__button admin-products__button--warning"
|
|
|
+ ) Массовые действия ({{ selectedProducts.length }})
|
|
|
+
|
|
|
+ div(class="admin-products__filters")
|
|
|
+ div(class="admin-products__search")
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="searchQuery"
|
|
|
+ placeholder="Поиск по названию или артикулу..."
|
|
|
+ class="admin-products__search-input"
|
|
|
+ )
|
|
|
+ div(class="admin-products__filter-group")
|
|
|
+ select(v-model="selectedCategory" class="admin-products__select")
|
|
|
+ option(value="") Все категории
|
|
|
+ option(
|
|
|
+ v-for="category in categories"
|
|
|
+ :value="category._id"
|
|
|
+ ) {{ category.name }} ({{ getCategoryProductCount(category._id) }})
|
|
|
+ select(v-model="selectedStatus" class="admin-products__select")
|
|
|
+ option(value="") Все статусы
|
|
|
+ option(value="active") Активные
|
|
|
+ option(value="inactive") Неактивные
|
|
|
|
|
|
div(class="admin-products__content")
|
|
|
- div(class="admin-products__filters")
|
|
|
- div(class="admin-products__filter-group")
|
|
|
- label(class="admin-products__label") Поиск
|
|
|
- input(
|
|
|
- v-model="searchQuery"
|
|
|
- type="text"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="Название или артикул..."
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__filter-group")
|
|
|
- label(class="admin-products__label") Категория
|
|
|
- select(v-model="selectedCategory" class="admin-products__select")
|
|
|
- option(value="") Все категории
|
|
|
- option(
|
|
|
- v-for="category in categories"
|
|
|
- :key="category._id"
|
|
|
- :value="category._id"
|
|
|
- ) {{ category.name }}
|
|
|
-
|
|
|
- div(class="admin-products__filter-group")
|
|
|
- label(class="admin-products__label") Статус
|
|
|
- select(v-model="selectedStatus" class="admin-products__select")
|
|
|
- option(value="") Все
|
|
|
- option(value="active") Активные
|
|
|
- option(value="inactive") Неактивные
|
|
|
-
|
|
|
- div(class="admin-products__mass-actions")
|
|
|
- div(class="admin-products__mass-header")
|
|
|
- div(class="admin-products__selection-info")
|
|
|
- span Выбрано товаров: {{ selectedProducts.length }}
|
|
|
- button(
|
|
|
- v-if="selectedProducts.length > 0"
|
|
|
- @click="clearSelection"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Сбросить
|
|
|
- div(class="admin-products__mass-buttons")
|
|
|
- button(
|
|
|
- @click="activateSelected"
|
|
|
- :disabled="selectedProducts.length === 0"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Активировать
|
|
|
- button(
|
|
|
- @click="deactivateSelected"
|
|
|
- :disabled="selectedProducts.length === 0"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Деактивировать
|
|
|
- button(
|
|
|
- @click="deleteSelected"
|
|
|
- :disabled="selectedProducts.length === 0"
|
|
|
- class="admin-products__btn admin-products__btn--danger"
|
|
|
- ) Удалить
|
|
|
- button(
|
|
|
- @click="showCategoryAssignModal = true"
|
|
|
- :disabled="selectedProducts.length === 0"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Назначить категорию
|
|
|
+ div(class="admin-products__table-container")
|
|
|
+ table(class="admin-products__table")
|
|
|
+ thead
|
|
|
+ tr
|
|
|
+ th(class="admin-products__th admin-products__th--checkbox")
|
|
|
+ input(
|
|
|
+ type="checkbox"
|
|
|
+ v-model="selectAll"
|
|
|
+ @change="toggleSelectAll"
|
|
|
+ class="admin-products__checkbox"
|
|
|
+ )
|
|
|
+ th(class="admin-products__th") Артикул
|
|
|
+ th(class="admin-products__th") Название
|
|
|
+ th(class="admin-products__th") Категория
|
|
|
+ th(class="admin-products__th") Цена
|
|
|
+ th(class="admin-products__th") Статус
|
|
|
+ th(class="admin-products__th") Действия
|
|
|
+ tbody
|
|
|
+ tr(
|
|
|
+ v-for="product in filteredProducts"
|
|
|
+ :key="product._id"
|
|
|
+ :class="['admin-products__tr', { 'admin-products__tr--inactive': !product.active }]"
|
|
|
+ )
|
|
|
+ td(class="admin-products__td admin-products__td--checkbox")
|
|
|
+ input(
|
|
|
+ type="checkbox"
|
|
|
+ :checked="isProductSelected(product._id)"
|
|
|
+ @change="toggleProductSelection(product._id)"
|
|
|
+ class="admin-products__checkbox"
|
|
|
+ )
|
|
|
+ td(class="admin-products__td admin-products__td--sku") {{ product.sku }}
|
|
|
+ td(class="admin-products__td admin-products__td--name") {{ product.name }}
|
|
|
+ td(class="admin-products__td") {{ getCategoryName(product.category) }}
|
|
|
+ td(class="admin-products__td admin-products__td--price")
|
|
|
+ span(v-if="product.oldPrice" class="admin-products__old-price") {{ product.oldPrice }} ₽
|
|
|
+ span(class="admin-products__current-price") {{ product.price }} ₽
|
|
|
+ td(class="admin-products__td")
|
|
|
+ span(
|
|
|
+ :class="['admin-products__status', product.active ? 'admin-products__status--active' : 'admin-products__status--inactive']"
|
|
|
+ ) {{ product.active ? 'Активен' : 'Неактивен' }}
|
|
|
+ td(class="admin-products__td admin-products__td--actions")
|
|
|
+ button(
|
|
|
+ @click="editProduct(product)"
|
|
|
+ class="admin-products__action-button admin-products__action-button--edit"
|
|
|
+ ) Редактировать
|
|
|
+ button(
|
|
|
+ @click="toggleProductStatus(product)"
|
|
|
+ :class="['admin-products__action-button', product.active ? 'admin-products__action-button--deactivate' : 'admin-products__action-button--activate']"
|
|
|
+ ) {{ product.active ? 'Деактивировать' : 'Активировать' }}
|
|
|
+
|
|
|
+ div(v-if="filteredProducts.length === 0" class="admin-products__empty")
|
|
|
+ p(class="admin-products__empty-text") Товары не найдены
|
|
|
|
|
|
- div(class="admin-products__list")
|
|
|
- div(class="admin-products__table-container")
|
|
|
- table(class="admin-products__table")
|
|
|
- thead
|
|
|
- tr
|
|
|
- th(class="admin-products__th admin-products__th--checkbox")
|
|
|
+ //- Модальное окно редактирования/создания товара
|
|
|
+ div(
|
|
|
+ v-if="showProductModal"
|
|
|
+ class="admin-products__modal"
|
|
|
+ )
|
|
|
+ div(class="admin-products__modal-content admin-products__modal-content--large")
|
|
|
+ div(class="admin-products__modal-header")
|
|
|
+ h2(class="admin-products__modal-title") {{ isEditing ? 'Редактирование товара' : 'Создание товара' }}
|
|
|
+ button(
|
|
|
+ @click="showProductModal = false"
|
|
|
+ class="admin-products__modal-close"
|
|
|
+ ) ×
|
|
|
+
|
|
|
+ div(class="admin-products__modal-body")
|
|
|
+ div(class="admin-products__form")
|
|
|
+ div(class="admin-products__form-row")
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Название товара *
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="productForm.name"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Введите название товара"
|
|
|
+ )
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Артикул *
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="productForm.sku"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Введите артикул"
|
|
|
+ )
|
|
|
+
|
|
|
+ div(class="admin-products__form-row")
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Категория
|
|
|
+ select(v-model="productForm.category" class="admin-products__select")
|
|
|
+ option(value="") Без категории
|
|
|
+ option(
|
|
|
+ v-for="category in categories"
|
|
|
+ :value="category._id"
|
|
|
+ ) {{ category.name }}
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Бренд
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="productForm.brand"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Введите бренд"
|
|
|
+ )
|
|
|
+
|
|
|
+ div(class="admin-products__form-row")
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Цена *
|
|
|
+ input(
|
|
|
+ type="number"
|
|
|
+ v-model="productForm.price"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="0.00"
|
|
|
+ step="0.01"
|
|
|
+ min="0"
|
|
|
+ )
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Старая цена
|
|
|
+ input(
|
|
|
+ type="number"
|
|
|
+ v-model="productForm.oldPrice"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="0.00"
|
|
|
+ step="0.01"
|
|
|
+ min="0"
|
|
|
+ )
|
|
|
+
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Описание
|
|
|
+ textarea(
|
|
|
+ v-model="productForm.description"
|
|
|
+ class="admin-products__textarea"
|
|
|
+ placeholder="Введите описание товара"
|
|
|
+ rows="4"
|
|
|
+ )
|
|
|
+
|
|
|
+ //- Управление атрибутами
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Атрибуты
|
|
|
+ div(class="admin-products__attributes")
|
|
|
+ div(
|
|
|
+ v-for="attr in attributesList"
|
|
|
+ :key="attr.key"
|
|
|
+ class="admin-products__attribute"
|
|
|
+ )
|
|
|
+ div(class="admin-products__attribute-key") {{ attr.key }}
|
|
|
input(
|
|
|
- type="checkbox"
|
|
|
- v-model="selectAll"
|
|
|
- @change="toggleSelectAll"
|
|
|
- class="admin-products__checkbox"
|
|
|
+ type="text"
|
|
|
+ :value="attr.value"
|
|
|
+ @input="updateAttribute(attr.key, $event.target.value)"
|
|
|
+ class="admin-products__input admin-products__input--small"
|
|
|
+ placeholder="Значение"
|
|
|
)
|
|
|
- th(class="admin-products__th") Изобр.
|
|
|
- th(class="admin-products__th") Название
|
|
|
- th(class="admin-products__th") Артикул
|
|
|
- th(class="admin-products__th") Цена
|
|
|
- th(class="admin-products__th") Категория
|
|
|
- th(class="admin-products__th") Статус
|
|
|
- th(class="admin-products__th") Действия
|
|
|
- tbody
|
|
|
- tr(
|
|
|
- v-for="product in filteredProducts"
|
|
|
- :key="product._id"
|
|
|
- class="admin-products__tr"
|
|
|
- :class="{'admin-products__tr--selected': isProductSelected(product._id)}"
|
|
|
- )
|
|
|
- td(class="admin-products__td admin-products__td--checkbox")
|
|
|
+ button(
|
|
|
+ @click="removeAttribute(attr.key)"
|
|
|
+ class="admin-products__attribute-remove"
|
|
|
+ ) ×
|
|
|
+
|
|
|
+ div(class="admin-products__attribute-add")
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="newAttributeKey"
|
|
|
+ class="admin-products__input admin-products__input--small"
|
|
|
+ placeholder="Название атрибута"
|
|
|
+ @keyup.enter="addAttribute"
|
|
|
+ )
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="newAttributeValue"
|
|
|
+ class="admin-products__input admin-products__input--small"
|
|
|
+ placeholder="Значение"
|
|
|
+ @keyup.enter="addAttribute"
|
|
|
+ )
|
|
|
+ button(
|
|
|
+ @click="addAttribute"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
+ ) Добавить
|
|
|
+
|
|
|
+ //- Управление тегами
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Теги
|
|
|
+ div(class="admin-products__tags")
|
|
|
+ span(
|
|
|
+ v-for="(tag, index) in productForm.tags"
|
|
|
+ :key="index"
|
|
|
+ class="admin-products__tag"
|
|
|
+ )
|
|
|
+ | {{ tag }}
|
|
|
+ button(
|
|
|
+ @click="removeTag(index)"
|
|
|
+ class="admin-products__tag-remove"
|
|
|
+ ) ×
|
|
|
+
|
|
|
+ div(class="admin-products__tag-add")
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="newTag"
|
|
|
+ class="admin-products__input admin-products__input--small"
|
|
|
+ placeholder="Новый тег"
|
|
|
+ @keyup.enter="addTag"
|
|
|
+ )
|
|
|
+ button(
|
|
|
+ @click="addTag"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
+ ) Добавить
|
|
|
+
|
|
|
+ //- Загрузка основного изображения
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Основное изображение
|
|
|
+ div(class="admin-products__image-upload")
|
|
|
+ div(v-if="productForm.image" class="admin-products__image-preview")
|
|
|
+ img(:src="productForm.image" class="admin-products__preview-img")
|
|
|
+ div(class="admin-products__image-info") Основное изображение
|
|
|
+ div(class="admin-products__upload-controls")
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="newImageUrl"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Введите URL изображения"
|
|
|
+ )
|
|
|
+ button(
|
|
|
+ @click="uploadMainImage"
|
|
|
+ :disabled="uploadingImages || !newImageUrl"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
+ ) {{ uploadingImages ? 'Загрузка...' : 'Загрузить' }}
|
|
|
+
|
|
|
+ //- Загрузка дополнительных изображений
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Дополнительные изображения
|
|
|
+ div(class="admin-products__additional-images")
|
|
|
+ div(
|
|
|
+ v-for="(image, index) in productForm.additionalImages"
|
|
|
+ :key="index"
|
|
|
+ class="admin-products__additional-image"
|
|
|
+ )
|
|
|
+ img(:src="image" class="admin-products__preview-img")
|
|
|
+ button(
|
|
|
+ @click="removeAdditionalImage(index)"
|
|
|
+ class="admin-products__image-remove"
|
|
|
+ ) ×
|
|
|
+
|
|
|
+ div(class="admin-products__upload-controls")
|
|
|
+ input(
|
|
|
+ type="text"
|
|
|
+ v-model="newAdditionalImageUrl"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Введите URL дополнительного изображения"
|
|
|
+ )
|
|
|
+ button(
|
|
|
+ @click="uploadAdditionalImage"
|
|
|
+ :disabled="uploadingImages || !newAdditionalImageUrl"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
+ ) {{ uploadingImages ? 'Загрузка...' : 'Добавить' }}
|
|
|
+
|
|
|
+ div(class="admin-products__form-row")
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label admin-products__label--checkbox")
|
|
|
input(
|
|
|
type="checkbox"
|
|
|
- :value="product._id"
|
|
|
- v-model="selectedProducts"
|
|
|
+ v-model="productForm.active"
|
|
|
class="admin-products__checkbox"
|
|
|
)
|
|
|
- td(class="admin-products__td")
|
|
|
- img(
|
|
|
- v-if="product.image"
|
|
|
- :src="product.image"
|
|
|
- :alt="product.name"
|
|
|
- class="admin-products__image"
|
|
|
- )
|
|
|
- div(v-else class="admin-products__no-image") Нет
|
|
|
- td(class="admin-products__td")
|
|
|
- div(class="admin-products__name") {{ product.name }}
|
|
|
- td(class="admin-products__td") {{ product.sku }}
|
|
|
- td(class="admin-products__td")
|
|
|
- div(class="admin-products__price") {{ formatPrice(product.price) }}
|
|
|
- div(
|
|
|
- v-if="product.oldPrice"
|
|
|
- class="admin-products__old-price"
|
|
|
- ) {{ formatPrice(product.oldPrice) }}
|
|
|
- td(class="admin-products__td") {{ getCategoryName(product.category) }}
|
|
|
- td(class="admin-products__td")
|
|
|
- span(
|
|
|
- :class="getStatusClass(product.active)"
|
|
|
- ) {{ product.active ? 'Активен' : 'Неактивен' }}
|
|
|
- td(class="admin-products__td")
|
|
|
- div(class="admin-products__action-buttons")
|
|
|
- button(
|
|
|
- @click="editProduct(product)"
|
|
|
- class="admin-products__action-btn admin-products__action-btn--edit"
|
|
|
- ) Редакт.
|
|
|
- button(
|
|
|
- @click="toggleProductStatus(product)"
|
|
|
- class="admin-products__action-btn admin-products__action-btn--toggle"
|
|
|
- ) {{ product.active ? 'Выкл.' : 'Вкл.' }}
|
|
|
- button(
|
|
|
- @click="deleteProduct(product._id)"
|
|
|
- class="admin-products__action-btn admin-products__action-btn--delete"
|
|
|
- ) Удалить
|
|
|
-
|
|
|
- // Модальное окно массового назначения категории
|
|
|
- div(v-if="showCategoryAssignModal" class="admin-products__modal")
|
|
|
- div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") Назначить категорию для {{ selectedProducts.length }} товаров
|
|
|
+ span Активный товар
|
|
|
|
|
|
- div(class="admin-products__modal-form")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Категория
|
|
|
- select(v-model="massCategory" class="admin-products__select")
|
|
|
- option(value="") Без категории
|
|
|
- option(
|
|
|
- v-for="category in categories"
|
|
|
- :key="category._id"
|
|
|
- :value="category._id"
|
|
|
- ) {{ category.name }}
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__checkbox-label")
|
|
|
- input(
|
|
|
- v-model="removeExistingCategories"
|
|
|
- type="checkbox"
|
|
|
- class="admin-products__checkbox"
|
|
|
- )
|
|
|
- span Удалить существующие категории
|
|
|
-
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
+ div(class="admin-products__modal-footer")
|
|
|
button(
|
|
|
- @click="assignCategoryToSelected"
|
|
|
- :disabled="!massCategory"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Назначить
|
|
|
+ @click="saveProduct"
|
|
|
+ :disabled="!productForm.name || !productForm.sku || !productForm.price"
|
|
|
+ class="admin-products__button admin-products__button--primary"
|
|
|
+ ) {{ isEditing ? 'Обновить' : 'Создать' }}
|
|
|
button(
|
|
|
- @click="showCategoryAssignModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
+ @click="showProductModal = false"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
) Отмена
|
|
|
|
|
|
- // Модальное окно массовых действий
|
|
|
- div(v-if="showMassActionsModal" class="admin-products__modal")
|
|
|
- div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") Массовые действия с товарами
|
|
|
-
|
|
|
- div(class="admin-products__mass-actions-grid")
|
|
|
- div(class="admin-products__mass-action")
|
|
|
- h4(class="admin-products__mass-action-title") Изменение статуса
|
|
|
- div(class="admin-products__mass-action-buttons")
|
|
|
- button(
|
|
|
- @click="massChangeStatus(true)"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Активировать все товары
|
|
|
- button(
|
|
|
- @click="massChangeStatus(false)"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Деактивировать все товары
|
|
|
-
|
|
|
- div(class="admin-products__mass-action")
|
|
|
- h4(class="admin-products__mass-action-title") Управление категориями
|
|
|
- div(class="admin-products__mass-action-buttons")
|
|
|
- button(
|
|
|
- @click="showMassCategoryAssign = true"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Назначить категорию всем
|
|
|
- button(
|
|
|
- @click="massRemoveCategories"
|
|
|
- class="admin-products__btn admin-products__btn--danger"
|
|
|
- ) Удалить все категории
|
|
|
-
|
|
|
- div(class="admin-products__mass-action")
|
|
|
- h4(class="admin-products__mass-action-title") Цены
|
|
|
- div(class="admin-products__mass-action-buttons")
|
|
|
- button(
|
|
|
- @click="showMassPriceModal = true"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Массовое изменение цен
|
|
|
-
|
|
|
- div(class="admin-products__mass-action")
|
|
|
- h4(class="admin-products__mass-action-title") Экспорт
|
|
|
- div(class="admin-products__mass-action-buttons")
|
|
|
- button(
|
|
|
- @click="exportProducts"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Экспорт в CSV
|
|
|
- button(
|
|
|
- @click="exportSelectedProducts"
|
|
|
- :disabled="selectedProducts.length === 0"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Экспорт выбранных
|
|
|
-
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
- button(
|
|
|
- @click="showMassActionsModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Закрыть
|
|
|
-
|
|
|
- // Модальное окно массового назначения категории всем товарам
|
|
|
- div(v-if="showMassCategoryAssign" class="admin-products__modal")
|
|
|
- div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") Назначить категорию всем товарам
|
|
|
-
|
|
|
- div(class="admin-products__modal-form")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Категория
|
|
|
- select(v-model="massAllCategory" class="admin-products__select")
|
|
|
- option(value="") Без категории
|
|
|
- option(
|
|
|
- v-for="category in categories"
|
|
|
- :key="category._id"
|
|
|
- :value="category._id"
|
|
|
- ) {{ category.name }}
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__checkbox-label")
|
|
|
- input(
|
|
|
- v-model="massRemoveAllCategories"
|
|
|
- type="checkbox"
|
|
|
- class="admin-products__checkbox"
|
|
|
- )
|
|
|
- span Удалить существующие категории у всех товаров
|
|
|
-
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
- button(
|
|
|
- @click="assignCategoryToAll"
|
|
|
- :disabled="!massAllCategory"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Назначить всем
|
|
|
+ //- Модальное окно управления категориями
|
|
|
+ div(
|
|
|
+ v-if="showCategoriesModal"
|
|
|
+ class="admin-products__modal"
|
|
|
+ )
|
|
|
+ div(class="admin-products__modal-content admin-products__modal-content--large")
|
|
|
+ div(class="admin-products__modal-header")
|
|
|
+ h2(class="admin-products__modal-title") Управление категориями
|
|
|
button(
|
|
|
- @click="showMassCategoryAssign = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Отмена
|
|
|
-
|
|
|
- // Модальное окно массового изменения цен
|
|
|
- div(v-if="showMassPriceModal" class="admin-products__modal")
|
|
|
- div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") Массовое изменение цен
|
|
|
+ @click="showCategoriesModal = false"
|
|
|
+ class="admin-products__modal-close"
|
|
|
+ ) ×
|
|
|
|
|
|
- div(class="admin-products__modal-form")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Тип изменения
|
|
|
- select(v-model="priceChangeType" class="admin-products__select")
|
|
|
- option(value="fixed") Фиксированная цена
|
|
|
- option(value="percent") Изменить на процент
|
|
|
- option(value="increase") Увеличить на сумму
|
|
|
- option(value="decrease") Уменьшить на сумму
|
|
|
+ div(class="admin-products__modal-body")
|
|
|
+ div(class="admin-products__categories-header")
|
|
|
+ button(
|
|
|
+ @click="createCategory"
|
|
|
+ class="admin-products__button admin-products__button--primary"
|
|
|
+ ) Создать категорию
|
|
|
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Значение
|
|
|
- input(
|
|
|
- v-model="priceChangeValue"
|
|
|
- type="number"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="Введите значение"
|
|
|
- step="0.01"
|
|
|
+ div(class="admin-products__categories-list")
|
|
|
+ div(
|
|
|
+ v-for="category in categories"
|
|
|
+ :key="category._id"
|
|
|
+ class="admin-products__category-item"
|
|
|
)
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__checkbox-label")
|
|
|
- input(
|
|
|
- v-model="applyToOldPrice"
|
|
|
- type="checkbox"
|
|
|
- class="admin-products__checkbox"
|
|
|
- )
|
|
|
- span Применить к старой цене
|
|
|
-
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
- button(
|
|
|
- @click="applyMassPriceChange"
|
|
|
- :disabled="!priceChangeValue"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Применить
|
|
|
- button(
|
|
|
- @click="showMassPriceModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Отмена
|
|
|
-
|
|
|
+ div(class="admin-products__category-info")
|
|
|
+ div(class="admin-products__category-name") {{ category.name }}
|
|
|
+ div(class="admin-products__category-meta")
|
|
|
+ span Товаров: {{ getCategoryProductCount(category._id) }}
|
|
|
+ span(v-if="category.slug") Slug: {{ category.slug }}
|
|
|
+ div(class="admin-products__category-actions")
|
|
|
+ button(
|
|
|
+ @click="editCategory(category)"
|
|
|
+ class="admin-products__action-button admin-products__action-button--edit"
|
|
|
+ ) Редактировать
|
|
|
+ button(
|
|
|
+ @click="deleteCategory(category)"
|
|
|
+ class="admin-products__action-button admin-products__action-button--danger"
|
|
|
+ ) Удалить
|
|
|
|
|
|
- // Модальное окно редактирования товара
|
|
|
- div(v-if="showProductModal" class="admin-products__modal")
|
|
|
+ //- Модальное окно редактирования/создания категории
|
|
|
+ div(
|
|
|
+ v-if="showCategoryModal"
|
|
|
+ class="admin-products__modal"
|
|
|
+ )
|
|
|
div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") {{ editingProduct ? 'Редактирование' : 'Добавление' }} товара
|
|
|
+ div(class="admin-products__modal-header")
|
|
|
+ h2(class="admin-products__modal-title") {{ editingCategory ? 'Редактирование категории' : 'Создание категории' }}
|
|
|
+ button(
|
|
|
+ @click="showCategoryModal = false"
|
|
|
+ class="admin-products__modal-close"
|
|
|
+ ) ×
|
|
|
|
|
|
- div(class="admin-products__modal-form")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Название товара *
|
|
|
- input(
|
|
|
- v-model="productForm.name"
|
|
|
- type="text"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="Введите название товара"
|
|
|
- required
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Артикул *
|
|
|
- input(
|
|
|
- v-model="productForm.sku"
|
|
|
- type="text"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="Артикул товара"
|
|
|
- required
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Категория
|
|
|
- select(v-model="productForm.category" class="admin-products__select")
|
|
|
- option(value="") Выберите категорию
|
|
|
- option(
|
|
|
- v-for="category in categories"
|
|
|
- :key="category._id"
|
|
|
- :value="category._id"
|
|
|
- ) {{ category.name }}
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Цена *
|
|
|
- input(
|
|
|
- v-model="productForm.price"
|
|
|
- type="number"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="0.00"
|
|
|
- min="0"
|
|
|
- step="0.01"
|
|
|
- required
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Старая цена
|
|
|
- input(
|
|
|
- v-model="productForm.oldPrice"
|
|
|
- type="number"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="0.00"
|
|
|
- min="0"
|
|
|
- step="0.01"
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Бренд
|
|
|
- input(
|
|
|
- v-model="productForm.brand"
|
|
|
- type="text"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="Бренд производителя"
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Описание
|
|
|
- textarea(
|
|
|
- v-model="productForm.description"
|
|
|
- class="admin-products__textarea"
|
|
|
- placeholder="Описание товара"
|
|
|
- rows="4"
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Изображение товара
|
|
|
- div(class="admin-products__image-upload")
|
|
|
- div(v-if="productForm.image" class="admin-products__image-preview")
|
|
|
- img(:src="productForm.image" :alt="productForm.name" class="admin-products__preview-image")
|
|
|
- button(
|
|
|
- @click="removeProductImage"
|
|
|
- class="admin-products__btn admin-products__btn--danger"
|
|
|
- ) Удалить
|
|
|
- div(v-else class="admin-products__image-placeholder") Изображение не загружено
|
|
|
-
|
|
|
+ div(class="admin-products__modal-body")
|
|
|
+ div(class="admin-products__form")
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Название категории *
|
|
|
input(
|
|
|
- type="file"
|
|
|
- ref="productImageInput"
|
|
|
- @change="onProductImageUpload"
|
|
|
- accept="image/*"
|
|
|
- class="admin-products__file-input"
|
|
|
- id="product-image-upload"
|
|
|
+ type="text"
|
|
|
+ v-model="categoryForm.name"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Введите название категории"
|
|
|
)
|
|
|
- label(for="product-image-upload" class="admin-products__btn admin-products__btn--secondary") Выбрать изображение
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__checkbox-label")
|
|
|
+
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Slug
|
|
|
input(
|
|
|
- v-model="productForm.active"
|
|
|
- type="checkbox"
|
|
|
- class="admin-products__checkbox"
|
|
|
+ type="text"
|
|
|
+ v-model="categoryForm.slug"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="Автоматически сгенерируется из названия"
|
|
|
)
|
|
|
- span Активный товар
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Домены
|
|
|
- div(class="admin-products__domains-list")
|
|
|
- label(
|
|
|
- v-for="domain in availableDomains"
|
|
|
- :key="domain._id"
|
|
|
- class="admin-products__domain-label"
|
|
|
+
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Описание
|
|
|
+ textarea(
|
|
|
+ v-model="categoryForm.description"
|
|
|
+ class="admin-products__textarea"
|
|
|
+ placeholder="Введите описание категории"
|
|
|
+ rows="3"
|
|
|
)
|
|
|
+
|
|
|
+ div(class="admin-products__form-row")
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Родительская категория
|
|
|
+ select(v-model="categoryForm.parentCategory" class="admin-products__select")
|
|
|
+ option(value="") Нет
|
|
|
+ option(
|
|
|
+ v-for="category in categories"
|
|
|
+ :value="category._id"
|
|
|
+ v-if="category._id != editingCategory?._id"
|
|
|
+ ) {{ category.name }}
|
|
|
+
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label") Порядок сортировки
|
|
|
+ input(
|
|
|
+ type="number"
|
|
|
+ v-model="categoryForm.sortOrder"
|
|
|
+ class="admin-products__input"
|
|
|
+ placeholder="0"
|
|
|
+ )
|
|
|
+
|
|
|
+ div(class="admin-products__form-group")
|
|
|
+ label(class="admin-products__label admin-products__label--checkbox")
|
|
|
input(
|
|
|
type="checkbox"
|
|
|
- :value="domain.domain"
|
|
|
- v-model="productForm.domains"
|
|
|
- class="admin-products__domain-checkbox"
|
|
|
+ v-model="categoryForm.active"
|
|
|
+ class="admin-products__checkbox"
|
|
|
)
|
|
|
- span {{ domain.domain }}
|
|
|
+ span Активная категория
|
|
|
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
+ div(class="admin-products__modal-footer")
|
|
|
button(
|
|
|
- @click="saveProduct"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) {{ editingProduct ? 'Обновить' : 'Создать' }}
|
|
|
+ @click="saveCategory"
|
|
|
+ :disabled="!categoryForm.name"
|
|
|
+ class="admin-products__button admin-products__button--primary"
|
|
|
+ ) {{ editingCategory ? 'Обновить' : 'Создать' }}
|
|
|
button(
|
|
|
- @click="showProductModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
+ @click="showCategoryModal = false"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
) Отмена
|
|
|
|
|
|
- // Модальное окно импорта
|
|
|
- div(v-if="showImportModal" class="admin-products__modal")
|
|
|
+ //- Модальное окно импорта
|
|
|
+ div(
|
|
|
+ v-if="showImportModal"
|
|
|
+ class="admin-products__modal"
|
|
|
+ )
|
|
|
div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") Импорт товаров из CSV
|
|
|
+ div(class="admin-products__modal-header")
|
|
|
+ h2(class="admin-products__modal-title") Импорт товаров из CSV
|
|
|
+ button(
|
|
|
+ @click="showImportModal = false"
|
|
|
+ class="admin-products__modal-close"
|
|
|
+ ) ×
|
|
|
|
|
|
- div(class="admin-products__import-form")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Выберите CSV файл
|
|
|
+ div(class="admin-products__modal-body")
|
|
|
+ div(v-if="importing" class="admin-products__import-progress")
|
|
|
+ div(class="admin-products__progress-bar")
|
|
|
+ div(
|
|
|
+ :style="{ width: importProgress + '%' }"
|
|
|
+ class="admin-products__progress-fill"
|
|
|
+ )
|
|
|
+ p(class="admin-products__progress-text") Обработано: {{ processedCount }} из {{ totalCount }} ({{ importProgress }}%)
|
|
|
+
|
|
|
+ div(v-else class="admin-products__import-form")
|
|
|
input(
|
|
|
type="file"
|
|
|
@change="onFileSelect"
|
|
|
accept=".csv"
|
|
|
class="admin-products__file-input"
|
|
|
)
|
|
|
- p(class="admin-products__help-text") Поддерживается формат CSV с разделителем ; и кодировкой UTF-8
|
|
|
-
|
|
|
- div(v-if="selectedFile" class="admin-products__file-info")
|
|
|
- p Выбран файл: {{ selectedFile.name }}
|
|
|
- button(
|
|
|
- @click="importProducts"
|
|
|
- :disabled="importing"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) {{ importing ? 'Импорт...' : 'Начать импорт' }}
|
|
|
+ p(class="admin-products__help-text") Поддерживается формат CSV с разделителем ";" и кодировкой UTF-8
|
|
|
|
|
|
div(v-if="importResults" class="admin-products__import-results")
|
|
|
- h4(v-if="importResults.success" class="admin-products__success") Импорт успешно завершен!
|
|
|
- h4(v-else class="admin-products__error") Ошибка импорта
|
|
|
- p Обработано товаров: {{ importResults.processed }}
|
|
|
- p(v-if="importResults.errors && importResults.errors.length")
|
|
|
- strong Ошибки:
|
|
|
- ul
|
|
|
- li(v-for="error in importResults.errors" :key="error") {{ error }}
|
|
|
- p(v-if="importResults.error") Ошибка: {{ importResults.error }}
|
|
|
+ div(
|
|
|
+ v-if="importResults.success"
|
|
|
+ class="admin-products__result admin-products__result--success"
|
|
|
+ )
|
|
|
+ h3 Успешно импортировано!
|
|
|
+ p Обработано товаров: {{ importResults.processed }} из {{ importResults.total }}
|
|
|
+ ul(v-if="importResults.errors.length > 0")
|
|
|
+ li(v-for="error in importResults.errors") {{ error }}
|
|
|
+ div(
|
|
|
+ v-else
|
|
|
+ class="admin-products__result admin-products__result--error"
|
|
|
+ )
|
|
|
+ h3 Ошибка импорта!
|
|
|
+ p {{ importResults.error }}
|
|
|
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
+ div(class="admin-products__modal-footer")
|
|
|
+ button(
|
|
|
+ @click="importProducts"
|
|
|
+ :disabled="!selectedFile || importing"
|
|
|
+ class="admin-products__button admin-products__button--primary"
|
|
|
+ ) {{ importing ? 'Импорт...' : 'Начать импорт' }}
|
|
|
button(
|
|
|
@click="showImportModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Закрыть
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
+ ) Отмена
|
|
|
|
|
|
- // Модальное окно управления категориями
|
|
|
- div(v-if="showCategoriesModal" class="admin-products__modal")
|
|
|
- div(class="admin-products__modal-content admin-products__modal-content--large")
|
|
|
- h3(class="admin-products__modal-title") Управление категориями
|
|
|
-
|
|
|
- div(class="admin-products__categories-tabs")
|
|
|
- button(
|
|
|
- @click="categoriesActiveTab = 'list'"
|
|
|
- :class="getCategoriesTabClass('list')"
|
|
|
- ) Список категорий
|
|
|
+ //- Модальное окно массовых действий
|
|
|
+ div(
|
|
|
+ v-if="showMassActionsModal"
|
|
|
+ class="admin-products__modal"
|
|
|
+ )
|
|
|
+ div(class="admin-products__modal-content")
|
|
|
+ div(class="admin-products__modal-header")
|
|
|
+ h2(class="admin-products__modal-title") Массовые действия ({{ selectedProducts.length }} товаров)
|
|
|
button(
|
|
|
- @click="categoriesActiveTab = 'import'"
|
|
|
- :class="getCategoriesTabClass('import')"
|
|
|
- ) Импорт категорий
|
|
|
+ @click="showMassActionsModal = false"
|
|
|
+ class="admin-products__modal-close"
|
|
|
+ ) ×
|
|
|
|
|
|
- // Список категорий
|
|
|
- div(v-if="categoriesActiveTab === 'list'" class="admin-products__categories-list")
|
|
|
- div(class="admin-products__categories-header")
|
|
|
+ div(class="admin-products__modal-body")
|
|
|
+ div(class="admin-products__mass-actions")
|
|
|
button(
|
|
|
- @click="showCategoryModal = true"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) Добавить категорию
|
|
|
-
|
|
|
- div(class="admin-products__categories-grid")
|
|
|
- div(
|
|
|
- v-for="category in categories"
|
|
|
- :key="category._id"
|
|
|
- class="admin-products__category-item"
|
|
|
- )
|
|
|
- div(class="admin-products__category-preview")
|
|
|
- img(
|
|
|
- v-if="category.image"
|
|
|
- :src="category.image"
|
|
|
- :alt="category.name"
|
|
|
- class="admin-products__category-image"
|
|
|
- )
|
|
|
- div(v-else class="admin-products__category-no-image") Нет изображения
|
|
|
- div(class="admin-products__category-info")
|
|
|
- h4(class="admin-products__category-name") {{ category.name }}
|
|
|
- p(class="admin-products__category-description") {{ category.description || 'Без описания' }}
|
|
|
- div(class="admin-products__category-meta")
|
|
|
- span(class="admin-products__category-products") Товаров: {{ getCategoryProductCount(category._id) }}
|
|
|
- span(
|
|
|
- :class="getStatusClass(category.active)"
|
|
|
- ) {{ category.active ? 'Активна' : 'Неактивна' }}
|
|
|
-
|
|
|
- div(class="admin-products__category-actions")
|
|
|
- button(
|
|
|
- @click="editCategory(category)"
|
|
|
- class="admin-products__btn admin-products__btn--edit"
|
|
|
- ) Редактировать
|
|
|
- button(
|
|
|
- @click="deleteCategory(category._id)"
|
|
|
- class="admin-products__btn admin-products__btn--delete"
|
|
|
- ) Удалить
|
|
|
-
|
|
|
- // Импорт категорий
|
|
|
- div(v-if="categoriesActiveTab === 'import'" class="admin-products__categories-import")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Выберите CSV файл категорий
|
|
|
- input(
|
|
|
- type="file"
|
|
|
- @change="onCategoriesFileSelect"
|
|
|
- accept=".csv"
|
|
|
- class="admin-products__file-input"
|
|
|
- )
|
|
|
- p(class="admin-products__help-text") Формат CSV с полями: name, slug, description, parentCategory, sortOrder, active
|
|
|
-
|
|
|
- div(v-if="selectedCategoriesFile" class="admin-products__file-info")
|
|
|
- p Выбран файл: {{ selectedCategoriesFile.name }}
|
|
|
+ @click="activateSelected"
|
|
|
+ class="admin-products__button admin-products__button--success"
|
|
|
+ ) Активировать
|
|
|
button(
|
|
|
- @click="importCategories"
|
|
|
- :disabled="importingCategories"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) {{ importingCategories ? 'Импорт...' : 'Импорт категорий' }}
|
|
|
-
|
|
|
- div(v-if="categoriesImportResults" class="admin-products__import-results")
|
|
|
- h4(v-if="categoriesImportResults.success" class="admin-products__success") Импорт категорий завершен!
|
|
|
- h4(v-else class="admin-products__error") Ошибка импорта категорий
|
|
|
- p Обработано категорий: {{ categoriesImportResults.processed }}
|
|
|
- p(v-if="categoriesImportResults.errors && categoriesImportResults.errors.length")
|
|
|
- strong Ошибки:
|
|
|
- ul
|
|
|
- li(v-for="error in categoriesImportResults.errors" :key="error") {{ error }}
|
|
|
+ @click="deactivateSelected"
|
|
|
+ class="admin-products__button admin-products__button--warning"
|
|
|
+ ) Деактивировать
|
|
|
+ button(
|
|
|
+ @click="deleteSelected"
|
|
|
+ class="admin-products__button admin-products__button--danger"
|
|
|
+ ) Удалить
|
|
|
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
+ div(class="admin-products__modal-footer")
|
|
|
button(
|
|
|
- @click="showCategoriesModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
+ @click="showMassActionsModal = false"
|
|
|
+ class="admin-products__button admin-products__button--secondary"
|
|
|
) Закрыть
|
|
|
-
|
|
|
- // Модальное окно редактирования категории
|
|
|
- div(v-if="showCategoryModal" class="admin-products__modal")
|
|
|
- div(class="admin-products__modal-content")
|
|
|
- h3(class="admin-products__modal-title") {{ editingCategory ? 'Редактирование' : 'Добавление' }} категории
|
|
|
-
|
|
|
- div(class="admin-products__modal-form")
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Название категории *
|
|
|
- input(
|
|
|
- v-model="categoryForm.name"
|
|
|
- type="text"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="Введите название категории"
|
|
|
- required
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") URL slug *
|
|
|
- input(
|
|
|
- v-model="categoryForm.slug"
|
|
|
- type="text"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="url-slug"
|
|
|
- required
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Описание
|
|
|
- textarea(
|
|
|
- v-model="categoryForm.description"
|
|
|
- class="admin-products__textarea"
|
|
|
- placeholder="Описание категории"
|
|
|
- rows="3"
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Родительская категория
|
|
|
- select(v-model="categoryForm.parentCategory" class="admin-products__select")
|
|
|
- option(value="") Без родительской категории
|
|
|
- option(
|
|
|
- v-for="cat in categories.filter(c => c._id !== editingCategory?._id)"
|
|
|
- :key="cat._id"
|
|
|
- :value="cat._id"
|
|
|
- ) {{ cat.name }}
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Порядок сортировки
|
|
|
- input(
|
|
|
- v-model="categoryForm.sortOrder"
|
|
|
- type="number"
|
|
|
- class="admin-products__input"
|
|
|
- placeholder="0"
|
|
|
- min="0"
|
|
|
- )
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Изображение категории
|
|
|
- div(class="admin-products__image-upload")
|
|
|
- div(v-if="categoryForm.image" class="admin-products__image-preview")
|
|
|
- img(:src="categoryForm.image" :alt="categoryForm.name" class="admin-products__preview-image")
|
|
|
- button(
|
|
|
- @click="removeCategoryImage"
|
|
|
- class="admin-products__btn admin-products__btn--danger"
|
|
|
- ) Удалить
|
|
|
- div(v-else class="admin-products__image-placeholder") Изображение не загружено
|
|
|
-
|
|
|
- input(
|
|
|
- type="file"
|
|
|
- ref="categoryImageInput"
|
|
|
- @change="onCategoryImageUpload"
|
|
|
- accept="image/*"
|
|
|
- class="admin-products__file-input"
|
|
|
- id="category-image-upload"
|
|
|
- )
|
|
|
- label(for="category-image-upload" class="admin-products__btn admin-products__btn--secondary") Выбрать изображение
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Иконка для меню
|
|
|
- div(class="admin-products__image-upload")
|
|
|
- div(v-if="categoryForm.icon" class="admin-products__image-preview admin-products__image-preview--small")
|
|
|
- img(:src="categoryForm.icon" :alt="categoryForm.name" class="admin-products__preview-image")
|
|
|
- button(
|
|
|
- @click="removeCategoryIcon"
|
|
|
- class="admin-products__btn admin-products__btn--danger"
|
|
|
- ) Удалить
|
|
|
- div(v-else class="admin-products__image-placeholder") Иконка не загружена
|
|
|
-
|
|
|
- input(
|
|
|
- type="file"
|
|
|
- ref="categoryIconInput"
|
|
|
- @change="onCategoryIconUpload"
|
|
|
- accept="image/*"
|
|
|
- class="admin-products__file-input"
|
|
|
- id="category-icon-upload"
|
|
|
- )
|
|
|
- label(for="category-icon-upload" class="admin-products__btn admin-products__btn--secondary") Выбрать иконку
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__checkbox-label")
|
|
|
- input(
|
|
|
- v-model="categoryForm.active"
|
|
|
- type="checkbox"
|
|
|
- class="admin-products__checkbox"
|
|
|
- )
|
|
|
- span Активная категория
|
|
|
-
|
|
|
- div(class="admin-products__form-group")
|
|
|
- label(class="admin-products__label") Домены
|
|
|
- div(class="admin-products__domains-list")
|
|
|
- label(
|
|
|
- v-for="domain in availableDomains"
|
|
|
- :key="domain._id"
|
|
|
- class="admin-products__domain-label"
|
|
|
- )
|
|
|
- input(
|
|
|
- type="checkbox"
|
|
|
- :value="domain.domain"
|
|
|
- v-model="categoryForm.domains"
|
|
|
- class="admin-products__domain-checkbox"
|
|
|
- )
|
|
|
- span {{ domain.domain }}
|
|
|
-
|
|
|
- div(class="admin-products__modal-actions")
|
|
|
- button(
|
|
|
- @click="saveCategory"
|
|
|
- class="admin-products__btn admin-products__btn--primary"
|
|
|
- ) {{ editingCategory ? 'Обновить' : 'Создать' }}
|
|
|
- button(
|
|
|
- @click="showCategoryModal = false"
|
|
|
- class="admin-products__btn admin-products__btn--secondary"
|
|
|
- ) Отмена
|