div(class="admin-products") div(class="admin-products__header") h1(class="admin-products__title") Управление товарами div(class="admin-products__actions") button( @click="showProductModal = true" class="admin-products__btn admin-products__btn--primary" ) Добавить товар button( @click="showImportModal = true" class="admin-products__btn admin-products__btn--secondary" ) Импорт из CSV button( @click="showCategoriesModal = true" class="admin-products__btn admin-products__btn--secondary" ) Управление категориями 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__list") div(class="admin-products__table-container") table(class="admin-products__table") thead tr 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" ) 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="showProductModal" class="admin-products__modal") div(class="admin-products__modal-content") h3(class="admin-products__modal-title") {{ editingProduct ? 'Редактирование' : 'Добавление' }} товара 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") Изображение не загружено input( type="file" ref="productImageInput" @change="onProductImageUpload" accept="image/*" class="admin-products__file-input" id="product-image-upload" ) 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") input( v-model="productForm.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="productForm.domains" class="admin-products__domain-checkbox" ) span {{ domain.domain }} div(class="admin-products__modal-actions") button( @click="saveProduct" class="admin-products__btn admin-products__btn--primary" ) {{ editingProduct ? 'Обновить' : 'Создать' }} button( @click="showProductModal = false" class="admin-products__btn admin-products__btn--secondary" ) Отмена // Модальное окно импорта 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__import-form") div(class="admin-products__form-group") label(class="admin-products__label") Выберите CSV файл 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 ? 'Импорт...' : 'Начать импорт' }} 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(class="admin-products__modal-actions") button( @click="showImportModal = false" class="admin-products__btn admin-products__btn--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')" ) Список категорий button( @click="categoriesActiveTab = 'import'" :class="getCategoriesTabClass('import')" ) Импорт категорий // Список категорий div(v-if="categoriesActiveTab === 'list'" class="admin-products__categories-list") div(class="admin-products__categories-header") 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 }} 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 }} div(class="admin-products__modal-actions") button( @click="showCategoriesModal = false" class="admin-products__btn admin-products__btn--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" ) Отмена