Files
DutyLog/src/dutylog/application/bot/admin_dialogs/rooms_management.py
T
2026-03-04 01:43:20 +03:00

889 lines
28 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.
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,
)
from dutylog.infrastructure.database.repositories.residents_repository import (
ResidentsRepository,
)
from dutylog.infrastructure.database.repositories.room_hours_transactions_repository import (
RoomHoursTransactionsRepository,
)
from dutylog.infrastructure.database.repositories.users_repository import (
UsersRepository,
)
from dutylog.infrastructure.utils.datetime import msk_now
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_info)
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_info_data(
dialog_manager: DialogManager,
rooms_repository: FromDishka[RoomsRepository],
floors_repository: FromDishka[FloorsRepository],
residents_repository: FromDishka[ResidentsRepository],
**kwargs,
):
room_id = dialog_manager.dialog_data.get("selected_room_id")
if not room_id:
return {"info_content": "Ошибка: комната не выбрана"}
room = await rooms_repository.get_room_by_id(room_id)
if not room:
return {"info_content": "Ошибка: комната не найдена"}
floor = await floors_repository.get_floor_by_id(room.on_floor)
floor_number = floor.number if floor else "???"
# Получаем резидентов комнаты
residents = await residents_repository.get_residents_by_room(room_id)
residents_info = ""
if residents:
residents_info = "\n<b>Проживающие:</b>\n"
for resident in residents:
status = "🟢" if resident.is_busy else "⚪️"
name = resident.real_name if resident.real_name else "Без имени"
residents_info += f"{status} {name}\n"
else:
residents_info = "\n<i>Нет проживающих</i>\n"
info_content = f"""
<blockquote>🚪 <b>Информация о комнате</b></blockquote>
<b>Номер:</b> <code>{room.number}</code>
<b>Этаж:</b> <code>{floor_number}</code>
{residents_info}
🟢 <b>Отработанные часы:</b> <code>{room.inactive_hours}</code> ч
🔴 <b>Неотработанные часы:</b> <code>{room.active_hours}</code> ч
"""
return {
"info_content": info_content,
"has_residents": len(residents) > 0,
}
async def on_room_add_hours_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.room_add_hours_select)
async def on_room_remove_hours_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.room_remove_hours_select)
async def get_room_hours_select_data(**kwargs):
hours_options = [
(5, "5"), (10, "10"), (15, "15"), (20, "20"),
(25, "25"), (30, "30"), (35, "35"), (40, "40"),
(45, "45"), (50, "50"), (55, "55"), (60, "60"),
(65, "65"), (70, "70"), (75, "75"), (80, "80"),
]
return {"hours_options": hours_options}
async def on_room_hours_selected(
callback: CallbackQuery,
widget: Select,
dialog_manager: DialogManager,
item_id: str,
):
dialog_manager.dialog_data["selected_hours"] = int(item_id)
if dialog_manager.current_context().state == AdminMenuSG.room_add_hours_select:
await dialog_manager.switch_to(AdminMenuSG.room_add_hours_remark)
else:
await dialog_manager.switch_to(AdminMenuSG.room_remove_hours_remark)
async def on_room_custom_hours_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
if dialog_manager.current_context().state == AdminMenuSG.room_add_hours_select:
await dialog_manager.switch_to(AdminMenuSG.room_add_hours_custom)
else:
await dialog_manager.switch_to(AdminMenuSG.room_remove_hours_custom)
async def on_room_custom_hours_input(
message: Message,
widget: MessageInput,
dialog_manager: DialogManager,
):
if not message.text:
await message.answer("⚠️ Пожалуйста, введите число")
return
try:
hours = int(message.text)
if hours <= 0:
await message.answer("⚠️ Количество часов должно быть положительным числом")
return
dialog_manager.dialog_data["selected_hours"] = hours
if dialog_manager.current_context().state == AdminMenuSG.room_add_hours_custom:
await dialog_manager.switch_to(AdminMenuSG.room_add_hours_remark)
else:
await dialog_manager.switch_to(AdminMenuSG.room_remove_hours_remark)
except ValueError:
await message.answer("⚠️ Пожалуйста, введите корректное число")
async def on_room_remark_input(
message: Message,
widget: MessageInput,
dialog_manager: DialogManager,
):
if message.text and message.text.strip():
dialog_manager.dialog_data["remark"] = message.text.strip()
else:
dialog_manager.dialog_data["remark"] = None
if dialog_manager.current_context().state == AdminMenuSG.room_add_hours_remark:
await dialog_manager.switch_to(AdminMenuSG.room_add_hours_confirm)
else:
await dialog_manager.switch_to(AdminMenuSG.room_remove_hours_confirm)
async def on_room_skip_remark(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
dialog_manager.dialog_data["remark"] = None
if dialog_manager.current_context().state == AdminMenuSG.room_add_hours_remark:
await dialog_manager.switch_to(AdminMenuSG.room_add_hours_confirm)
else:
await dialog_manager.switch_to(AdminMenuSG.room_remove_hours_confirm)
async def get_room_hours_confirm_data(
dialog_manager: DialogManager,
**kwargs,
):
hours = dialog_manager.dialog_data.get("selected_hours", 0)
remark = dialog_manager.dialog_data.get("remark", "")
remark_text = f"\n\n<b>Примечание:</b> {remark}" if remark else ""
return {
"hours": hours,
"remark_text": remark_text,
}
@inject
async def on_room_add_hours_confirm(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
room_transactions_repository: FromDishka[RoomHoursTransactionsRepository],
residents_repository: FromDishka[ResidentsRepository],
users_repository: FromDishka[UsersRepository],
**kwargs,
):
from aiogram import Bot
bot: Bot = dialog_manager.middleware_data.get("bot")
room_id = dialog_manager.dialog_data.get("selected_room_id")
hours = dialog_manager.dialog_data.get("selected_hours")
remark = dialog_manager.dialog_data.get("remark")
admin_id = callback.from_user.id
if room_id and hours:
transaction, _ = await room_transactions_repository.add_hours(
room_id=room_id,
amount=hours,
admin_id=admin_id,
is_active=True,
)
# Отправляем уведомления всем проживающим
residents = await residents_repository.get_residents_by_room(room_id)
for resident in residents:
if resident.user_entity:
user = await users_repository.get_user_by_id(resident.user_entity)
if user:
try:
remark_text = f"\n💬 <i>{remark}</i>" if remark else ""
await bot.send_message(
user.id,
f"<blockquote>📢 <b>Уведомление</b></blockquote>\n\n"
f"Вашей комнате начислено <b>+{hours}</b> ч{remark_text}"
)
except Exception:
pass
await dialog_manager.switch_to(AdminMenuSG.room_info)
@inject
async def on_room_remove_hours_confirm(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
room_transactions_repository: FromDishka[RoomHoursTransactionsRepository],
rooms_repository: FromDishka[RoomsRepository],
residents_repository: FromDishka[ResidentsRepository],
users_repository: FromDishka[UsersRepository],
**kwargs,
):
from aiogram import Bot
bot: Bot = dialog_manager.middleware_data.get("bot")
room_id = dialog_manager.dialog_data.get("selected_room_id")
hours = dialog_manager.dialog_data.get("selected_hours")
remark = dialog_manager.dialog_data.get("remark")
admin_id = callback.from_user.id
if room_id and hours:
room = await rooms_repository.get_room_by_id(room_id)
if room and room.active_hours < hours:
await callback.answer(
f"⚠️ Недостаточно часов! У комнаты {room.active_hours} неотработанных ч, а вы пытаетесь отнять {hours} ч",
show_alert=True
)
await dialog_manager.switch_to(AdminMenuSG.room_info)
return
await room_transactions_repository.move_hours_to_completed(
room_id=room_id,
amount=hours,
admin_id=admin_id,
)
# Отправляем уведомления всем проживающим
residents = await residents_repository.get_residents_by_room(room_id)
for resident in residents:
if resident.user_entity:
user = await users_repository.get_user_by_id(resident.user_entity)
if user:
try:
remark_text = f"\n💬 <i>{remark}</i>" if remark else ""
await bot.send_message(
user.id,
f"<blockquote>📢 <b>Уведомление</b></blockquote>\n\n"
f"С вашей комнаты списано <b>-{hours}</b> ч{remark_text}"
)
except Exception:
pass
await dialog_manager.switch_to(AdminMenuSG.room_info)
async def on_room_hours_cancel(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
):
await dialog_manager.switch_to(AdminMenuSG.room_info)
@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.room_info)
@inject
async def get_room_history_data(
dialog_manager: DialogManager,
rooms_repository: FromDishka[RoomsRepository],
room_transactions_repository: FromDishka[RoomHoursTransactionsRepository],
**kwargs,
):
room_id = dialog_manager.dialog_data.get("selected_room_id")
if not room_id:
return {"history_content": "Ошибка: комната не выбрана"}
room = await rooms_repository.get_room_by_id(room_id)
if not room:
return {"history_content": "Ошибка: комната не найдена"}
transactions = await room_transactions_repository.get_room_history(room_id)
transactions_sorted = sorted(transactions, key=lambda x: x.created_at)
last_10 = transactions_sorted[-10:]
if not last_10:
history_text = f"""
<blockquote>📜 <b>История операций</b></blockquote>
<b>Комната:</b> {room.number}
<i>История операций пуста</i>
"""
else:
history_text = f"""
<blockquote>📜 <b>История операций</b></blockquote>
<b>Комната:</b> {room.number}
"""
for tx in last_10:
operation = "Начислено" if tx.transaction_type == "increase" else "Списано"
emoji = "+" if tx.transaction_type == "increase" else ""
msk_time = tx.created_at.astimezone(msk_now().tzinfo).replace(tzinfo=None)
date_str = msk_time.strftime("%d.%m.%Y %H:%M")
remark_text = f"\n💬 <i>{tx.remark}</i>" if tx.remark else ""
history_text += f"<blockquote><b>{operation}</b> {emoji}<code>{tx.amount}</code> ч\n📅 {date_str}{remark_text}</blockquote>\n"
return {"history_content": history_text}
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_info_window = Window(
Format("{info_content}"),
Row(
Button(
Const("Добавить часы"),
id="room_add_hours_btn",
on_click=on_room_add_hours_click,
),
Button(
Const("Отнять часы"),
id="room_remove_hours_btn",
on_click=on_room_remove_hours_click,
),
),
Button(
Const("📜 История"),
id="room_history_btn",
on_click=lambda c, b, m: m.switch_to(AdminMenuSG.room_history),
),
Button(
Const("🗑 Удалить комнату"),
id="delete_room_btn",
on_click=lambda c, b, m: m.switch_to(AdminMenuSG.room_delete_confirm),
),
SwitchTo(
Const("◀️ Назад к списку"),
id="back_to_rooms_list",
state=AdminMenuSG.rooms_list,
),
state=AdminMenuSG.room_info,
getter=get_room_info_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,
)
room_add_hours_select_window = Window(
Const("<blockquote> <b>Добавить часы комнате</b></blockquote>\n\nВыберите количество часов:"),
Group(
Select(
Format("{item[1]} ч"),
id="room_hours_select_add",
item_id_getter=lambda x: x[0],
items="hours_options",
on_click=on_room_hours_selected,
),
width=4,
),
Button(
Const("✏️ Ввести свое количество"),
id="room_custom_hours_add_btn",
on_click=on_room_custom_hours_click,
),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_room_add_hours",
state=AdminMenuSG.room_info,
),
state=AdminMenuSG.room_add_hours_select,
getter=get_room_hours_select_data,
)
room_remove_hours_select_window = Window(
Const("<blockquote> <b>Отнять часы у комнаты</b></blockquote>\n\nВыберите количество часов:"),
Group(
Select(
Format("{item[1]} ч"),
id="room_hours_select_remove",
item_id_getter=lambda x: x[0],
items="hours_options",
on_click=on_room_hours_selected,
),
width=4,
),
Button(
Const("✏️ Ввести свое количество"),
id="room_custom_hours_remove_btn",
on_click=on_room_custom_hours_click,
),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_room_remove_hours",
state=AdminMenuSG.room_info,
),
state=AdminMenuSG.room_remove_hours_select,
getter=get_room_hours_select_data,
)
room_add_hours_custom_window = Window(
Const("<blockquote>✏️ <b>Добавить часы</b></blockquote>\n\nВведите количество часов:"),
MessageInput(on_room_custom_hours_input),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_room_custom_add",
state=AdminMenuSG.room_add_hours_select,
),
state=AdminMenuSG.room_add_hours_custom,
)
room_remove_hours_custom_window = Window(
Const("<blockquote>✏️ <b>Отнять часы</b></blockquote>\n\nВведите количество часов:"),
MessageInput(on_room_custom_hours_input),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_room_custom_remove",
state=AdminMenuSG.room_remove_hours_select,
),
state=AdminMenuSG.room_remove_hours_custom,
)
room_add_hours_remark_window = Window(
Const("<blockquote>💬 <b>Примечание</b></blockquote>\n\nВведите примечание к операции (или пропустите):"),
MessageInput(on_room_remark_input),
Button(
Const("⏭ Пропустить"),
id="skip_room_add_remark",
on_click=on_room_skip_remark,
),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_room_add_remark",
state=AdminMenuSG.room_info,
),
state=AdminMenuSG.room_add_hours_remark,
)
room_remove_hours_remark_window = Window(
Const("<blockquote>💬 <b>Примечание</b></blockquote>\n\nВведите примечание к операции (или пропустите):"),
MessageInput(on_room_remark_input),
Button(
Const("⏭ Пропустить"),
id="skip_room_remove_remark",
on_click=on_room_skip_remark,
),
SwitchTo(
Const("◀️ Отмена"),
id="cancel_room_remove_remark",
state=AdminMenuSG.room_info,
),
state=AdminMenuSG.room_remove_hours_remark,
)
room_add_hours_confirm_window = Window(
Format("<blockquote> <b>Подтверждение</b></blockquote>\n\nВы уверены, что хотите добавить <code>{hours}</code> часов?{remark_text}"),
Row(
Button(
Const("✅ Да"),
id="confirm_room_add_hours",
on_click=on_room_add_hours_confirm,
),
Button(
Const("❌ Нет"),
id="cancel_room_add_hours_confirm",
on_click=on_room_hours_cancel,
),
),
state=AdminMenuSG.room_add_hours_confirm,
getter=get_room_hours_confirm_data,
)
room_remove_hours_confirm_window = Window(
Format("<blockquote> <b>Подтверждение</b></blockquote>\n\nВы уверены, что хотите отнять <code>{hours}</code> часов?{remark_text}"),
Row(
Button(
Const("✅ Да"),
id="confirm_room_remove_hours",
on_click=on_room_remove_hours_confirm,
),
Button(
Const("❌ Нет"),
id="cancel_room_remove_hours_confirm",
on_click=on_room_hours_cancel,
),
),
state=AdminMenuSG.room_remove_hours_confirm,
getter=get_room_hours_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,
)
room_history_window = Window(
Format("{history_content}"),
SwitchTo(
Const("◀️ Назад"),
id="back_to_room_info",
state=AdminMenuSG.room_info,
),
state=AdminMenuSG.room_history,
getter=get_room_history_data,
)