This commit is contained in:
2026-03-01 15:32:25 +03:00
parent 8b05a2d512
commit 1110d89bb0
17 changed files with 150 additions and 59 deletions
@@ -0,0 +1,366 @@
from aiogram.types import Message, CallbackQuery
from aiogram_dialog import Window, DialogManager
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import SwitchTo, Button, ScrollingGroup, Select, Row, Group
from aiogram_dialog.widgets.input import MessageInput
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.rooms_repository import (
RoomsRepository,
)
from dutylog.infrastructure.database.repositories.floors_repository import (
FloorsRepository,
)
async def on_rooms_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
@inject
async def get_rooms_floors_data(
floors_repository: FromDishka[FloorsRepository],
**kwargs,
):
all_floors = await floors_repository.get_all_floors()
all_floors.sort(key=lambda f: f.number)
floors_data = [(f"🏢 Этаж {f.number}", f.id) for f in all_floors]
content = """
<blockquote>🚪 <b>Комнаты</b></blockquote>
Выберите этаж для просмотра комнат:
"""
return {
"content": content,
"floors": floors_data,
}
async def on_rooms_floor_selected(
callback: CallbackQuery,
widget: Select,
dialog_manager: DialogManager,
item_id: str,
):
dialog_manager.dialog_data["selected_floor_id"] = int(item_id)
await dialog_manager.switch_to(AdminMenuSG.rooms_list)
@inject
async def get_rooms_list_data(
dialog_manager: DialogManager,
rooms_repository: FromDishka[RoomsRepository],
floors_repository: FromDishka[FloorsRepository],
**kwargs,
):
floor_id = dialog_manager.dialog_data.get("selected_floor_id")
if not floor_id:
return {
"content": "Ошибка: этаж не выбран",
"rooms": [],
"floor_number": "???",
}
floor = await floors_repository.get_floor_by_id(floor_id)
floor_number = floor.number if floor else "???"
rooms = await rooms_repository.get_rooms_by_floor(floor_id)
rooms.sort(key=lambda r: r.number)
rooms_data = [(f"🚪 Комната {r.number}", r.id) for r in rooms]
content = f"""
<blockquote>🚪 <b>Комнаты на этаже {floor_number}</b></blockquote>
<b>Всего комнат:</b> <code>{len(rooms)}</code>
Выберите комнату для удаления:
"""
return {
"content": content,
"rooms": rooms_data,
"floor_number": floor_number,
}
async def on_room_selected(
callback: CallbackQuery,
widget: Select,
dialog_manager: DialogManager,
item_id: str,
):
dialog_manager.dialog_data["selected_room_id"] = int(item_id)
await dialog_manager.switch_to(AdminMenuSG.room_delete_confirm)
async def on_add_room_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.create_room_select_floor)
@inject
async def get_create_room_floors_data(
floors_repository: FromDishka[FloorsRepository],
**kwargs,
):
all_floors = await floors_repository.get_all_floors()
all_floors.sort(key=lambda f: f.number)
floors_data = [(f"🏢 Этаж {f.number}", f.id) for f in all_floors]
content = """
<blockquote> <b>Создание комнаты</b></blockquote>
Выберите этаж для новой комнаты:
"""
return {
"content": content,
"floors": floors_data,
}
async def on_create_room_floor_selected(
callback: CallbackQuery,
widget: Select,
dialog_manager: DialogManager,
item_id: str,
):
dialog_manager.dialog_data["new_room_floor_id"] = int(item_id)
await dialog_manager.switch_to(AdminMenuSG.create_room_input)
async def on_room_number_input(
message: Message,
widget: MessageInput,
dialog_manager: DialogManager,
):
if not message.text:
await message.answer("⚠️ Пожалуйста, введите номер комнаты")
return
try:
room_number = int(message.text)
if room_number <= 0:
await message.answer("⚠️ Номер комнаты должен быть положительным числом")
return
dialog_manager.dialog_data["new_room_number"] = room_number
await dialog_manager.switch_to(AdminMenuSG.create_room_confirm)
except ValueError:
await message.answer("⚠️ Пожалуйста, введите корректное число")
async def get_create_room_confirm_data(
dialog_manager: DialogManager,
**kwargs,
):
room_number = dialog_manager.dialog_data.get("new_room_number", "???")
return {"room_number": room_number}
@inject
async def on_create_room_confirm(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
rooms_repository: FromDishka[RoomsRepository],
):
room_number = dialog_manager.dialog_data.get("new_room_number")
floor_id = dialog_manager.dialog_data.get("new_room_floor_id")
if room_number and floor_id:
existing_room = await rooms_repository.get_room_by_number(room_number)
if existing_room:
await callback.answer(
f"⚠️ Комната {room_number} уже существует!",
show_alert=True
)
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
return
await rooms_repository.create_room(room_number, floor_id)
await callback.answer("✅ Комната создана!")
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
async def on_create_room_cancel(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.rooms_select_floor)
@inject
async def get_room_delete_confirm_data(
dialog_manager: DialogManager,
rooms_repository: FromDishka[RoomsRepository],
**kwargs,
):
room_id = dialog_manager.dialog_data.get("selected_room_id")
if not room_id:
return {"room_number": "???"}
room = await rooms_repository.get_room_by_id(room_id)
room_number = room.number if room else "???"
return {"room_number": room_number}
@inject
async def on_delete_room_confirm(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
rooms_repository: FromDishka[RoomsRepository],
):
room_id = dialog_manager.dialog_data.get("selected_room_id")
if room_id:
await rooms_repository.delete_room(room_id)
await callback.answer("✅ Комната удалена!")
await dialog_manager.switch_to(AdminMenuSG.rooms_list)
async def on_delete_room_cancel(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.rooms_list)
rooms_select_floor_window = Window(
Format("{content}"),
Group(
Select(
Format("{item[0]}"),
id="rooms_floors_select",
item_id_getter=lambda x: x[1],
items="floors",
on_click=on_rooms_floor_selected,
),
width=2,
),
Button(
Const(" Добавить комнату"),
id="add_room_btn",
on_click=on_add_room_click,
),
SwitchTo(
Const("◀️ Назад"),
id="back_to_admin_menu_from_rooms",
state=AdminMenuSG.main,
),
state=AdminMenuSG.rooms_select_floor,
getter=get_rooms_floors_data,
)
rooms_list_window = Window(
Format("{content}"),
ScrollingGroup(
Select(
Format("{item[0]}"),
id="rooms_select",
item_id_getter=lambda x: x[1],
items="rooms",
on_click=on_room_selected,
),
id="rooms_scroll",
width=1,
height=7,
),
SwitchTo(
Const("◀️ Назад к этажам"),
id="back_to_rooms_floors",
state=AdminMenuSG.rooms_select_floor,
),
state=AdminMenuSG.rooms_list,
getter=get_rooms_list_data,
)
room_delete_confirm_window = Window(
Format("<blockquote>⚠️ <b>Подтверждение удаления</b></blockquote>\n\nВы точно хотите удалить комнату <code>{room_number}</code>?\nЭто действие необратимо и удалит всех резидентов в этой комнате!"),
Row(
Button(
Const("✅ Да, удалить"),
id="confirm_delete_room",
on_click=on_delete_room_confirm,
),
Button(
Const("❌ Отмена"),
id="cancel_delete_room",
on_click=on_delete_room_cancel,
),
),
state=AdminMenuSG.room_delete_confirm,
getter=get_room_delete_confirm_data,
)
create_room_select_floor_window = Window(
Format("{content}"),
Group(
Select(
Format("{item[0]}"),
id="create_room_floors_select",
item_id_getter=lambda x: x[1],
items="floors",
on_click=on_create_room_floor_selected,
),
width=2,
),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_create_room_floor",
state=AdminMenuSG.rooms_select_floor,
),
state=AdminMenuSG.create_room_select_floor,
getter=get_create_room_floors_data,
)
create_room_input_window = Window(
Const("<blockquote> <b>Создание комнаты</b></blockquote>\n\nВведите номер комнаты:"),
MessageInput(on_room_number_input),
SwitchTo(
Const("◀️ Назад"),
id="back_to_create_room_floor",
state=AdminMenuSG.create_room_select_floor,
),
state=AdminMenuSG.create_room_input,
)
create_room_confirm_window = Window(
Format("<blockquote>✅ <b>Подтверждение</b></blockquote>\n\nСоздать комнату <code>{room_number}</code>?"),
Row(
Button(
Const("✅ Да"),
id="confirm_create_room",
on_click=on_create_room_confirm,
),
Button(
Const("❌ Нет"),
id="cancel_create_room",
on_click=on_create_room_cancel,
),
),
state=AdminMenuSG.create_room_confirm,
getter=get_create_room_confirm_data,
)