- CRM: configurable pipeline (default: New → Contact → Meeting → Negotiation → Connected / Lost), drag-and-drop board, lead card with call/meeting/note history, photos and files, tasks with Telegram reminders at the due time, map of venues (OpenStreetMap via Leaflet), lost reason. Sales reps see only their own leads. - "Connected" in one click: a venue becomes a club card partner with a one-time owner link to the work bot; an agency gets a code and a client link. The sales rep is recorded on the partner for the bonus. - Sales bonus formula in settings (per venue, per agency, % of revenue from the rep's agency clients for N months); defaults are 0 until the owner sets them. - Agencies (superadmin): clients, gift subscriptions, reward by month, payouts, client link, edit. Venues: offers by membership level (5 languages), staff, card checks, 8-week activity, owner link, map point. - Schema: SalesStage/SalesLead/SalesActivity/SalesTask; salesId on Agency and Partner; lat/lng/phone/note on Partner; agencyId on Payout. - Tests for stage rules, conversion, task reminders and bonus; dev:crm-demo. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2690 lines
136 KiB
TypeScript
2690 lines
136 KiB
TypeScript
import { createT as createSharedT, formatAmd, formatDateTime, type Locale as SharedLocale } from '@barev/i18n';
|
||
import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
|
||
|
||
/** Языки новой админки */
|
||
export const BO_LOCALES = ['ru', 'en', 'hy'] as const;
|
||
export type BoLocale = (typeof BO_LOCALES)[number];
|
||
export const BO_LOCALE_LABELS: Record<BoLocale, string> = { ru: 'Рус', en: 'Eng', hy: 'Հայ' };
|
||
|
||
const ru = {
|
||
'ui.save': 'Сохранить',
|
||
'ui.close': 'Закрыть',
|
||
'ui.loading': 'Загружаем…',
|
||
'ui.error': 'Не получилось: {msg}',
|
||
'ui.retry': 'Повторить',
|
||
'ui.copy': 'Скопировать',
|
||
'ui.copied': 'Скопировано',
|
||
'ui.days': '{n} дн.',
|
||
'ui.yes': 'Да',
|
||
'ui.no': 'Нет',
|
||
'ui.none': '—',
|
||
|
||
'err.PAYMENTS_NOT_CONFIGURED': 'Платёжная система ещё не подключена — отметьте оплату вручную.',
|
||
'err.REFUND_TOO_BIG': 'Сумма возврата больше, чем клиент заплатил.',
|
||
'err.ENDS_BEFORE_START': 'Подписка не может закончиться раньше, чем началась.',
|
||
'err.CANNOT_DEMOTE_SELF': 'Нельзя отключить себя или снять с себя роль суперадмина.',
|
||
'err.ROLE_FORBIDDEN': 'У вашей роли нет доступа к этому действию.',
|
||
'err.NO_ROLE': 'У вашего аккаунта нет ролей в новой админке. Попросите суперадмина их выдать.',
|
||
|
||
'login.coverWord': 'команда',
|
||
'login.title': 'Вход для команды',
|
||
'login.lead': 'Подтвердите вход в рабочем боте Barev Club. Пароль не нужен.',
|
||
'login.open': 'Подтвердить в Telegram',
|
||
'login.qr': 'С компьютера удобнее отсканировать код телефоном.',
|
||
'login.waiting': 'Ждём подтверждения в Telegram…',
|
||
'login.expired': 'Ссылка устарела.',
|
||
'login.retry': 'Получить новую ссылку',
|
||
'login.dev': 'Войти локально',
|
||
'login.devHint': 'Только на этом компьютере — на сервере этого блока нет.',
|
||
'login.noTelegram': 'Нет доступа? Попросите суперадмина добавить вас в команду и прислать ссылку для привязки Telegram.',
|
||
|
||
'nav.dashboard': 'Дашборд',
|
||
'nav.clients': 'Клиенты',
|
||
'nav.chats': 'Чаты',
|
||
'nav.orders': 'Заказы',
|
||
'nav.providers': 'Исполнители',
|
||
'nav.agencies': 'Агентства',
|
||
'nav.venues': 'Заведения',
|
||
'nav.crm': 'CRM',
|
||
'nav.products': 'Продукты',
|
||
'nav.journal': 'Журнал',
|
||
'nav.team': 'Команда',
|
||
'nav.more': 'Ещё',
|
||
'nav.soon': 'этап {n}',
|
||
'nav.groupWork': 'Работа',
|
||
'nav.groupPartners': 'Партнёры',
|
||
'nav.groupSetup': 'Настройка',
|
||
|
||
'role.SUPERADMIN': 'Суперадмин',
|
||
'role.SUPPORT': 'Поддержка',
|
||
'role.CONCIERGE': 'Консьерж',
|
||
'role.SALES': 'Продажи',
|
||
'roleHint.SUPERADMIN': 'Всё, включая деньги и команду',
|
||
'roleHint.SUPPORT': 'Чат поддержки, заказы, подписки',
|
||
'roleHint.CONCIERGE': 'Чат консьержа для подписчиков',
|
||
'roleHint.SALES': 'CRM: заведения и агентства',
|
||
|
||
'shell.logout': 'Выйти',
|
||
'shell.oldAdmin': 'Старая админка',
|
||
'shell.linkTg': 'Привяжите Telegram — через него вы входите и получаете уведомления.',
|
||
'shell.linkTgBtn': 'Привязать Telegram',
|
||
|
||
'soon.title': '{section} переезжает сюда',
|
||
'soon.text': 'Раздел появится на этапе {n}. Пока работайте в старой админке — данные общие.',
|
||
'soon.open': 'Открыть старую админку',
|
||
|
||
'dash.morning': 'Доброе утро, {name}',
|
||
'dash.day': 'Добрый день, {name}',
|
||
'dash.evening': 'Добрый вечер, {name}',
|
||
'dash.attention': 'Требует внимания',
|
||
'dash.allClear': 'Срочного нет — всё разобрано.',
|
||
'att.unassigned': 'Заказы без исполнителя',
|
||
'att.unreadChats': 'Ждут ответа в чатах',
|
||
'att.webRequests': 'Заявки с сайта',
|
||
'att.leads': 'Заявки на переезд',
|
||
'att.appRequests': 'Заявки из приложения',
|
||
'att.lowRatings': 'Оценки 3 и ниже за неделю',
|
||
'att.expiring': 'Подписки истекают за 7 дней',
|
||
'dash.money': 'Деньги',
|
||
'dash.today': 'Сегодня',
|
||
'dash.week': '7 дней',
|
||
'dash.month': '30 дней',
|
||
'dash.vsYesterday': 'вчера {sum}',
|
||
'dash.vsPrev': 'к прошлым {period}',
|
||
'dash.orders': 'заказы',
|
||
'dash.subs': 'подписки',
|
||
'dash.chart': 'Выручка по дням за 30 дней',
|
||
'dash.subsTitle': 'Подписки',
|
||
'dash.gifts': 'Из них подарочных: {n}',
|
||
'dash.expiring': 'Истекают в ближайшие 7 дней',
|
||
'dash.noExpiring': 'В ближайшую неделю ничего не истекает.',
|
||
'dash.conversion': 'Подарок → покупка',
|
||
'dash.conversionHint': '{paid} из {total} клиентов с подарком потом купили подписку',
|
||
'dash.growth': 'Рост',
|
||
'dash.newClients': 'Новые клиенты',
|
||
'dash.prevMonth': 'за прошлые 30 дней — {n}',
|
||
'dash.sources': 'Откуда пришли за 30 дней',
|
||
'dash.funnel': 'Воронка за 30 дней',
|
||
'funnel.leads': 'Заявки с сайта',
|
||
'funnel.clients': 'Клиенты в приложении',
|
||
'funnel.paying': 'Заплатили',
|
||
'dash.team': 'Команда и партнёры',
|
||
'dash.topProviders': 'Лучшие исполнители',
|
||
'dash.bottomProviders': 'Стоит поговорить',
|
||
'dash.topPartners': 'Заведения: сканы карты за 30 дней',
|
||
'dash.salesSoon': 'Результаты продажников появятся вместе с CRM.',
|
||
'dash.empty': 'Пока пусто',
|
||
'dash.feed': 'Лента',
|
||
'feed.subscription': '{plan} · {source}',
|
||
'feed.payment': 'Оплачен заказ №{number}',
|
||
'dash.ratings': '{n} оценок',
|
||
'dash.scans': '{n} сканов',
|
||
|
||
'source.organic': 'Сами нашли',
|
||
'source.deeplink': 'Ссылка агентства',
|
||
'source.manual_code': 'Код агентства',
|
||
'source.agency': 'Агентство «{name}»',
|
||
'source.utm': 'Реклама: {name}',
|
||
|
||
'plan.BAREV_PLUS': 'Barev+',
|
||
'plan.ELITE': 'Elite',
|
||
'plan.none': 'Без подписки',
|
||
'subSource.PAID': 'Покупка',
|
||
'subSource.MANUAL': 'Подарок команды',
|
||
'subSource.AGENCY_GIFT': 'Подарок агентства',
|
||
'subStatus.ACTIVE': 'Активна',
|
||
'subStatus.EXPIRED': 'Истекла',
|
||
'subStatus.CANCELLED': 'Отменена',
|
||
'pay.cash': 'Наличные',
|
||
'pay.transfer': 'Перевод',
|
||
'pay.card': 'Карта через терминал',
|
||
'pay.link': 'Ссылка на оплату',
|
||
'segment.MOVING': 'Переезжает',
|
||
'segment.LIVING': 'Живёт в Армении',
|
||
|
||
'clients.title': 'Клиенты',
|
||
'clients.search': 'Имя, @username, телефон или номер карты',
|
||
'clients.found': 'Найдено: {n}',
|
||
'clients.revenueTotal': 'принесли {sum}',
|
||
'col.client': 'Клиент',
|
||
'col.sub': 'Подписка',
|
||
'col.source': 'Откуда',
|
||
'col.revenue': 'Принёс',
|
||
'col.since': 'С нами с',
|
||
'filter.plan': 'Подписка',
|
||
'filter.all': 'Все',
|
||
'filter.any': 'С подпиской',
|
||
'filter.none': 'Без подписки',
|
||
'filter.subSource': 'Как получена',
|
||
'filter.source': 'Откуда',
|
||
'filter.agency': 'Агентство',
|
||
'filter.tag': 'Тег',
|
||
'filter.segment': 'Сценарий',
|
||
'filter.paying': 'Платили',
|
||
'filter.payingYes': 'Платили',
|
||
'filter.payingNo': 'Ни разу не платили',
|
||
'filter.expiring': 'Истекает за 7 дней',
|
||
'filter.reset': 'Сбросить фильтры',
|
||
'filter.more': 'Фильтры',
|
||
'filter.anyValue': 'Любое',
|
||
'sort.label': 'Порядок',
|
||
'sort.new': 'Сначала новые',
|
||
'sort.revenue': 'Больше принесли',
|
||
'sort.ends': 'Скоро истекает',
|
||
'segments.title': 'Мои выборки',
|
||
'segments.save': 'Сохранить выборку',
|
||
'segments.name': 'Название выборки',
|
||
'segments.saved': 'Выборка сохранена',
|
||
'segments.remove': 'Удалить выборку «{name}»',
|
||
'clients.export': 'Скачать для Excel',
|
||
'clients.exported': 'Файл скачан',
|
||
'clients.broadcast': 'Рассылка',
|
||
'clients.broadcastSoon': 'Рассылки по выборке появятся на этапе 5.',
|
||
'clients.empty': 'Под эти фильтры никто не подходит.',
|
||
'clients.emptyAll': 'Клиентов пока нет — они появятся, когда напишут боту.',
|
||
'clients.prev': 'Назад',
|
||
'clients.next': 'Дальше',
|
||
'clients.page': '{from}–{to} из {total}',
|
||
|
||
'card.back': 'Все клиенты',
|
||
'card.since': 'С нами с {date}',
|
||
'card.telegram': 'Открыть в Telegram',
|
||
'card.cardNo': 'Карта {code}',
|
||
'card.noSub': 'Нет активной подписки',
|
||
'card.noSubHint': 'Подарите или продайте подписку — клиент сразу получит скидки.',
|
||
'card.until': 'до {date}',
|
||
'card.daysLeft': 'осталось {n} дн.',
|
||
'card.history': 'Все подписки',
|
||
'card.grantedBy': 'начислил(а) {name}',
|
||
'card.giftFrom': 'подарок от «{name}»',
|
||
'card.paidVia': '{method}',
|
||
'card.refunded': 'возврат {sum}',
|
||
'card.cancelledAt': 'отменена {date}',
|
||
'card.upcoming': 'начнётся {date}',
|
||
'card.money': 'Принёс',
|
||
'card.fromOrders': 'заказы',
|
||
'card.fromSubs': 'подписки',
|
||
'card.orders': 'Заказы',
|
||
'card.noOrders': 'Заказов пока нет.',
|
||
'card.newOrder': 'Создать заказ',
|
||
'card.newOrderSoon': 'Заказ за клиента появится на этапе 3, вместе с разделом заказов.',
|
||
'card.profile': 'Профиль',
|
||
'card.source': 'Откуда пришёл',
|
||
'card.agency': 'Агентство',
|
||
'card.language': 'Язык',
|
||
'card.phone': 'Телефон',
|
||
'card.segment': 'Сценарий',
|
||
'card.consent': 'Согласие на обработку данных',
|
||
'card.tags': 'Теги',
|
||
'card.addTag': 'Новый тег',
|
||
'card.note': 'Заметка команды',
|
||
'card.notePh': 'Клиент не видит эту заметку',
|
||
'card.saved': 'Сохранено',
|
||
'card.activity': 'Журнал по клиенту',
|
||
'card.noActivity': 'Команда пока ничего не меняла.',
|
||
'card.stats': 'Активность',
|
||
'stat.cardUsages': 'сканов карты',
|
||
'stat.leads': 'заявок на переезд',
|
||
'stat.requests': 'заявок из приложения',
|
||
'stat.concierge': 'сообщений в чате',
|
||
|
||
'act.gift': 'Подарить',
|
||
'act.sell': 'Продать',
|
||
'act.extend': 'Изменить срок',
|
||
'act.cancel': 'Отменить',
|
||
'act.changePlan': 'Сменить тариф',
|
||
'act.refund': 'Вернуть деньги',
|
||
|
||
'audit.bo.clients.gift': 'подарил(а) подписку',
|
||
'audit.bo.clients.sell': 'продал(а) подписку',
|
||
'audit.bo.clients.extend': 'изменил(а) срок подписки',
|
||
'audit.bo.clients.cancel': 'отменил(а) подписку',
|
||
'audit.bo.clients.changePlan': 'сменил(а) тариф',
|
||
'audit.bo.clients.refund': 'оформил(а) возврат',
|
||
'audit.bo.clients.setTags': 'изменил(а) теги',
|
||
'audit.bo.clients.setNote': 'изменил(а) заметку',
|
||
|
||
'dlg.giftTitle': 'Подарить подписку',
|
||
'dlg.giftHint': 'Подписка будет помечена как подарок от вас.',
|
||
'dlg.sellTitle': 'Продать подписку',
|
||
'dlg.plan': 'Тариф',
|
||
'dlg.period': 'Срок',
|
||
'dlg.period1': '1 месяц',
|
||
'dlg.period3': '3 месяца',
|
||
'dlg.period6': '6 месяцев',
|
||
'dlg.period12': '1 год',
|
||
'dlg.periodCustom': 'Своё',
|
||
'dlg.days': 'Дней',
|
||
'dlg.amount': 'Сумма, ֏',
|
||
'dlg.method': 'Как оплатил',
|
||
'dlg.note': 'Комментарий для команды',
|
||
'dlg.linkSoon': 'Ссылку на оплату включим, когда подключим платёжную систему.',
|
||
'dlg.giftConfirm': 'Подарить',
|
||
'dlg.sellConfirm': 'Отметить оплату',
|
||
'dlg.extendTitle': 'Изменить срок',
|
||
'dlg.extendHint': 'Отрицательное число сокращает срок.',
|
||
'dlg.newEnd': 'Новая дата окончания: {date}',
|
||
'dlg.extendConfirm': 'Сохранить срок',
|
||
'dlg.cancelTitle': 'Отменить подписку',
|
||
'dlg.cancelHint': 'Клиент сразу потеряет скидки и привилегии подписки.',
|
||
'dlg.reason': 'Причина',
|
||
'dlg.cancelConfirm': 'Отменить подписку',
|
||
'dlg.planTitle': 'Сменить тариф',
|
||
'dlg.planConfirm': 'Сменить тариф',
|
||
'dlg.refundTitle': 'Вернуть деньги',
|
||
'dlg.refundPaid': 'Оплачено {sum}, уже возвращено {back}',
|
||
'dlg.refundCancel': 'Сразу отменить подписку',
|
||
'dlg.refundConfirm': 'Оформить возврат',
|
||
'done.gift': 'Подписка подарена',
|
||
'done.sell': 'Оплата отмечена',
|
||
'done.extend': 'Срок изменён',
|
||
'done.cancel': 'Подписка отменена',
|
||
'done.changePlan': 'Тариф изменён',
|
||
'done.refund': 'Возврат оформлен',
|
||
|
||
'team.title': 'Команда',
|
||
'team.lead': 'Кто работает в админке и что ему доступно. У одного человека может быть несколько ролей.',
|
||
'team.add': 'Добавить человека',
|
||
'team.name': 'Имя',
|
||
'team.roles': 'Роли',
|
||
'team.create': 'Добавить',
|
||
'team.linkTitle': 'Ссылка для {name}',
|
||
'team.linkHint': 'Отправьте её человеку. Он откроет рабочий бот, Telegram привяжется — и можно входить.',
|
||
'team.tgLinked': 'Telegram привязан',
|
||
'team.tgNotLinked': 'Telegram не привязан',
|
||
'team.newLink': 'Ссылка для привязки',
|
||
'team.disable': 'Отключить доступ',
|
||
'team.enable': 'Вернуть доступ',
|
||
'team.disabled': 'Доступ отключён',
|
||
'team.you': 'это вы',
|
||
'team.saved': 'Роли сохранены',
|
||
|
||
// ───── чаты (этап 2) ─────
|
||
'chat.title': 'Чаты',
|
||
'chat.all': 'Все',
|
||
'channel.SUPPORT': 'Поддержка',
|
||
'channel.CONCIERGE': 'Консьерж',
|
||
'chat.f.waiting': 'Ждут ответа',
|
||
'chat.f.mine': 'Мои',
|
||
'chat.f.unassigned': 'Без ответственного',
|
||
'chat.f.open': 'Открытые',
|
||
'chat.f.closed': 'Закрытые',
|
||
'chat.f.all': 'Все',
|
||
'chat.search': 'Имя, @username, телефон или текст',
|
||
'chat.emptyList': 'Здесь пусто. Новые сообщения появятся сами.',
|
||
'chat.emptyFilter': 'Ничего не нашли — попробуйте другой фильтр.',
|
||
'chat.pick': 'Выберите диалог',
|
||
'chat.pickHint': 'Сверху — те, кто ждёт ответа дольше всех.',
|
||
'chat.waiting': 'ждёт {t}',
|
||
'chat.you': 'Вы',
|
||
'chat.provider': 'Исполнитель',
|
||
'chat.unassigned': 'Никто не ведёт',
|
||
'chat.take': 'Взять себе',
|
||
'chat.transfer': 'Передать',
|
||
'chat.transferTo': 'Передать коллеге',
|
||
'chat.unassign': 'Снять ответственного',
|
||
'chat.close': 'Закрыть',
|
||
'chat.reopen': 'Открыть снова',
|
||
'chat.closedBanner': 'Диалог закрыт. Клиент напишет — откроется сам; ответить можно и сейчас.',
|
||
'chat.moveTo': 'Перенести в «{channel}»',
|
||
'chat.moved': 'Диалог перенесён в «{channel}»',
|
||
'chat.movedAway': 'Диалог перенесён в «{channel}». У вас нет доступа к этому каналу.',
|
||
'chat.other': 'Есть переписка в канале «{channel}»',
|
||
'chat.otherOpen': 'Открыть',
|
||
'chat.bot': 'Диалог ведёт ИИ-консьерж.',
|
||
'chat.botTake': 'Перехватить',
|
||
'chat.reply': 'Ответ',
|
||
'chat.note': 'Заметка',
|
||
'chat.replyPh': 'Ответ клиенту — придёт ему в Telegram',
|
||
'chat.notePh': 'Заметка для команды — клиент её не увидит',
|
||
'chat.send': 'Отправить',
|
||
'chat.saveNote': 'Сохранить заметку',
|
||
'chat.attach': 'Прикрепить файл',
|
||
'chat.templates': 'Шаблоны',
|
||
'chat.tplManage': 'Настроить шаблоны',
|
||
'chat.tplEmpty': 'Шаблонов пока нет.',
|
||
'chat.tplNew': 'Новый шаблон',
|
||
'chat.tplTitle': 'Название',
|
||
'chat.tplText': 'Текст',
|
||
'chat.tplTextHint': '{name} заменится на имя клиента',
|
||
'chat.tplChannel': 'Канал',
|
||
'chat.tplBoth': 'Оба канала',
|
||
'chat.tplDelete': 'Удалить',
|
||
'chat.tplSaved': 'Шаблон сохранён',
|
||
'chat.tplSearch': 'Найти шаблон',
|
||
'chat.noteLabel': 'Заметка · видит только команда',
|
||
'chat.fromApp': 'из приложения',
|
||
'chat.undelivered': 'Не доставлено: клиент заблокировал бота или ни разу его не открывал',
|
||
'chat.fileTooBig': 'Файл больше 10 МБ',
|
||
'chat.enterHint': 'Enter — отправить · Shift+Enter — новая строка',
|
||
'chat.providerNotLinked': 'Исполнитель ещё не открыл рабочий бот — пока можно оставить только заметку.',
|
||
'chat.client': 'О клиенте',
|
||
'chat.aboutProvider': 'Об исполнителе',
|
||
'chat.openCard': 'Карточка клиента',
|
||
'chat.write': 'Написать',
|
||
'chat.back': 'Все диалоги',
|
||
'chat.sys.took': '{name} взял(а) диалог',
|
||
'chat.sys.transferred': '{name} передал(а) диалог: {param}',
|
||
'chat.sys.unassigned': '{name} снял(а) ответственного',
|
||
'chat.sys.closed': '{name} закрыл(а) диалог',
|
||
'chat.sys.reopened': '{name} открыл(а) диалог снова',
|
||
'chat.sys.moved': '{name} перенёс(ла) диалог в «{param}»',
|
||
'chat.ago.now': 'только что',
|
||
'chat.ago.min': '{n} мин',
|
||
'chat.ago.h': '{n} ч',
|
||
'chat.ago.d': '{n} дн',
|
||
'chat.today': 'Сегодня',
|
||
'chat.yesterday': 'Вчера',
|
||
'chat.image': 'Фото',
|
||
'chat.file': 'Файл',
|
||
'chat.subUntil': 'до {date}',
|
||
'chat.orders': 'Заказы',
|
||
'chat.phone': 'Телефон',
|
||
'chat.lang': 'Язык',
|
||
'chat.source': 'Откуда',
|
||
'chat.linked': 'Рабочий бот открыт',
|
||
'chat.notLinked': 'Рабочий бот не открыт',
|
||
'chat.details': 'Подробнее',
|
||
'chat.more': 'Ещё действия',
|
||
|
||
// ───── партнёры и CRM (этап 4) ─────
|
||
'crm.title': 'CRM',
|
||
'crm.newLead': 'Новый лид',
|
||
'crm.editLead': 'Лид',
|
||
'crm.stagesBtn': 'Воронка',
|
||
'crm.tab.board': 'Воронка',
|
||
'crm.tab.tasks': 'Задачи',
|
||
'crm.tab.map': 'Карта',
|
||
'crm.search': 'Название, контакт, телефон или адрес',
|
||
'crm.kind.all': 'Все',
|
||
'crm.kind.VENUE': 'Заведения',
|
||
'crm.kind.AGENCY': 'Агентства',
|
||
'crm.kind1.VENUE': 'Заведение',
|
||
'crm.kind1.AGENCY': 'Агентство',
|
||
'crm.owner': 'Продажник',
|
||
'crm.allSales': 'Все продажники',
|
||
'crm.noOwner': 'Без продажника',
|
||
'crm.ownerIs': 'ведёт {name}',
|
||
'crm.connected': 'Подключён',
|
||
'crm.connect': 'Подключение',
|
||
'crm.days': '{n} дн',
|
||
'crm.inStage': 'Сколько дней на этом этапе',
|
||
'crm.dropHere': 'Перетащите сюда',
|
||
'crm.dragHint': 'Перетаскивайте карточки между этапами. «Подключён» сразу создаёт партнёра или агентство и выдаёт ссылку, «Отказ» спросит причину.',
|
||
'crm.overdue': 'просрочена',
|
||
'crm.tasksOpen': 'Открытые',
|
||
'crm.tasksDone': 'Выполненные',
|
||
'crm.addTask': 'Задача',
|
||
'crm.noTasks': 'Открытых задач нет.',
|
||
'crm.noDoneTasks': 'Выполненных задач пока нет.',
|
||
'crm.noLead': 'без лида',
|
||
'crm.tasksHint': 'В срок задачи придёт напоминание в рабочий бот (если привязан Telegram).',
|
||
'crm.taskTitle': 'Что сделать',
|
||
'crm.taskDay': 'День',
|
||
'crm.taskTime': 'Время',
|
||
'crm.taskHint': 'Напоминание придёт в рабочий бот в это время (по Еревану).',
|
||
'crm.tp.call': 'Позвонить',
|
||
'crm.tp.meet': 'Встреча',
|
||
'crm.tp.send': 'Отправить условия',
|
||
'crm.tp.check': 'Узнать решение',
|
||
'crm.partnerOnMap': 'партнёр клуба',
|
||
'crm.legendPartner': 'подключённые партнёры',
|
||
'crm.legendLead': 'лиды (цвет этапа)',
|
||
'crm.mapHint': 'Точка появляется, когда у лида есть координаты.',
|
||
'crm.name': 'Название',
|
||
'crm.namePhVenue': 'Например: Lumen Coffee',
|
||
'crm.namePhAgency': 'Например: Domik Realty',
|
||
'crm.category': 'Тип',
|
||
'crm.contactName': 'Контактное лицо',
|
||
'crm.contactPh': 'Имя и должность',
|
||
'crm.address': 'Адрес',
|
||
'crm.note': 'Заметка',
|
||
'crm.convert': 'Подключить',
|
||
'crm.convertTitle': 'Подключить «{name}»',
|
||
'crm.convertVenueHint': 'Создадим партнёра клубной карты и ссылку для собственника: он откроет рабочий бот и сможет проверять карты клиентов. Предложения по уровням добавите в карточке заведения.',
|
||
'crm.convertAgencyHint': 'Создадим агентство с кодом и ссылку для его клиентов: по ней они получают подарочный месяц и закрепляются за агентством.',
|
||
'crm.agencyCode': 'Код агентства',
|
||
'crm.agencyCodeHint': 'Латиница и цифры, клиенты могут ввести его вручную',
|
||
'crm.convertedTitle': 'Подключено 🎉',
|
||
'crm.convertedVenue': 'Отправьте эту ссылку собственнику заведения. Ссылка одноразовая.',
|
||
'crm.convertedAgency': 'Эту ссылку агентство раздаёт клиентам.',
|
||
'crm.openVenue': 'Карточка заведения',
|
||
'crm.openAgency': 'Карточка агентства',
|
||
'crm.ownerLinked': 'Собственник уже в рабочем боте.',
|
||
'crm.ownerNotYet': 'Собственник ещё не открыл ссылку. Отправьте её ещё раз:',
|
||
'crm.agencyInfo': 'Код {code}, клиентов: {n}',
|
||
'crm.lostTitle': 'Почему отказ?',
|
||
'crm.lostReason': 'Причина',
|
||
'crm.lr.price': 'Не устроили условия',
|
||
'crm.lr.notNow': 'Не сейчас, вернуться позже',
|
||
'crm.lr.noAnswer': 'Не выходят на связь',
|
||
'crm.lr.competitor': 'Работают с конкурентом',
|
||
'crm.lostBanner': 'Отказ: {reason}',
|
||
'crm.stagesTitle': 'Этапы воронки',
|
||
'crm.stagesHint': 'Порядок — стрелками. Нужен хотя бы один открытый этап и один «Подключён». Этап с лидами при удалении скрывается, лиды остаются.',
|
||
'crm.addStage': 'Этап',
|
||
'crm.stageKind.OPEN': 'в работе',
|
||
'crm.stageKind.WON': 'подключён',
|
||
'crm.stageKind.LOST': 'отказ',
|
||
'crm.bonusMonth': 'Бонус за месяц',
|
||
'crm.bonusMineSuper': 'Бонус (ваш), месяц',
|
||
'crm.bonusNotSet': 'не настроен',
|
||
'crm.bonusVenues': 'Заведения: {n} → {sum}',
|
||
'crm.bonusAgencies': 'Агентства: {n} → {sum}',
|
||
'crm.bonusRevenue': '{pct}% выручки клиентов агентств → {sum}',
|
||
'crm.bonusTitle': 'Формула бонуса продажника',
|
||
'crm.bonusHint': 'Бонус за месяц = подключённые заведения × ставка + агентства × ставка + % выручки клиентов агентств продажника (первые N месяцев после подключения). Выручка — оплаченные заказы и подписки.',
|
||
'crm.bonusPerVenue': 'За заведение, ֏',
|
||
'crm.bonusPerAgency': 'За агентство, ֏',
|
||
'crm.bonusPct': '% выручки клиентов агентств',
|
||
'crm.bonusMonths': 'Сколько месяцев',
|
||
'crm.back': 'CRM',
|
||
'crm.created': 'с {date}',
|
||
'crm.stage': 'Этап',
|
||
'crm.history': 'История контактов',
|
||
'crm.noHistory': 'Пока пусто — запишите первый звонок или встречу.',
|
||
'crm.act.CALL': 'Звонок',
|
||
'crm.act.MEETING': 'Встреча',
|
||
'crm.act.NOTE': 'Заметка',
|
||
'crm.act.FILE': 'Файл',
|
||
'crm.act.STAGE': 'Этап',
|
||
'crm.act.WON': 'Подключён',
|
||
'crm.actPh.CALL': 'О чём договорились по телефону?',
|
||
'crm.actPh.MEETING': 'Как прошла встреча, что дальше?',
|
||
'crm.actPh.NOTE': 'Заметка для себя и команды',
|
||
'crm.addAct': 'Записать',
|
||
'crm.attach': 'Фото или файл',
|
||
'crm.tasks': 'Задачи',
|
||
'crm.noLeadTasks': 'Задач нет. Поставьте следующий шаг — придёт напоминание.',
|
||
'crm.contacts': 'Контакты',
|
||
'crm.noCoords': 'На карте нет точки.',
|
||
'crm.coordsPh': 'Ссылка Google Maps или «40.18, 44.51»',
|
||
'crm.coordsBad': 'Не нашли координаты — вставьте ссылку из Google Maps или числа через запятую.',
|
||
'crm.remove': 'Удалить лид',
|
||
'crm.removeConfirm': 'Удалить лид вместе с историей и задачами?',
|
||
'venue.cat.cafe': 'Кафе',
|
||
'venue.cat.restaurant': 'Ресторан',
|
||
'venue.cat.shop': 'Магазин',
|
||
'venue.cat.beauty': 'Красота',
|
||
'venue.cat.other': 'Другое',
|
||
'ag.title': 'Агентства',
|
||
'ag.add': 'Новое агентство',
|
||
'ag.editTitle': 'Агентство',
|
||
'ag.empty': 'Агентств пока нет.',
|
||
'ag.col.name': 'Агентство',
|
||
'ag.col.clients': 'Клиенты',
|
||
'ag.col.gifts': 'Подарки',
|
||
'ag.col.month': 'Вознаграждение, месяц',
|
||
'ag.col.balance': 'К выплате',
|
||
'ag.hint': 'Вознаграждение — % от оплаченных заказов клиентов агентства, пока они закреплены за ним.',
|
||
'ag.inactive': 'выключено',
|
||
'ag.back': 'Все агентства',
|
||
'ag.pct': '{n}% с заказов клиентов',
|
||
'ag.byS': 'подключил(а) {name}',
|
||
'ag.link': 'Ссылка для клиентов',
|
||
'ag.linkHint': 'По ссылке клиент открывает бота, получает подарочный месяц и закрепляется за агентством. Или вводит код {code} командой /code.',
|
||
'ag.clients': 'Клиенты',
|
||
'ag.giftsN': 'подарков: {n}',
|
||
'ag.noClients': 'Клиентов пока нет.',
|
||
'ag.orders': 'заказов: {n}',
|
||
'ag.toPay': 'Вознаграждение к выплате',
|
||
'ag.accrued': 'Начислено',
|
||
'ag.payouts': 'Выплаты',
|
||
'ag.payoutTitle': 'Выплата агентству',
|
||
'ag.balanceHint': 'Начислено и не выплачено: {sum}',
|
||
'ag.pctLabel': 'Вознаграждение, %',
|
||
'ag.sales': 'Подключил продажник',
|
||
'ag.contactPh': 'Имя, телефон, Telegram',
|
||
'ag.active': 'Агентство работает (код принимается)',
|
||
'vn.title': 'Заведения',
|
||
'vn.add': 'Новое заведение',
|
||
'vn.editTitle': 'Заведение',
|
||
'vn.empty': 'Заведений пока нет.',
|
||
'vn.col.name': 'Заведение',
|
||
'vn.col.offers': 'Предложения',
|
||
'vn.col.staff': 'Сотрудники',
|
||
'vn.col.visits': 'Проверки за 30 дн',
|
||
'vn.col.last': 'Последняя проверка',
|
||
'vn.hint': 'Проверка — сотрудник заведения отсканировал клубную карту клиента в рабочем боте.',
|
||
'vn.noOwner': 'нет собственника',
|
||
'vn.noOffers': 'нет предложений',
|
||
'vn.back': 'Все заведения',
|
||
'vn.ownerHint': 'Собственник ещё не подключён — отправьте ему одноразовую ссылку в рабочий бот.',
|
||
'vn.makeLink': 'Создать ссылку',
|
||
'vn.offers': 'Предложения по уровням',
|
||
'vn.addOffer': 'Предложение',
|
||
'vn.editOffer': 'Предложение',
|
||
'vn.noOffersHint': 'Добавьте, что положено членам клуба: скидку, подарок, комплимент.',
|
||
'vn.level.any': 'Любой член клуба',
|
||
'vn.level.BAREV_PLUS': 'Barev+ и Elite',
|
||
'vn.level.ELITE': 'Только Elite',
|
||
'vn.limit.NONE': 'без ограничений',
|
||
'vn.limit.ONCE': 'один раз',
|
||
'vn.limit.WEEK': '{n} р. в неделю',
|
||
'vn.limit.MONTH': '{n} р. в месяц',
|
||
'vn.limitOpt.NONE': 'Без ограничений',
|
||
'vn.limitOpt.ONCE': 'Только первый визит',
|
||
'vn.limitOpt.WEEK': 'N раз в неделю',
|
||
'vn.limitOpt.MONTH': 'N раз в месяц',
|
||
'vn.offerOff': 'выключено',
|
||
'vn.offerTitle': 'Что получает клиент',
|
||
'vn.offerTitleHint': 'Например: «Капучино в подарок» или «−15% на всё меню»',
|
||
'vn.forWhom': 'Для кого',
|
||
'vn.howOften': 'Как часто',
|
||
'vn.times': 'Сколько раз',
|
||
'vn.offerActive': 'Предложение действует',
|
||
'vn.activity': 'Активность',
|
||
'vn.weeks8': 'за 8 недель',
|
||
'vn.checks': 'проверки карты',
|
||
'vn.redeemed': 'списания предложений',
|
||
'vn.cardCheck': 'проверка карты',
|
||
'vn.staff': 'Сотрудники',
|
||
'vn.noStaff': 'Пока никого.',
|
||
'vn.role.OWNER': 'собственник',
|
||
'vn.role.STAFF': 'сотрудник',
|
||
'vn.removeStaff': 'Убрать {name} из заведения?',
|
||
'vn.staffHint': 'Сотрудников приглашает собственник в рабочем боте (QR на сутки).',
|
||
'vn.newOwnerLink': 'Ссылка собственнику',
|
||
'vn.newOwnerLinkHint': 'Новая одноразовая ссылка — например, если сменился собственник',
|
||
'vn.blurb': 'Коротко о скидке (на карточке у клиента)',
|
||
'vn.blurbHint': 'Например: «−10% по клубной карте»',
|
||
'vn.coords': 'Точка на карте',
|
||
'vn.activeLabel': 'Заведение видно клиентам',
|
||
'err.LEAD_NOT_CONVERTED': 'Чтобы перевести в «Подключён», нажмите «Подключить» — так создастся партнёр.',
|
||
'err.ALREADY_CONVERTED': 'Лид уже подключён.',
|
||
'err.AGENCY_CODE_FORMAT': 'Код — латиница, цифры и «_», до 32 символов.',
|
||
'err.AGENCY_CODE_TAKEN': 'Такой код уже есть у другого агентства.',
|
||
'err.STAGES_INVALID': 'Нужен хотя бы один открытый этап и один «Подключён».',
|
||
'audit.bo.crm.create': 'добавил(а) лид',
|
||
'audit.bo.crm.update': 'изменил(а) лид',
|
||
'audit.bo.crm.move': 'перевёл(а) лид на другой этап',
|
||
'audit.bo.crm.convert': 'подключил(а) партнёра',
|
||
'audit.bo.crm.addActivity': 'записал(а) контакт',
|
||
'audit.bo.crm.saveStages': 'изменил(а) воронку',
|
||
'audit.bo.crm.setBonusRules': 'изменил(а) формулу бонуса',
|
||
'audit.bo.partners.saveAgency': 'изменил(а) агентство',
|
||
'audit.bo.partners.agencyPayout': 'отметил(а) выплату агентству',
|
||
'audit.bo.partners.saveVenue': 'изменил(а) заведение',
|
||
'audit.bo.partners.saveOffer': 'изменил(а) предложение заведения',
|
||
'audit.bo.partners.ownerInvite': 'выпустил(а) ссылку собственнику',
|
||
'audit.bo.partners.removeMember': 'убрал(а) сотрудника заведения',
|
||
|
||
// ───── заказы и исполнители (этап 3) ─────
|
||
'ord.title': 'Заказы',
|
||
'ord.new': 'Новый заказ',
|
||
'ord.search': '№, клиент, телефон, адрес или исполнитель',
|
||
'ord.period': 'Период',
|
||
'ord.period.all': 'Все даты',
|
||
'ord.period.today': 'Сегодня',
|
||
'ord.period.tomorrow': 'Завтра',
|
||
'ord.period.week': '7 дней',
|
||
'ord.period.past': 'Прошедшие',
|
||
'ord.group.active': 'В работе у команды',
|
||
'ord.group.new': 'Ждут исполнителя',
|
||
'ord.group.pending': 'Предложены',
|
||
'ord.group.assigned': 'Назначены',
|
||
'ord.group.in_progress': 'Выполняются',
|
||
'ord.group.done': 'Готово',
|
||
'ord.group.cancelled': 'Отменены',
|
||
'ord.today': 'Сегодня',
|
||
'ord.tomorrow': 'Завтра',
|
||
'ord.empty': 'Заказов с такими условиями нет.',
|
||
'ord.waitsAnswer': 'ждём ответа: {name}',
|
||
'ord.needsHuman': 'нужен диспетчер',
|
||
'ord.searching': 'система подбирает…',
|
||
'ord.overdue': 'время прошло, исполнителя нет',
|
||
'ord.needsDispatcher': 'Автораспределение не нашло исполнителя для заказов: {n}. Назначьте вручную.',
|
||
'ord.autoOn': 'Автораспределение включено',
|
||
'ord.autoOff': 'Автораспределение выключено',
|
||
'ord.autoHint': 'Новый заказ сам предлагается лучшему свободному исполнителю (язык клиента, район, загрузка, рейтинг). Нет ответа {minutes} мин или отказ — следующему; после {tries} попыток — диспетчеру.',
|
||
'ord.back': 'Все заказы',
|
||
'ord.progress': 'Ход заказа',
|
||
'ord.details': 'Детали',
|
||
'ord.when': 'Когда',
|
||
'ord.where': 'Где',
|
||
'ord.minutes': '{n} мин',
|
||
'ord.params': 'Параметры',
|
||
'ord.extras': 'Доп. услуги',
|
||
'ord.note': 'Комментарий клиента',
|
||
'ord.lang': 'Язык клиента',
|
||
'ord.created': 'Создан',
|
||
'ord.checklist': 'Чек-лист',
|
||
'ord.needsPhoto': 'нужно фото',
|
||
'ord.photo': 'Фото',
|
||
'ord.history': 'История',
|
||
'ord.client': 'Клиент',
|
||
'ord.writeClient': 'Написать клиенту',
|
||
'ord.writeProvider': 'Написать исполнителю',
|
||
'ord.call': 'Позвонить',
|
||
'ord.noPhone': 'Телефон исполнителя не указан — добавьте его в профиле',
|
||
'ord.money': 'Деньги',
|
||
'ord.base': 'Без скидки',
|
||
'ord.discount': 'Скидка {pct}%',
|
||
'ord.payout': 'Исполнителю',
|
||
'ord.cancelFee': 'Удержание за отмену',
|
||
'ord.payment': 'Оплата',
|
||
'ord.markPaid': 'Отметить оплату',
|
||
'ord.confirmPaid': 'Отметить, что клиент оплатил заказ?',
|
||
'ord.paidDone': 'Оплата отмечена',
|
||
'ord.actions': 'Действия',
|
||
'ord.setStatus': 'Статус: {status}',
|
||
'ord.confirmStatus': 'Перевести заказ в «{status}»? Клиент получит уведомление.',
|
||
'ord.statusChanged': 'Статус изменён',
|
||
'ord.reschedule': 'Перенести',
|
||
'ord.rescheduleTitle': 'Перенос заказа №{n}',
|
||
'ord.rescheduleHint': 'Если исполнитель занят в новое время, заказ вернётся в «Ждут исполнителя» и уйдёт в автораспределение.',
|
||
'ord.rescheduled': 'Заказ перенесён, исполнитель тот же',
|
||
'ord.rescheduledFree': 'Заказ перенесён; исполнитель занят — ищем нового',
|
||
'ord.comment': 'Комментарий',
|
||
'ord.commentPh': 'Например: клиент попросил по телефону',
|
||
'ord.cancel': 'Отменить заказ',
|
||
'ord.cancelTitle': 'Отмена заказа',
|
||
'ord.cancelReason': 'Причина отмены',
|
||
'ord.cancelReasonPh': 'Например: клиент передумал',
|
||
'ord.cancelFeeHint': 'Сколько удержать с клиента, ֏. Обычно 0.',
|
||
'ord.cancelHint': 'Клиент и исполнитель получат уведомление.',
|
||
'ord.cancelled': 'Заказ отменён',
|
||
'ord.rating': 'Оценка клиента',
|
||
'ord.noComment': 'Без комментария',
|
||
'ord.offers': 'Кому предлагали',
|
||
'ord.bySystem': 'система',
|
||
'ord.provider': 'Исполнитель',
|
||
'ord.unassign': 'Снять исполнителя',
|
||
'ord.revoke': 'Отозвать предложение',
|
||
'ord.confirmUnassign': 'Снять исполнителя? Заказ вернётся в «Ждут исполнителя».',
|
||
'ord.confirmRevoke': 'Отозвать предложение? Заказ снова будет ждать исполнителя.',
|
||
'ord.unassigned': 'Готово — заказ снова ждёт исполнителя',
|
||
'ord.pendingProvider': 'Предложен: {name}',
|
||
'ord.pendingCompany': 'Передан компании «{name}» — ждём, кого назначит диспетчер',
|
||
'ord.byAuto': 'предложила система',
|
||
'ord.minLeft': 'на ответ ≈ {n} мин',
|
||
'ord.pickHint': 'Свободные на это время — по порядку подбора. Или поручите выбор системе.',
|
||
'ord.autoPick': 'Подобрать автоматически',
|
||
'ord.autoOffered': 'Предложили: {name}',
|
||
'ord.autoNone': 'Свободных исполнителей не нашлось',
|
||
'ord.noFree': 'На это время все заняты. Перенесите заказ или договоритесь с исполнителем.',
|
||
'ord.busy': 'Заняты в это время: {n}',
|
||
'ord.company': 'компания',
|
||
'ord.tried': 'уже предлагали',
|
||
'ord.load': 'заказов в этот день: {n}',
|
||
'ord.offer': 'Предложить',
|
||
'ord.offered': 'Заказ отправлен исполнителю',
|
||
'ord.noProvider': 'Исполнитель не назначался.',
|
||
'ord.ev.created': 'Заказ создан',
|
||
'ord.ev.createdByStaff': 'Заказ оформила команда',
|
||
'ord.ev.offered': 'Предложен исполнителю',
|
||
'ord.ev.autoOffered': 'Автораспределение: предложен',
|
||
'ord.ev.autoNoCandidate': 'Автораспределение: свободных нет',
|
||
'ord.ev.autoGaveUp': 'Автораспределение остановлено — нужен диспетчер',
|
||
'no.title': 'Новый заказ',
|
||
'no.client': 'Клиент',
|
||
'no.clientPh': 'Имя, @username или телефон',
|
||
'no.noClients': 'Никого не нашли',
|
||
'no.changeClient': 'Другой клиент',
|
||
'no.service': 'Услуга',
|
||
'no.extras': 'Доп. услуги',
|
||
'no.address': 'Адрес',
|
||
'no.addressPh': 'Улица, дом, квартира',
|
||
'no.district': 'Район',
|
||
'no.when': 'Дата и время',
|
||
'no.day': 'День',
|
||
'no.noSlots': 'На этот день свободного времени нет — выберите другой день или «другое время».',
|
||
'no.otherTime': 'Другое время (договорились с исполнителем сами)',
|
||
'no.customTime': 'Время',
|
||
'no.customHint': 'По Еревану. Свободных исполнителей система не гарантирует.',
|
||
'no.note': 'Комментарий для исполнителя',
|
||
'no.notePh': 'Код домофона, животные…',
|
||
'no.payment': 'Оплата',
|
||
'no.hint': 'Цена — с учётом подписки клиента. Клиент получит уведомление в бота, заказ сразу уйдёт в автораспределение.',
|
||
'no.create': 'Оформить заказ',
|
||
'no.created': 'Заказ №{n} оформлен',
|
||
'prv.title': 'Исполнители',
|
||
'prv.add': 'Добавить',
|
||
'prv.search': 'Имя или телефон',
|
||
'prv.status.active': 'Работают',
|
||
'prv.status.blocked': 'Заблокированы',
|
||
'prv.status.all': 'Все',
|
||
'prv.empty': 'Никого не нашли.',
|
||
'prv.col.name': 'Исполнитель',
|
||
'prv.col.rating': 'Рейтинг',
|
||
'prv.col.done': 'Заказов',
|
||
'prv.col.refused': 'Отказы',
|
||
'prv.col.next': 'Ближайший заказ',
|
||
'prv.period30': 'Заказы, отказы и низкие оценки — за 30 дней.',
|
||
'prv.blocked': 'заблокирован',
|
||
'prv.onShift': 'на смене',
|
||
'prv.offShift': 'не на смене',
|
||
'prv.notLinked': 'не открыл бота',
|
||
'prv.noDocs': 'нет документов',
|
||
'prv.ratings': 'оценок: {n}',
|
||
'prv.low': 'низких: {n}',
|
||
'prv.today': 'сегодня: {n}',
|
||
'prv.back': 'Все исполнители',
|
||
'prv.write': 'Написать',
|
||
'prv.edit': 'Редактировать',
|
||
'prv.blockedSince': 'Заблокирован с {date}.',
|
||
'prv.unblock': 'Вернуть к работе',
|
||
'prv.inviteHint': 'Исполнитель ещё не открыл рабочий бот — отправьте ему ссылку.',
|
||
'prv.copyInvite': 'Скопировать ссылку',
|
||
'prv.quality': 'Качество',
|
||
'prv.days30': 'за 30 дней',
|
||
'prv.acceptRate': 'принял {a} из {n} предложений',
|
||
'prv.refusals': 'отказы: {d}, молчал: {e}',
|
||
'prv.lowRatings': 'оценок 3 и ниже',
|
||
'prv.upcoming': 'Ближайшие заказы',
|
||
'prv.noUpcoming': 'Назначенных заказов нет.',
|
||
'prv.recent': 'Последние выполненные',
|
||
'prv.balance': 'К выплате',
|
||
'prv.thisMonth': 'Этот месяц',
|
||
'prv.prevMonth': 'Прошлый',
|
||
'prv.paidTotal': 'Выплачено',
|
||
'prv.payout': 'Отметить выплату',
|
||
'prv.payoutTitle': 'Выплата исполнителю',
|
||
'prv.amount': 'Сумма, ֏',
|
||
'prv.balanceHint': 'Долг перед исполнителем: {sum}',
|
||
'prv.payoutNote': 'Как выплатили',
|
||
'prv.payoutNotePh': 'Наличные / перевод на карту…',
|
||
'prv.payoutConfirm': 'Выплачено',
|
||
'prv.payoutDone': 'Выплата отмечена',
|
||
'prv.rateCompany': 'ставка компании {v}',
|
||
'prv.rateOwn': 'ставка {v}',
|
||
'prv.ratePreset': 'по пресету «{name}»',
|
||
'prv.work': 'Работа',
|
||
'prv.languages': 'Языки',
|
||
'prv.districts': 'Районы',
|
||
'prv.anyDistrict': 'любые',
|
||
'prv.districtsHint': 'Подбор ставит выше тех, кто работает в районе заказа.',
|
||
'prv.docs': 'Документы для допуска',
|
||
'prv.noDocsHint': 'Паспорт, договор, справка — всё хранится в закрытом хранилище.',
|
||
'prv.docTitlePh': 'Название: паспорт, договор…',
|
||
'prv.upload': 'Загрузить',
|
||
'prv.docAdded': 'Документ добавлен',
|
||
'prv.removeDocConfirm': 'Удалить документ?',
|
||
'prv.access': 'Допуск',
|
||
'prv.block': 'Заблокировать',
|
||
'prv.blockTitle': 'Заблокировать исполнителя',
|
||
'prv.blockReason': 'Причина',
|
||
'prv.blockReasonPh': 'Например: жалобы клиентов, нет документов',
|
||
'prv.blockHint': 'Заказы ему больше не предлагаются, действующие предложения отзываются. Уже назначенные заказы остаются — переназначьте их вручную.',
|
||
'prv.resetInvite': 'Новая ссылка для входа в бот',
|
||
'prv.resetConfirm': 'Сделать новую ссылку? Текущая привязка к Telegram снимется — исполнителю нужно будет войти заново.',
|
||
'prv.since': 'С нами с {date}',
|
||
'prv.saved': 'Сохранено',
|
||
'prv.addTitle': 'Новый исполнитель',
|
||
'prv.editTitle': 'Профиль исполнителя',
|
||
'prv.name': 'Имя',
|
||
'prv.role': 'Роль',
|
||
'prv.company': 'Компания',
|
||
'prv.freelance': 'Частный исполнитель',
|
||
'prv.schedule': 'График',
|
||
'prv.rate': 'Ставка',
|
||
'prv.note': 'Заметка команды',
|
||
'err.REASON_REQUIRED': 'Укажите причину.',
|
||
'err.SLOT_UNAVAILABLE': 'Это время уже занято или прошло. Выберите другое или «другое время».',
|
||
'err.ALREADY_ASSIGNED': 'Заказ уже назначен или предложен — обновите страницу.',
|
||
'err.PROVIDER_BUSY': 'Исполнитель занят в это время.',
|
||
'err.TRANSITION_NOT_ALLOWED': 'Сейчас этот шаг для заказа недоступен.',
|
||
'err.CHECKLIST_INCOMPLETE': 'Сначала исполнитель должен закрыть чек-лист и приложить фото.',
|
||
'err.CONSENT_REQUIRED': 'Клиент ещё не дал согласие на обработку данных в боте — заказ оформить нельзя.',
|
||
'err.ADDRESS_REQUIRED': 'Укажите адрес и район.',
|
||
'err.INVALID_PARAMS': 'Проверьте параметры заказа.',
|
||
'err.OFFER_NOT_ACTIVE': 'Предложение уже неактуально.',
|
||
'err.BAD_FILE_TYPE_DOC': 'Можно фото или PDF.',
|
||
'audit.bo.orders.assign': 'предложил(а) заказ исполнителю',
|
||
'audit.bo.orders.auto': 'запустил(а) подбор исполнителя',
|
||
'audit.bo.orders.unassign': 'снял(а) исполнителя с заказа',
|
||
'audit.bo.orders.transition': 'сменил(а) статус заказа',
|
||
'audit.bo.orders.cancel': 'отменил(а) заказ',
|
||
'audit.bo.orders.reschedule': 'перенёс(ла) заказ',
|
||
'audit.bo.orders.markPaid': 'отметил(а) оплату заказа',
|
||
'audit.bo.orders.create': 'оформил(а) заказ за клиента',
|
||
'audit.bo.orders.setAutoSetting': 'изменил(а) автораспределение',
|
||
'audit.bo.providers.create': 'добавил(а) исполнителя',
|
||
'audit.bo.providers.update': 'изменил(а) профиль исполнителя',
|
||
'audit.bo.providers.setActive': 'изменил(а) допуск исполнителя',
|
||
'audit.bo.providers.resetInvite': 'выпустил(а) новую ссылку исполнителю',
|
||
'audit.bo.providers.removeDoc': 'удалил(а) документ исполнителя',
|
||
'audit.bo.providers.addDoc': 'загрузил(а) документ исполнителя',
|
||
'audit.bo.providers.payout': 'отметил(а) выплату исполнителю',
|
||
'chat.order': 'Заказ №{n}',
|
||
'chat.noOrder': 'Без заказа',
|
||
'chat.noOrderNow': 'Сейчас без заказа',
|
||
'chat.orderNow': 'Сейчас',
|
||
'chat.orderNext': 'Ближайший',
|
||
'chat.orderNoNext': 'Ближайших заказов нет',
|
||
'chat.orderClient': 'клиент {name}',
|
||
'chat.wroteNoOrder': 'писал(а) без заказа',
|
||
'err.CONCIERGE_SUBSCRIBERS_ONLY': 'Консьерж — только для подписчиков. Сначала выдайте клиенту подписку.',
|
||
'err.ASSIGNEE_NO_ACCESS': 'У этого сотрудника нет доступа к этому каналу.',
|
||
'err.PROVIDER_NOT_LINKED': 'Исполнитель ещё не открыл рабочий бот — написать ему пока некуда.',
|
||
'err.BAD_FILE_TYPE': 'Такой файл не подойдёт. Можно фото, PDF, Word, Excel, текст или ZIP.',
|
||
'audit.bo.chats.send': 'ответил(а) в чате',
|
||
'audit.bo.chats.sendFile': 'отправил(а) файл в чате',
|
||
'audit.bo.chats.assign': 'назначил(а) ответственного в чате',
|
||
'audit.bo.chats.close': 'закрыл(а) диалог',
|
||
'audit.bo.chats.reopen': 'открыл(а) диалог снова',
|
||
'audit.bo.chats.move': 'перенёс(ла) диалог в другой канал',
|
||
'audit.bo.chats.openFor': 'открыл(а) чат с клиентом',
|
||
'audit.bo.chats.templates.save': 'изменил(а) шаблон ответа',
|
||
'audit.bo.chats.templates.remove': 'удалил(а) шаблон ответа',
|
||
};
|
||
|
||
export type BoKey = keyof typeof ru;
|
||
type Dict = Record<BoKey, string>;
|
||
|
||
const en: Dict = {
|
||
'ui.save': 'Save',
|
||
'ui.close': 'Close',
|
||
'ui.loading': 'Loading…',
|
||
'ui.error': 'That didn’t work: {msg}',
|
||
'ui.retry': 'Try again',
|
||
'ui.copy': 'Copy',
|
||
'ui.copied': 'Copied',
|
||
'ui.days': '{n} d',
|
||
'ui.yes': 'Yes',
|
||
'ui.no': 'No',
|
||
'ui.none': '—',
|
||
|
||
'err.PAYMENTS_NOT_CONFIGURED': 'Online payments aren’t connected yet — mark the payment manually.',
|
||
'err.REFUND_TOO_BIG': 'The refund is larger than what the client paid.',
|
||
'err.ENDS_BEFORE_START': 'A subscription can’t end before it starts.',
|
||
'err.CANNOT_DEMOTE_SELF': 'You can’t disable yourself or remove your own super admin role.',
|
||
'err.ROLE_FORBIDDEN': 'Your role doesn’t have access to this action.',
|
||
'err.NO_ROLE': 'Your account has no roles in the new admin. Ask a super admin to grant them.',
|
||
|
||
'login.coverWord': 'team',
|
||
'login.title': 'Team sign-in',
|
||
'login.lead': 'Confirm sign-in in the Barev Club work bot. No password needed.',
|
||
'login.open': 'Confirm in Telegram',
|
||
'login.qr': 'On a computer, scan the code with your phone.',
|
||
'login.waiting': 'Waiting for confirmation in Telegram…',
|
||
'login.expired': 'The link has expired.',
|
||
'login.retry': 'Get a new link',
|
||
'login.dev': 'Local sign-in',
|
||
'login.devHint': 'Only on this computer — the server doesn’t show this block.',
|
||
'login.noTelegram': 'No access? Ask a super admin to add you to the team and send a Telegram link.',
|
||
|
||
'nav.dashboard': 'Dashboard',
|
||
'nav.clients': 'Clients',
|
||
'nav.chats': 'Chats',
|
||
'nav.orders': 'Orders',
|
||
'nav.providers': 'Providers',
|
||
'nav.agencies': 'Agencies',
|
||
'nav.venues': 'Venues',
|
||
'nav.crm': 'CRM',
|
||
'nav.products': 'Products',
|
||
'nav.journal': 'Activity log',
|
||
'nav.team': 'Team',
|
||
'nav.more': 'More',
|
||
'nav.soon': 'stage {n}',
|
||
'nav.groupWork': 'Work',
|
||
'nav.groupPartners': 'Partners',
|
||
'nav.groupSetup': 'Setup',
|
||
|
||
'role.SUPERADMIN': 'Super admin',
|
||
'role.SUPPORT': 'Support',
|
||
'role.CONCIERGE': 'Concierge',
|
||
'role.SALES': 'Sales',
|
||
'roleHint.SUPERADMIN': 'Everything, including money and the team',
|
||
'roleHint.SUPPORT': 'Support chat, orders, subscriptions',
|
||
'roleHint.CONCIERGE': 'Concierge chat for subscribers',
|
||
'roleHint.SALES': 'CRM: venues and agencies',
|
||
|
||
'shell.logout': 'Sign out',
|
||
'shell.oldAdmin': 'Old admin',
|
||
'shell.linkTg': 'Link Telegram — you sign in and get notifications through it.',
|
||
'shell.linkTgBtn': 'Link Telegram',
|
||
|
||
'soon.title': '{section} is moving here',
|
||
'soon.text': 'This section arrives in stage {n}. Until then, use the old admin — the data is shared.',
|
||
'soon.open': 'Open the old admin',
|
||
|
||
'dash.morning': 'Good morning, {name}',
|
||
'dash.day': 'Good afternoon, {name}',
|
||
'dash.evening': 'Good evening, {name}',
|
||
'dash.attention': 'Needs attention',
|
||
'dash.allClear': 'Nothing urgent — all caught up.',
|
||
'att.unassigned': 'Orders without a provider',
|
||
'att.unreadChats': 'Chats awaiting reply',
|
||
'att.webRequests': 'Website requests',
|
||
'att.leads': 'Relocation requests',
|
||
'att.appRequests': 'In-app requests',
|
||
'att.lowRatings': 'Ratings of 3 or lower this week',
|
||
'att.expiring': 'Subscriptions ending within 7 days',
|
||
'dash.money': 'Money',
|
||
'dash.today': 'Today',
|
||
'dash.week': '7 days',
|
||
'dash.month': '30 days',
|
||
'dash.vsYesterday': 'yesterday {sum}',
|
||
'dash.vsPrev': 'vs previous {period}',
|
||
'dash.orders': 'orders',
|
||
'dash.subs': 'subscriptions',
|
||
'dash.chart': 'Daily revenue, last 30 days',
|
||
'dash.subsTitle': 'Subscriptions',
|
||
'dash.gifts': 'Gifts among them: {n}',
|
||
'dash.expiring': 'Ending in the next 7 days',
|
||
'dash.noExpiring': 'Nothing ends in the coming week.',
|
||
'dash.conversion': 'Gift → purchase',
|
||
'dash.conversionHint': '{paid} of {total} gifted clients later bought a subscription',
|
||
'dash.growth': 'Growth',
|
||
'dash.newClients': 'New clients',
|
||
'dash.prevMonth': 'previous 30 days — {n}',
|
||
'dash.sources': 'Where they came from, 30 days',
|
||
'dash.funnel': 'Funnel, 30 days',
|
||
'funnel.leads': 'Website requests',
|
||
'funnel.clients': 'Clients in the app',
|
||
'funnel.paying': 'Paid',
|
||
'dash.team': 'Team and partners',
|
||
'dash.topProviders': 'Top providers',
|
||
'dash.bottomProviders': 'Worth a talk',
|
||
'dash.topPartners': 'Venues: card scans, 30 days',
|
||
'dash.salesSoon': 'Sales results will appear with the CRM.',
|
||
'dash.empty': 'Nothing yet',
|
||
'dash.feed': 'Feed',
|
||
'feed.subscription': '{plan} · {source}',
|
||
'feed.payment': 'Order #{number} paid',
|
||
'dash.ratings': '{n} ratings',
|
||
'dash.scans': '{n} scans',
|
||
|
||
'source.organic': 'Found us',
|
||
'source.deeplink': 'Agency link',
|
||
'source.manual_code': 'Agency code',
|
||
'source.agency': 'Agency “{name}”',
|
||
'source.utm': 'Ads: {name}',
|
||
|
||
'plan.BAREV_PLUS': 'Barev+',
|
||
'plan.ELITE': 'Elite',
|
||
'plan.none': 'No subscription',
|
||
'subSource.PAID': 'Purchase',
|
||
'subSource.MANUAL': 'Team gift',
|
||
'subSource.AGENCY_GIFT': 'Agency gift',
|
||
'subStatus.ACTIVE': 'Active',
|
||
'subStatus.EXPIRED': 'Expired',
|
||
'subStatus.CANCELLED': 'Cancelled',
|
||
'pay.cash': 'Cash',
|
||
'pay.transfer': 'Bank transfer',
|
||
'pay.card': 'Card via terminal',
|
||
'pay.link': 'Payment link',
|
||
'segment.MOVING': 'Relocating',
|
||
'segment.LIVING': 'Lives in Armenia',
|
||
|
||
'clients.title': 'Clients',
|
||
'clients.search': 'Name, @username, phone or card number',
|
||
'clients.found': 'Found: {n}',
|
||
'clients.revenueTotal': 'brought {sum}',
|
||
'col.client': 'Client',
|
||
'col.sub': 'Subscription',
|
||
'col.source': 'Source',
|
||
'col.revenue': 'Brought',
|
||
'col.since': 'Joined',
|
||
'filter.plan': 'Subscription',
|
||
'filter.all': 'All',
|
||
'filter.any': 'Subscribed',
|
||
'filter.none': 'Not subscribed',
|
||
'filter.subSource': 'How received',
|
||
'filter.source': 'Source',
|
||
'filter.agency': 'Agency',
|
||
'filter.tag': 'Tag',
|
||
'filter.segment': 'Scenario',
|
||
'filter.paying': 'Paid',
|
||
'filter.payingYes': 'Have paid',
|
||
'filter.payingNo': 'Never paid',
|
||
'filter.expiring': 'Ends within 7 days',
|
||
'filter.reset': 'Reset filters',
|
||
'filter.more': 'Filters',
|
||
'filter.anyValue': 'Any',
|
||
'sort.label': 'Order',
|
||
'sort.new': 'Newest first',
|
||
'sort.revenue': 'Brought the most',
|
||
'sort.ends': 'Ending soon',
|
||
'segments.title': 'My segments',
|
||
'segments.save': 'Save segment',
|
||
'segments.name': 'Segment name',
|
||
'segments.saved': 'Segment saved',
|
||
'segments.remove': 'Delete segment “{name}”',
|
||
'clients.export': 'Download for Excel',
|
||
'clients.exported': 'File downloaded',
|
||
'clients.broadcast': 'Broadcast',
|
||
'clients.broadcastSoon': 'Segment broadcasts arrive in stage 5.',
|
||
'clients.empty': 'No one matches these filters.',
|
||
'clients.emptyAll': 'No clients yet — they appear once they message the bot.',
|
||
'clients.prev': 'Back',
|
||
'clients.next': 'Next',
|
||
'clients.page': '{from}–{to} of {total}',
|
||
|
||
'card.back': 'All clients',
|
||
'card.since': 'With us since {date}',
|
||
'card.telegram': 'Open in Telegram',
|
||
'card.cardNo': 'Card {code}',
|
||
'card.noSub': 'No active subscription',
|
||
'card.noSubHint': 'Gift or sell a subscription — the client gets discounts right away.',
|
||
'card.until': 'until {date}',
|
||
'card.daysLeft': '{n} d left',
|
||
'card.history': 'All subscriptions',
|
||
'card.grantedBy': 'granted by {name}',
|
||
'card.giftFrom': 'gift from “{name}”',
|
||
'card.paidVia': '{method}',
|
||
'card.refunded': 'refund {sum}',
|
||
'card.cancelledAt': 'cancelled {date}',
|
||
'card.upcoming': 'starts {date}',
|
||
'card.money': 'Brought',
|
||
'card.fromOrders': 'orders',
|
||
'card.fromSubs': 'subscriptions',
|
||
'card.orders': 'Orders',
|
||
'card.noOrders': 'No orders yet.',
|
||
'card.newOrder': 'Create order',
|
||
'card.newOrderSoon': 'Ordering on a client’s behalf arrives in stage 3, together with the orders section.',
|
||
'card.profile': 'Profile',
|
||
'card.source': 'Source',
|
||
'card.agency': 'Agency',
|
||
'card.language': 'Language',
|
||
'card.phone': 'Phone',
|
||
'card.segment': 'Scenario',
|
||
'card.consent': 'Data processing consent',
|
||
'card.tags': 'Tags',
|
||
'card.addTag': 'New tag',
|
||
'card.note': 'Team note',
|
||
'card.notePh': 'The client doesn’t see this note',
|
||
'card.saved': 'Saved',
|
||
'card.activity': 'Client log',
|
||
'card.noActivity': 'The team hasn’t changed anything yet.',
|
||
'card.stats': 'Activity',
|
||
'stat.cardUsages': 'card scans',
|
||
'stat.leads': 'relocation requests',
|
||
'stat.requests': 'in-app requests',
|
||
'stat.concierge': 'chat messages',
|
||
|
||
'act.gift': 'Gift',
|
||
'act.sell': 'Sell',
|
||
'act.extend': 'Change term',
|
||
'act.cancel': 'Cancel',
|
||
'act.changePlan': 'Change plan',
|
||
'act.refund': 'Refund',
|
||
|
||
'audit.bo.clients.gift': 'gifted a subscription',
|
||
'audit.bo.clients.sell': 'sold a subscription',
|
||
'audit.bo.clients.extend': 'changed the subscription term',
|
||
'audit.bo.clients.cancel': 'cancelled a subscription',
|
||
'audit.bo.clients.changePlan': 'changed the plan',
|
||
'audit.bo.clients.refund': 'issued a refund',
|
||
'audit.bo.clients.setTags': 'changed tags',
|
||
'audit.bo.clients.setNote': 'changed the note',
|
||
|
||
'dlg.giftTitle': 'Gift a subscription',
|
||
'dlg.giftHint': 'It will be marked as a gift from you.',
|
||
'dlg.sellTitle': 'Sell a subscription',
|
||
'dlg.plan': 'Plan',
|
||
'dlg.period': 'Term',
|
||
'dlg.period1': '1 month',
|
||
'dlg.period3': '3 months',
|
||
'dlg.period6': '6 months',
|
||
'dlg.period12': '1 year',
|
||
'dlg.periodCustom': 'Custom',
|
||
'dlg.days': 'Days',
|
||
'dlg.amount': 'Amount, ֏',
|
||
'dlg.method': 'Paid by',
|
||
'dlg.note': 'Note for the team',
|
||
'dlg.linkSoon': 'Payment links turn on once a payment provider is connected.',
|
||
'dlg.giftConfirm': 'Gift',
|
||
'dlg.sellConfirm': 'Mark as paid',
|
||
'dlg.extendTitle': 'Change term',
|
||
'dlg.extendHint': 'A negative number shortens the term.',
|
||
'dlg.newEnd': 'New end date: {date}',
|
||
'dlg.extendConfirm': 'Save term',
|
||
'dlg.cancelTitle': 'Cancel subscription',
|
||
'dlg.cancelHint': 'The client loses subscription discounts and perks immediately.',
|
||
'dlg.reason': 'Reason',
|
||
'dlg.cancelConfirm': 'Cancel subscription',
|
||
'dlg.planTitle': 'Change plan',
|
||
'dlg.planConfirm': 'Change plan',
|
||
'dlg.refundTitle': 'Refund',
|
||
'dlg.refundPaid': 'Paid {sum}, already refunded {back}',
|
||
'dlg.refundCancel': 'Cancel the subscription too',
|
||
'dlg.refundConfirm': 'Issue refund',
|
||
'done.gift': 'Subscription gifted',
|
||
'done.sell': 'Payment recorded',
|
||
'done.extend': 'Term changed',
|
||
'done.cancel': 'Subscription cancelled',
|
||
'done.changePlan': 'Plan changed',
|
||
'done.refund': 'Refund issued',
|
||
|
||
'team.title': 'Team',
|
||
'team.lead': 'Who works in the admin and what they can access. One person can have several roles.',
|
||
'team.add': 'Add a person',
|
||
'team.name': 'Name',
|
||
'team.roles': 'Roles',
|
||
'team.create': 'Add',
|
||
'team.linkTitle': 'Link for {name}',
|
||
'team.linkHint': 'Send it to them. They open the work bot, Telegram gets linked, and they can sign in.',
|
||
'team.tgLinked': 'Telegram linked',
|
||
'team.tgNotLinked': 'Telegram not linked',
|
||
'team.newLink': 'Linking link',
|
||
'team.disable': 'Disable access',
|
||
'team.enable': 'Restore access',
|
||
'team.disabled': 'Access disabled',
|
||
'team.you': 'you',
|
||
'team.saved': 'Roles saved',
|
||
|
||
// ───── чаты (этап 2) ─────
|
||
'chat.title': 'Chats',
|
||
'chat.all': 'All',
|
||
'channel.SUPPORT': 'Support',
|
||
'channel.CONCIERGE': 'Concierge',
|
||
'chat.f.waiting': 'Awaiting reply',
|
||
'chat.f.mine': 'Mine',
|
||
'chat.f.unassigned': 'Unassigned',
|
||
'chat.f.open': 'Open',
|
||
'chat.f.closed': 'Closed',
|
||
'chat.f.all': 'All',
|
||
'chat.search': 'Name, @username, phone or text',
|
||
'chat.emptyList': 'Nothing here. New messages will appear on their own.',
|
||
'chat.emptyFilter': 'Nothing found — try another filter.',
|
||
'chat.pick': 'Pick a conversation',
|
||
'chat.pickHint': 'Those waiting longest are on top.',
|
||
'chat.waiting': 'waiting {t}',
|
||
'chat.you': 'You',
|
||
'chat.provider': 'Provider',
|
||
'chat.unassigned': 'Nobody assigned',
|
||
'chat.take': 'Take it',
|
||
'chat.transfer': 'Pass on',
|
||
'chat.transferTo': 'Pass to a colleague',
|
||
'chat.unassign': 'Remove assignee',
|
||
'chat.close': 'Close',
|
||
'chat.reopen': 'Reopen',
|
||
'chat.closedBanner': 'The conversation is closed. It reopens when the client writes; you can still reply now.',
|
||
'chat.moveTo': 'Move to {channel}',
|
||
'chat.moved': 'Moved to {channel}',
|
||
'chat.movedAway': 'Moved to {channel}. You have no access to that channel.',
|
||
'chat.other': 'There is also a {channel} conversation',
|
||
'chat.otherOpen': 'Open',
|
||
'chat.bot': 'The AI concierge is handling this conversation.',
|
||
'chat.botTake': 'Take over',
|
||
'chat.reply': 'Reply',
|
||
'chat.note': 'Note',
|
||
'chat.replyPh': 'Reply to the client — goes to their Telegram',
|
||
'chat.notePh': 'Note for the team — the client won’t see it',
|
||
'chat.send': 'Send',
|
||
'chat.saveNote': 'Save note',
|
||
'chat.attach': 'Attach a file',
|
||
'chat.templates': 'Templates',
|
||
'chat.tplManage': 'Manage templates',
|
||
'chat.tplEmpty': 'No templates yet.',
|
||
'chat.tplNew': 'New template',
|
||
'chat.tplTitle': 'Title',
|
||
'chat.tplText': 'Text',
|
||
'chat.tplTextHint': '{name} is replaced with the client’s name',
|
||
'chat.tplChannel': 'Channel',
|
||
'chat.tplBoth': 'Both channels',
|
||
'chat.tplDelete': 'Delete',
|
||
'chat.tplSaved': 'Template saved',
|
||
'chat.tplSearch': 'Find a template',
|
||
'chat.noteLabel': 'Note · team only',
|
||
'chat.fromApp': 'from the app',
|
||
'chat.undelivered': 'Not delivered: the client blocked the bot or never opened it',
|
||
'chat.fileTooBig': 'The file is larger than 10 MB',
|
||
'chat.enterHint': 'Enter to send · Shift+Enter for a new line',
|
||
'chat.providerNotLinked': 'The provider hasn’t opened the work bot yet — you can only leave a note for now.',
|
||
'chat.client': 'About the client',
|
||
'chat.aboutProvider': 'About the provider',
|
||
'chat.openCard': 'Client card',
|
||
'chat.write': 'Message',
|
||
'chat.back': 'All conversations',
|
||
'chat.sys.took': '{name} took the conversation',
|
||
'chat.sys.transferred': '{name} passed the conversation to {param}',
|
||
'chat.sys.unassigned': '{name} removed the assignee',
|
||
'chat.sys.closed': '{name} closed the conversation',
|
||
'chat.sys.reopened': '{name} reopened the conversation',
|
||
'chat.sys.moved': '{name} moved the conversation to {param}',
|
||
'chat.ago.now': 'just now',
|
||
'chat.ago.min': '{n} min',
|
||
'chat.ago.h': '{n} h',
|
||
'chat.ago.d': '{n} d',
|
||
'chat.today': 'Today',
|
||
'chat.yesterday': 'Yesterday',
|
||
'chat.image': 'Photo',
|
||
'chat.file': 'File',
|
||
'chat.subUntil': 'until {date}',
|
||
'chat.orders': 'Orders',
|
||
'chat.phone': 'Phone',
|
||
'chat.lang': 'Language',
|
||
'chat.source': 'Source',
|
||
'chat.linked': 'Work bot opened',
|
||
'chat.notLinked': 'Work bot not opened',
|
||
'chat.details': 'Details',
|
||
'chat.more': 'More actions',
|
||
|
||
// ───── партнёры и CRM (этап 4) ─────
|
||
'crm.title': 'CRM',
|
||
'crm.newLead': 'New lead',
|
||
'crm.editLead': 'Lead',
|
||
'crm.stagesBtn': 'Pipeline',
|
||
'crm.tab.board': 'Pipeline',
|
||
'crm.tab.tasks': 'Tasks',
|
||
'crm.tab.map': 'Map',
|
||
'crm.search': 'Name, contact, phone or address',
|
||
'crm.kind.all': 'All',
|
||
'crm.kind.VENUE': 'Venues',
|
||
'crm.kind.AGENCY': 'Agencies',
|
||
'crm.kind1.VENUE': 'Venue',
|
||
'crm.kind1.AGENCY': 'Agency',
|
||
'crm.owner': 'Sales rep',
|
||
'crm.allSales': 'All sales reps',
|
||
'crm.noOwner': 'Unassigned',
|
||
'crm.ownerIs': 'owned by {name}',
|
||
'crm.connected': 'Connected',
|
||
'crm.connect': 'Connecting',
|
||
'crm.days': '{n} d',
|
||
'crm.inStage': 'Days in this stage',
|
||
'crm.dropHere': 'Drop here',
|
||
'crm.dragHint': 'Drag cards between stages. “Connected” creates the partner or agency and gives you a link; “Lost” asks for a reason.',
|
||
'crm.overdue': 'overdue',
|
||
'crm.tasksOpen': 'Open',
|
||
'crm.tasksDone': 'Done',
|
||
'crm.addTask': 'Task',
|
||
'crm.noTasks': 'No open tasks.',
|
||
'crm.noDoneTasks': 'No completed tasks yet.',
|
||
'crm.noLead': 'no lead',
|
||
'crm.tasksHint': 'When a task is due you get a reminder in the work bot (if Telegram is linked).',
|
||
'crm.taskTitle': 'What to do',
|
||
'crm.taskDay': 'Day',
|
||
'crm.taskTime': 'Time',
|
||
'crm.taskHint': 'A reminder comes to the work bot at this time (Yerevan).',
|
||
'crm.tp.call': 'Call',
|
||
'crm.tp.meet': 'Meeting',
|
||
'crm.tp.send': 'Send the terms',
|
||
'crm.tp.check': 'Ask for a decision',
|
||
'crm.partnerOnMap': 'club partner',
|
||
'crm.legendPartner': 'connected partners',
|
||
'crm.legendLead': 'leads (stage colour)',
|
||
'crm.mapHint': 'A dot appears once a lead has coordinates.',
|
||
'crm.name': 'Name',
|
||
'crm.namePhVenue': 'E.g. Lumen Coffee',
|
||
'crm.namePhAgency': 'E.g. Domik Realty',
|
||
'crm.category': 'Type',
|
||
'crm.contactName': 'Contact person',
|
||
'crm.contactPh': 'Name and position',
|
||
'crm.address': 'Address',
|
||
'crm.note': 'Note',
|
||
'crm.convert': 'Connect',
|
||
'crm.convertTitle': 'Connect “{name}”',
|
||
'crm.convertVenueHint': 'We’ll create a club card partner and an owner link: the owner opens the work bot and can check client cards. Add offers in the venue card.',
|
||
'crm.convertAgencyHint': 'We’ll create the agency with a code and a client link: clients get a gift month and are attached to the agency.',
|
||
'crm.agencyCode': 'Agency code',
|
||
'crm.agencyCodeHint': 'Latin letters and digits; clients can type it in',
|
||
'crm.convertedTitle': 'Connected 🎉',
|
||
'crm.convertedVenue': 'Send this link to the venue owner. It works once.',
|
||
'crm.convertedAgency': 'The agency shares this link with clients.',
|
||
'crm.openVenue': 'Venue card',
|
||
'crm.openAgency': 'Agency card',
|
||
'crm.ownerLinked': 'The owner is already in the work bot.',
|
||
'crm.ownerNotYet': 'The owner hasn’t opened the link yet. Send it again:',
|
||
'crm.agencyInfo': 'Code {code}, clients: {n}',
|
||
'crm.lostTitle': 'Why lost?',
|
||
'crm.lostReason': 'Reason',
|
||
'crm.lr.price': 'Terms didn’t fit',
|
||
'crm.lr.notNow': 'Not now, come back later',
|
||
'crm.lr.noAnswer': 'Not responding',
|
||
'crm.lr.competitor': 'Work with a competitor',
|
||
'crm.lostBanner': 'Lost: {reason}',
|
||
'crm.stagesTitle': 'Pipeline stages',
|
||
'crm.stagesHint': 'Reorder with arrows. You need at least one open and one “Connected” stage. A stage with leads is hidden, not deleted.',
|
||
'crm.addStage': 'Stage',
|
||
'crm.stageKind.OPEN': 'open',
|
||
'crm.stageKind.WON': 'connected',
|
||
'crm.stageKind.LOST': 'lost',
|
||
'crm.bonusMonth': 'Bonus this month',
|
||
'crm.bonusMineSuper': 'Bonus (yours), month',
|
||
'crm.bonusNotSet': 'not set',
|
||
'crm.bonusVenues': 'Venues: {n} → {sum}',
|
||
'crm.bonusAgencies': 'Agencies: {n} → {sum}',
|
||
'crm.bonusRevenue': '{pct}% of agency client revenue → {sum}',
|
||
'crm.bonusTitle': 'Sales bonus formula',
|
||
'crm.bonusHint': 'Monthly bonus = connected venues × rate + agencies × rate + % of revenue from the rep’s agency clients (first N months). Revenue = paid orders and subscriptions.',
|
||
'crm.bonusPerVenue': 'Per venue, ֏',
|
||
'crm.bonusPerAgency': 'Per agency, ֏',
|
||
'crm.bonusPct': '% of agency client revenue',
|
||
'crm.bonusMonths': 'For how many months',
|
||
'crm.back': 'CRM',
|
||
'crm.created': 'since {date}',
|
||
'crm.stage': 'Stage',
|
||
'crm.history': 'Contact history',
|
||
'crm.noHistory': 'Empty so far — log the first call or meeting.',
|
||
'crm.act.CALL': 'Call',
|
||
'crm.act.MEETING': 'Meeting',
|
||
'crm.act.NOTE': 'Note',
|
||
'crm.act.FILE': 'File',
|
||
'crm.act.STAGE': 'Stage',
|
||
'crm.act.WON': 'Connected',
|
||
'crm.actPh.CALL': 'What did you agree on the call?',
|
||
'crm.actPh.MEETING': 'How did the meeting go, what’s next?',
|
||
'crm.actPh.NOTE': 'A note for yourself and the team',
|
||
'crm.addAct': 'Log it',
|
||
'crm.attach': 'Photo or file',
|
||
'crm.tasks': 'Tasks',
|
||
'crm.noLeadTasks': 'No tasks. Set the next step — you’ll get a reminder.',
|
||
'crm.contacts': 'Contacts',
|
||
'crm.noCoords': 'Not on the map yet.',
|
||
'crm.coordsPh': 'Google Maps link or “40.18, 44.51”',
|
||
'crm.coordsBad': 'No coordinates found — paste a Google Maps link or two numbers.',
|
||
'crm.remove': 'Delete lead',
|
||
'crm.removeConfirm': 'Delete the lead with its history and tasks?',
|
||
'venue.cat.cafe': 'Café',
|
||
'venue.cat.restaurant': 'Restaurant',
|
||
'venue.cat.shop': 'Shop',
|
||
'venue.cat.beauty': 'Beauty',
|
||
'venue.cat.other': 'Other',
|
||
'ag.title': 'Agencies',
|
||
'ag.add': 'New agency',
|
||
'ag.editTitle': 'Agency',
|
||
'ag.empty': 'No agencies yet.',
|
||
'ag.col.name': 'Agency',
|
||
'ag.col.clients': 'Clients',
|
||
'ag.col.gifts': 'Gifts',
|
||
'ag.col.month': 'Reward, month',
|
||
'ag.col.balance': 'To pay',
|
||
'ag.hint': 'Reward = % of paid orders of the agency’s clients while they’re attached.',
|
||
'ag.inactive': 'inactive',
|
||
'ag.back': 'All agencies',
|
||
'ag.pct': '{n}% of client orders',
|
||
'ag.byS': 'connected by {name}',
|
||
'ag.link': 'Client link',
|
||
'ag.linkHint': 'The client opens the bot, gets a gift month and is attached to the agency. Or types code {code} via /code.',
|
||
'ag.clients': 'Clients',
|
||
'ag.giftsN': 'gifts: {n}',
|
||
'ag.noClients': 'No clients yet.',
|
||
'ag.orders': 'orders: {n}',
|
||
'ag.toPay': 'Reward to pay',
|
||
'ag.accrued': 'Accrued',
|
||
'ag.payouts': 'Payouts',
|
||
'ag.payoutTitle': 'Payout to agency',
|
||
'ag.balanceHint': 'Accrued and unpaid: {sum}',
|
||
'ag.pctLabel': 'Reward, %',
|
||
'ag.sales': 'Connected by',
|
||
'ag.contactPh': 'Name, phone, Telegram',
|
||
'ag.active': 'Agency active (code accepted)',
|
||
'vn.title': 'Venues',
|
||
'vn.add': 'New venue',
|
||
'vn.editTitle': 'Venue',
|
||
'vn.empty': 'No venues yet.',
|
||
'vn.col.name': 'Venue',
|
||
'vn.col.offers': 'Offers',
|
||
'vn.col.staff': 'Staff',
|
||
'vn.col.visits': 'Checks, 30 d',
|
||
'vn.col.last': 'Last check',
|
||
'vn.hint': 'A check = venue staff scanned a client’s club card in the work bot.',
|
||
'vn.noOwner': 'no owner',
|
||
'vn.noOffers': 'no offers',
|
||
'vn.back': 'All venues',
|
||
'vn.ownerHint': 'The owner isn’t connected yet — send them a one-time work bot link.',
|
||
'vn.makeLink': 'Create link',
|
||
'vn.offers': 'Offers by level',
|
||
'vn.addOffer': 'Offer',
|
||
'vn.editOffer': 'Offer',
|
||
'vn.noOffersHint': 'Add what members get: a discount, a gift, a treat.',
|
||
'vn.level.any': 'Any member',
|
||
'vn.level.BAREV_PLUS': 'Barev+ and Elite',
|
||
'vn.level.ELITE': 'Elite only',
|
||
'vn.limit.NONE': 'unlimited',
|
||
'vn.limit.ONCE': 'once',
|
||
'vn.limit.WEEK': '{n}× a week',
|
||
'vn.limit.MONTH': '{n}× a month',
|
||
'vn.limitOpt.NONE': 'Unlimited',
|
||
'vn.limitOpt.ONCE': 'First visit only',
|
||
'vn.limitOpt.WEEK': 'N times a week',
|
||
'vn.limitOpt.MONTH': 'N times a month',
|
||
'vn.offerOff': 'off',
|
||
'vn.offerTitle': 'What the client gets',
|
||
'vn.offerTitleHint': 'E.g. “Free cappuccino” or “−15% on the menu”',
|
||
'vn.forWhom': 'For whom',
|
||
'vn.howOften': 'How often',
|
||
'vn.times': 'Times',
|
||
'vn.offerActive': 'Offer active',
|
||
'vn.activity': 'Activity',
|
||
'vn.weeks8': 'last 8 weeks',
|
||
'vn.checks': 'card checks',
|
||
'vn.redeemed': 'offers redeemed',
|
||
'vn.cardCheck': 'card check',
|
||
'vn.staff': 'Staff',
|
||
'vn.noStaff': 'Nobody yet.',
|
||
'vn.role.OWNER': 'owner',
|
||
'vn.role.STAFF': 'staff',
|
||
'vn.removeStaff': 'Remove {name} from the venue?',
|
||
'vn.staffHint': 'Staff are invited by the owner in the work bot (24-hour QR).',
|
||
'vn.newOwnerLink': 'Owner link',
|
||
'vn.newOwnerLinkHint': 'A new one-time link — e.g. if the owner changed',
|
||
'vn.blurb': 'Short offer line (shown to clients)',
|
||
'vn.blurbHint': 'E.g. “−10% with the club card”',
|
||
'vn.coords': 'Map point',
|
||
'vn.activeLabel': 'Visible to clients',
|
||
'err.LEAD_NOT_CONVERTED': 'To move to “Connected”, use “Connect” — it creates the partner.',
|
||
'err.ALREADY_CONVERTED': 'The lead is already connected.',
|
||
'err.AGENCY_CODE_FORMAT': 'Code: Latin letters, digits and “_”, up to 32.',
|
||
'err.AGENCY_CODE_TAKEN': 'This code is already taken.',
|
||
'err.STAGES_INVALID': 'You need at least one open and one “Connected” stage.',
|
||
'audit.bo.crm.create': 'added a lead',
|
||
'audit.bo.crm.update': 'edited a lead',
|
||
'audit.bo.crm.move': 'moved a lead',
|
||
'audit.bo.crm.convert': 'connected a partner',
|
||
'audit.bo.crm.addActivity': 'logged a contact',
|
||
'audit.bo.crm.saveStages': 'edited the pipeline',
|
||
'audit.bo.crm.setBonusRules': 'changed the bonus formula',
|
||
'audit.bo.partners.saveAgency': 'edited an agency',
|
||
'audit.bo.partners.agencyPayout': 'recorded an agency payout',
|
||
'audit.bo.partners.saveVenue': 'edited a venue',
|
||
'audit.bo.partners.saveOffer': 'edited a venue offer',
|
||
'audit.bo.partners.ownerInvite': 'issued an owner link',
|
||
'audit.bo.partners.removeMember': 'removed venue staff',
|
||
|
||
// ───── заказы и исполнители (этап 3) ─────
|
||
'ord.title': 'Orders',
|
||
'ord.new': 'New order',
|
||
'ord.search': 'No., client, phone, address or provider',
|
||
'ord.period': 'Period',
|
||
'ord.period.all': 'All dates',
|
||
'ord.period.today': 'Today',
|
||
'ord.period.tomorrow': 'Tomorrow',
|
||
'ord.period.week': '7 days',
|
||
'ord.period.past': 'Past',
|
||
'ord.group.active': 'Active',
|
||
'ord.group.new': 'Need a provider',
|
||
'ord.group.pending': 'Offered',
|
||
'ord.group.assigned': 'Assigned',
|
||
'ord.group.in_progress': 'In progress',
|
||
'ord.group.done': 'Done',
|
||
'ord.group.cancelled': 'Cancelled',
|
||
'ord.today': 'Today',
|
||
'ord.tomorrow': 'Tomorrow',
|
||
'ord.empty': 'No orders match these filters.',
|
||
'ord.waitsAnswer': 'awaiting: {name}',
|
||
'ord.needsHuman': 'needs a dispatcher',
|
||
'ord.searching': 'auto-assigning…',
|
||
'ord.overdue': 'time passed, no provider',
|
||
'ord.needsDispatcher': 'Auto-assignment found no provider for {n} order(s). Assign manually.',
|
||
'ord.autoOn': 'Auto-assign on',
|
||
'ord.autoOff': 'Auto-assign off',
|
||
'ord.autoHint': 'A new order is offered to the best free provider (client language, district, load, rating). No answer in {minutes} min or a decline — the next one; after {tries} tries — to a dispatcher.',
|
||
'ord.back': 'All orders',
|
||
'ord.progress': 'Progress',
|
||
'ord.details': 'Details',
|
||
'ord.when': 'When',
|
||
'ord.where': 'Where',
|
||
'ord.minutes': '{n} min',
|
||
'ord.params': 'Details',
|
||
'ord.extras': 'Extras',
|
||
'ord.note': 'Client comment',
|
||
'ord.lang': 'Client language',
|
||
'ord.created': 'Created',
|
||
'ord.checklist': 'Checklist',
|
||
'ord.needsPhoto': 'photo needed',
|
||
'ord.photo': 'Photo',
|
||
'ord.history': 'History',
|
||
'ord.client': 'Client',
|
||
'ord.writeClient': 'Message the client',
|
||
'ord.writeProvider': 'Message the provider',
|
||
'ord.call': 'Call',
|
||
'ord.noPhone': 'No phone number — add it to the profile',
|
||
'ord.money': 'Money',
|
||
'ord.base': 'Before discount',
|
||
'ord.discount': 'Discount {pct}%',
|
||
'ord.payout': 'To the provider',
|
||
'ord.cancelFee': 'Cancellation fee',
|
||
'ord.payment': 'Payment',
|
||
'ord.markPaid': 'Mark as paid',
|
||
'ord.confirmPaid': 'Mark the order as paid?',
|
||
'ord.paidDone': 'Marked as paid',
|
||
'ord.actions': 'Actions',
|
||
'ord.setStatus': 'Status: {status}',
|
||
'ord.confirmStatus': 'Move the order to “{status}”? The client will be notified.',
|
||
'ord.statusChanged': 'Status changed',
|
||
'ord.reschedule': 'Reschedule',
|
||
'ord.rescheduleTitle': 'Reschedule order #{n}',
|
||
'ord.rescheduleHint': 'If the provider is busy at the new time, the order goes back to “Need a provider” and to auto-assignment.',
|
||
'ord.rescheduled': 'Rescheduled, same provider',
|
||
'ord.rescheduledFree': 'Rescheduled; the provider is busy — looking for a new one',
|
||
'ord.comment': 'Comment',
|
||
'ord.commentPh': 'E.g. the client asked by phone',
|
||
'ord.cancel': 'Cancel order',
|
||
'ord.cancelTitle': 'Cancel the order',
|
||
'ord.cancelReason': 'Reason',
|
||
'ord.cancelReasonPh': 'E.g. the client changed their mind',
|
||
'ord.cancelFeeHint': 'How much to charge the client, ֏. Usually 0.',
|
||
'ord.cancelHint': 'The client and the provider will be notified.',
|
||
'ord.cancelled': 'Order cancelled',
|
||
'ord.rating': 'Client rating',
|
||
'ord.noComment': 'No comment',
|
||
'ord.offers': 'Offers',
|
||
'ord.bySystem': 'system',
|
||
'ord.provider': 'Provider',
|
||
'ord.unassign': 'Remove provider',
|
||
'ord.revoke': 'Withdraw offer',
|
||
'ord.confirmUnassign': 'Remove the provider? The order goes back to “Need a provider”.',
|
||
'ord.confirmRevoke': 'Withdraw the offer? The order will wait for a provider again.',
|
||
'ord.unassigned': 'Done — the order needs a provider again',
|
||
'ord.pendingProvider': 'Offered to {name}',
|
||
'ord.pendingCompany': 'Passed to {name} — waiting for their dispatcher',
|
||
'ord.byAuto': 'offered automatically',
|
||
'ord.minLeft': '≈ {n} min to answer',
|
||
'ord.pickHint': 'Free at this time, best match first. Or let the system pick.',
|
||
'ord.autoPick': 'Pick automatically',
|
||
'ord.autoOffered': 'Offered to {name}',
|
||
'ord.autoNone': 'No free provider found',
|
||
'ord.noFree': 'Everyone is busy at this time. Reschedule or arrange with a provider.',
|
||
'ord.busy': 'Busy at this time: {n}',
|
||
'ord.company': 'company',
|
||
'ord.tried': 'already offered',
|
||
'ord.load': '{n} orders that day',
|
||
'ord.offer': 'Offer',
|
||
'ord.offered': 'Offer sent',
|
||
'ord.noProvider': 'No provider was assigned.',
|
||
'ord.ev.created': 'Order created',
|
||
'ord.ev.createdByStaff': 'Created by the team',
|
||
'ord.ev.offered': 'Offered to a provider',
|
||
'ord.ev.autoOffered': 'Auto-assign: offered',
|
||
'ord.ev.autoNoCandidate': 'Auto-assign: nobody free',
|
||
'ord.ev.autoGaveUp': 'Auto-assign stopped — needs a dispatcher',
|
||
'no.title': 'New order',
|
||
'no.client': 'Client',
|
||
'no.clientPh': 'Name, @username or phone',
|
||
'no.noClients': 'Nobody found',
|
||
'no.changeClient': 'Another client',
|
||
'no.service': 'Service',
|
||
'no.extras': 'Extras',
|
||
'no.address': 'Address',
|
||
'no.addressPh': 'Street, building, apartment',
|
||
'no.district': 'District',
|
||
'no.when': 'Date and time',
|
||
'no.day': 'Day',
|
||
'no.noSlots': 'No free time that day — pick another day or “other time”.',
|
||
'no.otherTime': 'Other time (arranged with a provider directly)',
|
||
'no.customTime': 'Time',
|
||
'no.customHint': 'Yerevan time. A free provider is not guaranteed.',
|
||
'no.note': 'Comment for the provider',
|
||
'no.notePh': 'Door code, pets…',
|
||
'no.payment': 'Payment',
|
||
'no.hint': 'The price includes the client’s subscription discount. The client is notified and the order goes to auto-assignment.',
|
||
'no.create': 'Create order',
|
||
'no.created': 'Order #{n} created',
|
||
'prv.title': 'Providers',
|
||
'prv.add': 'Add',
|
||
'prv.search': 'Name or phone',
|
||
'prv.status.active': 'Active',
|
||
'prv.status.blocked': 'Blocked',
|
||
'prv.status.all': 'All',
|
||
'prv.empty': 'Nobody found.',
|
||
'prv.col.name': 'Provider',
|
||
'prv.col.rating': 'Rating',
|
||
'prv.col.done': 'Orders',
|
||
'prv.col.refused': 'Declines',
|
||
'prv.col.next': 'Next order',
|
||
'prv.period30': 'Orders, declines and low ratings — last 30 days.',
|
||
'prv.blocked': 'blocked',
|
||
'prv.onShift': 'on shift',
|
||
'prv.offShift': 'off shift',
|
||
'prv.notLinked': 'bot not opened',
|
||
'prv.noDocs': 'no documents',
|
||
'prv.ratings': '{n} ratings',
|
||
'prv.low': '{n} low',
|
||
'prv.today': 'today: {n}',
|
||
'prv.back': 'All providers',
|
||
'prv.write': 'Message',
|
||
'prv.edit': 'Edit',
|
||
'prv.blockedSince': 'Blocked since {date}.',
|
||
'prv.unblock': 'Unblock',
|
||
'prv.inviteHint': 'The provider hasn’t opened the work bot yet — send them the link.',
|
||
'prv.copyInvite': 'Copy link',
|
||
'prv.quality': 'Quality',
|
||
'prv.days30': 'last 30 days',
|
||
'prv.acceptRate': 'accepted {a} of {n} offers',
|
||
'prv.refusals': 'declined: {d}, no answer: {e}',
|
||
'prv.lowRatings': 'ratings of 3 or less',
|
||
'prv.upcoming': 'Upcoming orders',
|
||
'prv.noUpcoming': 'No assigned orders.',
|
||
'prv.recent': 'Recently done',
|
||
'prv.balance': 'To pay',
|
||
'prv.thisMonth': 'This month',
|
||
'prv.prevMonth': 'Last month',
|
||
'prv.paidTotal': 'Paid',
|
||
'prv.payout': 'Record a payout',
|
||
'prv.payoutTitle': 'Payout to provider',
|
||
'prv.amount': 'Amount, ֏',
|
||
'prv.balanceHint': 'Owed to the provider: {sum}',
|
||
'prv.payoutNote': 'How it was paid',
|
||
'prv.payoutNotePh': 'Cash / card transfer…',
|
||
'prv.payoutConfirm': 'Paid',
|
||
'prv.payoutDone': 'Payout recorded',
|
||
'prv.rateCompany': 'company rate {v}',
|
||
'prv.rateOwn': 'rate {v}',
|
||
'prv.ratePreset': 'preset “{name}”',
|
||
'prv.work': 'Work',
|
||
'prv.languages': 'Languages',
|
||
'prv.districts': 'Districts',
|
||
'prv.anyDistrict': 'any',
|
||
'prv.districtsHint': 'Assignment favors providers working in the order’s district.',
|
||
'prv.docs': 'Admission documents',
|
||
'prv.noDocsHint': 'Passport, contract, certificate — kept in private storage.',
|
||
'prv.docTitlePh': 'Title: passport, contract…',
|
||
'prv.upload': 'Upload',
|
||
'prv.docAdded': 'Document added',
|
||
'prv.removeDocConfirm': 'Delete the document?',
|
||
'prv.access': 'Access',
|
||
'prv.block': 'Block',
|
||
'prv.blockTitle': 'Block the provider',
|
||
'prv.blockReason': 'Reason',
|
||
'prv.blockReasonPh': 'E.g. client complaints, missing documents',
|
||
'prv.blockHint': 'No new offers; pending offers are withdrawn. Already assigned orders stay — reassign them manually.',
|
||
'prv.resetInvite': 'New bot link',
|
||
'prv.resetConfirm': 'Create a new link? The current Telegram link is removed — the provider will need to log in again.',
|
||
'prv.since': 'With us since {date}',
|
||
'prv.saved': 'Saved',
|
||
'prv.addTitle': 'New provider',
|
||
'prv.editTitle': 'Provider profile',
|
||
'prv.name': 'Name',
|
||
'prv.role': 'Role',
|
||
'prv.company': 'Company',
|
||
'prv.freelance': 'Freelancer',
|
||
'prv.schedule': 'Schedule',
|
||
'prv.rate': 'Rate',
|
||
'prv.note': 'Team note',
|
||
'err.REASON_REQUIRED': 'Please give a reason.',
|
||
'err.SLOT_UNAVAILABLE': 'This time is taken or has passed. Pick another one.',
|
||
'err.ALREADY_ASSIGNED': 'The order is already assigned or offered — refresh the page.',
|
||
'err.PROVIDER_BUSY': 'The provider is busy at this time.',
|
||
'err.TRANSITION_NOT_ALLOWED': 'This step isn’t available for the order now.',
|
||
'err.CHECKLIST_INCOMPLETE': 'The provider must finish the checklist and add photos first.',
|
||
'err.CONSENT_REQUIRED': 'The client hasn’t given data-processing consent in the bot yet.',
|
||
'err.ADDRESS_REQUIRED': 'Please enter the address and district.',
|
||
'err.INVALID_PARAMS': 'Check the order details.',
|
||
'err.OFFER_NOT_ACTIVE': 'The offer is no longer active.',
|
||
'err.BAD_FILE_TYPE_DOC': 'Photo or PDF only.',
|
||
'audit.bo.orders.assign': 'offered an order',
|
||
'audit.bo.orders.auto': 'ran auto-assignment',
|
||
'audit.bo.orders.unassign': 'removed a provider from an order',
|
||
'audit.bo.orders.transition': 'changed an order status',
|
||
'audit.bo.orders.cancel': 'cancelled an order',
|
||
'audit.bo.orders.reschedule': 'rescheduled an order',
|
||
'audit.bo.orders.markPaid': 'marked an order as paid',
|
||
'audit.bo.orders.create': 'created an order for a client',
|
||
'audit.bo.orders.setAutoSetting': 'changed auto-assignment',
|
||
'audit.bo.providers.create': 'added a provider',
|
||
'audit.bo.providers.update': 'edited a provider',
|
||
'audit.bo.providers.setActive': 'changed provider access',
|
||
'audit.bo.providers.resetInvite': 'reissued a provider link',
|
||
'audit.bo.providers.removeDoc': 'deleted a provider document',
|
||
'audit.bo.providers.addDoc': 'uploaded a provider document',
|
||
'audit.bo.providers.payout': 'recorded a payout',
|
||
'chat.order': 'Order #{n}',
|
||
'chat.noOrder': 'No order',
|
||
'chat.noOrderNow': 'No current order',
|
||
'chat.orderNow': 'Now',
|
||
'chat.orderNext': 'Next',
|
||
'chat.orderNoNext': 'No upcoming orders',
|
||
'chat.orderClient': 'client {name}',
|
||
'chat.wroteNoOrder': 'wrote without an order',
|
||
'err.CONCIERGE_SUBSCRIBERS_ONLY': 'The concierge is for members only. Give the client a subscription first.',
|
||
'err.ASSIGNEE_NO_ACCESS': 'This team member has no access to this channel.',
|
||
'err.PROVIDER_NOT_LINKED': 'The provider hasn’t opened the work bot yet.',
|
||
'err.BAD_FILE_TYPE': 'This file type isn’t supported. Use a photo, PDF, Word, Excel, text or ZIP.',
|
||
'audit.bo.chats.send': 'replied in a chat',
|
||
'audit.bo.chats.sendFile': 'sent a file in a chat',
|
||
'audit.bo.chats.assign': 'assigned a chat',
|
||
'audit.bo.chats.close': 'closed a conversation',
|
||
'audit.bo.chats.reopen': 'reopened a conversation',
|
||
'audit.bo.chats.move': 'moved a conversation to another channel',
|
||
'audit.bo.chats.openFor': 'opened a chat with a client',
|
||
'audit.bo.chats.templates.save': 'edited a reply template',
|
||
'audit.bo.chats.templates.remove': 'deleted a reply template',
|
||
};
|
||
|
||
const hy: Dict = {
|
||
'ui.save': 'Պահպանել',
|
||
'ui.close': 'Փակել',
|
||
'ui.loading': 'Բեռնվում է…',
|
||
'ui.error': 'Չստացվեց՝ {msg}',
|
||
'ui.retry': 'Կրկնել',
|
||
'ui.copy': 'Պատճենել',
|
||
'ui.copied': 'Պատճենված է',
|
||
'ui.days': '{n} օր',
|
||
'ui.yes': 'Այո',
|
||
'ui.no': 'Ոչ',
|
||
'ui.none': '—',
|
||
|
||
'err.PAYMENTS_NOT_CONFIGURED': 'Առցանց վճարումները դեռ միացված չեն․ նշեք վճարումը ձեռքով։',
|
||
'err.REFUND_TOO_BIG': 'Վերադարձի գումարը մեծ է հաճախորդի վճարածից։',
|
||
'err.ENDS_BEFORE_START': 'Բաժանորդագրությունը չի կարող ավարտվել սկսվելուց առաջ։',
|
||
'err.CANNOT_DEMOTE_SELF': 'Չեք կարող անջատել ինքներդ ձեզ կամ հանել ձեր սուպերադմինի դերը։',
|
||
'err.ROLE_FORBIDDEN': 'Ձեր դերը մուտք չունի այս գործողությանը։',
|
||
'err.NO_ROLE': 'Ձեր հաշիվը նոր ադմինում դերեր չունի։ Խնդրեք սուպերադմինին տրամադրել։',
|
||
|
||
'login.coverWord': 'թիմ',
|
||
'login.title': 'Մուտք թիմի համար',
|
||
'login.lead': 'Հաստատեք մուտքը Barev Club-ի աշխատանքային բոտում։ Գաղտնաբառ պետք չէ։',
|
||
'login.open': 'Հաստատել Telegram-ում',
|
||
'login.qr': 'Համակարգչից հարմար է կոդը սկանավորել հեռախոսով։',
|
||
'login.waiting': 'Սպասում ենք հաստատմանը Telegram-ում…',
|
||
'login.expired': 'Հղումը հնացել է։',
|
||
'login.retry': 'Ստանալ նոր հղում',
|
||
'login.dev': 'Տեղային մուտք',
|
||
'login.devHint': 'Միայն այս համակարգչում․ սերվերում այս բլոկը չկա։',
|
||
'login.noTelegram': 'Մուտք չունե՞ք։ Խնդրեք սուպերադմինին ավելացնել ձեզ թիմում և ուղարկել Telegram-ի կապման հղում։',
|
||
|
||
'nav.dashboard': 'Վահանակ',
|
||
'nav.clients': 'Հաճախորդներ',
|
||
'nav.chats': 'Չատեր',
|
||
'nav.orders': 'Պատվերներ',
|
||
'nav.providers': 'Կատարողներ',
|
||
'nav.agencies': 'Գործակալություններ',
|
||
'nav.venues': 'Հաստատություններ',
|
||
'nav.crm': 'CRM',
|
||
'nav.products': 'Ապրանքներ',
|
||
'nav.journal': 'Մատյան',
|
||
'nav.team': 'Թիմ',
|
||
'nav.more': 'Ավելին',
|
||
'nav.soon': 'փուլ {n}',
|
||
'nav.groupWork': 'Աշխատանք',
|
||
'nav.groupPartners': 'Գործընկերներ',
|
||
'nav.groupSetup': 'Կարգավորում',
|
||
|
||
'role.SUPERADMIN': 'Սուպերադմին',
|
||
'role.SUPPORT': 'Աջակցություն',
|
||
'role.CONCIERGE': 'Կոնսիերժ',
|
||
'role.SALES': 'Վաճառք',
|
||
'roleHint.SUPERADMIN': 'Ամեն ինչ, ներառյալ գումարներն ու թիմը',
|
||
'roleHint.SUPPORT': 'Աջակցության չատ, պատվերներ, բաժանորդագրություններ',
|
||
'roleHint.CONCIERGE': 'Կոնսիերժի չատ բաժանորդների համար',
|
||
'roleHint.SALES': 'CRM՝ հաստատություններ և գործակալություններ',
|
||
|
||
'shell.logout': 'Ելք',
|
||
'shell.oldAdmin': 'Հին ադմին',
|
||
'shell.linkTg': 'Կապեք Telegram-ը․ դրանով եք մուտք գործում և ստանում ծանուցումներ։',
|
||
'shell.linkTgBtn': 'Կապել Telegram-ը',
|
||
|
||
'soon.title': '{section} բաժինը տեղափոխվում է այստեղ',
|
||
'soon.text': 'Բաժինը կհայտնվի {n}-րդ փուլում։ Մինչ այդ աշխատեք հին ադմինում․ տվյալները ընդհանուր են։',
|
||
'soon.open': 'Բացել հին ադմինը',
|
||
|
||
'dash.morning': 'Բարի լույս, {name}',
|
||
'dash.day': 'Բարի օր, {name}',
|
||
'dash.evening': 'Բարի երեկո, {name}',
|
||
'dash.attention': 'Պահանջում է ուշադրություն',
|
||
'dash.allClear': 'Շտապ ոչինչ չկա․ ամեն ինչ արված է։',
|
||
'att.unassigned': 'Պատվերներ առանց կատարողի',
|
||
'att.unreadChats': 'Պատասխանի սպասող զրույցներ',
|
||
'att.webRequests': 'Հայտեր կայքից',
|
||
'att.leads': 'Տեղափոխման հայտեր',
|
||
'att.appRequests': 'Հայտեր հավելվածից',
|
||
'att.lowRatings': '3 և ցածր գնահատականներ այս շաբաթ',
|
||
'att.expiring': 'Ավարտվում են 7 օրում',
|
||
'dash.money': 'Գումար',
|
||
'dash.today': 'Այսօր',
|
||
'dash.week': '7 օր',
|
||
'dash.month': '30 օր',
|
||
'dash.vsYesterday': 'երեկ՝ {sum}',
|
||
'dash.vsPrev': 'նախորդ {period}-ի համեմատ',
|
||
'dash.orders': 'պատվերներ',
|
||
'dash.subs': 'բաժանորդագրություններ',
|
||
'dash.chart': 'Եկամուտն ըստ օրերի, 30 օր',
|
||
'dash.subsTitle': 'Բաժանորդագրություններ',
|
||
'dash.gifts': 'Որից նվեր՝ {n}',
|
||
'dash.expiring': 'Ավարտվում են առաջիկա 7 օրում',
|
||
'dash.noExpiring': 'Առաջիկա շաբաթ ոչինչ չի ավարտվում։',
|
||
'dash.conversion': 'Նվեր → գնում',
|
||
'dash.conversionHint': 'Նվեր ստացած {total} հաճախորդից {paid}-ը հետո գնել են',
|
||
'dash.growth': 'Աճ',
|
||
'dash.newClients': 'Նոր հաճախորդներ',
|
||
'dash.prevMonth': 'նախորդ 30 օրում՝ {n}',
|
||
'dash.sources': 'Որտեղից են եկել, 30 օր',
|
||
'dash.funnel': 'Ձագար, 30 օր',
|
||
'funnel.leads': 'Հայտեր կայքից',
|
||
'funnel.clients': 'Հաճախորդներ հավելվածում',
|
||
'funnel.paying': 'Վճարել են',
|
||
'dash.team': 'Թիմ և գործընկերներ',
|
||
'dash.topProviders': 'Լավագույն կատարողներ',
|
||
'dash.bottomProviders': 'Արժե խոսել',
|
||
'dash.topPartners': 'Հաստատություններ՝ քարտի սկանավորումներ, 30 օր',
|
||
'dash.salesSoon': 'Վաճառողների արդյունքները կհայտնվեն CRM-ի հետ։',
|
||
'dash.empty': 'Դեռ դատարկ է',
|
||
'dash.feed': 'Լրահոս',
|
||
'feed.subscription': '{plan} · {source}',
|
||
'feed.payment': '№{number} պատվերը վճարված է',
|
||
'dash.ratings': '{n} գնահատական',
|
||
'dash.scans': '{n} սկան',
|
||
|
||
'source.organic': 'Ինքն են գտել',
|
||
'source.deeplink': 'Գործակալության հղում',
|
||
'source.manual_code': 'Գործակալության կոդ',
|
||
'source.agency': '«{name}» գործակալություն',
|
||
'source.utm': 'Գովազդ՝ {name}',
|
||
|
||
'plan.BAREV_PLUS': 'Barev+',
|
||
'plan.ELITE': 'Elite',
|
||
'plan.none': 'Առանց բաժանորդագրության',
|
||
'subSource.PAID': 'Գնում',
|
||
'subSource.MANUAL': 'Թիմի նվեր',
|
||
'subSource.AGENCY_GIFT': 'Գործակալության նվեր',
|
||
'subStatus.ACTIVE': 'Ակտիվ',
|
||
'subStatus.EXPIRED': 'Ավարտված',
|
||
'subStatus.CANCELLED': 'Չեղարկված',
|
||
'pay.cash': 'Կանխիկ',
|
||
'pay.transfer': 'Փոխանցում',
|
||
'pay.card': 'Քարտ տերմինալով',
|
||
'pay.link': 'Վճարման հղում',
|
||
'segment.MOVING': 'Տեղափոխվում է',
|
||
'segment.LIVING': 'Ապրում է Հայաստանում',
|
||
|
||
'clients.title': 'Հաճախորդներ',
|
||
'clients.search': 'Անուն, @username, հեռախոս կամ քարտի համար',
|
||
'clients.found': 'Գտնվել է՝ {n}',
|
||
'clients.revenueTotal': 'բերել են {sum}',
|
||
'col.client': 'Հաճախորդ',
|
||
'col.sub': 'Բաժանորդագրություն',
|
||
'col.source': 'Աղբյուր',
|
||
'col.revenue': 'Բերել է',
|
||
'col.since': 'Մեզ հետ է',
|
||
'filter.plan': 'Բաժանորդագրություն',
|
||
'filter.all': 'Բոլորը',
|
||
'filter.any': 'Բաժանորդագրությամբ',
|
||
'filter.none': 'Առանց բաժանորդագրության',
|
||
'filter.subSource': 'Ինչպես է ստացել',
|
||
'filter.source': 'Աղբյուր',
|
||
'filter.agency': 'Գործակալություն',
|
||
'filter.tag': 'Պիտակ',
|
||
'filter.segment': 'Սցենար',
|
||
'filter.paying': 'Վճարել են',
|
||
'filter.payingYes': 'Վճարել են',
|
||
'filter.payingNo': 'Երբեք չեն վճարել',
|
||
'filter.expiring': 'Ավարտվում է 7 օրում',
|
||
'filter.reset': 'Զրոյացնել ֆիլտրերը',
|
||
'filter.more': 'Ֆիլտրեր',
|
||
'filter.anyValue': 'Ցանկացած',
|
||
'sort.label': 'Հերթականություն',
|
||
'sort.new': 'Նախ նորերը',
|
||
'sort.revenue': 'Ամենաշատը բերածները',
|
||
'sort.ends': 'Շուտով ավարտվող',
|
||
'segments.title': 'Իմ ընտրանիները',
|
||
'segments.save': 'Պահպանել ընտրանին',
|
||
'segments.name': 'Ընտրանու անունը',
|
||
'segments.saved': 'Ընտրանին պահպանված է',
|
||
'segments.remove': 'Ջնջել «{name}» ընտրանին',
|
||
'clients.export': 'Ներբեռնել Excel-ի համար',
|
||
'clients.exported': 'Ֆայլը ներբեռնված է',
|
||
'clients.broadcast': 'Առաքում',
|
||
'clients.broadcastSoon': 'Ըստ ընտրանու առաքումները կհայտնվեն 5-րդ փուլում։',
|
||
'clients.empty': 'Այս ֆիլտրերին ոչ ոք չի համապատասխանում։',
|
||
'clients.emptyAll': 'Հաճախորդներ դեռ չկան․ կհայտնվեն, երբ գրեն բոտին։',
|
||
'clients.prev': 'Հետ',
|
||
'clients.next': 'Առաջ',
|
||
'clients.page': '{from}–{to}՝ {total}-ից',
|
||
|
||
'card.back': 'Բոլոր հաճախորդները',
|
||
'card.since': 'Մեզ հետ է {date}-ից',
|
||
'card.telegram': 'Բացել Telegram-ում',
|
||
'card.cardNo': 'Քարտ {code}',
|
||
'card.noSub': 'Ակտիվ բաժանորդագրություն չկա',
|
||
'card.noSubHint': 'Նվիրեք կամ վաճառեք բաժանորդագրություն․ հաճախորդը միանգամից կստանա զեղչեր։',
|
||
'card.until': 'մինչև {date}',
|
||
'card.daysLeft': 'մնաց {n} օր',
|
||
'card.history': 'Բոլոր բաժանորդագրությունները',
|
||
'card.grantedBy': 'տրամադրել է {name}',
|
||
'card.giftFrom': 'նվեր «{name}»-ից',
|
||
'card.paidVia': '{method}',
|
||
'card.refunded': 'վերադարձ {sum}',
|
||
'card.cancelledAt': 'չեղարկված {date}',
|
||
'card.upcoming': 'կսկսվի {date}',
|
||
'card.money': 'Բերել է',
|
||
'card.fromOrders': 'պատվերներ',
|
||
'card.fromSubs': 'բաժանորդագրություններ',
|
||
'card.orders': 'Պատվերներ',
|
||
'card.noOrders': 'Պատվերներ դեռ չկան։',
|
||
'card.newOrder': 'Ստեղծել պատվեր',
|
||
'card.newOrderSoon': 'Պատվեր հաճախորդի անունից՝ 3-րդ փուլում, պատվերների բաժնի հետ։',
|
||
'card.profile': 'Պրոֆիլ',
|
||
'card.source': 'Որտեղից է եկել',
|
||
'card.agency': 'Գործակալություն',
|
||
'card.language': 'Լեզու',
|
||
'card.phone': 'Հեռախոս',
|
||
'card.segment': 'Սցենար',
|
||
'card.consent': 'Տվյալների մշակման համաձայնություն',
|
||
'card.tags': 'Պիտակներ',
|
||
'card.addTag': 'Նոր պիտակ',
|
||
'card.note': 'Թիմի նշում',
|
||
'card.notePh': 'Հաճախորդը չի տեսնում այս նշումը',
|
||
'card.saved': 'Պահպանված է',
|
||
'card.activity': 'Հաճախորդի մատյան',
|
||
'card.noActivity': 'Թիմը դեռ ոչինչ չի փոխել։',
|
||
'card.stats': 'Ակտիվություն',
|
||
'stat.cardUsages': 'քարտի սկան',
|
||
'stat.leads': 'տեղափոխման հայտ',
|
||
'stat.requests': 'հայտ հավելվածից',
|
||
'stat.concierge': 'հաղորդագրություն չատում',
|
||
|
||
'act.gift': 'Նվիրել',
|
||
'act.sell': 'Վաճառել',
|
||
'act.extend': 'Փոխել ժամկետը',
|
||
'act.cancel': 'Չեղարկել',
|
||
'act.changePlan': 'Փոխել սակագինը',
|
||
'act.refund': 'Վերադարձնել գումարը',
|
||
|
||
'audit.bo.clients.gift': 'նվիրել է բաժանորդագրություն',
|
||
'audit.bo.clients.sell': 'վաճառել է բաժանորդագրություն',
|
||
'audit.bo.clients.extend': 'փոխել է ժամկետը',
|
||
'audit.bo.clients.cancel': 'չեղարկել է բաժանորդագրությունը',
|
||
'audit.bo.clients.changePlan': 'փոխել է սակագինը',
|
||
'audit.bo.clients.refund': 'ձևակերպել է վերադարձ',
|
||
'audit.bo.clients.setTags': 'փոխել է պիտակները',
|
||
'audit.bo.clients.setNote': 'փոխել է նշումը',
|
||
|
||
'dlg.giftTitle': 'Նվիրել բաժանորդագրություն',
|
||
'dlg.giftHint': 'Այն կնշվի որպես ձեր նվերը։',
|
||
'dlg.sellTitle': 'Վաճառել բաժանորդագրություն',
|
||
'dlg.plan': 'Սակագին',
|
||
'dlg.period': 'Ժամկետ',
|
||
'dlg.period1': '1 ամիս',
|
||
'dlg.period3': '3 ամիս',
|
||
'dlg.period6': '6 ամիս',
|
||
'dlg.period12': '1 տարի',
|
||
'dlg.periodCustom': 'Այլ',
|
||
'dlg.days': 'Օր',
|
||
'dlg.amount': 'Գումար, ֏',
|
||
'dlg.method': 'Ինչպես է վճարել',
|
||
'dlg.note': 'Մեկնաբանություն թիմի համար',
|
||
'dlg.linkSoon': 'Վճարման հղումը կմիացնենք վճարային համակարգը միացնելուց հետո։',
|
||
'dlg.giftConfirm': 'Նվիրել',
|
||
'dlg.sellConfirm': 'Նշել վճարումը',
|
||
'dlg.extendTitle': 'Փոխել ժամկետը',
|
||
'dlg.extendHint': 'Բացասական թիվը կրճատում է ժամկետը։',
|
||
'dlg.newEnd': 'Նոր ավարտի ամսաթիվ՝ {date}',
|
||
'dlg.extendConfirm': 'Պահպանել ժամկետը',
|
||
'dlg.cancelTitle': 'Չեղարկել բաժանորդագրությունը',
|
||
'dlg.cancelHint': 'Հաճախորդը միանգամից կկորցնի զեղչերն ու արտոնությունները։',
|
||
'dlg.reason': 'Պատճառ',
|
||
'dlg.cancelConfirm': 'Չեղարկել բաժանորդագրությունը',
|
||
'dlg.planTitle': 'Փոխել սակագինը',
|
||
'dlg.planConfirm': 'Փոխել սակագինը',
|
||
'dlg.refundTitle': 'Վերադարձնել գումարը',
|
||
'dlg.refundPaid': 'Վճարված է {sum}, արդեն վերադարձված՝ {back}',
|
||
'dlg.refundCancel': 'Միանգամից չեղարկել բաժանորդագրությունը',
|
||
'dlg.refundConfirm': 'Ձևակերպել վերադարձ',
|
||
'done.gift': 'Բաժանորդագրությունը նվիրված է',
|
||
'done.sell': 'Վճարումը նշված է',
|
||
'done.extend': 'Ժամկետը փոխված է',
|
||
'done.cancel': 'Բաժանորդագրությունը չեղարկված է',
|
||
'done.changePlan': 'Սակագինը փոխված է',
|
||
'done.refund': 'Վերադարձը ձևակերպված է',
|
||
|
||
'team.title': 'Թիմ',
|
||
'team.lead': 'Ով է աշխատում ադմինում և ինչ հասանելիություն ունի։ Մեկ մարդը կարող է ունենալ մի քանի դեր։',
|
||
'team.add': 'Ավելացնել մարդու',
|
||
'team.name': 'Անուն',
|
||
'team.roles': 'Դերեր',
|
||
'team.create': 'Ավելացնել',
|
||
'team.linkTitle': 'Հղում {name}-ի համար',
|
||
'team.linkHint': 'Ուղարկեք նրան։ Կբացի աշխատանքային բոտը, Telegram-ը կկապվի, և կարող է մուտք գործել։',
|
||
'team.tgLinked': 'Telegram-ը կապված է',
|
||
'team.tgNotLinked': 'Telegram-ը կապված չէ',
|
||
'team.newLink': 'Կապման հղում',
|
||
'team.disable': 'Անջատել մուտքը',
|
||
'team.enable': 'Վերադարձնել մուտքը',
|
||
'team.disabled': 'Մուտքն անջատված է',
|
||
'team.you': 'դուք',
|
||
'team.saved': 'Դերերը պահպանված են',
|
||
|
||
// ───── чаты (этап 2) ─────
|
||
'chat.title': 'Զրույցներ',
|
||
'chat.all': 'Բոլորը',
|
||
'channel.SUPPORT': 'Աջակցություն',
|
||
'channel.CONCIERGE': 'Կոնսիերժ',
|
||
'chat.f.waiting': 'Սպասում են պատասխանի',
|
||
'chat.f.mine': 'Իմը',
|
||
'chat.f.unassigned': 'Առանց պատասխանատուի',
|
||
'chat.f.open': 'Բաց',
|
||
'chat.f.closed': 'Փակ',
|
||
'chat.f.all': 'Բոլորը',
|
||
'chat.search': 'Անուն, @username, հեռախոս կամ տեքստ',
|
||
'chat.emptyList': 'Այստեղ դատարկ է։ Նոր հաղորդագրությունները կհայտնվեն ինքնուրույն։',
|
||
'chat.emptyFilter': 'Ոչինչ չգտանք․ փորձեք այլ ֆիլտր։',
|
||
'chat.pick': 'Ընտրեք զրույցը',
|
||
'chat.pickHint': 'Վերևում նրանք են, ովքեր ամենաերկար են սպասում։',
|
||
'chat.waiting': 'սպասում է {t}',
|
||
'chat.you': 'Դուք',
|
||
'chat.provider': 'Կատարող',
|
||
'chat.unassigned': 'Պատասխանատու չկա',
|
||
'chat.take': 'Վերցնել ինձ',
|
||
'chat.transfer': 'Փոխանցել',
|
||
'chat.transferTo': 'Փոխանցել գործընկերոջը',
|
||
'chat.unassign': 'Հանել պատասխանատուին',
|
||
'chat.close': 'Փակել',
|
||
'chat.reopen': 'Կրկին բացել',
|
||
'chat.closedBanner': 'Զրույցը փակ է։ Կբացվի, երբ հաճախորդը գրի․ կարող եք պատասխանել նաև հիմա։',
|
||
'chat.moveTo': 'Տեղափոխել «{channel}»',
|
||
'chat.moved': 'Տեղափոխվեց «{channel}»',
|
||
'chat.movedAway': 'Տեղափոխվեց «{channel}»։ Դուք մուտք չունեք այդ ալիքին։',
|
||
'chat.other': 'Կա նաև զրույց «{channel}» ալիքում',
|
||
'chat.otherOpen': 'Բացել',
|
||
'chat.bot': 'Զրույցը վարում է ԱԲ կոնսիերժը։',
|
||
'chat.botTake': 'Վերցնել',
|
||
'chat.reply': 'Պատասխան',
|
||
'chat.note': 'Նշում',
|
||
'chat.replyPh': 'Պատասխան հաճախորդին՝ կգա Telegram-ում',
|
||
'chat.notePh': 'Նշում թիմի համար՝ հաճախորդը չի տեսնի',
|
||
'chat.send': 'Ուղարկել',
|
||
'chat.saveNote': 'Պահել նշումը',
|
||
'chat.attach': 'Կցել ֆայլ',
|
||
'chat.templates': 'Ձևանմուշներ',
|
||
'chat.tplManage': 'Կարգավորել ձևանմուշները',
|
||
'chat.tplEmpty': 'Ձևանմուշներ դեռ չկան։',
|
||
'chat.tplNew': 'Նոր ձևանմուշ',
|
||
'chat.tplTitle': 'Անվանում',
|
||
'chat.tplText': 'Տեքստ',
|
||
'chat.tplTextHint': '{name}-ը կփոխարինվի հաճախորդի անունով',
|
||
'chat.tplChannel': 'Ալիք',
|
||
'chat.tplBoth': 'Երկու ալիքները',
|
||
'chat.tplDelete': 'Ջնջել',
|
||
'chat.tplSaved': 'Ձևանմուշը պահպանված է',
|
||
'chat.tplSearch': 'Գտնել ձևանմուշ',
|
||
'chat.noteLabel': 'Նշում · տեսանելի է միայն թիմին',
|
||
'chat.fromApp': 'հավելվածից',
|
||
'chat.undelivered': 'Չի առաքվել․ հաճախորդը արգելափակել է բոտը կամ երբեք չի բացել',
|
||
'chat.fileTooBig': 'Ֆայլը 10 ՄԲ-ից մեծ է',
|
||
'chat.enterHint': 'Enter՝ ուղարկել · Shift+Enter՝ նոր տող',
|
||
'chat.providerNotLinked': 'Կատարողը դեռ չի բացել աշխատանքային բոտը․ առայժմ կարող եք թողնել միայն նշում։',
|
||
'chat.client': 'Հաճախորդի մասին',
|
||
'chat.aboutProvider': 'Կատարողի մասին',
|
||
'chat.openCard': 'Հաճախորդի քարտ',
|
||
'chat.write': 'Գրել',
|
||
'chat.back': 'Բոլոր զրույցները',
|
||
'chat.sys.took': '{name}-ը վերցրեց զրույցը',
|
||
'chat.sys.transferred': '{name}-ը զրույցը փոխանցեց {param}-ին',
|
||
'chat.sys.unassigned': '{name}-ը հանեց պատասխանատուին',
|
||
'chat.sys.closed': '{name}-ը փակեց զրույցը',
|
||
'chat.sys.reopened': '{name}-ը կրկին բացեց զրույցը',
|
||
'chat.sys.moved': '{name}-ը զրույցը տեղափոխեց «{param}»',
|
||
'chat.ago.now': 'հենց հիմա',
|
||
'chat.ago.min': '{n} ր',
|
||
'chat.ago.h': '{n} ժ',
|
||
'chat.ago.d': '{n} օր',
|
||
'chat.today': 'Այսօր',
|
||
'chat.yesterday': 'Երեկ',
|
||
'chat.image': 'Լուսանկար',
|
||
'chat.file': 'Ֆայլ',
|
||
'chat.subUntil': 'մինչև {date}',
|
||
'chat.orders': 'Պատվերներ',
|
||
'chat.phone': 'Հեռախոս',
|
||
'chat.lang': 'Լեզու',
|
||
'chat.source': 'Աղբյուր',
|
||
'chat.linked': 'Աշխատանքային բոտը բացված է',
|
||
'chat.notLinked': 'Աշխատանքային բոտը բացված չէ',
|
||
'chat.details': 'Մանրամասներ',
|
||
'chat.more': 'Այլ գործողություններ',
|
||
|
||
// ───── партнёры и CRM (этап 4) ─────
|
||
'crm.title': 'CRM',
|
||
'crm.newLead': 'Նոր լիդ',
|
||
'crm.editLead': 'Լիդ',
|
||
'crm.stagesBtn': 'Ձագար',
|
||
'crm.tab.board': 'Ձագար',
|
||
'crm.tab.tasks': 'Առաջադրանքներ',
|
||
'crm.tab.map': 'Քարտեզ',
|
||
'crm.search': 'Անուն, կոնտակտ, հեռախոս կամ հասցե',
|
||
'crm.kind.all': 'Բոլորը',
|
||
'crm.kind.VENUE': 'Հաստատություններ',
|
||
'crm.kind.AGENCY': 'Գործակալություններ',
|
||
'crm.kind1.VENUE': 'Հաստատություն',
|
||
'crm.kind1.AGENCY': 'Գործակալություն',
|
||
'crm.owner': 'Վաճառող',
|
||
'crm.allSales': 'Բոլոր վաճառողները',
|
||
'crm.noOwner': 'Առանց վաճառողի',
|
||
'crm.ownerIs': 'վարում է {name}',
|
||
'crm.connected': 'Միացված',
|
||
'crm.connect': 'Միացում',
|
||
'crm.days': '{n} օր',
|
||
'crm.inStage': 'Օրեր այս փուլում',
|
||
'crm.dropHere': 'Քաշեք այստեղ',
|
||
'crm.dragHint': 'Քաշեք քարտերը փուլերի միջև։ «Միացված»-ը ստեղծում է գործընկեր կամ գործակալություն։',
|
||
'crm.overdue': 'ժամկետանց',
|
||
'crm.tasksOpen': 'Բաց',
|
||
'crm.tasksDone': 'Կատարված',
|
||
'crm.addTask': 'Առաջադրանք',
|
||
'crm.noTasks': 'Բաց առաջադրանքներ չկան։',
|
||
'crm.noDoneTasks': 'Կատարված առաջադրանքներ դեռ չկան։',
|
||
'crm.noLead': 'առանց լիդի',
|
||
'crm.tasksHint': 'Ժամկետին հիշեցում կգա աշխատանքային բոտում։',
|
||
'crm.taskTitle': 'Ինչ անել',
|
||
'crm.taskDay': 'Օր',
|
||
'crm.taskTime': 'Ժամ',
|
||
'crm.taskHint': 'Հիշեցումը կգա այդ ժամին (Երևան)։',
|
||
'crm.tp.call': 'Զանգահարել',
|
||
'crm.tp.meet': 'Հանդիպում',
|
||
'crm.tp.send': 'Ուղարկել պայմանները',
|
||
'crm.tp.check': 'Իմանալ որոշումը',
|
||
'crm.partnerOnMap': 'ակումբի գործընկեր',
|
||
'crm.legendPartner': 'միացված գործընկերներ',
|
||
'crm.legendLead': 'լիդեր (փուլի գույն)',
|
||
'crm.mapHint': 'Կետը հայտնվում է կոորդինատներ ունենալիս։',
|
||
'crm.name': 'Անվանում',
|
||
'crm.namePhVenue': 'Օրինակ՝ Lumen Coffee',
|
||
'crm.namePhAgency': 'Օրինակ՝ Domik Realty',
|
||
'crm.category': 'Տեսակ',
|
||
'crm.contactName': 'Կոնտակտային անձ',
|
||
'crm.contactPh': 'Անուն և պաշտոն',
|
||
'crm.address': 'Հասցե',
|
||
'crm.note': 'Նշում',
|
||
'crm.convert': 'Միացնել',
|
||
'crm.convertTitle': 'Միացնել «{name}»',
|
||
'crm.convertVenueHint': 'Կստեղծենք գործընկեր և հղում սեփականատիրոջ համար։',
|
||
'crm.convertAgencyHint': 'Կստեղծենք գործակալություն կոդով և հղում հաճախորդների համար։',
|
||
'crm.agencyCode': 'Գործակալության կոդ',
|
||
'crm.agencyCodeHint': 'Լատինատառ և թվեր',
|
||
'crm.convertedTitle': 'Միացված է 🎉',
|
||
'crm.convertedVenue': 'Ուղարկեք այս հղումը սեփականատիրոջը։ Միանգամյա է։',
|
||
'crm.convertedAgency': 'Այս հղումը գործակալությունը տալիս է հաճախորդներին։',
|
||
'crm.openVenue': 'Հաստատության քարտ',
|
||
'crm.openAgency': 'Գործակալության քարտ',
|
||
'crm.ownerLinked': 'Սեփականատերն արդեն բոտում է։',
|
||
'crm.ownerNotYet': 'Սեփականատերը դեռ չի բացել հղումը։ Ուղարկեք կրկին՝',
|
||
'crm.agencyInfo': 'Կոդ {code}, հաճախորդներ՝ {n}',
|
||
'crm.lostTitle': 'Ինչու՞ հրաժարում',
|
||
'crm.lostReason': 'Պատճառ',
|
||
'crm.lr.price': 'Պայմանները չհամապատասխանեցին',
|
||
'crm.lr.notNow': 'Ոչ հիմա',
|
||
'crm.lr.noAnswer': 'Չեն պատասխանում',
|
||
'crm.lr.competitor': 'Աշխատում են մրցակցի հետ',
|
||
'crm.lostBanner': 'Հրաժարում՝ {reason}',
|
||
'crm.stagesTitle': 'Ձագարի փուլեր',
|
||
'crm.stagesHint': 'Հերթականությունը՝ սլաքներով։',
|
||
'crm.addStage': 'Փուլ',
|
||
'crm.stageKind.OPEN': 'ընթացքում',
|
||
'crm.stageKind.WON': 'միացված',
|
||
'crm.stageKind.LOST': 'հրաժարում',
|
||
'crm.bonusMonth': 'Բոնուս այս ամիս',
|
||
'crm.bonusMineSuper': 'Բոնուս (ձեր), ամիս',
|
||
'crm.bonusNotSet': 'կարգավորված չէ',
|
||
'crm.bonusVenues': 'Հաստատություններ՝ {n} → {sum}',
|
||
'crm.bonusAgencies': 'Գործակալություններ՝ {n} → {sum}',
|
||
'crm.bonusRevenue': '{pct}% եկամուտից → {sum}',
|
||
'crm.bonusTitle': 'Վաճառողի բոնուսի բանաձև',
|
||
'crm.bonusHint': 'Բոնուս = հաստատություններ × դրույք + գործակալություններ × դրույք + % եկամուտից։',
|
||
'crm.bonusPerVenue': 'Հաստատության համար, ֏',
|
||
'crm.bonusPerAgency': 'Գործակալության համար, ֏',
|
||
'crm.bonusPct': '% եկամուտից',
|
||
'crm.bonusMonths': 'Քանի ամիս',
|
||
'crm.back': 'CRM',
|
||
'crm.created': '{date}-ից',
|
||
'crm.stage': 'Փուլ',
|
||
'crm.history': 'Կոնտակտների պատմություն',
|
||
'crm.noHistory': 'Դեռ դատարկ է։',
|
||
'crm.act.CALL': 'Զանգ',
|
||
'crm.act.MEETING': 'Հանդիպում',
|
||
'crm.act.NOTE': 'Նշում',
|
||
'crm.act.FILE': 'Ֆայլ',
|
||
'crm.act.STAGE': 'Փուլ',
|
||
'crm.act.WON': 'Միացված',
|
||
'crm.actPh.CALL': 'Ինչի՞ մասին պայմանավորվեցիք',
|
||
'crm.actPh.MEETING': 'Ինչպե՞ս անցավ հանդիպումը',
|
||
'crm.actPh.NOTE': 'Նշում ձեզ և թիմի համար',
|
||
'crm.addAct': 'Գրանցել',
|
||
'crm.attach': 'Լուսանկար կամ ֆայլ',
|
||
'crm.tasks': 'Առաջադրանքներ',
|
||
'crm.noLeadTasks': 'Առաջադրանքներ չկան։',
|
||
'crm.contacts': 'Կոնտակտներ',
|
||
'crm.noCoords': 'Քարտեզում չկա։',
|
||
'crm.coordsPh': 'Google Maps հղում կամ «40.18, 44.51»',
|
||
'crm.coordsBad': 'Կոորդինատներ չգտնվեցին։',
|
||
'crm.remove': 'Ջնջել լիդը',
|
||
'crm.removeConfirm': 'Ջնջե՞լ լիդը։',
|
||
'venue.cat.cafe': 'Սրճարան',
|
||
'venue.cat.restaurant': 'Ռեստորան',
|
||
'venue.cat.shop': 'Խանութ',
|
||
'venue.cat.beauty': 'Գեղեցկություն',
|
||
'venue.cat.other': 'Այլ',
|
||
'ag.title': 'Գործակալություններ',
|
||
'ag.add': 'Նոր գործակալություն',
|
||
'ag.editTitle': 'Գործակալություն',
|
||
'ag.empty': 'Գործակալություններ դեռ չկան։',
|
||
'ag.col.name': 'Գործակալություն',
|
||
'ag.col.clients': 'Հաճախորդներ',
|
||
'ag.col.gifts': 'Նվերներ',
|
||
'ag.col.month': 'Պարգև, ամիս',
|
||
'ag.col.balance': 'Վճարման',
|
||
'ag.hint': 'Պարգև՝ % վճարված պատվերներից։',
|
||
'ag.inactive': 'անջատված',
|
||
'ag.back': 'Բոլոր գործակալությունները',
|
||
'ag.pct': '{n}% հաճախորդների պատվերներից',
|
||
'ag.byS': 'միացրել է {name}',
|
||
'ag.link': 'Հղում հաճախորդների համար',
|
||
'ag.linkHint': 'Հաճախորդը բացում է բոտը և ստանում նվեր ամիս։ Կամ մուտքագրում է {code} կոդը։',
|
||
'ag.clients': 'Հաճախորդներ',
|
||
'ag.giftsN': 'նվերներ՝ {n}',
|
||
'ag.noClients': 'Հաճախորդներ դեռ չկան։',
|
||
'ag.orders': 'պատվերներ՝ {n}',
|
||
'ag.toPay': 'Վճարման ենթակա պարգև',
|
||
'ag.accrued': 'Հաշվեգրված',
|
||
'ag.payouts': 'Վճարումներ',
|
||
'ag.payoutTitle': 'Վճարում գործակալությանը',
|
||
'ag.balanceHint': 'Չվճարված՝ {sum}',
|
||
'ag.pctLabel': 'Պարգև, %',
|
||
'ag.sales': 'Միացրել է',
|
||
'ag.contactPh': 'Անուն, հեռախոս, Telegram',
|
||
'ag.active': 'Գործակալությունն աշխատում է',
|
||
'vn.title': 'Հաստատություններ',
|
||
'vn.add': 'Նոր հաստատություն',
|
||
'vn.editTitle': 'Հաստատություն',
|
||
'vn.empty': 'Հաստատություններ դեռ չկան։',
|
||
'vn.col.name': 'Հաստատություն',
|
||
'vn.col.offers': 'Առաջարկներ',
|
||
'vn.col.staff': 'Աշխատակիցներ',
|
||
'vn.col.visits': 'Ստուգումներ, 30 օր',
|
||
'vn.col.last': 'Վերջին ստուգումը',
|
||
'vn.hint': 'Ստուգում՝ աշխատակիցը սկանավորել է ակումբային քարտը։',
|
||
'vn.noOwner': 'սեփականատեր չկա',
|
||
'vn.noOffers': 'առաջարկներ չկան',
|
||
'vn.back': 'Բոլոր հաստատությունները',
|
||
'vn.ownerHint': 'Սեփականատերը դեռ միացված չէ՝ ուղարկեք միանգամյա հղում։',
|
||
'vn.makeLink': 'Ստեղծել հղում',
|
||
'vn.offers': 'Առաջարկներ ըստ մակարդակի',
|
||
'vn.addOffer': 'Առաջարկ',
|
||
'vn.editOffer': 'Առաջարկ',
|
||
'vn.noOffersHint': 'Ավելացրեք, թե ինչ են ստանում անդամները։',
|
||
'vn.level.any': 'Ցանկացած անդամ',
|
||
'vn.level.BAREV_PLUS': 'Barev+ և Elite',
|
||
'vn.level.ELITE': 'Միայն Elite',
|
||
'vn.limit.NONE': 'առանց սահմանափակման',
|
||
'vn.limit.ONCE': 'մեկ անգամ',
|
||
'vn.limit.WEEK': 'շաբաթական {n} անգամ',
|
||
'vn.limit.MONTH': 'ամսական {n} անգամ',
|
||
'vn.limitOpt.NONE': 'Առանց սահմանափակման',
|
||
'vn.limitOpt.ONCE': 'Միայն առաջին այցը',
|
||
'vn.limitOpt.WEEK': 'N անգամ շաբաթական',
|
||
'vn.limitOpt.MONTH': 'N անգամ ամսական',
|
||
'vn.offerOff': 'անջատված',
|
||
'vn.offerTitle': 'Ինչ է ստանում հաճախորդը',
|
||
'vn.offerTitleHint': 'Օրինակ՝ «Կապուչինո նվեր»',
|
||
'vn.forWhom': 'Ում համար',
|
||
'vn.howOften': 'Որքան հաճախ',
|
||
'vn.times': 'Քանի անգամ',
|
||
'vn.offerActive': 'Առաջարկն ակտիվ է',
|
||
'vn.activity': 'Ակտիվություն',
|
||
'vn.weeks8': '8 շաբաթում',
|
||
'vn.checks': 'քարտի ստուգումներ',
|
||
'vn.redeemed': 'օգտագործված առաջարկներ',
|
||
'vn.cardCheck': 'քարտի ստուգում',
|
||
'vn.staff': 'Աշխատակիցներ',
|
||
'vn.noStaff': 'Դեռ ոչ ոք։',
|
||
'vn.role.OWNER': 'սեփականատեր',
|
||
'vn.role.STAFF': 'աշխատակից',
|
||
'vn.removeStaff': 'Հեռացնե՞լ {name}-ին։',
|
||
'vn.staffHint': 'Աշխատակիցներին հրավիրում է սեփականատերը։',
|
||
'vn.newOwnerLink': 'Հղում սեփականատիրոջը',
|
||
'vn.newOwnerLinkHint': 'Նոր միանգամյա հղում',
|
||
'vn.blurb': 'Կարճ նկարագրություն',
|
||
'vn.blurbHint': 'Օրինակ՝ «−10% ակումբային քարտով»',
|
||
'vn.coords': 'Քարտեզի կետ',
|
||
'vn.activeLabel': 'Տեսանելի է հաճախորդներին',
|
||
'err.LEAD_NOT_CONVERTED': 'Օգտագործեք «Միացնել»։',
|
||
'err.ALREADY_CONVERTED': 'Լիդն արդեն միացված է։',
|
||
'err.AGENCY_CODE_FORMAT': 'Կոդ՝ լատինատառ և թվեր։',
|
||
'err.AGENCY_CODE_TAKEN': 'Այս կոդն արդեն զբաղված է։',
|
||
'err.STAGES_INVALID': 'Անհրաժեշտ է գոնե մեկ բաց և մեկ «Միացված» փուլ։',
|
||
'audit.bo.crm.create': 'ավելացրեց լիդ',
|
||
'audit.bo.crm.update': 'փոխեց լիդը',
|
||
'audit.bo.crm.move': 'տեղափոխեց լիդը',
|
||
'audit.bo.crm.convert': 'միացրեց գործընկեր',
|
||
'audit.bo.crm.addActivity': 'գրանցեց կոնտակտ',
|
||
'audit.bo.crm.saveStages': 'փոխեց ձագարը',
|
||
'audit.bo.crm.setBonusRules': 'փոխեց բոնուսի բանաձևը',
|
||
'audit.bo.partners.saveAgency': 'փոխեց գործակալությունը',
|
||
'audit.bo.partners.agencyPayout': 'նշեց վճարում գործակալությանը',
|
||
'audit.bo.partners.saveVenue': 'փոխեց հաստատությունը',
|
||
'audit.bo.partners.saveOffer': 'փոխեց առաջարկը',
|
||
'audit.bo.partners.ownerInvite': 'հղում տվեց սեփականատիրոջը',
|
||
'audit.bo.partners.removeMember': 'հեռացրեց աշխատակցին',
|
||
|
||
// ───── заказы и исполнители (этап 3) ─────
|
||
'ord.title': 'Պատվերներ',
|
||
'ord.new': 'Նոր պատվեր',
|
||
'ord.search': '№, հաճախորդ, հեռախոս, հասցե կամ կատարող',
|
||
'ord.period': 'Ժամանակահատված',
|
||
'ord.period.all': 'Բոլոր օրերը',
|
||
'ord.period.today': 'Այսօր',
|
||
'ord.period.tomorrow': 'Վաղը',
|
||
'ord.period.week': '7 օր',
|
||
'ord.period.past': 'Անցածները',
|
||
'ord.group.active': 'Ակտիվ',
|
||
'ord.group.new': 'Սպասում են կատարողի',
|
||
'ord.group.pending': 'Առաջարկված',
|
||
'ord.group.assigned': 'Նշանակված',
|
||
'ord.group.in_progress': 'Կատարվում են',
|
||
'ord.group.done': 'Պատրաստ',
|
||
'ord.group.cancelled': 'Չեղարկված',
|
||
'ord.today': 'Այսօր',
|
||
'ord.tomorrow': 'Վաղը',
|
||
'ord.empty': 'Այս պայմաններով պատվերներ չկան։',
|
||
'ord.waitsAnswer': 'սպասում ենք՝ {name}',
|
||
'ord.needsHuman': 'պետք է դիսպետչեր',
|
||
'ord.searching': 'համակարգը ընտրում է…',
|
||
'ord.overdue': 'ժամն անցել է, կատարող չկա',
|
||
'ord.needsDispatcher': 'Ավտոմատ բաշխումը կատարող չգտավ {n} պատվերի համար։ Նշանակեք ձեռքով։',
|
||
'ord.autoOn': 'Ավտոմատ բաշխումը միացված է',
|
||
'ord.autoOff': 'Ավտոմատ բաշխումն անջատված է',
|
||
'ord.autoHint': 'Նոր պատվերն ինքնաբերաբար առաջարկվում է լավագույն ազատ կատարողին։ {minutes} րոպեում պատասխան չկա կամ հրաժարվեց՝ հաջորդին, {tries} փորձից հետո՝ դիսպետչերին։',
|
||
'ord.back': 'Բոլոր պատվերները',
|
||
'ord.progress': 'Ընթացք',
|
||
'ord.details': 'Մանրամասներ',
|
||
'ord.when': 'Երբ',
|
||
'ord.where': 'Որտեղ',
|
||
'ord.minutes': '{n} ր',
|
||
'ord.params': 'Պարամետրեր',
|
||
'ord.extras': 'Լրացուցիչ',
|
||
'ord.note': 'Հաճախորդի մեկնաբանություն',
|
||
'ord.lang': 'Հաճախորդի լեզուն',
|
||
'ord.created': 'Ստեղծված',
|
||
'ord.checklist': 'Ստուգացանկ',
|
||
'ord.needsPhoto': 'լուսանկար է պետք',
|
||
'ord.photo': 'Լուսանկար',
|
||
'ord.history': 'Պատմություն',
|
||
'ord.client': 'Հաճախորդ',
|
||
'ord.writeClient': 'Գրել հաճախորդին',
|
||
'ord.writeProvider': 'Գրել կատարողին',
|
||
'ord.call': 'Զանգահարել',
|
||
'ord.noPhone': 'Հեռախոսահամարը նշված չէ',
|
||
'ord.money': 'Գումար',
|
||
'ord.base': 'Առանց զեղչի',
|
||
'ord.discount': 'Զեղչ {pct}%',
|
||
'ord.payout': 'Կատարողին',
|
||
'ord.cancelFee': 'Չեղարկման պահում',
|
||
'ord.payment': 'Վճարում',
|
||
'ord.markPaid': 'Նշել վճարումը',
|
||
'ord.confirmPaid': 'Նշե՞լ, որ հաճախորդը վճարել է։',
|
||
'ord.paidDone': 'Վճարումը նշված է',
|
||
'ord.actions': 'Գործողություններ',
|
||
'ord.setStatus': 'Կարգավիճակ՝ {status}',
|
||
'ord.confirmStatus': 'Տեղափոխե՞լ «{status}»։ Հաճախորդը ծանուցում կստանա։',
|
||
'ord.statusChanged': 'Կարգավիճակը փոխված է',
|
||
'ord.reschedule': 'Տեղափոխել',
|
||
'ord.rescheduleTitle': 'Պատվեր №{n}-ի տեղափոխում',
|
||
'ord.rescheduleHint': 'Եթե կատարողը զբաղված է նոր ժամին, պատվերը կվերադառնա «Սպասում են կատարողի»։',
|
||
'ord.rescheduled': 'Տեղափոխված է, կատարողը նույնն է',
|
||
'ord.rescheduledFree': 'Տեղափոխված է, կատարողը զբաղված է՝ փնտրում ենք նորը',
|
||
'ord.comment': 'Մեկնաբանություն',
|
||
'ord.commentPh': 'Օրինակ՝ հաճախորդը խնդրեց հեռախոսով',
|
||
'ord.cancel': 'Չեղարկել պատվերը',
|
||
'ord.cancelTitle': 'Պատվերի չեղարկում',
|
||
'ord.cancelReason': 'Չեղարկման պատճառը',
|
||
'ord.cancelReasonPh': 'Օրինակ՝ հաճախորդը փոխեց միտքը',
|
||
'ord.cancelFeeHint': 'Որքան պահել հաճախորդից, ֏։ Սովորաբար 0։',
|
||
'ord.cancelHint': 'Հաճախորդը և կատարողը ծանուցում կստանան։',
|
||
'ord.cancelled': 'Պատվերը չեղարկված է',
|
||
'ord.rating': 'Հաճախորդի գնահատականը',
|
||
'ord.noComment': 'Առանց մեկնաբանության',
|
||
'ord.offers': 'Ում է առաջարկվել',
|
||
'ord.bySystem': 'համակարգ',
|
||
'ord.provider': 'Կատարող',
|
||
'ord.unassign': 'Հանել կատարողին',
|
||
'ord.revoke': 'Հետ կանչել առաջարկը',
|
||
'ord.confirmUnassign': 'Հանե՞լ կատարողին։ Պատվերը կվերադառնա։',
|
||
'ord.confirmRevoke': 'Հետ կանչե՞լ առաջարկը։',
|
||
'ord.unassigned': 'Պատվերը կրկին սպասում է կատարողի',
|
||
'ord.pendingProvider': 'Առաջարկված է՝ {name}',
|
||
'ord.pendingCompany': 'Հանձնված է «{name}» ընկերությանը',
|
||
'ord.byAuto': 'առաջարկել է համակարգը',
|
||
'ord.minLeft': 'պատասխանի համար ≈ {n} ր',
|
||
'ord.pickHint': 'Այս ժամին ազատներ՝ ըստ համապատասխանության։',
|
||
'ord.autoPick': 'Ընտրել ավտոմատ',
|
||
'ord.autoOffered': 'Առաջարկվեց՝ {name}',
|
||
'ord.autoNone': 'Ազատ կատարող չգտնվեց',
|
||
'ord.noFree': 'Այս ժամին բոլորը զբաղված են։',
|
||
'ord.busy': 'Զբաղված են՝ {n}',
|
||
'ord.company': 'ընկերություն',
|
||
'ord.tried': 'արդեն առաջարկվել է',
|
||
'ord.load': 'այդ օրը պատվերներ՝ {n}',
|
||
'ord.offer': 'Առաջարկել',
|
||
'ord.offered': 'Առաջարկն ուղարկված է',
|
||
'ord.noProvider': 'Կատարող չի նշանակվել։',
|
||
'ord.ev.created': 'Պատվերը ստեղծված է',
|
||
'ord.ev.createdByStaff': 'Ստեղծել է թիմը',
|
||
'ord.ev.offered': 'Առաջարկվել է կատարողին',
|
||
'ord.ev.autoOffered': 'Ավտոմատ բաշխում՝ առաջարկված',
|
||
'ord.ev.autoNoCandidate': 'Ավտոմատ բաշխում՝ ազատ չկա',
|
||
'ord.ev.autoGaveUp': 'Ավտոմատ բաշխումը կանգնեց',
|
||
'no.title': 'Նոր պատվեր',
|
||
'no.client': 'Հաճախորդ',
|
||
'no.clientPh': 'Անուն, @username կամ հեռախոս',
|
||
'no.noClients': 'Ոչ ոք չգտնվեց',
|
||
'no.changeClient': 'Այլ հաճախորդ',
|
||
'no.service': 'Ծառայություն',
|
||
'no.extras': 'Լրացուցիչ',
|
||
'no.address': 'Հասցե',
|
||
'no.addressPh': 'Փողոց, շենք, բնակարան',
|
||
'no.district': 'Վարչական շրջան',
|
||
'no.when': 'Օր և ժամ',
|
||
'no.day': 'Օր',
|
||
'no.noSlots': 'Այս օրը ազատ ժամ չկա։',
|
||
'no.otherTime': 'Այլ ժամ (պայմանավորվել ենք կատարողի հետ)',
|
||
'no.customTime': 'Ժամ',
|
||
'no.customHint': 'Երևանի ժամով։',
|
||
'no.note': 'Մեկնաբանություն կատարողի համար',
|
||
'no.notePh': 'Դոմոֆոնի կոդ, կենդանիներ…',
|
||
'no.payment': 'Վճարում',
|
||
'no.hint': 'Գինը՝ հաշվի առնելով բաժանորդագրությունը։ Հաճախորդը ծանուցում կստանա։',
|
||
'no.create': 'Ձևակերպել պատվերը',
|
||
'no.created': 'Պատվեր №{n}-ը ձևակերպված է',
|
||
'prv.title': 'Կատարողներ',
|
||
'prv.add': 'Ավելացնել',
|
||
'prv.search': 'Անուն կամ հեռախոս',
|
||
'prv.status.active': 'Աշխատում են',
|
||
'prv.status.blocked': 'Արգելափակված',
|
||
'prv.status.all': 'Բոլորը',
|
||
'prv.empty': 'Ոչ ոք չգտնվեց։',
|
||
'prv.col.name': 'Կատարող',
|
||
'prv.col.rating': 'Վարկանիշ',
|
||
'prv.col.done': 'Պատվերներ',
|
||
'prv.col.refused': 'Հրաժարումներ',
|
||
'prv.col.next': 'Մոտակա պատվերը',
|
||
'prv.period30': 'Պատվերներ, հրաժարումներ, ցածր գնահատականներ՝ 30 օրում։',
|
||
'prv.blocked': 'արգելափակված',
|
||
'prv.onShift': 'հերթափոխում',
|
||
'prv.offShift': 'հերթափոխում չէ',
|
||
'prv.notLinked': 'բոտը բացված չէ',
|
||
'prv.noDocs': 'փաստաթղթեր չկան',
|
||
'prv.ratings': 'գնահատականներ՝ {n}',
|
||
'prv.low': 'ցածր՝ {n}',
|
||
'prv.today': 'այսօր՝ {n}',
|
||
'prv.back': 'Բոլոր կատարողները',
|
||
'prv.write': 'Գրել',
|
||
'prv.edit': 'Խմբագրել',
|
||
'prv.blockedSince': 'Արգելափակված է {date}-ից։',
|
||
'prv.unblock': 'Վերադարձնել աշխատանքի',
|
||
'prv.inviteHint': 'Կատարողը դեռ չի բացել աշխատանքային բոտը՝ ուղարկեք հղումը։',
|
||
'prv.copyInvite': 'Պատճենել հղումը',
|
||
'prv.quality': 'Որակ',
|
||
'prv.days30': '30 օրում',
|
||
'prv.acceptRate': 'ընդունել է {a}-ը {n}-ից',
|
||
'prv.refusals': 'հրաժարվել՝ {d}, լռել՝ {e}',
|
||
'prv.lowRatings': 'գնահատական 3 և ցածր',
|
||
'prv.upcoming': 'Մոտակա պատվերներ',
|
||
'prv.noUpcoming': 'Նշանակված պատվերներ չկան։',
|
||
'prv.recent': 'Վերջին կատարվածները',
|
||
'prv.balance': 'Վճարման ենթակա',
|
||
'prv.thisMonth': 'Այս ամիս',
|
||
'prv.prevMonth': 'Անցյալ',
|
||
'prv.paidTotal': 'Վճարված',
|
||
'prv.payout': 'Նշել վճարումը',
|
||
'prv.payoutTitle': 'Վճարում կատարողին',
|
||
'prv.amount': 'Գումար, ֏',
|
||
'prv.balanceHint': 'Պարտք կատարողին՝ {sum}',
|
||
'prv.payoutNote': 'Ինչպես է վճարվել',
|
||
'prv.payoutNotePh': 'Կանխիկ / փոխանցում…',
|
||
'prv.payoutConfirm': 'Վճարված է',
|
||
'prv.payoutDone': 'Վճարումը նշված է',
|
||
'prv.rateCompany': 'ընկերության դրույք {v}',
|
||
'prv.rateOwn': 'դրույք {v}',
|
||
'prv.ratePreset': '«{name}» նախադրույքով',
|
||
'prv.work': 'Աշխատանք',
|
||
'prv.languages': 'Լեզուներ',
|
||
'prv.districts': 'Շրջաններ',
|
||
'prv.anyDistrict': 'ցանկացած',
|
||
'prv.districtsHint': 'Ընտրությունը նախապատվություն է տալիս շրջանում աշխատողներին։',
|
||
'prv.docs': 'Թույլտվության փաստաթղթեր',
|
||
'prv.noDocsHint': 'Անձնագիր, պայմանագիր, տեղեկանք՝ փակ պահոցում։',
|
||
'prv.docTitlePh': 'Անվանում՝ անձնագիր, պայմանագիր…',
|
||
'prv.upload': 'Վերբեռնել',
|
||
'prv.docAdded': 'Փաստաթուղթն ավելացված է',
|
||
'prv.removeDocConfirm': 'Ջնջե՞լ փաստաթուղթը։',
|
||
'prv.access': 'Թույլտվություն',
|
||
'prv.block': 'Արգելափակել',
|
||
'prv.blockTitle': 'Արգելափակել կատարողին',
|
||
'prv.blockReason': 'Պատճառը',
|
||
'prv.blockReasonPh': 'Օրինակ՝ բողոքներ, փաստաթղթեր չկան',
|
||
'prv.blockHint': 'Նոր առաջարկներ չեն լինի։ Նշանակված պատվերները վերանշանակեք ձեռքով։',
|
||
'prv.resetInvite': 'Նոր հղում բոտի համար',
|
||
'prv.resetConfirm': 'Ստեղծե՞լ նոր հղում։ Ընթացիկ կապը կհանվի։',
|
||
'prv.since': 'Մեզ հետ է {date}-ից',
|
||
'prv.saved': 'Պահպանված է',
|
||
'prv.addTitle': 'Նոր կատարող',
|
||
'prv.editTitle': 'Կատարողի պրոֆիլ',
|
||
'prv.name': 'Անուն',
|
||
'prv.role': 'Դեր',
|
||
'prv.company': 'Ընկերություն',
|
||
'prv.freelance': 'Անհատ կատարող',
|
||
'prv.schedule': 'Ժամանակացույց',
|
||
'prv.rate': 'Դրույք',
|
||
'prv.note': 'Թիմի նշում',
|
||
'err.REASON_REQUIRED': 'Նշեք պատճառը։',
|
||
'err.SLOT_UNAVAILABLE': 'Այս ժամը զբաղված է կամ անցել է։',
|
||
'err.ALREADY_ASSIGNED': 'Պատվերն արդեն նշանակված է։',
|
||
'err.PROVIDER_BUSY': 'Կատարողը զբաղված է այդ ժամին։',
|
||
'err.TRANSITION_NOT_ALLOWED': 'Այս քայլը հիմա հասանելի չէ։',
|
||
'err.CHECKLIST_INCOMPLETE': 'Կատարողը նախ պետք է ավարտի ստուգացանկը։',
|
||
'err.CONSENT_REQUIRED': 'Հաճախորդը դեռ համաձայնություն չի տվել։',
|
||
'err.ADDRESS_REQUIRED': 'Նշեք հասցեն և շրջանը։',
|
||
'err.INVALID_PARAMS': 'Ստուգեք պատվերի պարամետրերը։',
|
||
'err.OFFER_NOT_ACTIVE': 'Առաջարկն այլևս ակտիվ չէ։',
|
||
'err.BAD_FILE_TYPE_DOC': 'Միայն լուսանկար կամ PDF։',
|
||
'audit.bo.orders.assign': 'առաջարկեց պատվերը',
|
||
'audit.bo.orders.auto': 'գործարկեց ավտոմատ ընտրությունը',
|
||
'audit.bo.orders.unassign': 'հանեց կատարողին',
|
||
'audit.bo.orders.transition': 'փոխեց պատվերի կարգավիճակը',
|
||
'audit.bo.orders.cancel': 'չեղարկեց պատվերը',
|
||
'audit.bo.orders.reschedule': 'տեղափոխեց պատվերը',
|
||
'audit.bo.orders.markPaid': 'նշեց վճարումը',
|
||
'audit.bo.orders.create': 'ձևակերպեց պատվեր',
|
||
'audit.bo.orders.setAutoSetting': 'փոխեց ավտոմատ բաշխումը',
|
||
'audit.bo.providers.create': 'ավելացրեց կատարող',
|
||
'audit.bo.providers.update': 'փոխեց կատարողի պրոֆիլը',
|
||
'audit.bo.providers.setActive': 'փոխեց կատարողի թույլտվությունը',
|
||
'audit.bo.providers.resetInvite': 'նոր հղում տվեց կատարողին',
|
||
'audit.bo.providers.removeDoc': 'ջնջեց կատարողի փաստաթուղթը',
|
||
'audit.bo.providers.addDoc': 'վերբեռնեց կատարողի փաստաթուղթը',
|
||
'audit.bo.providers.payout': 'նշեց վճարում կատարողին',
|
||
'chat.order': 'Պատվեր №{n}',
|
||
'chat.noOrder': 'Առանց պատվերի',
|
||
'chat.noOrderNow': 'Այժմ պատվեր չկա',
|
||
'chat.orderNow': 'Այժմ',
|
||
'chat.orderNext': 'Հաջորդը',
|
||
'chat.orderNoNext': 'Մոտակա պատվերներ չկան',
|
||
'chat.orderClient': 'հաճախորդ {name}',
|
||
'chat.wroteNoOrder': 'գրել է առանց պատվերի',
|
||
'err.CONCIERGE_SUBSCRIBERS_ONLY': 'Կոնսիերժը միայն բաժանորդների համար է։ Նախ տրամադրեք բաժանորդագրություն։',
|
||
'err.ASSIGNEE_NO_ACCESS': 'Այս աշխատակիցը մուտք չունի այս ալիքին։',
|
||
'err.PROVIDER_NOT_LINKED': 'Կատարողը դեռ չի բացել աշխատանքային բոտը։',
|
||
'err.BAD_FILE_TYPE': 'Այս ֆայլը չի համապատասխանում։ Կարելի է լուսանկար, PDF, Word, Excel, տեքստ կամ ZIP։',
|
||
'audit.bo.chats.send': 'պատասխանեց զրույցում',
|
||
'audit.bo.chats.sendFile': 'ֆայլ ուղարկեց զրույցում',
|
||
'audit.bo.chats.assign': 'նշանակեց զրույցի պատասխանատու',
|
||
'audit.bo.chats.close': 'փակեց զրույցը',
|
||
'audit.bo.chats.reopen': 'կրկին բացեց զրույցը',
|
||
'audit.bo.chats.move': 'զրույցը տեղափոխեց այլ ալիք',
|
||
'audit.bo.chats.openFor': 'բացեց զրույց հաճախորդի հետ',
|
||
'audit.bo.chats.templates.save': 'փոխեց պատասխանի ձևանմուշը',
|
||
'audit.bo.chats.templates.remove': 'ջնջեց պատասխանի ձևանմուշը',
|
||
};
|
||
|
||
const DICTS: Record<BoLocale, Dict> = { ru, en, hy };
|
||
|
||
export type T = (key: BoKey | (string & {}), params?: Record<string, string | number | null | undefined>) => string;
|
||
|
||
function makeT(locale: BoLocale): T {
|
||
const dict = DICTS[locale];
|
||
return (key, params) => {
|
||
let s: string = (dict as Record<string, string>)[key] ?? (ru as Record<string, string>)[key] ?? key;
|
||
if (params) for (const [k, v] of Object.entries(params)) s = s.replaceAll(`{${k}}`, String(v ?? ''));
|
||
return s;
|
||
};
|
||
}
|
||
|
||
interface Ctx {
|
||
locale: BoLocale;
|
||
setLocale: (l: BoLocale) => void;
|
||
t: T;
|
||
/** общие переводы проекта: services.<code>.name, roles.<ROLE>, params.* и т.п. */
|
||
shared: (key: string, params?: Record<string, string | number>) => string;
|
||
/** время по Еревану: 14:00 */
|
||
time: (d: Date) => string;
|
||
/** общий t проекта целиком — для хелперов @barev/web (paramsSummary и т.п.) */
|
||
sharedT: ReturnType<typeof createSharedT>;
|
||
amd: (n: number) => string;
|
||
date: (d: Date) => string;
|
||
dateTime: (d: Date) => string;
|
||
/** сокращённая сумма для плотных мест: 1,2 млн */
|
||
amdShort: (n: number) => string;
|
||
}
|
||
|
||
const I18nCtx = createContext<Ctx | null>(null);
|
||
const KEY = 'barev.bo.locale';
|
||
|
||
function initialLocale(): BoLocale {
|
||
try {
|
||
const saved = localStorage.getItem(KEY);
|
||
if (saved && (BO_LOCALES as readonly string[]).includes(saved)) return saved as BoLocale;
|
||
} catch {
|
||
/* приватный режим */
|
||
}
|
||
const nav = navigator.language.slice(0, 2);
|
||
return (BO_LOCALES as readonly string[]).includes(nav) ? (nav as BoLocale) : 'ru';
|
||
}
|
||
|
||
export function BoI18nProvider({ children }: { children: ReactNode }) {
|
||
const [locale, setLocaleState] = useState<BoLocale>(initialLocale);
|
||
useEffect(() => {
|
||
document.documentElement.lang = locale;
|
||
}, [locale]);
|
||
const value = useMemo<Ctx>(() => {
|
||
const sharedT = createSharedT(locale as SharedLocale);
|
||
const intl = locale === 'en' ? 'en-GB' : locale === 'hy' ? 'hy-AM' : 'ru-RU';
|
||
const compact = new Intl.NumberFormat(intl, { notation: 'compact', maximumFractionDigits: 1 });
|
||
return {
|
||
locale,
|
||
setLocale: (l) => {
|
||
setLocaleState(l);
|
||
try {
|
||
localStorage.setItem(KEY, l);
|
||
} catch {
|
||
/* приватный режим */
|
||
}
|
||
},
|
||
t: makeT(locale),
|
||
shared: sharedT,
|
||
sharedT,
|
||
amd: (n) => formatAmd(locale as SharedLocale, n),
|
||
amdShort: (n) => `${compact.format(n)} ֏`,
|
||
date: (d) => formatDateTime(locale as SharedLocale, d, { day: 'numeric', month: 'short', year: 'numeric' }),
|
||
dateTime: (d) => formatDateTime(locale as SharedLocale, d, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' }),
|
||
time: (d) => formatDateTime(locale as SharedLocale, d, { hour: '2-digit', minute: '2-digit' }),
|
||
};
|
||
}, [locale]);
|
||
return <I18nCtx.Provider value={value}>{children}</I18nCtx.Provider>;
|
||
}
|
||
|
||
export function useT() {
|
||
const v = useContext(I18nCtx);
|
||
if (!v) throw new Error('BoI18nProvider missing');
|
||
return v;
|
||
}
|
||
|
||
/** Текст ошибки API: код бизнес-ошибки → перевод, иначе сообщение */
|
||
export function errText(t: T, err: unknown): string {
|
||
const msg = (err as { message?: string })?.message ?? '';
|
||
const known = `err.${msg}`;
|
||
const tr = t(known);
|
||
return tr !== known ? tr : t('ui.error', { msg: msg || '—' });
|
||
}
|