from aiogram.types import CallbackQuery from aiogram_dialog import Window, DialogManager from aiogram_dialog.widgets.text import Format, Const from aiogram_dialog.widgets.kbd import SwitchTo, Button, Select, ScrollingGroup, Row from dishka import FromDishka from dishka.integrations.aiogram_dialog import inject from dutylog.application.bot.user_dialogs.states import AdminMenuSG from dutylog.infrastructure.database.repositories.users_repository import UsersRepository @inject async def get_admins_list_data( users_repository: FromDishka[UsersRepository], **kwargs, ) -> dict[str, str | list[tuple[str, int]]]: all_users = await users_repository.get_all_users() admins = [u for u in all_users if u.is_admin] if not admins: content = """
👨‍💼 Администраторы
⚠️ Нет администраторов в системе. """ admins_list = [] else: content = f"""
👨‍💼 Администраторы
Всего администраторов: {len(admins)} Выберите администратора для просмотра информации: """ admins_list = [] for admin in admins: display_name = f"@{admin.username}" if admin.username else f"ID: {admin.id}" if admin.first_name: display_name = f"{admin.first_name} ({display_name})" admins_list.append((display_name, admin.id)) return { "content": content, "admins": admins_list, } async def on_admin_selected( callback: CallbackQuery, widget, dialog_manager: DialogManager, item_id: str, ) -> None: dialog_manager.dialog_data["selected_admin_id"] = int(item_id) await dialog_manager.switch_to(AdminMenuSG.admin_info) async def on_add_admin_click( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, ) -> None: await dialog_manager.switch_to(AdminMenuSG.add_admin_select_user) @inject async def get_admin_info_data( users_repository: FromDishka[UsersRepository], dialog_manager: DialogManager, **kwargs, ) -> dict[str, str]: admin_id = dialog_manager.dialog_data.get("selected_admin_id") if not admin_id: return {"content": "⚠️ Администратор не выбран"} admin = await users_repository.get_user_by_id(int(admin_id)) if not admin: return {"content": "⚠️ Администратор не найден"} username = f"@{admin.username}" if admin.username else "—" first_name = admin.first_name or "—" last_name = admin.last_name or "—" content = f"""
👨‍💼 Информация об администраторе
ID: {admin.id} Username: {username} Имя: {first_name} Фамилия: {last_name} Дата добавления: {admin.created_at.strftime('%d.%m.%Y %H:%M')} """ return {"content": content} async def on_remove_admin_click( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, ) -> None: await dialog_manager.switch_to(AdminMenuSG.remove_admin_confirm) @inject async def get_remove_admin_confirm_data( users_repository: FromDishka[UsersRepository], dialog_manager: DialogManager, **kwargs, ) -> dict[str, str]: admin_id = dialog_manager.dialog_data.get("selected_admin_id") if not admin_id: return {"content": "⚠️ Администратор не выбран"} admin = await users_repository.get_user_by_id(int(admin_id)) if not admin: return {"content": "⚠️ Администратор не найден"} username = f"@{admin.username}" if admin.username else f"ID: {admin.id}" display_name = admin.first_name or username content = f"""
⚠️ Подтверждение удаления
Вы уверены, что хотите удалить администратора {display_name}? Пользователь потеряет права администратора. """ return {"content": content} @inject async def on_remove_admin_confirm( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, users_repository: FromDishka[UsersRepository], ) -> None: admin_id = dialog_manager.dialog_data.get("selected_admin_id") if not admin_id: await callback.answer("⚠️ Администратор не выбран", show_alert=True) return await users_repository.update_user(int(admin_id), is_admin=False) await callback.answer("✅ Администратор удалён!") await dialog_manager.switch_to(AdminMenuSG.admins_list) async def on_remove_admin_cancel( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, ) -> None: await dialog_manager.switch_to(AdminMenuSG.admin_info) @inject async def get_add_admin_select_user_data( users_repository: FromDishka[UsersRepository], **kwargs, ) -> dict[str, str | list[tuple[str, int]]]: all_users = await users_repository.get_all_users() non_admin_users = [u for u in all_users if not u.is_admin] if not non_admin_users: content = """
Добавить администратора
⚠️ Нет пользователей, которых можно сделать администраторами. Все пользователи уже являются администраторами. """ users_list = [] else: content = f"""
Добавить администратора
Всего пользователей: {len(non_admin_users)} Выберите пользователя для назначения администратором: """ users_list = [] for user in non_admin_users: display_name = f"@{user.username}" if user.username else f"ID: {user.id}" if user.first_name: display_name = f"{user.first_name} ({display_name})" users_list.append((display_name, user.id)) return { "content": content, "users": users_list, } async def on_user_selected( callback: CallbackQuery, widget, dialog_manager: DialogManager, item_id: str, ) -> None: dialog_manager.dialog_data["selected_user_id"] = int(item_id) await dialog_manager.switch_to(AdminMenuSG.add_admin_confirm) @inject async def get_add_admin_confirm_data( users_repository: FromDishka[UsersRepository], dialog_manager: DialogManager, **kwargs, ) -> dict[str, str]: user_id = dialog_manager.dialog_data.get("selected_user_id") if not user_id: return {"content": "⚠️ Пользователь не выбран"} user = await users_repository.get_user_by_id(int(user_id)) if not user: return {"content": "⚠️ Пользователь не найден"} username = f"@{user.username}" if user.username else f"ID: {user.id}" display_name = user.first_name or username content = f"""
⚠️ Подтверждение
Вы уверены, что хотите назначить {display_name} администратором? Пользователь получит доступ к панели управления. """ return {"content": content} @inject async def on_add_admin_confirm( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, users_repository: FromDishka[UsersRepository], ) -> None: user_id = dialog_manager.dialog_data.get("selected_user_id") if not user_id: await callback.answer("⚠️ Пользователь не выбран", show_alert=True) return await users_repository.update_user(int(user_id), is_admin=True) await callback.answer("✅ Администратор добавлен!") await dialog_manager.switch_to(AdminMenuSG.admins_list) async def on_add_admin_cancel( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, ) -> None: await dialog_manager.switch_to(AdminMenuSG.add_admin_select_user) async def on_back_to_main( callback: CallbackQuery, button: Button, dialog_manager: DialogManager, ) -> None: await dialog_manager.switch_to(AdminMenuSG.main) admins_list_window = Window( Format("{content}"), ScrollingGroup( Select( Format("{item[0]}"), id="admin_select", item_id_getter=lambda x: x[1], items="admins", on_click=on_admin_selected, ), id="admins_scroll", width=1, height=8, ), Button( Const("➕ Добавить администратора"), id="add_admin_btn", on_click=on_add_admin_click, ), Button( Const("◀️ Назад"), id="back_to_main_from_admins", on_click=on_back_to_main, ), state=AdminMenuSG.admins_list, getter=get_admins_list_data, ) admin_info_window = Window( Format("{content}"), Button( Const("🗑 Удалить администратора"), id="remove_admin_btn", on_click=on_remove_admin_click, ), SwitchTo( Const("◀️ Назад"), id="back_to_admins_list", state=AdminMenuSG.admins_list, ), state=AdminMenuSG.admin_info, getter=get_admin_info_data, ) remove_admin_confirm_window = Window( Format("{content}"), Row( Button( Const("✅ Да"), id="confirm_remove_admin", on_click=on_remove_admin_confirm, ), Button( Const("❌ Нет"), id="cancel_remove_admin", on_click=on_remove_admin_cancel, ), ), state=AdminMenuSG.remove_admin_confirm, getter=get_remove_admin_confirm_data, ) add_admin_select_user_window = Window( Format("{content}"), ScrollingGroup( Select( Format("{item[0]}"), id="user_select", item_id_getter=lambda x: x[1], items="users", on_click=on_user_selected, ), id="users_scroll", width=1, height=8, ), SwitchTo( Const("◀️ Назад"), id="back_to_admins_from_add", state=AdminMenuSG.admins_list, ), state=AdminMenuSG.add_admin_select_user, getter=get_add_admin_select_user_data, ) add_admin_confirm_window = Window( Format("{content}"), Row( Button( Const("✅ Да"), id="confirm_add_admin", on_click=on_add_admin_confirm, ), Button( Const("❌ Нет"), id="cancel_add_admin", on_click=on_add_admin_cancel, ), ), state=AdminMenuSG.add_admin_confirm, getter=get_add_admin_confirm_data, )