diff --git a/src/dutylog/application/bot/admin_dialogs/admin_menu_dialog.py b/src/dutylog/application/bot/admin_dialogs/admin_menu_dialog.py index 50f119d..19eea16 100644 --- a/src/dutylog/application/bot/admin_dialogs/admin_menu_dialog.py +++ b/src/dutylog/application/bot/admin_dialogs/admin_menu_dialog.py @@ -55,6 +55,9 @@ from dutylog.application.bot.admin_dialogs.broadcast import ( broadcast_window, broadcast_confirm_window, ) +from dutylog.application.bot.admin_dialogs.faq import ( + admin_faq_window, +) admin_menu_dialog = Dialog( @@ -90,6 +93,7 @@ admin_menu_dialog = Dialog( generate_report_select_period_window, generate_report_confirm_window, statistics_window, + admin_faq_window, broadcast_window, broadcast_confirm_window, search_input_window, diff --git a/src/dutylog/application/bot/admin_dialogs/faq.py b/src/dutylog/application/bot/admin_dialogs/faq.py new file mode 100644 index 0000000..d6a505b --- /dev/null +++ b/src/dutylog/application/bot/admin_dialogs/faq.py @@ -0,0 +1,91 @@ +from aiogram_dialog import Window +from aiogram_dialog.widgets.text import Format, Const +from aiogram_dialog.widgets.kbd import SwitchTo + +from dutylog.application.bot.user_dialogs.states import AdminMenuSG + + +async def get_admin_faq_data(**kwargs) -> dict[str, str]: + content = """ +
Гайд по админке
+ +Привет! Ты теперь админ, и это круто 😎 +Давай разберёмся, что тут к чему. + +
🏠 Резиденты — твоя главная тусовка + +Здесь живут все жители общаги. Можешь: +• Искать кого угодно — по имени, комнате или нику в телеге +• Фильтровать по часам (кто должник, а кто молодец) +• Начислять или снимать часы (не забывай писать за что!) +• Добавлять новых людей или удалять старых +• Отвязывать юзеров от резидентов (если кто-то съехал)
+ +
🚪 Комнаты и 🏢 Этажи + +Тут всё просто — структура общежития. +Добавляй этажи, создавай комнаты, привязывай их друг к другу. +Без этого резидентов не создать!
+ +
📅 Отчётный период — важная штука! + +Система работает по месяцам. Один период = один месяц учёта. + +Как это работает: +• Создаёшь новый период → старый автоматом закрывается +• Дата начала = когда создал +• Дата конца = когда создал следующий + +Зачем это нужно? Чтобы потом сделать красивый отчёт за месяц и показать всем, кто сколько отработал.
+ +
📊 Отчёты — твоя суперсила + +После закрытия периода можешь сгенерить Excel-файл. +В нём будет: +• Все начисления и списания за месяц +• Кто и когда начислил/снял часы +• Примечания (поэтому их важно писать!) +• Автоматический подсчёт итогов + +Отчёт можно скинуть старосте или куратору — всё наглядно.
+ +
📊 Статистика + +Быстрый взгляд на цифры: +• Сколько всего людей в системе +• Сколько админов (ты не один!) +• Общая сумма часов по всем резидентам
+ +
📢 Рассылка + +Нужно всем что-то сообщить? Жми сюда. +Сообщение улетит всем пользователям бота. +Можно использовать HTML для красоты.
+ +
💡 Лайфхаки: + +• Всегда пиши примечание при начислении/списании часов + Через месяц никто не вспомнит, за что было + +• Делай отчёты регулярно + Это твоя страховка и архив данных + +• Проверяй статистику перед закрытием периода + Вдруг что-то забыл начислить?
+ +Вопросы? Пиши создателю бота 👑 +""" + + return {"content": content} + + +admin_faq_window = Window( + Format("{content}"), + SwitchTo( + Const("◀️ Назад"), + id="back_to_main_from_faq", + state=AdminMenuSG.main, + ), + state=AdminMenuSG.faq, + getter=get_admin_faq_data, +) diff --git a/src/dutylog/application/bot/admin_dialogs/floors_management.py b/src/dutylog/application/bot/admin_dialogs/floors_management.py index 3874f3f..fde1b1b 100644 --- a/src/dutylog/application/bot/admin_dialogs/floors_management.py +++ b/src/dutylog/application/bot/admin_dialogs/floors_management.py @@ -194,7 +194,7 @@ floors_list_window = Window( ) floor_delete_confirm_window = Window( - Format("
⚠️ Подтверждение удаления
\n\nВы точно хотите удалить этаж {floor_number}? Это действие необратимо и удалит все комнаты на этом этаже!"), + Format("
⚠️ Подтверждение удаления
\n\nВы точно хотите удалить этаж {floor_number}?\nЭто действие необратимо и удалит все комнаты на этом этаже!"), Row( Button( Const("✅ Да, удалить"), diff --git a/src/dutylog/application/bot/admin_dialogs/main_menu.py b/src/dutylog/application/bot/admin_dialogs/main_menu.py index 79e9212..37fc463 100644 --- a/src/dutylog/application/bot/admin_dialogs/main_menu.py +++ b/src/dutylog/application/bot/admin_dialogs/main_menu.py @@ -171,10 +171,17 @@ main_menu_window = Window( on_click=on_admins_click, when="is_creator", ), - SwitchTo( - Const("📊 Статистика"), - id="stats_btn", - state=AdminMenuSG.statistics, + Row( + SwitchTo( + Const("📊 Статистика"), + id="stats_btn", + state=AdminMenuSG.statistics, + ), + SwitchTo( + Const("❓ FAQ"), + id="faq_btn", + state=AdminMenuSG.faq, + ), ), SwitchTo( Const("📢 Рассылка"), diff --git a/src/dutylog/application/bot/user_dialogs/states.py b/src/dutylog/application/bot/user_dialogs/states.py index e54428b..df6d19f 100644 --- a/src/dutylog/application/bot/user_dialogs/states.py +++ b/src/dutylog/application/bot/user_dialogs/states.py @@ -46,6 +46,7 @@ class AdminMenuSG(StatesGroup): generate_report_select_period = State() generate_report_confirm = State() statistics = State() + faq = State() broadcast = State() broadcast_confirm = State() diff --git a/src/dutylog/application/bot/user_handlers.py b/src/dutylog/application/bot/user_handlers.py index 7199888..d8645cb 100644 --- a/src/dutylog/application/bot/user_handlers.py +++ b/src/dutylog/application/bot/user_handlers.py @@ -1,5 +1,5 @@ from aiogram import Router -from aiogram.filters import CommandStart +from aiogram.filters import CommandStart, ExceptionTypeFilter from aiogram.types import Message, CallbackQuery, ErrorEvent from aiogram_dialog import DialogManager, StartMode from aiogram_dialog.api.exceptions import UnknownIntent @@ -56,7 +56,7 @@ async def start_handler( await dialog_manager.start(RegistrationSG.select_floor, mode=StartMode.RESET_STACK) -@router.error() +@router.error(ExceptionTypeFilter(UnknownIntent)) async def unknown_intent_handler( event: ErrorEvent, dialog_manager: DialogManager,