Files
bot_vk_ikp_prodagi/keyboards.py
T
Kenik 7caecb1c72 Тикеты заявок, «пробное занятие», доработка ветки вебинара
- Тикеты: add_lead возвращает id заявки; при передаче менеджеру клиент получает
  «🎫 Номер вашей заявки: №N», тот же номер — в карточке оператору и в письме.
  Один тикет на заход (сбрасывается при новом старте воронки/интенсива).
- Кнопка «Записаться на пробное» → «Записаться на пробное занятие» (лейблы + распознавание).
- Ветка вебинара: вход по callback-кнопке и по тексту «записаться на вебинар»,
  текст выровнен по ТЗ, после регистрации состояние FREE_CHAT — основное меню
  остаётся доступным (не блокирует продающую ветку). Дата/время — в config.

Тесты: test_baza_question_ticket, test_webinar_registration. pytest 36 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:04:19 +03:00

202 lines
9.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Клавиатуры интерфейса бота (VK)."""
from vk_api.keyboard import VkKeyboard, VkKeyboardColor
import config
# ==========================================
# КЛАВИАТУРЫ ДЛЯ ИНТЕРФЕЙСА (UX/UI ВКонтакте)
# ==========================================
def get_main_keyboard(is_admin: bool = False) -> str:
"""Главное меню Кибершколы БАЗА. Для админа добавляется кнопка «Админка ⚙️»."""
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Подобрать тренировку 🎯", color=VkKeyboardColor.PRIMARY)
keyboard.add_line()
keyboard.add_button("Летний интенсив CS2 🔥", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Посмотреть цены 💰", color=VkKeyboardColor.SECONDARY)
keyboard.add_button("Задать вопрос 💬", color=VkKeyboardColor.SECONDARY)
if is_admin:
keyboard.add_line()
keyboard.add_button("Админка ⚙️", color=VkKeyboardColor.POSITIVE)
return keyboard.get_keyboard()
# ==========================================
# КЛАВИАТУРЫ ВОРОНКИ «ПОДОБРАТЬ ТРЕНИРОВКУ» (БАЗА)
# ==========================================
def _kb(rows, back=False, ask_manager=False, back_menu=True):
"""Хелпер: строит нижнюю клавиатуру из строк кнопок + служебные кнопки снизу.
back — кнопка «Назад ⬅️» (к предыдущему вопросу воронки);
ask_manager — кнопка «Задать вопрос менеджеру 💬»;
back_menu — кнопка «В главное меню ↩️».
"""
keyboard = VkKeyboard(one_time=False)
for i, row in enumerate(rows):
if i:
keyboard.add_line()
for label in row:
keyboard.add_button(label, color=VkKeyboardColor.SECONDARY)
if ask_manager:
keyboard.add_line()
keyboard.add_button("Задать вопрос менеджеру 💬", color=VkKeyboardColor.SECONDARY)
if back or back_menu:
keyboard.add_line()
if back:
keyboard.add_button("Назад ⬅️", color=VkKeyboardColor.SECONDARY)
if back_menu:
keyboard.add_button("В главное меню ↩️", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_baza_forwho_keyboard() -> str:
return _kb([["Для себя", "Для подростка"]])
def get_baza_age_keyboard() -> str:
return _kb([["1213 лет", "1415 лет"], ["16 лет и старше", "Младше 12 лет"]], back=True)
def get_baza_younger12_keyboard() -> str:
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Обсудить с менеджером 💬", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Вернуться назад ↩️", color=VkKeyboardColor.SECONDARY)
keyboard.add_button("В главное меню ↩️", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_baza_game_keyboard() -> str:
return _kb([["CS2", "Dota 2"], ["World of Tanks", "Другая игра"]], back=True)
def get_baza_level_keyboard() -> str:
return _kb([["Только начинает"], ["Играет для себя"],
["Есть рейтинг или ранг"], ["Играет в команде или турнирах"]], back=True)
def get_baza_format_keyboard() -> str:
return _kb([["Групповые тренировки"], ["Индивидуальные тренировки"],
["Пока не знаю, нужен совет"]], back=True)
def get_baza_group_keyboard() -> str:
return _kb([["Записаться на пробное занятие"], ["Купить 4 тренировки", "Купить 8 тренировок"]],
back=True, ask_manager=True)
def get_baza_individual_keyboard() -> str:
return _kb([["Купить 1 тренировку"],
["Купить 4 тренировки", "Купить 8 тренировок"]],
back=True, ask_manager=True)
def get_baza_menu_only_keyboard() -> str:
"""Только «В главное меню» — для шагов со свободным вводом (совет/вопрос)."""
return _kb([])
def get_baza_intensive_keyboard() -> str:
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Хочу участвовать 🔥", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Задать вопрос 💬", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Посмотреть другие тренировки", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_baza_int_level_keyboard() -> str:
return _kb([["Только начинаю"], ["Уже знаю основы"],
["Играю регулярно"], ["Есть рейтинг или командный опыт"]], back=True)
def get_baza_int_pay_keyboard() -> str:
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Оплатить интенсив 💳", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Сначала задать вопрос 💬", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Вернуться в меню ↩️", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_baza_int_young_keyboard() -> str:
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Передать менеджеру 💬", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Посмотреть другие тренировки", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_baza_prices_keyboard() -> str:
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Подобрать тренировку 🎯", color=VkKeyboardColor.PRIMARY)
keyboard.add_line()
keyboard.add_button("Записаться на пробное занятие", color=VkKeyboardColor.SECONDARY)
keyboard.add_button("Выбрать абонемент", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Задать вопрос 💬", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_admin_keyboard(is_super: bool = False) -> str:
"""Клавиатура админ-панели с разделами. Супер-админу — раздел «Администраторы»."""
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Статистика 📊", color=VkKeyboardColor.SECONDARY)
keyboard.add_button("Быстрые ответы 💬", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("Рассылка 📣", color=VkKeyboardColor.SECONDARY)
keyboard.add_button("Ссылки 🔗", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
if is_super:
keyboard.add_button("Администраторы 👑", color=VkKeyboardColor.SECONDARY)
keyboard.add_line()
keyboard.add_button("В главное меню ↩️", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_faq_admin_keyboard() -> str:
"""Клавиатура раздела управления быстрыми ответами."""
keyboard = VkKeyboard(one_time=False)
keyboard.add_button(" Добавить ответ", color=VkKeyboardColor.PRIMARY)
keyboard.add_line()
keyboard.add_button("✏️ Изменить ответ", color=VkKeyboardColor.SECONDARY)
keyboard.add_button("🗑 Удалить ответ", color=VkKeyboardColor.NEGATIVE)
keyboard.add_line()
keyboard.add_button("В админку ↩️", color=VkKeyboardColor.SECONDARY)
return keyboard.get_keyboard()
def get_pick_keyboard(items: list) -> str:
"""Клавиатура выбора из списка пар (id, label). Кнопка отправляет '<id>. <label>'."""
keyboard = VkKeyboard(one_time=False)
count = 0
for _id, label in items[:10]:
if count and count % 2 == 0:
keyboard.add_line()
short = label if len(label) <= 30 else label[:29] + ""
keyboard.add_button(f"{_id}. {short}", color=VkKeyboardColor.SECONDARY)
count += 1
keyboard.add_line()
keyboard.add_button("Отмена ❌", color=VkKeyboardColor.NEGATIVE)
return keyboard.get_keyboard()
def get_cancel_admin_keyboard() -> str:
"""Кнопка отмены для админских мастеров ввода."""
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Отмена ❌", color=VkKeyboardColor.NEGATIVE)
return keyboard.get_keyboard()
def get_operator_keyboard() -> str:
"""Клавиатура при активном диалоге с оператором."""
keyboard = VkKeyboard(one_time=False)
keyboard.add_button("Завершить диалог 🚪", color=VkKeyboardColor.NEGATIVE)
return keyboard.get_keyboard()