div(class="admin-products") div(class="admin-products__header") h1(class="admin-products__title") Управление товарами div(class="admin-products__actions") button( @click="createProduct" class="admin-products__button admin-products__button--primary" ) Добавить товар button( @click="showImportModal = true" class="admin-products__button admin-products__button--secondary" ) Импорт из CSV button( @click="showCategoriesManager" class="admin-products__button admin-products__button--secondary" ) Управление категориями button( v-if="selectedProducts.length > 0" @click="showMassActionsModal = true" 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__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( 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="text" :value="attr.value" @input="updateAttribute(attr.key, $event.target.value)" class="admin-products__input admin-products__input--small" placeholder="Значение" ) 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" v-model="productForm.active" class="admin-products__checkbox" ) span Активный товар div(class="admin-products__modal-footer") button( @click="saveProduct" :disabled="!productForm.name || !productForm.sku || !productForm.price" class="admin-products__button admin-products__button--primary" ) {{ isEditing ? 'Обновить' : 'Создать' }} button( @click="showProductModal = false" 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") div(class="admin-products__modal-header") h2(class="admin-products__modal-title") Управление категориями button( @click="showCategoriesModal = false" class="admin-products__modal-close" ) × 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__categories-list") div( v-for="category in categories" :key="category._id" class="admin-products__category-item" ) 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="showCategoryModal" class="admin-products__modal" ) div(class="admin-products__modal-content") 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-body") div(class="admin-products__form") div(class="admin-products__form-group") label(class="admin-products__label") Название категории * input( type="text" v-model="categoryForm.name" class="admin-products__input" placeholder="Введите название категории" ) div(class="admin-products__form-group") label(class="admin-products__label") Slug input( type="text" v-model="categoryForm.slug" class="admin-products__input" placeholder="Автоматически сгенерируется из названия" ) 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" v-model="categoryForm.active" class="admin-products__checkbox" ) span Активная категория div(class="admin-products__modal-footer") button( @click="saveCategory" :disabled="!categoryForm.name" class="admin-products__button admin-products__button--primary" ) {{ editingCategory ? 'Обновить' : 'Создать' }} button( @click="showCategoryModal = false" class="admin-products__button admin-products__button--secondary" ) Отмена //- Модальное окно импорта div( v-if="showImportModal" class="admin-products__modal" ) div(class="admin-products__modal-content") 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__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="importResults" class="admin-products__import-results") 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-footer") button( @click="importProducts" :disabled="!selectedFile || importing" class="admin-products__button admin-products__button--primary" ) {{ importing ? 'Импорт...' : 'Начать импорт' }} button( @click="showImportModal = false" class="admin-products__button admin-products__button--secondary" ) Отмена //- Модальное окно массовых действий 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="showMassActionsModal = false" class="admin-products__modal-close" ) × div(class="admin-products__modal-body") div(class="admin-products__mass-actions") button( @click="activateSelected" class="admin-products__button admin-products__button--success" ) Активировать button( @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-footer") button( @click="showMassActionsModal = false" class="admin-products__button admin-products__button--secondary" ) Закрыть