.admin-products .admin-products__header h1.admin-products__title Управление товарами .admin-products__actions button.admin-products__btn.admin-products__btn--primary( @click="showProductModal = true" ) Добавить товар button.admin-products__btn.admin-products__btn--secondary( @click="showImportModal = true" ) Импорт из CSV .admin-products__filters .admin-products__search input.admin-products__search-input( type="text" placeholder="Поиск по названию или артикулу..." v-model="searchQuery" ) .admin-products__category-filter select.admin-products__category-select(v-model="selectedCategory") option(value="") Все категории option( v-for="category in categories" :value="category.slug" ) {{ category.name }} .admin-products__content .admin-products__table-container table.admin-products__table thead tr th.admin-products__th-checkbox input( type="checkbox" @change="toggleAllProducts" :checked="selectedProducts.length === filteredProducts.length" ) th.admin-products__th Название th.admin-products__th Артикул th.admin-products__th Категория th.admin-products__th Цена th.admin-products__th Статус th.admin-products__th Действия tbody tr.admin-products__tr( v-for="product in filteredProducts" :key="product._id" ) td.admin-products__td-checkbox input( type="checkbox" :value="product._id" v-model="selectedProducts" ) td.admin-products__td {{ product.name }} td.admin-products__td {{ product.sku }} td.admin-products__td {{ product.category }} td.admin-products__td {{ product.price }} ₽ td.admin-products__td span.admin-products__status( :class="{'admin-products__status--active': product.active, 'admin-products__status--inactive': !product.active}" ) {{ product.active ? 'Активен' : 'Неактивен' }} td.admin-products__td .admin-products__actions button.admin-products__action-btn.admin-products__action-btn--edit( @click="editProduct(product)" ) Редактировать button.admin-products__action-btn.admin-products__action-btn--delete( @click="deleteProduct(product)" ) Удалить .admin-products__empty(v-if="filteredProducts.length === 0") p.admin-products__empty-text Товары не найдены //- Модальное окно товара .admin-modal(v-if="showProductModal") .admin-modal__overlay(@click="showProductModal = false") .admin-modal__content .admin-modal__header h2.admin-modal__title {{ currentProduct._id ? 'Редактировать товар' : 'Добавить товар' }} button.admin-modal__close(@click="showProductModal = false") × .admin-modal__body .admin-form .admin-form__group label.admin-form__label Название товара * input.admin-form__input( type="text" v-model="currentProduct.name" placeholder="Введите название товара" ) .admin-form__group label.admin-form__label Артикул * input.admin-form__input( type="text" v-model="currentProduct.sku" placeholder="Введите артикул" ) .admin-form__group label.admin-form__label Категория select.admin-form__select(v-model="currentProduct.category") option(value="") Выберите категорию option( v-for="category in categories" :value="category.slug" ) {{ category.name }} .admin-form__row .admin-form__group label.admin-form__label Цена * input.admin-form__input( type="number" v-model.number="currentProduct.price" placeholder="0.00" step="0.01" ) .admin-form__group label.admin-form__label Старая цена input.admin-form__input( type="number" v-model.number="currentProduct.oldPrice" placeholder="0.00" step="0.01" ) .admin-form__group label.admin-form__label Описание textarea.admin-form__textarea( v-model="currentProduct.description" placeholder="Введите описание товара" rows="4" ) .admin-form__group label.admin-form__label input.admin-form__checkbox( type="checkbox" v-model="currentProduct.active" ) span Активный товар .admin-modal__footer button.admin-modal__btn.admin-modal__btn--secondary( @click="showProductModal = false" ) Отмена button.admin-modal__btn.admin-modal__btn--primary( @click="saveProductForm" ) Сохранить //- Модальное окно импорта .admin-modal(v-if="showImportModal") .admin-modal__overlay(@click="showImportModal = false") .admin-modal__content .admin-modal__header h2.admin-modal__title Импорт товаров из CSV button.admin-modal__close(@click="showImportModal = false") × .admin-modal__body .admin-import .admin-import__upload input.admin-import__file-input( type="file" accept=".csv" @change="handleFileSelect" ) .admin-import__upload-area( :class="{'admin-import__upload-area--dragover': dragOver}" @drop="handleDrop" @dragover="handleDragOver" @dragleave="dragOver = false" ) p.admin-import__upload-text span Выберите CSV файл | или перетащите его сюда .admin-import__info(v-if="selectedFile") .admin-import__file-info span.admin-import__file-name {{ selectedFile.name }} span.admin-import__file-size ({{ (selectedFile.size / 1024).toFixed(2) }} KB) .admin-import__progress(v-if="importing") .admin-import__progress-bar .admin-import__progress-fill(:style="{width: importProgress + '%'}") .admin-import__progress-text {{ importProgress }}% .admin-import__results(v-if="importResults") .admin-import__result( :class="{'admin-import__result--success': importResults.success, 'admin-import__result--error': !importResults.success}" ) h4.admin-import__result-title {{ importResults.success ? 'Импорт завершен' : 'Ошибка импорта' }} p.admin-import__result-text | Обработано: {{ importResults.processed }}, | Успешно: {{ importResults.successful }}, | С ошибками: {{ importResults.failed }} .admin-import__errors(v-if="importResults.errors && importResults.errors.length > 0") h5.admin-import__errors-title Ошибки: ul.admin-import__errors-list li.admin-import__error( v-for="error in importResults.errors" :key="error" ) {{ error }} .admin-modal__footer button.admin-modal__btn.admin-modal__btn--secondary( @click="showImportModal = false" :disabled="importing" ) Отмена button.admin-modal__btn.admin-modal__btn--primary( @click="importProducts" :disabled="!selectedFile || importing" ) {{ importing ? 'Импорт...' : 'Начать импорт' }}