2026-02-26 23:09:20 +04:00
|
|
|
|
import { Translations } from './translations';
|
|
|
|
|
|
|
|
|
|
|
|
export const ru: Translations = {
|
|
|
|
|
|
header: {
|
|
|
|
|
|
home: 'Главная',
|
|
|
|
|
|
search: 'Поиск',
|
|
|
|
|
|
about: 'О нас',
|
|
|
|
|
|
contacts: 'Контакты',
|
|
|
|
|
|
searchPlaceholder: 'Искать...',
|
|
|
|
|
|
catalog: 'Каталог',
|
2026-07-09 01:13:54 +04:00
|
|
|
|
wishlist: 'Избранное',
|
|
|
|
|
|
compare: 'Сравнение',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
openMenu: 'Открыть меню',
|
|
|
|
|
|
closeMenu: 'Закрыть меню',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
},
|
|
|
|
|
|
footer: {
|
|
|
|
|
|
description: 'Современный маркетплейс для комфортных покупок',
|
|
|
|
|
|
company: 'Компания',
|
|
|
|
|
|
aboutUs: 'О нас',
|
|
|
|
|
|
contacts: 'Контакты',
|
|
|
|
|
|
requisites: 'Реквизиты',
|
|
|
|
|
|
support: 'Поддержка',
|
|
|
|
|
|
faq: 'FAQ',
|
|
|
|
|
|
delivery: 'Доставка',
|
|
|
|
|
|
guarantee: 'Гарантия',
|
|
|
|
|
|
legal: 'Правовая информация',
|
|
|
|
|
|
offer: 'Оферта',
|
|
|
|
|
|
privacy: 'Конфиденциальность',
|
|
|
|
|
|
returns: 'Возврат',
|
|
|
|
|
|
info: 'Информация',
|
|
|
|
|
|
aboutCompany: 'О компании',
|
|
|
|
|
|
documents: 'Документы',
|
|
|
|
|
|
paymentRules: 'Правила оплаты',
|
|
|
|
|
|
returnPolicy: 'Политика возврата',
|
|
|
|
|
|
publicOffer: 'Публичная оферта',
|
|
|
|
|
|
help: 'Помощь',
|
|
|
|
|
|
payment: 'Оплата',
|
|
|
|
|
|
allRightsReserved: 'Все права защищены.',
|
|
|
|
|
|
},
|
|
|
|
|
|
home: {
|
|
|
|
|
|
welcomeTo: 'Добро пожаловать в {{brand}}',
|
|
|
|
|
|
subtitle: 'Найдите всё, что нужно, в одном месте',
|
|
|
|
|
|
startSearch: 'Начать поиск',
|
|
|
|
|
|
loading: 'Загружаем категории...',
|
|
|
|
|
|
errorTitle: 'Что-то пошло не так',
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
categoriesTitle: 'Категории товаров',
|
|
|
|
|
|
categoriesSubtitle: 'Выберите интересующую категорию',
|
|
|
|
|
|
categoriesEmpty: 'Категории скоро появятся',
|
|
|
|
|
|
categoriesEmptyDesc: 'Мы работаем над наполнением каталога',
|
|
|
|
|
|
dexarHeroTitle: 'Здесь ты найдёшь всё',
|
|
|
|
|
|
dexarHeroSubtitle: 'Тысячи товаров в одном месте',
|
|
|
|
|
|
dexarHeroTagline: 'просто и удобно',
|
|
|
|
|
|
goToCatalog: 'Перейти в каталог',
|
|
|
|
|
|
findProduct: 'Найти товар',
|
|
|
|
|
|
loadingDexar: 'Загрузка категорий...',
|
|
|
|
|
|
catalogTitle: 'Каталог товаров',
|
|
|
|
|
|
emptyCategoriesDexar: 'Категории пока отсутствуют',
|
|
|
|
|
|
categoriesSoonDexar: 'Скоро здесь появятся категории товаров',
|
|
|
|
|
|
itemsCount: '{{count}} товаров',
|
|
|
|
|
|
},
|
|
|
|
|
|
cart: {
|
|
|
|
|
|
title: 'Корзина',
|
|
|
|
|
|
clear: 'Очистить',
|
|
|
|
|
|
empty: 'Корзина пуста',
|
|
|
|
|
|
emptyDesc: 'Добавьте товары, чтобы начать покупки',
|
|
|
|
|
|
goShopping: 'Перейти к покупкам',
|
|
|
|
|
|
total: 'Итого',
|
|
|
|
|
|
items: 'Товары',
|
|
|
|
|
|
deliveryLabel: 'Доставка',
|
2026-06-21 23:13:01 +04:00
|
|
|
|
deliveryMethod: 'Способ доставки',
|
|
|
|
|
|
selectDelivery: 'Выберите способ доставки',
|
|
|
|
|
|
deliveryPlace: 'Место',
|
|
|
|
|
|
deliveryTime: 'Срок доставки',
|
|
|
|
|
|
digitalDelivery: 'Цифровая доставка',
|
|
|
|
|
|
deliveryRequired: 'Выберите доставку для всех товаров с доставкой перед оформлением заказа.',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
toPay: 'К оплате',
|
|
|
|
|
|
agreeWith: 'Я согласен с',
|
|
|
|
|
|
publicOffer: 'публичной офертой',
|
|
|
|
|
|
returnPolicy: 'политикой возврата',
|
|
|
|
|
|
guaranteeTerms: 'условиями гарантии',
|
|
|
|
|
|
privacyPolicy: 'политикой конфиденциальности',
|
|
|
|
|
|
and: 'и',
|
|
|
|
|
|
checkout: 'Оформить заказ',
|
2026-06-29 00:06:18 +04:00
|
|
|
|
payViaQr: 'Оплатить через QR',
|
|
|
|
|
|
payViaCard: 'Оплатить картой',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
close: 'Закрыть',
|
|
|
|
|
|
creatingPayment: 'Создание платежа...',
|
|
|
|
|
|
waitFewSeconds: 'Подождите несколько секунд',
|
|
|
|
|
|
scanQr: 'Сканируйте QR-код для оплаты',
|
|
|
|
|
|
amountToPay: 'Сумма к оплате:',
|
|
|
|
|
|
waitingPayment: 'Ожидание оплаты...',
|
|
|
|
|
|
copied: '✓ Скопировано',
|
|
|
|
|
|
copyLink: 'Скопировать ссылку',
|
|
|
|
|
|
openNewTab: 'Открыть в новой вкладке',
|
|
|
|
|
|
paymentSuccess: 'Поздравляем! Оплата прошла успешно!',
|
|
|
|
|
|
paymentSuccessDesc: 'Введите ваши контактные данные, и мы отправим вам покупку в течение нескольких минут',
|
|
|
|
|
|
sending: 'Отправка...',
|
|
|
|
|
|
send: 'Отправить',
|
2026-06-02 00:57:36 +04:00
|
|
|
|
paymentError: 'Не удалось создать платеж',
|
|
|
|
|
|
paymentErrorDesc: 'Сейчас не получилось подготовить QR-код для оплаты. Попробуйте еще раз через минуту.',
|
|
|
|
|
|
retryPayment: 'Попробовать снова',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
paymentTimeout: 'Время ожидания истекло',
|
|
|
|
|
|
paymentTimeoutDesc: 'Мы не получили подтверждение оплаты в течение 3 минут.',
|
|
|
|
|
|
autoClose: 'Окно закроется автоматически...',
|
|
|
|
|
|
confirmClear: 'Вы уверены, что хотите очистить корзину?',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
removeItem: 'Удалить товар',
|
|
|
|
|
|
paymentQrAlt: 'QR-код для оплаты',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
acceptTerms: 'Пожалуйста, примите условия оферты, политику возврата и возврата для подтверждения оформления заказа.',
|
|
|
|
|
|
copyError: 'Ошибка копирования:',
|
|
|
|
|
|
emailSuccess: 'Email успешно отправлен! Проверьте свою почту.',
|
|
|
|
|
|
emailError: 'Произошла ошибка при отправке email. Пожалуйста, попробуйте снова.',
|
|
|
|
|
|
phoneRequired: 'Номер телефона обязателен',
|
|
|
|
|
|
phoneMoreDigits: 'Введите ещё {{count}} цифр',
|
|
|
|
|
|
phoneTooMany: 'Слишком много цифр',
|
|
|
|
|
|
emailRequired: 'Email обязателен',
|
|
|
|
|
|
emailTooShort: 'Email слишком короткий (минимум 5 символов)',
|
|
|
|
|
|
emailTooLong: 'Email слишком длинный (максимум 100 символов)',
|
|
|
|
|
|
emailNeedsAt: 'Email должен содержать @',
|
|
|
|
|
|
emailNeedsDomain: 'Email должен содержать домен (.com, .ru и т.д.)',
|
|
|
|
|
|
emailInvalid: 'Некорректный формат email',
|
2026-03-24 00:09:11 +04:00
|
|
|
|
loginRequired: 'Войдите для оформления',
|
|
|
|
|
|
loginRequiredDesc: 'Для оформления заказа войдите через Telegram',
|
|
|
|
|
|
loginWithTelegram: 'Войти через Telegram',
|
|
|
|
|
|
orScanQr: 'Или отсканируйте QR-код',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
},
|
|
|
|
|
|
search: {
|
|
|
|
|
|
title: 'Поиск товаров',
|
|
|
|
|
|
placeholder: 'Введите название товара...',
|
2026-07-10 13:25:31 +04:00
|
|
|
|
searchBarAria: 'Поисковая строка',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
resultsCount: 'Найдено товаров:',
|
|
|
|
|
|
searching: 'Поиск...',
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
noResults: 'Ничего не найдено',
|
|
|
|
|
|
noResultsFor: 'По запросу "{{query}}" товары не найдены',
|
|
|
|
|
|
noResultsHint: 'Попробуйте изменить запрос или используйте другие ключевые слова',
|
2026-07-10 13:25:31 +04:00
|
|
|
|
emptyResultsAria: 'Пустые результаты поиска',
|
|
|
|
|
|
popularCategories: 'Популярные категории',
|
|
|
|
|
|
recommendedProducts: 'Рекомендуемые товары',
|
|
|
|
|
|
aiSuggestionHint: 'AI-подсказка (в будущем)',
|
|
|
|
|
|
suggestionType: {
|
|
|
|
|
|
product: 'Товар',
|
|
|
|
|
|
category: 'Категория',
|
|
|
|
|
|
brand: 'Бренд',
|
|
|
|
|
|
collection: 'Подборка',
|
|
|
|
|
|
seller: 'Продавец',
|
|
|
|
|
|
'static-page': 'Страница',
|
|
|
|
|
|
ai: 'AI',
|
|
|
|
|
|
},
|
2026-02-26 23:09:20 +04:00
|
|
|
|
addToCart: 'В корзину',
|
|
|
|
|
|
loadingMore: 'Загрузка...',
|
|
|
|
|
|
allLoaded: 'Все результаты загружены',
|
|
|
|
|
|
emptyState: 'Введите запрос для поиска товаров',
|
2026-07-05 01:10:56 +04:00
|
|
|
|
minLength: 'Введите минимум {{count}} символа для поиска',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
of: 'из',
|
|
|
|
|
|
},
|
|
|
|
|
|
category: {
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
addToCart: 'В корзину',
|
|
|
|
|
|
loadingMore: 'Загрузка...',
|
|
|
|
|
|
allLoaded: 'Все товары загружены',
|
|
|
|
|
|
emptyTitle: 'Упс! Здесь пока пусто',
|
|
|
|
|
|
emptyDesc: 'В этой категории ещё нет товаров, но скоро они появятся',
|
|
|
|
|
|
goHome: 'На главную',
|
|
|
|
|
|
loading: 'Загрузка товаров...',
|
|
|
|
|
|
},
|
2026-07-05 01:36:21 +04:00
|
|
|
|
catalog: {
|
|
|
|
|
|
title: 'Каталог',
|
|
|
|
|
|
breadcrumb: 'Навигация по каталогу',
|
|
|
|
|
|
allCategories: 'Все категории',
|
|
|
|
|
|
products: 'Товары',
|
|
|
|
|
|
loading: 'Загрузка каталога...',
|
|
|
|
|
|
loadingProducts: 'Загрузка товаров...',
|
|
|
|
|
|
errorTitle: 'Каталог недоступен',
|
|
|
|
|
|
error: 'Не удалось загрузить каталог. Попробуйте позже.',
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
categoryHint: 'Выберите категорию, чтобы продолжить',
|
|
|
|
|
|
productHint: 'Товары в выбранной категории',
|
|
|
|
|
|
emptyTitle: 'Здесь пока пусто',
|
|
|
|
|
|
emptyCategories: 'В этом разделе пока нет дочерних категорий.',
|
|
|
|
|
|
emptyProducts: 'В этой категории пока нет товаров.',
|
|
|
|
|
|
addToCart: 'В корзину',
|
|
|
|
|
|
categoriesCount: '{{count}} категорий',
|
|
|
|
|
|
productsCount: '{{count}} товаров',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
entriesCount: '{{count}} позиций',
|
|
|
|
|
|
categoryBannerPlaceholder: 'Баннер категории подготовлен для медиа и описания из backend.',
|
|
|
|
|
|
navigationPlaceholder: 'Макет навигации подготовлен для конфигурации из backend/bootstrap.',
|
|
|
|
|
|
removeSavedSearch: 'Удалить сохраненный поиск',
|
|
|
|
|
|
resetFilters: 'Сбросить',
|
|
|
|
|
|
filtersTitle: 'Фильтры',
|
2026-07-09 02:57:48 +04:00
|
|
|
|
from: 'От',
|
|
|
|
|
|
to: 'До',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
minValue: 'От {{value}}',
|
|
|
|
|
|
maxValue: 'До {{value}}',
|
|
|
|
|
|
enabled: 'Включено',
|
|
|
|
|
|
searchPlaceholder: 'Поиск товаров, брендов и категорий',
|
|
|
|
|
|
searchSubmit: 'Найти',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
clearSearch: 'Очистить',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
suggestionsTitle: 'Подсказки',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
popularSearchesTitle: 'Популярные запросы',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
recentSearchesTitle: 'Недавние запросы',
|
|
|
|
|
|
searchHistoryTitle: 'История поиска',
|
|
|
|
|
|
clearHistory: 'Очистить',
|
|
|
|
|
|
searchNoResultsHint: 'Ничего не найдено. Попробуйте более общий запрос.',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
searchProductsFound: 'Найдено товаров: {{total}}',
|
|
|
|
|
|
searchResultsSummary: '{{total}} результатов по запросу "{{query}}"',
|
2026-07-10 15:55:38 +04:00
|
|
|
|
loadMore: 'Показать еще',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
sortBy: 'Сортировать по',
|
2026-07-09 01:46:32 +04:00
|
|
|
|
sortRelevance: 'Рекомендуемые',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
sortLatest: 'Новизне',
|
|
|
|
|
|
sortPriceAsc: 'Цене: по возрастанию',
|
|
|
|
|
|
sortPriceDesc: 'Цене: по убыванию',
|
|
|
|
|
|
sortRating: 'Рейтингу',
|
|
|
|
|
|
sortPopular: 'Популярности',
|
|
|
|
|
|
sortDiscount: 'Скидке',
|
|
|
|
|
|
layoutGrid: 'Сетка',
|
|
|
|
|
|
layoutLargeGrid: 'Крупная сетка',
|
|
|
|
|
|
layoutCompactGrid: 'Компактная сетка',
|
2026-07-10 15:55:38 +04:00
|
|
|
|
layoutGrid2: '2 колонки',
|
|
|
|
|
|
layoutGrid3: '3 колонки',
|
|
|
|
|
|
layoutGrid4: '4 колонки',
|
|
|
|
|
|
layoutCompact: 'Компактно',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
layoutList: 'Список',
|
|
|
|
|
|
noResults: 'Нет результатов',
|
|
|
|
|
|
itemsCount: '{{count}} товаров',
|
|
|
|
|
|
emptyResultsTitle: 'Результаты не найдены',
|
|
|
|
|
|
emptyResultsDescription: 'Попробуйте изменить фильтры, сортировку или поисковый запрос.',
|
|
|
|
|
|
previousPage: 'Назад',
|
|
|
|
|
|
nextPage: 'Вперед',
|
|
|
|
|
|
pageOf: 'Страница {{page}} / {{total}}',
|
2026-07-09 01:46:32 +04:00
|
|
|
|
emptyCategoryTitle: 'В этой категории пока нет товаров',
|
|
|
|
|
|
emptyCategoryMessage: 'Попробуйте перейти в родительские категории или вернуться в общий каталог.',
|
2026-07-10 15:55:38 +04:00
|
|
|
|
goToParentCategory: 'Перейти в родительскую категорию',
|
2026-07-09 01:46:32 +04:00
|
|
|
|
browseCategories: 'Смотреть категории',
|
2026-07-10 15:55:38 +04:00
|
|
|
|
offlineTitle: 'Нет подключения',
|
|
|
|
|
|
offlineMessage: 'Подключитесь к сети, чтобы продолжить просмотр каталога.',
|
2026-07-09 01:46:32 +04:00
|
|
|
|
noFilterMatchTitle: 'Нет товаров, соответствующих выбранным фильтрам.',
|
|
|
|
|
|
noFilterMatchMessage: 'Попробуйте расширить диапазон цены, атрибуты или бренды.',
|
|
|
|
|
|
clearFilters: 'Очистить фильтры',
|
|
|
|
|
|
openFilters: 'Открыть фильтры',
|
|
|
|
|
|
applyFilters: 'Применить',
|
|
|
|
|
|
close: 'Закрыть',
|
|
|
|
|
|
filtersDrawerAria: 'Панель фильтров',
|
|
|
|
|
|
sortSheetAria: 'Параметры сортировки',
|
|
|
|
|
|
mobileToolbarAria: 'Мобильная панель каталога',
|
|
|
|
|
|
gridCycle: 'Сетка',
|
|
|
|
|
|
filtersPanelAria: 'Фильтры каталога',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
filterPrice: 'Цена',
|
|
|
|
|
|
filterAvailability: 'Наличие',
|
|
|
|
|
|
filterInStock: 'В наличии',
|
|
|
|
|
|
filterLowStock: 'Мало в наличии',
|
|
|
|
|
|
filterOutOfStock: 'Нет в наличии',
|
|
|
|
|
|
filterRating: 'Рейтинг',
|
|
|
|
|
|
filterStars: '{{count}} звезд',
|
|
|
|
|
|
filterBrand: 'Бренд',
|
|
|
|
|
|
filterCategory: 'Категория',
|
|
|
|
|
|
filterCategoryValue: 'Категория {{value}}',
|
|
|
|
|
|
filterSubcategory: 'Подкатегория',
|
|
|
|
|
|
filterDiscount: 'Скидка',
|
|
|
|
|
|
filterNew: 'Новинки',
|
|
|
|
|
|
filterColor: 'Цвет',
|
|
|
|
|
|
filterSize: 'Размер',
|
|
|
|
|
|
filterAttributes: 'Атрибуты',
|
|
|
|
|
|
},
|
|
|
|
|
|
productDetails: {
|
|
|
|
|
|
loading: 'Загрузка товара...',
|
|
|
|
|
|
errorTitle: 'Товар недоступен',
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
missingTitle: 'Товар не найден',
|
|
|
|
|
|
missingDescription: 'Этот товар не существует или больше недоступен.',
|
|
|
|
|
|
backToCatalog: 'Вернуться в каталог',
|
|
|
|
|
|
tabsAria: 'Вкладки товара',
|
|
|
|
|
|
mediaAria: 'Медиа товара',
|
|
|
|
|
|
ratingStarsAria: 'Рейтинг в звездах',
|
|
|
|
|
|
selectRatingAria: 'Выберите оценку',
|
|
|
|
|
|
reviewsEmpty: 'Пока нет отзывов.',
|
|
|
|
|
|
questionsEmpty: 'Пока нет вопросов.',
|
|
|
|
|
|
askQuestion: 'Задать вопрос',
|
|
|
|
|
|
hideQuestionForm: 'Скрыть форму вопроса',
|
|
|
|
|
|
questionFormTitle: 'Задать вопрос',
|
|
|
|
|
|
questionFormPlaceholder: 'Спросите о размере, доставке, совместимости или использовании',
|
|
|
|
|
|
questionFormAnonymous: 'Задать анонимно',
|
|
|
|
|
|
submitQuestion: 'Отправить вопрос',
|
|
|
|
|
|
reviewFormTitle: 'Оставить отзыв',
|
|
|
|
|
|
reviewRatingLabel: 'Оценка',
|
|
|
|
|
|
reviewTitleLabel: 'Заголовок',
|
|
|
|
|
|
reviewTitlePlaceholder: 'Короткий заголовок',
|
|
|
|
|
|
reviewTextLabel: 'Отзыв',
|
|
|
|
|
|
reviewTextPlaceholder: 'Опишите ваш опыт использования',
|
|
|
|
|
|
reviewAnonymous: 'Отправить анонимно',
|
|
|
|
|
|
reviewUploadPlaceholder: 'Загрузка фото запланирована в следующем спринте.',
|
2026-07-10 13:10:35 +04:00
|
|
|
|
reviewRatingRequired: 'Выберите оценку.',
|
|
|
|
|
|
reviewTextRequired: 'Добавьте текст отзыва.',
|
|
|
|
|
|
reviewSuccess: 'Отзыв успешно отправлен.',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
submitReview: 'Отправить отзыв',
|
|
|
|
|
|
submitting: 'Отправка...',
|
2026-07-10 13:10:35 +04:00
|
|
|
|
loadMore: 'Показать еще',
|
|
|
|
|
|
showingOf: 'Показано {{shown}} из {{total}}',
|
|
|
|
|
|
questionsSubmissionFuture: 'Отправку вопросов можно включить позже без изменения компонента.',
|
|
|
|
|
|
specificationsGeneral: 'Общие',
|
|
|
|
|
|
actionsAria: 'Действия с товаром',
|
|
|
|
|
|
buyNow: 'Купить сейчас',
|
|
|
|
|
|
wishlist: 'В избранное',
|
|
|
|
|
|
compare: 'Сравнить',
|
|
|
|
|
|
share: 'Поделиться',
|
|
|
|
|
|
notifyMe: 'Сообщить о наличии',
|
|
|
|
|
|
zoom: 'Увеличить',
|
|
|
|
|
|
fullscreen: 'Полный экран',
|
|
|
|
|
|
pdfDocument: 'PDF документ товара',
|
|
|
|
|
|
manualDocument: 'Инструкция товара',
|
|
|
|
|
|
warrantyDocument: 'Гарантийный документ',
|
|
|
|
|
|
openDocument: 'Открыть документ',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
specificationsEmpty: 'Характеристики пока не указаны.',
|
|
|
|
|
|
warrantyTitle: 'Гарантия и возврат',
|
|
|
|
|
|
warrantyItem1: 'Условия гарантии определяются продавцом и местным законодательством.',
|
|
|
|
|
|
warrantyItem2: 'Возможность возврата зависит от состояния и категории товара.',
|
|
|
|
|
|
warrantyItem3: 'Подробная инструкция по возврату доступна после покупки.',
|
|
|
|
|
|
verifiedPurchase: 'Подтвержденная покупка',
|
|
|
|
|
|
officialSeller: 'Официальный продавец',
|
|
|
|
|
|
acceptedAnswer: 'Принятый ответ',
|
|
|
|
|
|
like: 'Нравится',
|
|
|
|
|
|
dislike: 'Не нравится',
|
|
|
|
|
|
reviewsCountLabel: '{{count}} отзывов',
|
|
|
|
|
|
previous: 'Назад',
|
|
|
|
|
|
next: 'Вперед',
|
|
|
|
|
|
pageOf: 'Страница {{page}} / {{total}}',
|
2026-07-05 01:36:21 +04:00
|
|
|
|
},
|
2026-02-26 23:09:20 +04:00
|
|
|
|
subcategories: {
|
|
|
|
|
|
loading: 'Загрузка подкатегорий...',
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
emptyTitle: 'Упс! Подкатегорий пока нет',
|
|
|
|
|
|
emptyDesc: 'В этом разделе ещё нет подкатегорий, но скоро они появятся',
|
|
|
|
|
|
goHome: 'На главную',
|
2026-03-24 00:09:11 +04:00
|
|
|
|
itemsInCategory: 'Товары в этой категории',
|
2026-07-05 01:09:55 +04:00
|
|
|
|
childrenCount: '{{count}} категорий',
|
|
|
|
|
|
productsCount: '{{count}} товаров',
|
|
|
|
|
|
includesProducts: 'Есть товары',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
},
|
|
|
|
|
|
itemDetail: {
|
|
|
|
|
|
loading: 'Загрузка...',
|
|
|
|
|
|
loadingDexar: 'Загрузка товара...',
|
|
|
|
|
|
back: 'Вернуться',
|
|
|
|
|
|
backHome: 'Вернуться на главную',
|
|
|
|
|
|
noImage: 'Нет изображения',
|
|
|
|
|
|
stock: 'Наличие:',
|
|
|
|
|
|
inStock: 'В наличии',
|
|
|
|
|
|
lowStock: 'Осталось немного',
|
|
|
|
|
|
lastItems: 'Последние штуки',
|
|
|
|
|
|
mediumStock: 'Заканчивается',
|
|
|
|
|
|
addToCart: 'Добавить в корзину',
|
|
|
|
|
|
description: 'Описание',
|
2026-02-28 16:13:14 +04:00
|
|
|
|
specifications: 'Характеристики',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
reviews: 'Отзывы',
|
|
|
|
|
|
yourReview: 'Ваш отзыв',
|
|
|
|
|
|
leaveReview: 'Оставить отзыв',
|
|
|
|
|
|
rating: 'Оценка:',
|
|
|
|
|
|
reviewPlaceholder: 'Поделитесь своими впечатлениями о товаре...',
|
|
|
|
|
|
reviewPlaceholderDexar: 'Поделитесь впечатлениями о товаре...',
|
|
|
|
|
|
anonymous: 'Анонимно',
|
|
|
|
|
|
submitting: 'Отправка...',
|
|
|
|
|
|
submit: 'Отправить',
|
|
|
|
|
|
reviewSuccess: 'Спасибо за ваш отзыв!',
|
|
|
|
|
|
reviewError: 'Ошибка отправки. Попробуйте позже.',
|
|
|
|
|
|
defaultUser: 'Пользователь',
|
|
|
|
|
|
defaultUserDexar: 'Аноним',
|
|
|
|
|
|
noReviews: 'Пока нет отзывов. Станьте первым!',
|
|
|
|
|
|
qna: 'Вопросы и ответы',
|
|
|
|
|
|
photo: 'Фото',
|
|
|
|
|
|
reviewsCount: 'отзывов',
|
|
|
|
|
|
today: 'Сегодня',
|
|
|
|
|
|
yesterday: 'Вчера',
|
|
|
|
|
|
daysAgo: 'дн. назад',
|
|
|
|
|
|
weeksAgo: 'нед. назад',
|
2026-03-24 00:09:11 +04:00
|
|
|
|
colour: 'Цвет',
|
|
|
|
|
|
size: 'Размер',
|
2026-07-05 01:07:53 +04:00
|
|
|
|
relatedProducts: 'Похожие товары',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
},
|
|
|
|
|
|
app: {
|
|
|
|
|
|
connecting: 'Подключение к серверу...',
|
|
|
|
|
|
serverUnavailable: 'Сервер недоступен',
|
|
|
|
|
|
serverError: 'Не удалось подключиться к серверу. Проверьте подключение к интернету.',
|
|
|
|
|
|
retryConnection: 'Повторить попытку',
|
|
|
|
|
|
pageTitle: 'Маркетплейс товаров и услуг',
|
|
|
|
|
|
},
|
2026-07-09 02:29:12 +04:00
|
|
|
|
platform: {
|
|
|
|
|
|
loadingPage: 'Загрузка страницы платформы...',
|
|
|
|
|
|
emptyConfig: 'Конфигурация страницы не найдена.',
|
|
|
|
|
|
},
|
|
|
|
|
|
backoffice: {
|
|
|
|
|
|
title: 'Песочница Backoffice',
|
|
|
|
|
|
subtitle: 'Домен управления бизнес-данными (mock для платформенного фундамента).',
|
|
|
|
|
|
loading: 'Загрузка данных backoffice...',
|
|
|
|
|
|
products: 'Товары',
|
|
|
|
|
|
categories: 'Категории',
|
|
|
|
|
|
otherDomains: 'Другие домены',
|
|
|
|
|
|
sku: 'SKU',
|
|
|
|
|
|
titleColumn: 'Название',
|
|
|
|
|
|
price: 'Цена',
|
|
|
|
|
|
status: 'Статус',
|
|
|
|
|
|
itemsCount: 'шт.',
|
|
|
|
|
|
orders: 'Заказы',
|
|
|
|
|
|
customers: 'Клиенты',
|
|
|
|
|
|
inventory: 'Склад',
|
|
|
|
|
|
media: 'Медиа',
|
|
|
|
|
|
settings: 'Настройки',
|
|
|
|
|
|
notAvailable: 'н/д',
|
|
|
|
|
|
},
|
|
|
|
|
|
builder: {
|
2026-07-10 13:43:53 +04:00
|
|
|
|
title: 'Редактор проекта маркетплейса',
|
|
|
|
|
|
subtitle: 'Поверхность редактирования только bootstrap-конфигурации.',
|
|
|
|
|
|
general: 'Общие',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
branding: 'Брендинг',
|
2026-07-10 13:43:53 +04:00
|
|
|
|
theme: 'Тема',
|
|
|
|
|
|
header: 'Хедер',
|
|
|
|
|
|
footer: 'Футер',
|
|
|
|
|
|
homepage: 'Главная страница',
|
|
|
|
|
|
widgets: 'Виджеты',
|
2026-07-10 13:52:01 +04:00
|
|
|
|
staticPages: 'Статические страницы',
|
2026-07-10 13:43:53 +04:00
|
|
|
|
marketplaceFeatures: 'Функции маркетплейса',
|
|
|
|
|
|
preview: 'Превью',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
brandName: 'Название бренда',
|
2026-07-10 13:43:53 +04:00
|
|
|
|
marketplaceName: 'Название маркетплейса',
|
|
|
|
|
|
domain: 'Домен',
|
|
|
|
|
|
descriptionLabel: 'Описание',
|
|
|
|
|
|
defaultLanguage: 'Язык по умолчанию',
|
|
|
|
|
|
supportedLanguages: 'Поддерживаемые языки',
|
|
|
|
|
|
logo: 'Логотип',
|
|
|
|
|
|
smallLogo: 'Малый логотип',
|
|
|
|
|
|
favicon: 'Favicon',
|
2026-07-17 15:22:45 +04:00
|
|
|
|
socialImage: 'Изображение для соцсетей',
|
|
|
|
|
|
gallery: 'Галерея',
|
|
|
|
|
|
addGalleryImage: 'Добавить изображение',
|
2026-07-17 15:29:55 +04:00
|
|
|
|
headerLayout: 'Расположение шапки',
|
|
|
|
|
|
headerLayoutDefault: 'По умолчанию',
|
|
|
|
|
|
headerLayoutCentered: 'По центру',
|
|
|
|
|
|
headerSticky: 'Липкая шапка',
|
2026-07-10 13:43:53 +04:00
|
|
|
|
marketplaceTitle: 'Заголовок маркетплейса',
|
|
|
|
|
|
primaryColor: 'Основной цвет',
|
|
|
|
|
|
secondaryColor: 'Вторичный цвет',
|
|
|
|
|
|
backgroundColor: 'Фон',
|
|
|
|
|
|
surfaceColor: 'Поверхность',
|
|
|
|
|
|
textColor: 'Текст',
|
|
|
|
|
|
successColor: 'Success',
|
|
|
|
|
|
warningColor: 'Warning',
|
|
|
|
|
|
dangerColor: 'Danger',
|
|
|
|
|
|
showLogo: 'Логотип',
|
|
|
|
|
|
showSearch: 'Поиск',
|
|
|
|
|
|
showCategories: 'Категории',
|
|
|
|
|
|
showLanguages: 'Языки',
|
|
|
|
|
|
showCart: 'Корзина',
|
|
|
|
|
|
showProfile: 'Профиль',
|
|
|
|
|
|
showWishlist: 'Избранное',
|
|
|
|
|
|
showCompare: 'Сравнение',
|
|
|
|
|
|
showRegion: 'Регион',
|
|
|
|
|
|
companyName: 'Информация о компании',
|
|
|
|
|
|
address: 'Адрес',
|
|
|
|
|
|
phone: 'Телефон',
|
|
|
|
|
|
email: 'Email',
|
|
|
|
|
|
copyright: 'Копирайт',
|
|
|
|
|
|
paymentIcons: 'Иконки оплаты',
|
|
|
|
|
|
socialLinks: 'Социальные ссылки',
|
2026-07-16 02:06:26 +04:00
|
|
|
|
footerLogo: 'Логотип в футере',
|
|
|
|
|
|
addPaymentIcon: 'Добавить иконку оплаты',
|
|
|
|
|
|
removePaymentIcon: 'Удалить',
|
|
|
|
|
|
iconAltLabel: 'Подпись иконки',
|
|
|
|
|
|
addSocialLink: 'Добавить соцсеть',
|
|
|
|
|
|
removeSocialLink: 'Удалить',
|
|
|
|
|
|
socialLinkLabel: 'Платформа',
|
|
|
|
|
|
socialLinkUrl: 'URL',
|
|
|
|
|
|
invalidUrl: 'Введите корректный URL, начинающийся с http:// или https://.',
|
2026-07-10 13:52:01 +04:00
|
|
|
|
createPage: 'Создать страницу',
|
|
|
|
|
|
deletePage: 'Удалить страницу',
|
|
|
|
|
|
pageId: 'ID страницы',
|
|
|
|
|
|
slug: 'Slug',
|
|
|
|
|
|
iconLabel: 'Иконка',
|
|
|
|
|
|
showInFooter: 'Показывать в футере',
|
|
|
|
|
|
showInHeader: 'Показывать в хедере',
|
|
|
|
|
|
showInSitemap: 'Показывать в sitemap',
|
|
|
|
|
|
requiresAuthentication: 'Требует авторизацию',
|
|
|
|
|
|
footerGroup: 'Группа футера',
|
|
|
|
|
|
orderLabel: 'Порядок',
|
|
|
|
|
|
translationTitle: 'Заголовок перевода',
|
|
|
|
|
|
htmlPreview: 'HTML',
|
2026-07-15 04:11:18 +04:00
|
|
|
|
seoSection: 'SEO',
|
|
|
|
|
|
seoTitle: 'SEO заголовок',
|
|
|
|
|
|
seoDescription: 'SEO описание',
|
|
|
|
|
|
seoKeywords: 'Ключевые слова',
|
|
|
|
|
|
seoCanonical: 'Canonical URL',
|
|
|
|
|
|
seoOgTitle: 'OG заголовок',
|
|
|
|
|
|
seoOgDescription: 'OG описание',
|
|
|
|
|
|
seoOgImage: 'OG изображение',
|
2026-07-10 13:43:53 +04:00
|
|
|
|
visible: 'Видимость',
|
|
|
|
|
|
layoutLabel: 'Layout',
|
|
|
|
|
|
columns: 'Колонки',
|
|
|
|
|
|
height: 'Высота',
|
|
|
|
|
|
overlay: 'Overlay',
|
|
|
|
|
|
autoplay: 'Autoplay',
|
|
|
|
|
|
cardsPerRow: 'Карточек в ряд',
|
|
|
|
|
|
filtersLabel: 'Фильтры',
|
|
|
|
|
|
showBadges: 'Показывать badges',
|
|
|
|
|
|
showRating: 'Показывать рейтинг',
|
|
|
|
|
|
showPrice: 'Показывать цену',
|
|
|
|
|
|
widgetJson: 'JSON виджета',
|
|
|
|
|
|
reviews: 'Отзывы',
|
|
|
|
|
|
questions: 'Вопросы',
|
|
|
|
|
|
comments: 'Комментарии',
|
|
|
|
|
|
recommendations: 'Рекомендации',
|
|
|
|
|
|
recentlyViewed: 'Недавно просмотренные',
|
|
|
|
|
|
searchSuggestions: 'Поисковые подсказки',
|
|
|
|
|
|
searchHistory: 'История поиска',
|
|
|
|
|
|
livePreview: 'Живое превью',
|
2026-07-17 09:00:47 +04:00
|
|
|
|
previewChangesTitle: 'Изменения с последней публикации',
|
|
|
|
|
|
previewNoIssues: 'Нет проблем валидации.',
|
|
|
|
|
|
previewNoChanges: 'Нет изменений с последней публикации.',
|
|
|
|
|
|
previewChangeField: 'Поле',
|
|
|
|
|
|
previewChangeBefore: 'До',
|
|
|
|
|
|
previewChangeAfter: 'После',
|
2026-07-13 08:10:00 +04:00
|
|
|
|
languagesTab: 'Языки',
|
|
|
|
|
|
addLanguage: 'Добавить язык',
|
|
|
|
|
|
removeLanguage: 'Удалить',
|
|
|
|
|
|
setDefaultLanguage: 'Сделать языком по умолчанию',
|
|
|
|
|
|
defaultLanguageLabel: 'По умолчанию',
|
2026-07-13 08:57:42 +04:00
|
|
|
|
navigationTab: 'Навигация',
|
|
|
|
|
|
navigationHeader: 'Навигация в шапке',
|
|
|
|
|
|
navigationFooter: 'Навигация в подвале',
|
|
|
|
|
|
navigationFooterGrouped: 'Навигация подвала сгруппирована по колонкам и пока недоступна для редактирования здесь — используйте вкладку "Подвал".',
|
|
|
|
|
|
addLink: 'Добавить ссылку',
|
2026-07-17 10:18:08 +04:00
|
|
|
|
insertPageLink: 'Вставить ссылку на страницу',
|
|
|
|
|
|
linkedToPage: 'Связано со страницей',
|
2026-07-13 08:57:42 +04:00
|
|
|
|
removeLink: 'Удалить',
|
|
|
|
|
|
linkLabel: 'Название',
|
|
|
|
|
|
linkUrl: 'URL',
|
2026-07-10 13:43:53 +04:00
|
|
|
|
exportBootstrap: 'Экспорт bootstrap',
|
|
|
|
|
|
importBootstrap: 'Импорт bootstrap',
|
|
|
|
|
|
exportedBootstrap: 'Экспортированный bootstrap',
|
|
|
|
|
|
importSource: 'Источник импорта',
|
|
|
|
|
|
importError: 'Импорт не удался. Некорректный JSON bootstrap.',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
featureFlags: 'Фичи-флаги',
|
2026-07-13 10:51:05 +04:00
|
|
|
|
validationMissingLogo: 'В брендинге отсутствует логотип.',
|
|
|
|
|
|
validationNoLanguages: 'Не настроены языки.',
|
2026-07-17 19:00:17 +04:00
|
|
|
|
validationDefaultLocaleNotSupported: 'Язык по умолчанию отсутствует в списке поддерживаемых языков.',
|
2026-07-13 10:51:05 +04:00
|
|
|
|
validationInvalidUrl: 'Некорректный URL маркетплейса.',
|
|
|
|
|
|
validationDuplicateSlugs: 'Две или более статические страницы имеют одинаковый slug.',
|
|
|
|
|
|
validationEmptyHomepage: 'На главной странице нет секций.',
|
|
|
|
|
|
validationMissingWidget: 'В секции главной страницы есть виджет без типа.',
|
|
|
|
|
|
validationDuplicateNavLinks: 'Две или более ссылки в навигации шапки дублируются.',
|
|
|
|
|
|
validationInvalidColors: 'Один или несколько цветов темы указаны некорректно.',
|
2026-07-14 12:21:33 +04:00
|
|
|
|
validationMissingTranslations: 'Часть контента не переведена на один из поддерживаемых языков.',
|
|
|
|
|
|
validationInvalidLayouts: 'Один или несколько макетов ссылаются на неизвестный тип раскладки.',
|
feat(project-editor): centralize schema-driven validation
Milestone 2 of the Configuration Engine sprint.
- Add schema/validators/primitives: pure isValidHexColor/HttpUrl/Email,
validateJson, validateCss, extractStyleBlocks, normalizeRoute. One function
per concern, no duplicated validator logic.
- Refactor ProjectValidator to compose the primitives and tag every issue with
section + fieldKey + severity ('error' blocks publish, 'warning' advisory).
Preserves all existing codes/messages; adds duplicate-routes, invalid-css,
invalid-widget-config checks.
- Facade: issuesByField, issuesBySection, blockingIssues, hasBlockingIssues;
publish() now gates on severity==='error' instead of any issue.
- i18n: add validationInvalidJson/Css/DuplicateRoutes/InvalidWidgetConfig to
the Translations interface + en/ru/hy.
- Specs: primitives + ProjectValidator (25 passing total).
Gate: tsc --noEmit, npm test (25/25), arch:check, build all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 01:58:36 +04:00
|
|
|
|
validationInvalidJson: 'Конфигурация не является допустимым JSON.',
|
|
|
|
|
|
validationInvalidCss: 'Статическая страница содержит недопустимый CSS.',
|
|
|
|
|
|
validationDuplicateRoutes: 'Две или более страницы используют один и тот же маршрут.',
|
|
|
|
|
|
validationInvalidWidgetConfig: 'У виджета отсутствует обязательное поле (id, type, version или props).',
|
2026-07-17 16:57:43 +04:00
|
|
|
|
validationInvalidContactEmail: 'Контактный email компании указан некорректно.',
|
|
|
|
|
|
validationInvalidSocialLinkUrl: 'У одной или нескольких социальных ссылок в футере некорректный URL.',
|
|
|
|
|
|
validationIncompletePaymentIcon: 'У иконки оплаты в футере отсутствует изображение или альтернативный текст.',
|
2026-07-17 02:13:34 +04:00
|
|
|
|
undo: 'Отменить',
|
|
|
|
|
|
redo: 'Повторить',
|
2026-07-13 15:00:03 +04:00
|
|
|
|
statusDraft: 'Черновик',
|
|
|
|
|
|
statusPublished: 'Опубликовано',
|
|
|
|
|
|
unsavedChanges: 'Есть несохранённые изменения',
|
|
|
|
|
|
save: 'Сохранить',
|
|
|
|
|
|
publish: 'Опубликовать',
|
2026-07-13 15:57:54 +04:00
|
|
|
|
confirmLeaveUnsaved: 'Есть несохранённые изменения. Всё равно уйти?',
|
|
|
|
|
|
promptLinkUrl: 'URL',
|
|
|
|
|
|
promptImageUrl: 'URL изображения',
|
2026-07-17 10:00:33 +04:00
|
|
|
|
promptEmbedUrl: 'URL для встраивания',
|
|
|
|
|
|
htmlEditorInvalidHtml: 'В этом HTML есть незакрытый или несовпадающий тег. Исправьте перед возвратом к визуальному редактору.',
|
2026-07-13 15:57:54 +04:00
|
|
|
|
htmlEditorCode: 'Код',
|
|
|
|
|
|
htmlEditorPreview: 'Предпросмотр',
|
2026-07-14 09:50:03 +04:00
|
|
|
|
lastSaved: 'Последнее сохранение',
|
|
|
|
|
|
draftRestored: 'Локальный черновик восстановлен из предыдущей сессии.',
|
|
|
|
|
|
dismiss: 'Скрыть',
|
|
|
|
|
|
resetDraft: 'Сбросить черновик',
|
|
|
|
|
|
resetSection: 'Сбросить секцию',
|
|
|
|
|
|
confirmResetDraft: 'Это отменит все неопубликованные изменения и восстановит последнюю опубликованную конфигурацию. Продолжить?',
|
|
|
|
|
|
confirmResetSection: 'Это отменит неопубликованные изменения только в этой секции. Продолжить?',
|
2026-07-14 16:05:09 +04:00
|
|
|
|
marketplaceNameDesc: 'Название, которое видят покупатели на витрине и во вкладке браузера.',
|
|
|
|
|
|
domainDesc: 'Домен, по которому покупатели заходят на маркетплейс. Изменение поля не переносит DNS.',
|
|
|
|
|
|
descriptionFieldDesc: 'Краткое описание для поисковых систем и превью в соцсетях.',
|
|
|
|
|
|
defaultLanguageDesc: 'Язык, который показывается, если у покупателя нет сохранённого предпочтения.',
|
|
|
|
|
|
supportedLanguagesDesc: 'Коды языков через запятую, между которыми может переключаться покупатель (например, en, ru, hy).',
|
|
|
|
|
|
logoDesc: 'URL полного логотипа, отображается в шапке на десктопе.',
|
|
|
|
|
|
smallLogoDesc: 'URL компактного логотипа для ограниченного пространства (например, мобильная шапка).',
|
|
|
|
|
|
faviconDesc: 'URL иконки вкладки браузера. Должен быть небольшим квадратным изображением.',
|
2026-07-17 15:22:45 +04:00
|
|
|
|
socialImageDesc: 'Изображение по умолчанию при публикации маркетплейса в соцсетях (Open Graph).',
|
|
|
|
|
|
galleryDesc: 'Дополнительные брендовые изображения для будущего использования в витрине.',
|
2026-07-17 15:29:55 +04:00
|
|
|
|
headerLayoutDesc: 'Как расположен контент шапки: по умолчанию (логотип слева, навигация разнесена) или по центру.',
|
|
|
|
|
|
headerStickyDesc: 'Закреплять шапку вверху экрана при прокрутке.',
|
2026-07-14 16:05:09 +04:00
|
|
|
|
marketplaceTitleDesc: 'Заголовок страницы для поисковых систем и вкладок браузера.',
|
|
|
|
|
|
primaryColorDesc: 'Основной цвет бренда для главных кнопок и акцентов. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
secondaryColorDesc: 'Дополнительный цвет бренда для второстепенных элементов. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
backgroundColorDesc: 'Цвет фона страницы по умолчанию. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
surfaceColorDesc: 'Цвет фона карточек и приподнятых поверхностей. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
textColorDesc: 'Цвет основного текста. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
successColorDesc: 'Цвет для сообщений об успехе и положительных состояний. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
warningColorDesc: 'Цвет для предупреждающих сообщений. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
dangerColorDesc: 'Цвет для ошибок и разрушительных действий. Должен быть корректным hex-цветом.',
|
|
|
|
|
|
themeModeLabel: 'Цветовой режим',
|
|
|
|
|
|
themeModeDesc: 'Определяет, отображается ли витрина в светлой, тёмной теме или по системным настройкам покупателя.',
|
|
|
|
|
|
themeModeLight: 'Светлый',
|
|
|
|
|
|
themeModeLightDesc: 'Всегда использовать светлую тему.',
|
|
|
|
|
|
themeModeDark: 'Тёмный',
|
|
|
|
|
|
themeModeDarkDesc: 'Всегда использовать тёмную тему.',
|
|
|
|
|
|
themeModeSystem: 'Системный',
|
|
|
|
|
|
themeModeSystemDesc: 'Использовать системные/браузерные настройки цветовой темы устройства покупателя.',
|
|
|
|
|
|
siteLayoutLabel: 'Макет сайта',
|
|
|
|
|
|
siteLayoutDesc: 'Общий режим оформления страниц на витрине.',
|
|
|
|
|
|
siteLayoutDefault: 'По умолчанию',
|
|
|
|
|
|
siteLayoutDefaultDesc: 'Стандартный макет с верхней навигацией.',
|
|
|
|
|
|
siteLayoutSidebarLeft: 'Боковая панель (слева)',
|
|
|
|
|
|
siteLayoutSidebarLeftDesc: 'Добавляет левую боковую панель, обычно для навигации по категориям.',
|
|
|
|
|
|
siteLayoutCarouselHome: 'Карусель на главной',
|
|
|
|
|
|
siteLayoutCarouselHomeDesc: 'Главная страница начинается с полноширинной карусели/hero-блока.',
|
|
|
|
|
|
siteLayoutMinimal: 'Минимальный',
|
|
|
|
|
|
siteLayoutMinimalDesc: 'Упрощённое оформление с минимумом элементов навигации.',
|
|
|
|
|
|
showLogoDesc: 'Показывать логотип маркетплейса в шапке.',
|
|
|
|
|
|
showSearchDesc: 'Показывать строку поиска в шапке.',
|
|
|
|
|
|
showCategoriesDesc: 'Показывать вход в меню категорий в шапке.',
|
|
|
|
|
|
showLanguagesDesc: 'Показывать переключатель языка в шапке.',
|
|
|
|
|
|
showCartDesc: 'Показывать иконку/ссылку корзины в шапке.',
|
|
|
|
|
|
showProfileDesc: 'Показывать вход в профиль/аккаунт в шапке.',
|
|
|
|
|
|
showWishlistDesc: 'Показывать вход в избранное в шапке.',
|
|
|
|
|
|
showCompareDesc: 'Показывать вход в сравнение товаров в шапке.',
|
|
|
|
|
|
showRegionDesc: 'Показывать выбор региона/страны в шапке.',
|
|
|
|
|
|
companyNameDesc: 'Юридическое название компании, показывается в футере и на статических страницах.',
|
|
|
|
|
|
addressDesc: 'Юридический/фактический адрес компании, показывается в футере.',
|
|
|
|
|
|
phoneDesc: 'Контактный телефон, показывается в футере.',
|
|
|
|
|
|
emailDesc: 'Контактный email, показывается в футере.',
|
|
|
|
|
|
copyrightDesc: 'Строка копирайта внизу каждой страницы.',
|
|
|
|
|
|
paymentIconsDesc: 'По одной иконке оплаты на строку (URL изображения и подпись), показываются в футере.',
|
|
|
|
|
|
socialLinksDesc: 'По одной социальной ссылке на строку (платформа и URL), показываются в футере.',
|
2026-07-16 02:06:26 +04:00
|
|
|
|
footerLogoDesc: 'Логотип, отображаемый в футере, если отличается от логотипа в шапке.',
|
|
|
|
|
|
iconAltLabelDesc: 'Альтернативный текст для иконки оплаты (для доступности).',
|
|
|
|
|
|
socialLinkUrlDesc: 'Полный URL профиля в соцсети, должен начинаться с http:// или https://.',
|
2026-07-14 16:05:09 +04:00
|
|
|
|
staticPagesFieldDesc: 'Статические страницы (о компании, условия, политика и т.д.), на которые ссылается футер.',
|
|
|
|
|
|
sectionVisibleDesc: 'Показывать ли эту секцию главной страницы покупателям.',
|
|
|
|
|
|
layoutStrategyLabel: 'Стратегия раскладки',
|
|
|
|
|
|
layoutStrategyDesc: 'Как располагаются виджеты внутри этой секции.',
|
|
|
|
|
|
layoutStrategyStack: 'Стопка',
|
|
|
|
|
|
layoutStrategyStackDesc: 'Виджеты располагаются друг под другом вертикально.',
|
|
|
|
|
|
layoutStrategyGrid: 'Сетка',
|
|
|
|
|
|
layoutStrategyGridDesc: 'Виджеты располагаются в многоколоночной сетке.',
|
|
|
|
|
|
layoutStrategyHero: 'Hero',
|
|
|
|
|
|
layoutStrategyHeroDesc: 'Один крупный полноширинный промо-блок.',
|
|
|
|
|
|
layoutStrategyCarousel: 'Карусель',
|
|
|
|
|
|
layoutStrategyCarouselDesc: 'Виджеты прокручиваются горизонтально как карусель.',
|
|
|
|
|
|
layoutStrategySplit: 'Разделение',
|
|
|
|
|
|
layoutStrategySplitDesc: 'Контент делится на две колонки рядом друг с другом.',
|
|
|
|
|
|
sectionColumnsDesc: 'Количество колонок, если стратегия раскладки их поддерживает.',
|
|
|
|
|
|
widgetLayoutDesc: 'Название варианта раскладки в свободной форме, понятное этому виджету (например, "full-bleed", "boxed").',
|
|
|
|
|
|
widgetHeightDesc: 'Предпочтительная высота виджета (например, "480px" или "60vh").',
|
|
|
|
|
|
widgetOverlayDesc: 'Показывать тёмную подложку под текстом hero для читаемости.',
|
|
|
|
|
|
widgetAutoplayDesc: 'Автоматически прокручивать слайды hero без участия покупателя.',
|
|
|
|
|
|
widgetColumnsDesc: 'Количество плиток категорий в ряду.',
|
|
|
|
|
|
widgetCardsPerRowDesc: 'Количество карточек товаров в ряду.',
|
|
|
|
|
|
widgetFiltersDesc: 'Показывать элементы управления фильтрами рядом с подборкой товаров.',
|
|
|
|
|
|
widgetShowBadgesDesc: 'Показывать бейджи, например "Новинка" или "Скидка", на карточках товаров.',
|
|
|
|
|
|
widgetShowRatingDesc: 'Показывать рейтинг звёздами на карточках товаров.',
|
|
|
|
|
|
widgetShowPriceDesc: 'Показывать цену на карточках товаров.',
|
|
|
|
|
|
widgetJsonDesc: 'Сырые свойства виджета в формате JSON. Используется, если для этого типа виджета нет отдельного редактора.',
|
2026-07-17 18:14:58 +04:00
|
|
|
|
widgetJsonInvalid: 'Некорректный JSON — сохранена последняя корректная версия.',
|
2026-07-14 16:05:09 +04:00
|
|
|
|
wishlistFeatureDesc: 'Разрешить покупателям сохранять товары в избранное.',
|
|
|
|
|
|
compareFeatureDesc: 'Разрешить покупателям сравнивать несколько товаров одновременно.',
|
|
|
|
|
|
reviewsFeatureDesc: 'Разрешить покупателям оставлять и читать отзывы о товарах.',
|
|
|
|
|
|
questionsFeatureDesc: 'Разрешить покупателям задавать вопросы о товарах и читать ответы.',
|
|
|
|
|
|
commentsFeatureDesc: 'Включить общие комментарии к контенту маркетплейса.',
|
|
|
|
|
|
recommendationsFeatureDesc: 'Показывать блоки рекомендованных товаров на витрине.',
|
|
|
|
|
|
recentlyViewedFeatureDesc: 'Показывать покупателям список "недавно просмотренные".',
|
|
|
|
|
|
searchSuggestionsDesc: 'Показывать живые подсказки поиска по мере ввода запроса.',
|
|
|
|
|
|
searchHistoryDesc: 'Запоминать и показывать недавние поисковые запросы покупателя.',
|
|
|
|
|
|
catalogNavigationModeLabel: 'Режим навигации каталога',
|
|
|
|
|
|
catalogNavigationModeDesc: 'Как покупатели перемещаются по категориям в каталоге.',
|
|
|
|
|
|
catalogNavDefault: 'По умолчанию',
|
|
|
|
|
|
catalogNavDefaultDesc: 'Стандартная навигация по категориям через хлебные крошки.',
|
|
|
|
|
|
catalogNavLeftCategory: 'Левая навигация по категориям',
|
|
|
|
|
|
catalogNavLeftCategoryDesc: 'Постоянное дерево категорий в левой боковой панели.',
|
|
|
|
|
|
catalogNavMegaCategory: 'Мега-меню категорий',
|
|
|
|
|
|
catalogNavMegaCategoryDesc: 'Развёрнутый выпадающий список с подкатегориями и избранными товарами.',
|
|
|
|
|
|
catalogNavTopCarousel: 'Карусель категорий сверху',
|
|
|
|
|
|
catalogNavTopCarouselDesc: 'Горизонтально прокручиваемые чипы категорий над сеткой каталога.',
|
|
|
|
|
|
newLanguageDesc: 'Код языка ISO для добавления в поддерживаемые языки витрины (например, de, fr).',
|
2026-07-17 18:31:01 +04:00
|
|
|
|
languageAlreadyAdded: 'Этот язык уже добавлен.',
|
2026-07-14 16:05:09 +04:00
|
|
|
|
languagesTabDesc: 'Языки, доступные покупателям. Язык по умолчанию используется как резервный везде.',
|
|
|
|
|
|
linkLabelDesc: 'Текст, отображаемый для этой ссылки навигации.',
|
|
|
|
|
|
linkUrlDesc: 'Путь или URL, на который ведёт эта ссылка навигации.',
|
|
|
|
|
|
linkVisibleDesc: 'Показывать ли эту ссылку навигации покупателям.',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
},
|
2026-07-14 12:21:33 +04:00
|
|
|
|
dashboard: {
|
|
|
|
|
|
title: 'Панель управления',
|
|
|
|
|
|
subtitle: 'Обзор вашего маркетплейса',
|
|
|
|
|
|
cardMarketplaceStatus: 'Статус маркетплейса',
|
|
|
|
|
|
cardProjectName: 'Название проекта',
|
|
|
|
|
|
cardCurrentTheme: 'Текущая тема',
|
|
|
|
|
|
cardLanguages: 'Языки',
|
|
|
|
|
|
cardCategoriesCount: 'Категории',
|
|
|
|
|
|
cardProductsCount: 'Товары',
|
|
|
|
|
|
cardOrders: 'Заказы',
|
|
|
|
|
|
cardRevenue: 'Выручка',
|
|
|
|
|
|
cardLastPublish: 'Последняя публикация',
|
|
|
|
|
|
cardLastDraftSave: 'Последнее сохранение черновика',
|
|
|
|
|
|
cardBootstrapVersion: 'Версия конфигурации',
|
|
|
|
|
|
cardActiveLayout: 'Активный макет',
|
|
|
|
|
|
cardEnabledWidgets: 'Активные виджеты',
|
|
|
|
|
|
stateLoading: 'Загрузка...',
|
|
|
|
|
|
stateEmpty: 'Пока нет данных',
|
|
|
|
|
|
stateError: 'Не удалось загрузить карточку',
|
|
|
|
|
|
statePendingBackend: 'Ожидает интеграции с бэкендом',
|
|
|
|
|
|
never: 'Никогда',
|
|
|
|
|
|
quickActionsTitle: 'Быстрые действия',
|
|
|
|
|
|
actionEditProject: 'Редактировать проект',
|
|
|
|
|
|
actionCategories: 'Категории',
|
|
|
|
|
|
actionProducts: 'Товары',
|
|
|
|
|
|
actionStaticPages: 'Статические страницы',
|
|
|
|
|
|
actionTransactions: 'Транзакции',
|
|
|
|
|
|
actionOrders: 'Заказы',
|
|
|
|
|
|
actionMediaLibrary: 'Медиатека',
|
2026-07-15 20:25:12 +04:00
|
|
|
|
actionUsers: 'Пользователи и права',
|
|
|
|
|
|
actionMonitoring: 'Мониторинг',
|
|
|
|
|
|
actionAnalytics: 'Аналитика',
|
2026-07-14 12:21:33 +04:00
|
|
|
|
actionPreviewMarketplace: 'Просмотр маркетплейса',
|
|
|
|
|
|
activityTitle: 'Недавняя активность',
|
|
|
|
|
|
activityEmpty: 'Пока нет активности. Сохраните или опубликуйте изменение, чтобы увидеть его здесь.',
|
|
|
|
|
|
activityDraftSaved: 'Черновик сохранён',
|
|
|
|
|
|
activityPublished: 'Опубликовано',
|
|
|
|
|
|
healthTitle: 'Состояние системы',
|
|
|
|
|
|
healthAllClear: 'Все проверки пройдены',
|
|
|
|
|
|
healthBootstrapValid: 'Bootstrap корректен',
|
|
|
|
|
|
healthConfigurationValid: 'Конфигурация корректна',
|
|
|
|
|
|
healthMissingTranslations: 'Отсутствуют переводы',
|
|
|
|
|
|
healthInvalidColors: 'Некорректные цвета',
|
|
|
|
|
|
healthInvalidWidgetReferences: 'Некорректные ссылки виджетов',
|
|
|
|
|
|
healthInvalidLayouts: 'Некорректные макеты',
|
|
|
|
|
|
comingSoonTitle: 'Скоро',
|
|
|
|
|
|
comingSoonDescription: 'Этот раздел ещё не реализован. Загляните позже.',
|
|
|
|
|
|
backToDashboard: 'Вернуться на панель управления',
|
|
|
|
|
|
},
|
2026-07-10 13:52:01 +04:00
|
|
|
|
staticPages: {
|
|
|
|
|
|
notFound: 'Страница не найдена',
|
|
|
|
|
|
backHome: 'На главную',
|
|
|
|
|
|
duplicateSlug: 'Дублирующиеся slug запрещены.',
|
|
|
|
|
|
emptyTitle: 'У каждой страницы должен быть хотя бы один заголовок.',
|
feat(static-pages): CRUD completion + search/filter/bulk actions
Milestone 2 of the Static Pages Module sprint.
- StaticPagesEditorComponent: duplicate page, confirm-before-delete/bulk-
delete (matches the resetDraft confirm pattern), route/enabled/customTemplate/
media(hero/thumbnail/gallery) fields wired into the card, per-page publish/
unpublish action, status + duplicate-route/invalid-html/invalid-seo badges.
- Search (id/slug/route/title across all locales), filter by status
(draft/published) and by locale (hides pages missing a translation for the
selected locale) - all local computed() filters, no new service.
- Bulk selection (per-row + select-all-visible checkboxes) with bulk delete/
enable/disable/publish/unpublish, one updateBootstrap() call each.
- Correctness note: introduced `allPages` (unfiltered) vs `pages` (filtered
view) computeds. Every mutation (create/duplicate/delete/move/bulk) reads
from allPages(), never the filtered pages() - reading from the filtered
view would have silently deleted whatever an active search/filter hid on
the next persist(). Documented inline on persist() as a guardrail for
future edits.
- Fixed a template compile error found by the build gate: Angular templates
don't support inline arrow functions in binding expressions
((ngModelChange)="...map(v => v.trim())..." failed to parse) - moved the
gallery CSV-parsing into a component method (updateGallery).
- SEO robots field added to the page card (validated against a known-token
set from M1).
- i18n: staticPages.* extended (search/filter/bulk/route/enabled/status/
media/robots/disabled labels) across the interface + en/ru/hy.
Gate: tsc --noEmit, npm test (57/57), arch:check, build all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 09:55:21 +04:00
|
|
|
|
duplicateRoute: 'Два или более страниц используют один и тот же маршрут.',
|
|
|
|
|
|
invalidHtml: 'На этой странице некорректный HTML-контент.',
|
|
|
|
|
|
invalidSeo: 'У этой страницы некорректное SEO-поле (canonical/OG-изображение или значение robots).',
|
|
|
|
|
|
searchPlaceholder: 'Поиск страниц…',
|
|
|
|
|
|
filterAll: 'Все статусы',
|
|
|
|
|
|
filterAllLocales: 'Все языки',
|
|
|
|
|
|
confirmDeletePage: 'Удалить эту страницу? Это действие нельзя отменить.',
|
|
|
|
|
|
confirmBulkDelete: 'Удалить выбранные страницы? Это действие нельзя отменить.',
|
|
|
|
|
|
duplicatePage: 'Дублировать',
|
|
|
|
|
|
selectAll: 'Выбрать все',
|
|
|
|
|
|
selectedCount: 'выбрано',
|
|
|
|
|
|
bulkDelete: 'Удалить выбранные',
|
|
|
|
|
|
bulkEnable: 'Включить выбранные',
|
|
|
|
|
|
bulkDisable: 'Отключить выбранные',
|
|
|
|
|
|
bulkPublishAction: 'Опубликовать выбранные',
|
|
|
|
|
|
bulkUnpublish: 'Снять с публикации выбранные',
|
|
|
|
|
|
routeLabel: 'Маршрут',
|
|
|
|
|
|
enabledLabel: 'Включена',
|
|
|
|
|
|
statusLabel: 'Статус',
|
|
|
|
|
|
publishPageAction: 'Опубликовать страницу',
|
|
|
|
|
|
unpublishPageAction: 'Снять страницу с публикации',
|
|
|
|
|
|
heroImageLabel: 'Главное изображение',
|
|
|
|
|
|
thumbnailLabel: 'Миниатюра',
|
|
|
|
|
|
galleryLabel: 'Галерея',
|
|
|
|
|
|
customTemplateLabel: 'Пользовательский шаблон',
|
|
|
|
|
|
seoRobotsLabel: 'Robots',
|
|
|
|
|
|
disabledBadge: 'Отключена',
|
2026-07-17 10:11:31 +04:00
|
|
|
|
previewDesktop: 'Десктоп',
|
|
|
|
|
|
previewTablet: 'Планшет',
|
|
|
|
|
|
previewMobile: 'Телефон',
|
|
|
|
|
|
previewToggle: 'Превью',
|
2026-07-10 13:52:01 +04:00
|
|
|
|
},
|
2026-07-09 02:29:12 +04:00
|
|
|
|
widgets: {
|
|
|
|
|
|
unavailable: 'Виджет недоступен',
|
|
|
|
|
|
},
|
2026-02-26 23:09:20 +04:00
|
|
|
|
carousel: {
|
|
|
|
|
|
loading: 'Загрузка товаров...',
|
|
|
|
|
|
addToCart: 'Добавить в корзину',
|
|
|
|
|
|
},
|
|
|
|
|
|
common: {
|
|
|
|
|
|
retry: 'Попробовать снова',
|
|
|
|
|
|
loading: 'Загрузка...',
|
2026-07-17 15:22:45 +04:00
|
|
|
|
remove: 'Удалить',
|
2026-02-26 23:09:20 +04:00
|
|
|
|
},
|
2026-02-28 17:18:24 +04:00
|
|
|
|
location: {
|
|
|
|
|
|
allRegions: 'Все регионы',
|
|
|
|
|
|
chooseRegion: 'Выберите регион',
|
|
|
|
|
|
detectAuto: 'Определить автоматически',
|
|
|
|
|
|
},
|
|
|
|
|
|
auth: {
|
|
|
|
|
|
loginRequired: 'Требуется авторизация',
|
|
|
|
|
|
loginDescription: 'Для оформления заказа войдите через Telegram',
|
|
|
|
|
|
checking: 'Проверка...',
|
|
|
|
|
|
loginWithTelegram: 'Войти через Telegram',
|
|
|
|
|
|
orScanQr: 'Или отсканируйте QR-код',
|
|
|
|
|
|
loginNote: 'После входа вы будете перенаправлены обратно',
|
2026-03-25 15:32:50 +04:00
|
|
|
|
qrExpired: 'QR-код устарел. Нажмите, чтобы обновить',
|
2026-06-01 00:47:26 +04:00
|
|
|
|
qrError: 'Не удалось создать сессию входа. Нажмите, чтобы повторить',
|
2026-02-28 17:18:24 +04:00
|
|
|
|
},
|
2026-07-09 01:13:54 +04:00
|
|
|
|
ux: {
|
|
|
|
|
|
items: 'товаров',
|
|
|
|
|
|
wishlistTitle: 'Избранное',
|
|
|
|
|
|
wishlistEmptyTitle: 'Избранное пока пусто',
|
|
|
|
|
|
wishlistEmptyDescription: 'Сохраняйте товары, чтобы быстро вернуться к ним позже.',
|
|
|
|
|
|
clearWishlist: 'Очистить избранное',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
wishlistCleared: 'Избранное очищено',
|
2026-07-09 01:13:54 +04:00
|
|
|
|
compareTitle: 'Сравнение товаров',
|
|
|
|
|
|
compareEmptyTitle: 'Нет товаров для сравнения',
|
|
|
|
|
|
compareEmptyDescription: 'Добавьте товары из каталога, чтобы сравнить характеристики и цену.',
|
|
|
|
|
|
clearCompare: 'Очистить сравнение',
|
|
|
|
|
|
hideIdentical: 'Скрыть одинаковые значения',
|
|
|
|
|
|
highlightDifferences: 'Подсвечивать различия',
|
|
|
|
|
|
clearRecentlyViewed: 'Очистить просмотренные',
|
|
|
|
|
|
recentlyViewedEmpty: 'Вы пока не просматривали товары.',
|
|
|
|
|
|
saveSearch: 'Сохранить поиск',
|
|
|
|
|
|
goToCatalog: 'Перейти в каталог',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
wishlistAdded: 'Добавлено в избранное',
|
|
|
|
|
|
wishlistRemoved: 'Удалено из избранного',
|
|
|
|
|
|
compareAdded: 'Добавлено в сравнение',
|
|
|
|
|
|
compareRemoved: 'Удалено из сравнения',
|
|
|
|
|
|
compareLimitReached: 'Достигнут лимит сравнения ({{maxItems}})',
|
|
|
|
|
|
productShared: 'Товар отправлен',
|
|
|
|
|
|
productLinkCopied: 'Ссылка на товар скопирована',
|
|
|
|
|
|
sharingUnsupported: 'На этом устройстве нет поддержки шаринга',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
addedToCart: 'Добавлено в корзину',
|
2026-07-09 01:40:22 +04:00
|
|
|
|
enterQueryBeforeSave: 'Введите поисковый запрос перед сохранением',
|
|
|
|
|
|
savedSearchNamed: 'Сохраненный поиск: {{name}}',
|
2026-07-09 02:29:12 +04:00
|
|
|
|
recentlyViewedTitle: 'Недавно просмотренные',
|
|
|
|
|
|
compareAttribute: 'Атрибут',
|
|
|
|
|
|
comparePrice: 'Цена',
|
|
|
|
|
|
compareRating: 'Рейтинг',
|
|
|
|
|
|
compareStock: 'Наличие',
|
|
|
|
|
|
compareDiscount: 'Скидка',
|
|
|
|
|
|
compareColor: 'Цвет',
|
|
|
|
|
|
compareSize: 'Размер',
|
|
|
|
|
|
compareUnknown: 'неизвестно',
|
2026-07-09 01:13:54 +04:00
|
|
|
|
},
|
2026-07-10 13:34:25 +04:00
|
|
|
|
diagnostics: {
|
|
|
|
|
|
title: 'Диагностика маркетплейса',
|
|
|
|
|
|
disabledTitle: 'Диагностика недоступна',
|
|
|
|
|
|
disabledDescription: 'Страница диагностики доступна только в режиме разработки.',
|
|
|
|
|
|
generatedAt: 'Сформировано: {{value}}',
|
|
|
|
|
|
healthScore: 'Оценка состояния',
|
|
|
|
|
|
summary: 'Сводка',
|
|
|
|
|
|
passedChecks: '{{count}} успешных проверок',
|
|
|
|
|
|
warnings: '{{count}} предупреждений',
|
|
|
|
|
|
errors: '{{count}} ошибок',
|
|
|
|
|
|
critical: '{{count}} критических',
|
|
|
|
|
|
healthChecks: 'Проверки состояния',
|
|
|
|
|
|
results: 'Подробные результаты',
|
|
|
|
|
|
noIssues: 'Проблем диагностики не найдено.',
|
|
|
|
|
|
ok: 'OK',
|
|
|
|
|
|
failed: 'Ошибка',
|
|
|
|
|
|
affectedComponent: 'Затронутый компонент',
|
|
|
|
|
|
suggestedResolution: 'Рекомендация',
|
|
|
|
|
|
severity: { info: 'Инфо', warning: 'Предупреждение', error: 'Ошибка', critical: 'Критично' },
|
|
|
|
|
|
checks: {
|
|
|
|
|
|
bootstrapLoaded: 'Bootstrap загружен',
|
|
|
|
|
|
tenantResolved: 'Tenant определен',
|
|
|
|
|
|
runtimeInitialized: 'Runtime инициализирован',
|
|
|
|
|
|
themeLoaded: 'Тема загружена',
|
|
|
|
|
|
widgetManifestLoaded: 'Манифест виджетов загружен',
|
|
|
|
|
|
sectionEngineInitialized: 'Section Engine доступен',
|
|
|
|
|
|
configurationEngineInitialized: 'Configuration Engine инициализирован',
|
|
|
|
|
|
translationResourcesAvailable: 'Переводы доступны',
|
|
|
|
|
|
requiredAssetsAvailable: 'Обязательные assets доступны',
|
|
|
|
|
|
},
|
|
|
|
|
|
bootstrapMissingTitle: 'Bootstrap отсутствует',
|
|
|
|
|
|
bootstrapMissingDescription: 'Конфигурация bootstrap не загружена.',
|
|
|
|
|
|
bootstrapMissingResolution: 'Проверьте provider bootstrap и локальный mock.',
|
|
|
|
|
|
requiredPropertyMissingTitle: 'Отсутствует обязательное свойство',
|
|
|
|
|
|
requiredPropertyMissingDescription: 'В bootstrap отсутствует обязательное свойство.',
|
|
|
|
|
|
requiredPropertyMissingResolution: 'Добавьте свойство в bootstrap payload.',
|
|
|
|
|
|
unknownWidgetTypeTitle: 'Неизвестный тип виджета',
|
|
|
|
|
|
unknownWidgetTypeDescription: 'Тип виджета отсутствует в widget manifest.',
|
|
|
|
|
|
unknownWidgetTypeResolution: 'Добавьте виджет в manifest или удалите неверную конфигурацию.',
|
|
|
|
|
|
duplicateIdTitle: 'Дублирующийся идентификатор',
|
|
|
|
|
|
duplicatePageIdDescription: 'Обнаружен дублирующийся id страницы.',
|
|
|
|
|
|
duplicateSectionIdDescription: 'Обнаружен дублирующийся id секции.',
|
|
|
|
|
|
duplicateWidgetIdDescription: 'Обнаружен дублирующийся id виджета.',
|
|
|
|
|
|
duplicateIdResolution: 'Сделайте id уникальными в bootstrap конфигурации.',
|
|
|
|
|
|
unknownLayoutTitle: 'Неизвестный layout',
|
|
|
|
|
|
unknownLayoutDescription: 'Значение layout страницы не распознано.',
|
|
|
|
|
|
unknownLayoutResolution: 'Используйте поддерживаемый layout или расширьте allow-list.',
|
|
|
|
|
|
invalidFeatureFlagTitle: 'Некорректный feature flag',
|
|
|
|
|
|
invalidFeatureFlagDescription: 'Значение feature flag должно быть boolean.',
|
|
|
|
|
|
invalidFeatureFlagResolution: 'Нормализуйте значение к true или false.',
|
|
|
|
|
|
brokenPageDefinitionTitle: 'Некорректное описание страницы',
|
|
|
|
|
|
brokenPageDefinitionDescription: 'Описание страницы неполное.',
|
|
|
|
|
|
brokenPageDefinitionResolution: 'Добавьте route, title, key или sections.',
|
|
|
|
|
|
invalidNavigationTargetTitle: 'Некорректная цель навигации',
|
|
|
|
|
|
invalidNavigationTargetDescription: 'Route навигации не совпадает с известными route.',
|
|
|
|
|
|
invalidNavigationTargetResolution: 'Исправьте target route или добавьте route.',
|
|
|
|
|
|
missingTranslationTitle: 'Отсутствует перевод',
|
|
|
|
|
|
missingTranslationDescription: 'Ключ перевода не разрешается.',
|
|
|
|
|
|
missingTranslationResolution: 'Добавьте ключ в translation resources.',
|
|
|
|
|
|
missingMediaTitle: 'Отсутствует media',
|
|
|
|
|
|
missingMediaDescription: 'Ожидаемый branding media ресурс отсутствует.',
|
|
|
|
|
|
missingMediaResolution: 'Укажите корректные media URL в branding конфиге.',
|
|
|
|
|
|
runtimeNotInitializedTitle: 'Runtime не инициализирован',
|
|
|
|
|
|
runtimeNotInitializedDescription: 'Platform runtime state не помечен как initialized.',
|
|
|
|
|
|
runtimeNotInitializedResolution: 'Проверьте цепочку initialize в PlatformRuntimeService.',
|
|
|
|
|
|
configFallbackUsageTitle: 'Используется fallback конфигурация',
|
|
|
|
|
|
configFallbackUsageDescription: 'Runtime разработки использует fallback или mock конфигурацию.',
|
|
|
|
|
|
configFallbackUsageResolution: 'Смените provider mode, если нужна проверка реального bootstrap.',
|
|
|
|
|
|
missingDatasourceTitle: 'Отсутствует datasource',
|
|
|
|
|
|
missingDatasourceDescription: 'Виджет поддерживает datasource, но он не задан.',
|
|
|
|
|
|
missingDatasourceResolution: 'Укажите source в props виджета или default settings manifest.',
|
|
|
|
|
|
widgetRenderFailureTitle: 'Сбой рендера виджета',
|
|
|
|
|
|
widgetRenderFailureDescription: 'Виджет откатился на unknown widget renderer.',
|
|
|
|
|
|
widgetRenderFailureResolution: 'Зарегистрируйте компонент виджета или исправьте component key.',
|
|
|
|
|
|
brokenRouteTitle: 'Нарушено ожидание route',
|
|
|
|
|
|
brokenRouteDescription: 'Ожидаемый route отсутствует.',
|
|
|
|
|
|
brokenRouteResolution: 'Верните регистрацию route или обновите правило диагностики.',
|
|
|
|
|
|
imageLoadFailedTitle: 'Ошибка загрузки изображения',
|
|
|
|
|
|
imageLoadFailedDescription: 'Отображаемое изображение не загрузилось.',
|
|
|
|
|
|
imageLoadFailedResolution: 'Проверьте asset path, CORS и доступность media.',
|
|
|
|
|
|
optionalDataMissingTitle: 'Отсутствуют необязательные данные',
|
|
|
|
|
|
optionalDataMissingDescription: 'Необязательное конфигурационное значение отсутствует.',
|
|
|
|
|
|
optionalDataMissingResolution: 'Добавьте значение, если оно нужно UX.',
|
|
|
|
|
|
},
|
feat(media): add Media Manager UI (grid, upload, delete)
MediaLibraryPageComponent replaces the coming-soon placeholder at
/backoffice/media. Built entirely on Sprint 6 Design System primitives
(app-card, app-button, app-input, app-empty-state, app-dialog, app-pagination,
app-skeleton) and Sprint 4 Task 2's MediaRepository/MockMediaRepository.
- Grid view with per-tile filename/size and delete action
- Hidden native file input triggered by an app-button, uploads via
MediaLibraryFacade -> MediaRepository.upload()
- Delete requires confirmation through app-dialog (destructive action)
- Search + pagination wired to MockMediaRepository's list() params
- Loading state shows app-skeleton tiles; empty state shows app-empty-state
- New mediaLibrary.* translation namespace across en/ru/hy
Verified in browser (via a temporary unguarded route, reverted before
commit - /backoffice/media itself requires Telegram QR admin auth not
available in this session): empty state renders correctly with translated
copy, search input and upload button present, no console errors.
2026-07-15 07:14:16 +04:00
|
|
|
|
mediaLibrary: {
|
|
|
|
|
|
title: 'Медиатека',
|
|
|
|
|
|
upload: 'Загрузить',
|
|
|
|
|
|
uploading: 'Загрузка...',
|
|
|
|
|
|
searchPlaceholder: 'Поиск файлов...',
|
|
|
|
|
|
delete: 'Удалить',
|
|
|
|
|
|
deleteConfirmTitle: 'Удалить файл?',
|
|
|
|
|
|
deleteConfirmBody: 'Это действие необратимо.',
|
|
|
|
|
|
cancel: 'Отмена',
|
|
|
|
|
|
confirm: 'Удалить',
|
|
|
|
|
|
emptyTitle: 'Пока нет файлов',
|
|
|
|
|
|
emptyDescription: 'Загрузите изображение или документ, чтобы начать.',
|
|
|
|
|
|
},
|
fix(static-pages): backfill enabled/status in export, fix missing i18n key
Independent review pass over the Static Pages Module sprint (M1-M7),
including live browser E2E per the task's own verification checklist.
- ProjectEditorFacade.normalize() now backfills enabled/status on
record-format static pages (defaulting missing values to enabled+published,
same rule ContentPageService.normalizePage applies for display - mirrored
rather than imported, to avoid a project-editor <-> content-management
circular dependency since ContentManagementFacade already depends on this
facade). Found live: exporting a page that predates this sprint and was
never touched/re-saved in the current session produced JSON missing
enabled/status entirely - the editor UI and storefront resolver both
normalize-on-read so nothing was actually broken live, but Export/Import
fidelity should match what the editor shows. Verified fixed live (export
now includes "enabled":true,"status":"published" for an untouched legacy
page) and via the full gate.
- Added the missing adminCategories.chooseImage i18n key (interface +
en/ru/hy). Found live: the media-picker "choose image" button rendered as
the literal string "adminCategories.chooseImage" - a pre-existing,
repo-wide bug (5 templates reference this key; none of the locale files
ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new
occurrences by copying the existing branding-section/footer-section
pattern into static-pages-editor. Fixed the actual defect (missing
translation) rather than renaming the key, which would have required
touching 2 unrelated admin components outside this sprint's scope.
Live-verified this pass: Static Pages editor renders with all new fields;
create page works (page count 4->confirmed); device preview toggles
desktop/tablet/mobile widths correctly; navigation "Insert page link"
creates a real type:'staticPage' nav item end-to-end (confirmed in the
exported JSON); export includes all Sprint X+2 fields after the fix; no
console errors throughout.
Gate: tsc --noEmit, npm test (57/57), arch:check, build all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 11:27:29 +04:00
|
|
|
|
adminCategories: {
|
|
|
|
|
|
chooseImage: 'Выбрать изображение',
|
2026-07-17 15:22:45 +04:00
|
|
|
|
replaceImage: 'Заменить изображение',
|
fix(static-pages): backfill enabled/status in export, fix missing i18n key
Independent review pass over the Static Pages Module sprint (M1-M7),
including live browser E2E per the task's own verification checklist.
- ProjectEditorFacade.normalize() now backfills enabled/status on
record-format static pages (defaulting missing values to enabled+published,
same rule ContentPageService.normalizePage applies for display - mirrored
rather than imported, to avoid a project-editor <-> content-management
circular dependency since ContentManagementFacade already depends on this
facade). Found live: exporting a page that predates this sprint and was
never touched/re-saved in the current session produced JSON missing
enabled/status entirely - the editor UI and storefront resolver both
normalize-on-read so nothing was actually broken live, but Export/Import
fidelity should match what the editor shows. Verified fixed live (export
now includes "enabled":true,"status":"published" for an untouched legacy
page) and via the full gate.
- Added the missing adminCategories.chooseImage i18n key (interface +
en/ru/hy). Found live: the media-picker "choose image" button rendered as
the literal string "adminCategories.chooseImage" - a pre-existing,
repo-wide bug (5 templates reference this key; none of the locale files
ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new
occurrences by copying the existing branding-section/footer-section
pattern into static-pages-editor. Fixed the actual defect (missing
translation) rather than renaming the key, which would have required
touching 2 unrelated admin components outside this sprint's scope.
Live-verified this pass: Static Pages editor renders with all new fields;
create page works (page count 4->confirmed); device preview toggles
desktop/tablet/mobile widths correctly; navigation "Insert page link"
creates a real type:'staticPage' nav item end-to-end (confirmed in the
exported JSON); export includes all Sprint X+2 fields after the fix; no
console errors throughout.
Gate: tsc --noEmit, npm test (57/57), arch:check, build all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 11:27:29 +04:00
|
|
|
|
},
|
2026-07-16 00:19:41 +04:00
|
|
|
|
adminProducts: {
|
|
|
|
|
|
emptyTitle: 'Товары не найдены',
|
|
|
|
|
|
emptyDescription: 'Измените фильтры или создайте новый товар.',
|
|
|
|
|
|
},
|
|
|
|
|
|
adminUsers: {
|
|
|
|
|
|
emptyTitle: 'Пользователи не найдены',
|
|
|
|
|
|
emptyDescription: 'Пригласите коллегу, чтобы начать.',
|
|
|
|
|
|
invitationsEmptyTitle: 'Нет ожидающих приглашений',
|
|
|
|
|
|
},
|
|
|
|
|
|
adminMonitoring: {
|
|
|
|
|
|
eventsEmptyTitle: 'События не найдены',
|
|
|
|
|
|
eventsEmptyDescription: 'Попробуйте изменить фильтр категории или поисковый запрос.',
|
|
|
|
|
|
},
|
|
|
|
|
|
adminAnalytics: {
|
|
|
|
|
|
topProductsEmptyTitle: 'Нет продаж товаров за этот период',
|
|
|
|
|
|
topProductsEmptyDescription: 'Попробуйте выбрать более широкий диапазон дат.',
|
|
|
|
|
|
},
|
feat(admin): build shared admin shell
Sidebar (Dashboard/Catalog group/Products/Categories/Orders/Transactions/
Reviews/Reports/Content/Media/Marketplace Builder/Users/Settings/
Monitoring/Analytics + Documentation/Help/Logout), sticky topbar
(breadcrumbs, page title/description, search, notifications, tenant
selector and quick-publish placeholders, current user), reserved
right-rail slot, scrollable content area. Desktop 280px sidebar, tablet
icon rail, mobile drawer with focus management and Escape-to-close.
Nav items without a built page (Reviews, Reports, Settings, Docs, Help)
render disabled with a coming-soon badge instead of dead links; Content
and Marketplace Builder route to the existing project-editor pages
(static-pages / general) rather than duplicating them.
All 15 /backoffice/** routes now render through AdminLayoutComponent;
the public storefront header/back-button/footer no longer render on
admin routes (app.ts/app.html gate on a new isAdminRoute signal).
Added the adminShell i18n namespace (ru/en/hy) for every new shell
string so this doesn't add to the existing untranslated-admin-UI gap
tracked in KNOWN-ISSUES.md.
Colors/type sizes follow DESIGN.md tokens; the two rgba() modal-scrim
values are a documented, intentional exception (neutral overlay,
not a themed token).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 00:12:19 +04:00
|
|
|
|
adminShell: {
|
|
|
|
|
|
skipToContent: 'Перейти к содержимому',
|
|
|
|
|
|
openSidebar: 'Открыть меню',
|
|
|
|
|
|
closeSidebar: 'Закрыть меню',
|
|
|
|
|
|
collapseSidebar: 'Свернуть меню',
|
|
|
|
|
|
expandSidebar: 'Развернуть меню',
|
|
|
|
|
|
nav: {
|
|
|
|
|
|
dashboard: 'Панель управления',
|
|
|
|
|
|
catalogGroup: 'Каталог',
|
|
|
|
|
|
products: 'Товары',
|
|
|
|
|
|
categories: 'Категории',
|
|
|
|
|
|
orders: 'Заказы',
|
|
|
|
|
|
transactions: 'Транзакции',
|
|
|
|
|
|
reviews: 'Отзывы',
|
|
|
|
|
|
reports: 'Отчёты',
|
|
|
|
|
|
content: 'Контент',
|
|
|
|
|
|
mediaLibrary: 'Медиатека',
|
|
|
|
|
|
marketplaceBuilder: 'Конструктор маркетплейса',
|
|
|
|
|
|
users: 'Пользователи',
|
|
|
|
|
|
settings: 'Настройки',
|
|
|
|
|
|
monitoring: 'Мониторинг',
|
|
|
|
|
|
analytics: 'Аналитика',
|
|
|
|
|
|
documentation: 'Документация',
|
|
|
|
|
|
help: 'Помощь',
|
|
|
|
|
|
logout: 'Выйти',
|
|
|
|
|
|
comingSoonBadge: 'Скоро',
|
|
|
|
|
|
},
|
|
|
|
|
|
topbar: {
|
|
|
|
|
|
searchLabel: 'Поиск по админ-панели',
|
|
|
|
|
|
searchPlaceholder: 'Искать товары, заказы, страницы...',
|
|
|
|
|
|
notifications: 'Уведомления',
|
|
|
|
|
|
notificationsEmpty: 'Новых уведомлений нет',
|
|
|
|
|
|
account: 'Аккаунт администратора',
|
|
|
|
|
|
tenantSelector: 'Магазин',
|
|
|
|
|
|
tenantSelectorComingSoon: 'Переключение между магазинами скоро появится',
|
|
|
|
|
|
quickPublish: 'Опубликовать',
|
|
|
|
|
|
quickPublishComingSoon: 'Быстрая публикация скоро появится',
|
|
|
|
|
|
},
|
|
|
|
|
|
breadcrumbHome: 'Админ-панель',
|
|
|
|
|
|
pages: {
|
|
|
|
|
|
dashboard: { title: 'Панель управления', description: 'Обзор состояния вашего маркетплейса' },
|
|
|
|
|
|
products: { title: 'Товары', description: 'Управляйте карточками товаров и их видимостью' },
|
|
|
|
|
|
productCreate: { title: 'Новый товар', description: 'Заполните карточку, чтобы добавить товар в каталог' },
|
|
|
|
|
|
productEdit: { title: 'Редактирование товара', description: 'Измените данные товара' },
|
|
|
|
|
|
productDuplicate: { title: 'Копия товара', description: 'Создайте новый товар на основе существующего' },
|
|
|
|
|
|
categories: { title: 'Категории', description: 'Постройте дерево категорий каталога' },
|
|
|
|
|
|
categoryCreate: { title: 'Новая категория', description: 'Добавьте категорию в дерево каталога' },
|
|
|
|
|
|
categoryEdit: { title: 'Редактирование категории', description: 'Измените данные категории' },
|
|
|
|
|
|
orders: { title: 'Заказы', description: 'Просматривайте и обрабатывайте заказы покупателей' },
|
|
|
|
|
|
orderDetail: { title: 'Заказ', description: 'Детали и статус заказа' },
|
|
|
|
|
|
transactions: { title: 'Транзакции', description: 'Платежи, возвраты и проверка мошенничества' },
|
|
|
|
|
|
media: { title: 'Медиатека', description: 'Изображения и файлы для товаров и страниц' },
|
|
|
|
|
|
users: { title: 'Пользователи', description: 'Команда администраторов и права доступа' },
|
|
|
|
|
|
monitoring: { title: 'Мониторинг', description: 'Состояние очередей, вебхуков и системных событий' },
|
|
|
|
|
|
analytics: { title: 'Аналитика', description: 'Продажи, товары и поведение покупателей' },
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2026-02-26 23:09:20 +04:00
|
|
|
|
};
|