domovoy_bot/keyboards/inline.py

433 lines
16 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.

"""
Inline-клавиатуры
"""
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from utils.ui_styles import LEVEL_EMOJI
def get_main_menu(verified: bool = False, is_ig: bool = False, is_admin: bool = False, is_superadmin: bool = False) -> InlineKeyboardMarkup:
"""
Стабильное главное меню LKM37 (Grid 2xN)
"""
builder = InlineKeyboardBuilder()
# СТРОКА 1: БАЗА (ВСЕГДА ТУТ)
builder.row(
InlineKeyboardButton(text='📞 Телефоны', callback_data='phones'),
InlineKeyboardButton(text='🏢 О доме', callback_data='about_house')
)
# СТРОКА 2-3: ДЛЯ ВЕРИФИЦИРОВАННЫХ (ФИКСИРОВАННОЕ МЕСТО)
if verified:
builder.row(
InlineKeyboardButton(text='📅 График', callback_data='schedule'),
InlineKeyboardButton(text='💰 Платежи', callback_data='payments')
)
builder.row(
InlineKeyboardButton(text='📋 Опросы', callback_data='polls'),
InlineKeyboardButton(text='🎉 События', callback_data='events')
)
builder.row(
InlineKeyboardButton(text='🏪 Маркет', callback_data='market'),
InlineKeyboardButton(text='🏆 Рейтинг', callback_data='achievements')
)
else:
# Для гостей кнопка верификации на видном месте
builder.row(
InlineKeyboardButton(text='🛡️ ВЕРИФИКАЦИЯ', callback_data='start_verification')
)
# СТРОКА 4: ИНИЦИАТИВНАЯ ГРУППА И АДМИН
if is_ig or is_admin:
buttons = []
if is_ig:
buttons.append(InlineKeyboardButton(text='🎯 ТИМ-МЕНЮ', callback_data='ig_menu'))
if is_admin:
buttons.append(InlineKeyboardButton(text='⚙️ АДМИНКА', callback_data='admin_menu'))
builder.row(*buttons)
# СТРОКА 5: СУПЕР-АДМИН (ТЫ)
if is_superadmin:
builder.row(
InlineKeyboardButton(text='👑 [ROOT: УПРАВЛЕНИЕ]', callback_data='superadmin_menu')
)
# СТРОКА 6: СЛУЖЕБНОЕ (НИЗ)
builder.row(
InlineKeyboardButton(text='❓ Помощь', callback_data='help'),
InlineKeyboardButton(text='🌦️ Погода', callback_data='weather'),
InlineKeyboardButton(text='👤 Профиль', callback_data='my_profile')
)
return builder.as_markup()
def get_thank_user_keyboard(users: list, page: int = 0, page_size: int = 20) -> InlineKeyboardMarkup:
"""
Клавиатура для выбора пользователя чтобы поблагодарить
:param users: список пользователей (User модели)
:param page: текущая страница (0-based)
:param page_size: размер страницы
"""
builder = InlineKeyboardBuilder()
total_pages = (len(users) + page_size - 1) // page_size if users else 1
start_idx = page * page_size
end_idx = min(start_idx + page_size, len(users))
page_users = users[start_idx:end_idx]
for user in page_users:
name = user.full_name or f'user{user.user_id}'
apt = f' (кв. {user.apartment})' if user.apartment else ''
builder.button(
text=f'🙏 {name}{apt}',
callback_data=f'thank_select_{user.user_id}'
)
# Кнопки навигации
nav_buttons = []
if page > 0:
nav_buttons.append(InlineKeyboardButton(text='⬅️', callback_data=f'thank_page_{page - 1}'))
if page < total_pages - 1:
nav_buttons.append(InlineKeyboardButton(text='➡️', callback_data=f'thank_page_{page + 1}'))
if nav_buttons:
builder.row(*nav_buttons)
builder.row(
InlineKeyboardButton(text='🔙 Назад', callback_data='main_menu'),
)
return builder.as_markup()
def get_thank_confirm_keyboard(user_id: int) -> InlineKeyboardMarkup:
"""Клавиатура подтверждения благодарности"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='✅ Поблагодарить', callback_data=f'thank_confirm_{user_id}'),
InlineKeyboardButton(text='❌ Отмена', callback_data='thank_user'),
)
return builder.as_markup()
def get_admin_menu() -> InlineKeyboardMarkup:
"""Меню администратора"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='📊 Статистика', callback_data='admin_stats'),
InlineKeyboardButton(text='🕵️ Шпионы', callback_data='admin_spies'),
)
builder.row(
InlineKeyboardButton(text='👥 Пользователи', callback_data='admin_users'),
InlineKeyboardButton(text='⏳ Непроверенные', callback_data='admin_unverified'),
)
builder.row(
InlineKeyboardButton(text='📥 Экспорт JSON', callback_data='admin_export'),
InlineKeyboardButton(text='📤 Рассылка', callback_data='admin_broadcast'),
)
builder.row(
InlineKeyboardButton(text='🔙 В главное меню', callback_data='main_menu'),
)
return builder.as_markup()
def get_verification_menu() -> InlineKeyboardMarkup:
"""Меню верификации"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='✅ Подтвердить верификацию', callback_data='verify_approve'),
InlineKeyboardButton(text='❌ Отклонить', callback_data='verify_reject'),
)
builder.row(
InlineKeyboardButton(text='📝 Написать жильцу', callback_data='verify_message'),
)
return builder.as_markup()
def get_phones_menu() -> InlineKeyboardMarkup:
"""Меню телефонов"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='🚨 Экстренные', callback_data='phones_emergency'),
InlineKeyboardButton(text='🔧 ЖКХ', callback_data='phones_utility'),
)
builder.row(
InlineKeyboardButton(text='👮 Полиция', callback_data='phones_police'),
InlineKeyboardButton(text='👷 Мастера', callback_data='phones_masters'),
)
builder.row(
InlineKeyboardButton(text='🔙 Назад', callback_data='main_menu'),
)
return builder.as_markup()
def get_unverified_menu() -> InlineKeyboardMarkup:
"""Меню для НЕверифицированных пользователей (красный стиль)"""
builder = InlineKeyboardBuilder()
emoji = LEVEL_EMOJI['unverified'] # 🔴
builder.row(
InlineKeyboardButton(text=f'{emoji} 📞 Экстренные телефоны', callback_data='phones'),
)
builder.row(
InlineKeyboardButton(text=f'{emoji} 👮 Участковый', callback_data='police'),
)
builder.row(
InlineKeyboardButton(text=f'{emoji} 📜 Правила чата', callback_data='rules'),
)
builder.row(
InlineKeyboardButton(text=f'{emoji} ❓ Помощь', callback_data='help'),
)
return builder.as_markup()
def get_spy_detail_menu(user_id: int) -> InlineKeyboardMarkup:
"""Детали шпиона"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='⚠️ Предупредить', callback_data=f'spy_warn_{user_id}'),
InlineKeyboardButton(text='🚫 Забанить', callback_data=f'spy_ban_{user_id}'),
)
builder.row(
InlineKeyboardButton(text='📝 Профиль', callback_data=f'spy_profile_{user_id}'),
InlineKeyboardButton(text='🔙 Назад', callback_data='admin_spies'),
)
return builder.as_markup()
def get_yes_no_keyboard() -> InlineKeyboardMarkup:
"""Клавиатура Да/Нет"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='✅ Да', callback_data='yes'),
InlineKeyboardButton(text='❌ Нет', callback_data='no'),
)
return builder.as_markup()
def get_poll_keyboard(poll_id: int, options: list) -> InlineKeyboardMarkup:
"""Клавиатура для голосования"""
builder = InlineKeyboardBuilder()
# Кнопки для каждого варианта
for i, option in enumerate(options):
builder.row(
InlineKeyboardButton(
text=f"🔘 {option}",
callback_data=f'poll_vote_{poll_id}_{i}'
)
)
return builder.as_markup()
def get_poll_results_keyboard(poll_id: int) -> InlineKeyboardMarkup:
"""Клавиатура для просмотра результатов"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(
text='📊 Показать результаты',
callback_data=f'poll_results_{poll_id}'
)
)
return builder.as_markup()
def get_poll_close_keyboard(poll_id: int) -> InlineKeyboardMarkup:
"""Клавиатура для закрытия опроса (только админ)"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(
text='🔒 Закрыть опрос',
callback_data=f'poll_close_{poll_id}'
)
)
return builder.as_markup()
def get_schedule_menu() -> InlineKeyboardMarkup:
"""Меню выбора типа отключения"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='💧 Вода', callback_data='schedule_type_water'),
InlineKeyboardButton(text='⚡ Электричество', callback_data='schedule_type_electricity'),
)
builder.row(
InlineKeyboardButton(text='🔥 Отопление', callback_data='schedule_type_heating'),
InlineKeyboardButton(text='🔶 Газ', callback_data='schedule_type_gas'),
)
builder.row(
InlineKeyboardButton(text='🛗 Лифт', callback_data='schedule_type_elevator'),
InlineKeyboardButton(text='📋 Общее', callback_data='schedule_type_general'),
)
return builder.as_markup()
def get_schedule_item_menu(skip: bool = False) -> InlineKeyboardMarkup:
"""Меню для пропуска описания"""
builder = InlineKeyboardBuilder()
if skip:
builder.row(
InlineKeyboardButton(text='⏭️ Пропустить', callback_data='schedule_skip_desc'),
)
return builder.as_markup()
def get_ads_category_menu() -> InlineKeyboardMarkup:
"""Меню выбора категории объявления"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='💰 Продам', callback_data='ads_category_sell'),
InlineKeyboardButton(text='🛒 Куплю', callback_data='ads_category_buy'),
)
builder.row(
InlineKeyboardButton(text='🎁 Отдам', callback_data='ads_category_give'),
InlineKeyboardButton(text='😿 Потеряно', callback_data='ads_category_lost'),
)
builder.row(
InlineKeyboardButton(text='😺 Нашлось', callback_data='ads_category_found'),
InlineKeyboardButton(text='🔧 Услуга', callback_data='ads_category_service'),
)
return builder.as_markup()
def get_ads_item_menu() -> InlineKeyboardMarkup:
"""Меню для объявления (просмотр)"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='📞 Показать телефон', callback_data='ads_show_phone'),
)
return builder.as_markup()
def get_payment_type_menu() -> InlineKeyboardMarkup:
"""Меню выбора типа платежа"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='⚡ Электро', callback_data='payment_type_electricity'),
InlineKeyboardButton(text='💧 Вода', callback_data='payment_type_water'),
)
builder.row(
InlineKeyboardButton(text='🔥 Отопление', callback_data='payment_type_heating'),
InlineKeyboardButton(text='🔶 Газ', callback_data='payment_type_gas'),
)
builder.row(
InlineKeyboardButton(text='🏠 Жильё', callback_data='payment_type_maintenance'),
InlineKeyboardButton(text='🗑️ Мусор', callback_data='payment_type_trash'),
)
builder.row(
InlineKeyboardButton(text='📡 Интернет', callback_data='payment_type_internet'),
InlineKeyboardButton(text='📋 Другое', callback_data='payment_type_other'),
)
return builder.as_markup()
def get_events_keyboard(events: list) -> InlineKeyboardMarkup:
"""Список событий"""
builder = InlineKeyboardBuilder()
for event in events:
builder.row(InlineKeyboardButton(
text=f"📅 {event['title']}",
callback_data=f"event_view_{event['id']}"
))
builder.row(InlineKeyboardButton(text='🔙 Назад', callback_data='main_menu'))
return builder.as_markup()
def get_event_view_keyboard(event_id: int, is_participant: bool, is_admin: bool = False) -> InlineKeyboardMarkup:
"""Просмотр события"""
builder = InlineKeyboardBuilder()
if is_participant:
builder.row(InlineKeyboardButton(text='❌ Покинуть', callback_data=f"event_leave_{event_id}"))
else:
builder.row(InlineKeyboardButton(text='✅ Участвовать', callback_data=f"event_join_{event_id}"))
if is_admin:
builder.row(InlineKeyboardButton(text='🗑️ Удалить (Админ)', callback_data=f"event_delete_{event_id}"))
builder.row(InlineKeyboardButton(text='🔙 К списку', callback_data='events'))
return builder.as_markup()
def get_polls_list_keyboard(polls: list) -> InlineKeyboardMarkup:
"""Список активных опросов"""
builder = InlineKeyboardBuilder()
for poll in polls:
builder.row(InlineKeyboardButton(
text=f"📊 {poll.question[:40]}",
callback_data=f"poll_view_{poll.poll_id}"
))
builder.row(InlineKeyboardButton(text='🔙 Назад', callback_data='main_menu'))
return builder.as_markup()
def get_poll_view_keyboard(poll_id: int, is_admin: bool = False) -> InlineKeyboardMarkup:
"""Меню просмотра опроса"""
builder = InlineKeyboardBuilder()
builder.row(InlineKeyboardButton(text='🗳️ Голосовать', callback_data=f"poll_vote_menu_{poll_id}"))
builder.row(InlineKeyboardButton(text='📊 Результаты', callback_data=f"poll_results_{poll_id}"))
if is_admin:
builder.row(InlineKeyboardButton(text='🔒 Закрыть опрос', callback_data=f"poll_close_{poll_id}"))
builder.row(InlineKeyboardButton(text='🔙 К списку', callback_data='polls'))
return builder.as_markup()
def get_profile_keyboard(meter_reminders_enabled: bool = True) -> InlineKeyboardMarkup:
"""Клавиатура профиля"""
builder = InlineKeyboardBuilder()
# Кнопка переключения напоминаний о счетчиках
reminders_text = "🔔 Напоминания: ВКЛ" if meter_reminders_enabled else "🔕 Напоминания: ВЫКЛ"
builder.row(InlineKeyboardButton(text=reminders_text, callback_data="toggle_meter_reminders"))
builder.row(InlineKeyboardButton(text='🔄 Обновить', callback_data='my_profile'))
builder.row(InlineKeyboardButton(text='🔙 Назад', callback_data='main_menu'))
return builder.as_markup()
def get_weather_keyboard() -> InlineKeyboardMarkup:
"""Клавиатура меню погоды"""
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text='🌦️ Сегодня (Подробно)', callback_data='weather_today'),
)
builder.row(
InlineKeyboardButton(text='📅 На 3 дня', callback_data='weather_3days'),
InlineKeyboardButton(text='📅 На неделю', callback_data='weather_7days'),
)
builder.row(
InlineKeyboardButton(text='🔙 Назад', callback_data='main_menu')
)
return builder.as_markup()