mirror of
https://github.com/koloideal/Quizzi.git
synced 2026-06-10 18:35:28 +03:00
commit
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Row
|
||||
from aiogram_dialog.widgets.text import Const
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.admin_dialogs.states import AdminBroadcastSG, AdminMenuSG
|
||||
from trudex.application.bot.admin_dialogs.states import (AdminBroadcastSG,
|
||||
AdminMenuSG)
|
||||
from trudex.infrastructure.database.dao.user import UserDAO
|
||||
from trudex.infrastructure.utils.broadcast import broadcast_message
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Column, Row, ScrollingGroup, Select
|
||||
from aiogram_dialog.widgets.kbd import (Button, Column, Row, ScrollingGroup,
|
||||
Select)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka.integrations.aiogram import CONTAINER_NAME
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.admin_dialogs.states import AdminGroupsSG, AdminMenuSG
|
||||
from trudex.application.bot.admin_dialogs.states import (AdminGroupsSG,
|
||||
AdminMenuSG)
|
||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||
|
||||
|
||||
@@ -13,10 +16,8 @@ async def on_group_click(_callback: CallbackQuery, _widget, _manager: DialogMana
|
||||
await _callback.answer("ℹ️ Для удаления используйте кнопку 'Удалить группу'")
|
||||
|
||||
|
||||
async def get_groups_data(dialog_manager: DialogManager, **_kwargs):
|
||||
container = dialog_manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def get_groups_data(dialog_manager: DialogManager, group_dao: FromDishka[GroupDAO], **_kwargs):
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
success_message = dialog_manager.dialog_data.pop("success_message", None)
|
||||
@@ -45,7 +46,8 @@ async def on_back_to_menu(_callback: CallbackQuery, _button: Button, manager: Di
|
||||
await manager.start(AdminMenuSG.main, mode=StartMode.RESET_STACK)
|
||||
|
||||
|
||||
async def on_group_number_input(message: Message, _widget: MessageInput, manager: DialogManager):
|
||||
@inject
|
||||
async def on_group_number_input(message: Message, _widget: MessageInput, manager: DialogManager, group_dao: FromDishka[GroupDAO]):
|
||||
if not message.text:
|
||||
await message.answer("❌ Номер группы не может быть пустым")
|
||||
return
|
||||
@@ -62,9 +64,6 @@ async def on_group_number_input(message: Message, _widget: MessageInput, manager
|
||||
await message.answer("❌ Номер группы должен быть четырехзначным (1000-9999)")
|
||||
return
|
||||
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
existing = await group_dao.get_by_number(number)
|
||||
if existing:
|
||||
await message.answer(f"❌ Группа с номером {number} уже существует")
|
||||
@@ -84,10 +83,8 @@ async def on_cancel_add(_callback: CallbackQuery, _button: Button, manager: Dial
|
||||
await manager.switch_to(AdminGroupsSG.groups_list)
|
||||
|
||||
|
||||
async def get_delete_groups_data(dialog_manager: DialogManager, **_kwargs):
|
||||
container = dialog_manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def get_delete_groups_data(dialog_manager: DialogManager, group_dao: FromDishka[GroupDAO], **_kwargs):
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
return {
|
||||
@@ -96,10 +93,8 @@ async def get_delete_groups_data(dialog_manager: DialogManager, **_kwargs):
|
||||
}
|
||||
|
||||
|
||||
async def on_select_group_to_delete(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def on_select_group_to_delete(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str, group_dao: FromDishka[GroupDAO]):
|
||||
group = await group_dao.get_by_id(int(item_id))
|
||||
if not group:
|
||||
await _callback.answer("❌ Группа не найдена", show_alert=True)
|
||||
@@ -118,10 +113,8 @@ async def get_delete_confirm_data(dialog_manager: DialogManager, **_kwargs):
|
||||
}
|
||||
|
||||
|
||||
async def on_confirm_delete(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def on_confirm_delete(_callback: CallbackQuery, _button: Button, manager: DialogManager, group_dao: FromDishka[GroupDAO]):
|
||||
group_id = manager.dialog_data.get("delete_group_id")
|
||||
|
||||
await group_dao.delete(group_id)
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
from aiogram.types import CallbackQuery
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.kbd import Button, Column
|
||||
from aiogram_dialog.widgets.text import Const
|
||||
|
||||
from trudex.application.bot.admin_dialogs.states import AdminMenuSG, AdminUsersSG, AdminTestsSG, AdminBroadcastSG, AdminGroupsSG
|
||||
from trudex.application.bot.admin_dialogs.states import (AdminBroadcastSG,
|
||||
AdminGroupsSG,
|
||||
AdminMenuSG,
|
||||
AdminTestsSG,
|
||||
AdminUsersSG)
|
||||
|
||||
|
||||
async def on_tests_clicked(_callback: CallbackQuery, _button: Button, manager: DialogManager) -> None:
|
||||
|
||||
@@ -13,6 +13,7 @@ class AdminUsersSG(StatesGroup):
|
||||
|
||||
class AdminTestsSG(StatesGroup):
|
||||
tests_list = State()
|
||||
test_detail = State()
|
||||
|
||||
|
||||
class AdminBroadcastSG(StatesGroup):
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from aiogram.types import CallbackQuery
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog.widgets.kbd import Button, Column, ScrollingGroup, Select
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.kbd import (Button, Column, Row, ScrollingGroup,
|
||||
Select)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.admin_dialogs.states import AdminTestsSG, AdminMenuSG
|
||||
from trudex.application.bot.admin_dialogs.states import (AdminMenuSG,
|
||||
AdminTestsSG)
|
||||
from trudex.infrastructure.database.dao.test import TestDAO
|
||||
from trudex.infrastructure.database.repo.test import TestRepository
|
||||
|
||||
|
||||
@inject
|
||||
@@ -24,7 +27,74 @@ async def get_tests_data(test_dao: FromDishka[TestDAO], **_kwargs):
|
||||
|
||||
async def on_test_selected(_callback: CallbackQuery, _widget: Select, manager: DialogManager, item_id: str):
|
||||
manager.dialog_data["selected_test_id"] = int(item_id)
|
||||
await _callback.answer("Тест выбран")
|
||||
await manager.switch_to(AdminTestsSG.test_detail)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_test_detail(test_dao: FromDishka[TestDAO], test_repo: FromDishka[TestRepository], dialog_manager: DialogManager, **_kwargs):
|
||||
test_id = dialog_manager.dialog_data.get("selected_test_id")
|
||||
|
||||
if not test_id:
|
||||
return {
|
||||
"test_info": "Тест не найден",
|
||||
"is_active": False,
|
||||
"button_text": "◀️ Назад",
|
||||
}
|
||||
|
||||
test = await test_dao.get_by_id(test_id)
|
||||
questions_count = await test_repo.count_questions_in_test(test_id)
|
||||
|
||||
if not test:
|
||||
return {
|
||||
"test_info": "Тест не найден",
|
||||
"is_active": False,
|
||||
"button_text": "◀️ Назад",
|
||||
}
|
||||
|
||||
status = "🟢 Активен" if test.is_active else "🔴 Деактивирован"
|
||||
password_str = f"🔒 {test.password}" if test.password else "🔓 Без пароля"
|
||||
expires_str = test.expires_at.strftime("%d.%m.%Y %H:%M") if test.expires_at else "♾️ Без срока"
|
||||
group_str = f"🎓 Группа {test.for_group}" if test.for_group else "👥 Для всех"
|
||||
|
||||
test_info = (
|
||||
f"<b>📝 Информация о тесте</b>\n\n"
|
||||
f"<b>Название:</b> {test.title}\n"
|
||||
f"<b>Описание:</b> {test.description or '—'}\n\n"
|
||||
f"<b>Статус:</b> {status}\n"
|
||||
f"<b>Вопросов:</b> {questions_count}\n"
|
||||
f"{password_str}\n"
|
||||
f"{expires_str}\n"
|
||||
f"{group_str}\n\n"
|
||||
f"<b>Создан:</b> {test.created_at.strftime('%d.%m.%Y %H:%M') if test.created_at else '—'}"
|
||||
)
|
||||
|
||||
button_text = "🔴 Деактивировать" if test.is_active else "🟢 Активировать"
|
||||
|
||||
return {
|
||||
"test_info": test_info,
|
||||
"is_active": test.is_active,
|
||||
"button_text": button_text,
|
||||
}
|
||||
|
||||
|
||||
@inject
|
||||
async def on_toggle_active(_callback: CallbackQuery, _button: Button, manager: DialogManager, test_dao: FromDishka[TestDAO]):
|
||||
test_id = manager.dialog_data.get("selected_test_id")
|
||||
if not test_id:
|
||||
await _callback.answer("❌ Тест не найден")
|
||||
return
|
||||
|
||||
test = await test_dao.get_by_id(test_id)
|
||||
|
||||
if test:
|
||||
await test_dao.update(test_id, is_active=not test.is_active)
|
||||
action = "деактивирован" if test.is_active else "активирован"
|
||||
await _callback.answer(f"✅ Тест {action}")
|
||||
await manager.switch_to(AdminTestsSG.test_detail)
|
||||
|
||||
|
||||
async def on_back_to_list(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
await manager.switch_to(AdminTestsSG.tests_list)
|
||||
|
||||
|
||||
async def on_add_test_clicked(_callback: CallbackQuery, _button: Button, _manager: DialogManager):
|
||||
@@ -57,4 +127,17 @@ tests_dialog = Dialog(
|
||||
state=AdminTestsSG.tests_list,
|
||||
getter=get_tests_data,
|
||||
),
|
||||
Window(
|
||||
Format("{test_info}"),
|
||||
Row(
|
||||
Button(
|
||||
Format("{button_text}"),
|
||||
id="toggle_active",
|
||||
on_click=on_toggle_active
|
||||
),
|
||||
Button(Const("◀️ Назад"), id="back", on_click=on_back_to_list),
|
||||
),
|
||||
state=AdminTestsSG.test_detail,
|
||||
getter=get_test_detail,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Column, ScrollingGroup, Select, SwitchTo
|
||||
from aiogram_dialog.widgets.kbd import (Button, Column, ScrollingGroup, Select,
|
||||
SwitchTo)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram import CONTAINER_NAME
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.admin_dialogs.states import AdminUsersSG, AdminMenuSG
|
||||
from trudex.application.bot.admin_dialogs.states import (AdminMenuSG,
|
||||
AdminUsersSG)
|
||||
from trudex.infrastructure.database.dao.user import UserDAO
|
||||
|
||||
|
||||
@@ -61,10 +62,8 @@ async def on_input_mode(_callback: CallbackQuery, _button: Button, manager: Dial
|
||||
await manager.switch_to(AdminUsersSG.users_input)
|
||||
|
||||
|
||||
async def on_user_input(message: Message, _widget: MessageInput, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
user_dao = await container.get(UserDAO)
|
||||
|
||||
@inject
|
||||
async def on_user_input(message: Message, _widget: MessageInput, manager: DialogManager, user_dao: FromDishka[UserDAO]):
|
||||
text = (message.text or "").strip()
|
||||
|
||||
user = None
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Row, Cancel
|
||||
from aiogram_dialog.widgets.kbd import Button, Cancel, Row
|
||||
from aiogram_dialog.widgets.text import Const
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
from datetime import date, datetime
|
||||
|
||||
from aiogram.types import CallbackQuery, ContentType, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Calendar, Cancel, Column, Row, ScrollingGroup, Select
|
||||
from aiogram_dialog.widgets.kbd import (Button, Calendar, Cancel, Column, Row,
|
||||
ScrollingGroup, Select)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka.integrations.aiogram import CONTAINER_NAME
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.creator_dialogs.states import CreateTestSG, CreatorTestsSG
|
||||
from trudex.application.bot.creator_dialogs.states import (CreateTestSG,
|
||||
CreatorTestsSG)
|
||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||
from trudex.infrastructure.database.dao.option import OptionDAO
|
||||
from trudex.infrastructure.database.dao.question import QuestionDAO
|
||||
@@ -52,7 +54,8 @@ async def on_description_input(message: Message, _widget: MessageInput, manager:
|
||||
await manager.switch_to(CreateTestSG.input_password)
|
||||
|
||||
|
||||
async def on_password_input(message: Message, _widget: MessageInput, manager: DialogManager):
|
||||
@inject
|
||||
async def on_password_input(message: Message, _widget: MessageInput, manager: DialogManager, group_dao: FromDishka[GroupDAO]):
|
||||
if not message.text:
|
||||
await message.answer("❌ Пароль не может быть пустым")
|
||||
return
|
||||
@@ -68,8 +71,6 @@ async def on_password_input(message: Message, _widget: MessageInput, manager: Di
|
||||
|
||||
manager.dialog_data["password"] = password
|
||||
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
if len(groups) == 0:
|
||||
@@ -79,10 +80,9 @@ async def on_password_input(message: Message, _widget: MessageInput, manager: Di
|
||||
await manager.switch_to(CreateTestSG.input_expires_at)
|
||||
|
||||
|
||||
async def on_skip_password(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
@inject
|
||||
async def on_skip_password(_callback: CallbackQuery, _button: Button, manager: DialogManager, group_dao: FromDishka[GroupDAO]):
|
||||
manager.dialog_data["password"] = None
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
if len(groups) == 0:
|
||||
@@ -102,9 +102,8 @@ async def on_skip_expires(_callback: CallbackQuery, _button: Button, manager: Di
|
||||
await manager.switch_to(CreateTestSG.input_for_group)
|
||||
|
||||
|
||||
async def get_groups_for_test(dialog_manager: DialogManager, **_kwargs):
|
||||
container = dialog_manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
@inject
|
||||
async def get_groups_for_test(dialog_manager: DialogManager, group_dao: FromDishka[GroupDAO], **_kwargs):
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
return {
|
||||
@@ -145,10 +144,8 @@ async def get_test_info(dialog_manager: DialogManager, **_kwargs):
|
||||
}
|
||||
|
||||
|
||||
async def on_confirm_test(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
test_dao = await container.get(TestDAO)
|
||||
|
||||
@inject
|
||||
async def on_confirm_test(_callback: CallbackQuery, _button: Button, manager: DialogManager, test_dao: FromDishka[TestDAO]):
|
||||
title = manager.dialog_data.get("title")
|
||||
description = manager.dialog_data.get("description")
|
||||
password = manager.dialog_data.get("password")
|
||||
@@ -351,12 +348,15 @@ async def get_question_preview(dialog_manager: DialogManager, **_kwargs):
|
||||
return {"preview": preview}
|
||||
|
||||
|
||||
async def on_save_question(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
question_dao = await container.get(QuestionDAO)
|
||||
option_dao = await container.get(OptionDAO)
|
||||
test_repo = await container.get(TestRepository)
|
||||
|
||||
@inject
|
||||
async def on_save_question(
|
||||
_callback: CallbackQuery,
|
||||
_button: Button,
|
||||
manager: DialogManager,
|
||||
question_dao: FromDishka[QuestionDAO],
|
||||
option_dao: FromDishka[OptionDAO],
|
||||
test_repo: FromDishka[TestRepository],
|
||||
):
|
||||
test_id = manager.dialog_data.get("test_id")
|
||||
current_question = manager.dialog_data.get("current_question", {})
|
||||
current_options = manager.dialog_data.get("current_options", [])
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Column, Row, ScrollingGroup, Select
|
||||
from aiogram_dialog.widgets.kbd import (Button, Column, Row, ScrollingGroup,
|
||||
Select)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka.integrations.aiogram import CONTAINER_NAME
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.creator_dialogs.states import CreatorGroupsSG
|
||||
from trudex.application.bot.creator_dialogs.states import (CreatorGroupsSG,
|
||||
CreatorMenuSG)
|
||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||
|
||||
|
||||
@@ -13,10 +16,8 @@ async def on_group_click(_callback: CallbackQuery, _widget, _manager: DialogMana
|
||||
await _callback.answer("ℹ️ Для удаления используйте кнопку 'Удалить группу'")
|
||||
|
||||
|
||||
async def get_groups_data(dialog_manager: DialogManager, **_kwargs):
|
||||
container = dialog_manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def get_groups_data(group_dao: FromDishka[GroupDAO], dialog_manager: DialogManager, **_kwargs):
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
success_message = dialog_manager.dialog_data.pop("success_message", None)
|
||||
@@ -46,7 +47,8 @@ async def on_back_to_menu(_callback: CallbackQuery, _button: Button, manager: Di
|
||||
await manager.start(CreatorMenuSG.main, mode=StartMode.RESET_STACK)
|
||||
|
||||
|
||||
async def on_group_number_input(message: Message, _widget: MessageInput, manager: DialogManager):
|
||||
@inject
|
||||
async def on_group_number_input(message: Message, _widget: MessageInput, manager: DialogManager, group_dao: FromDishka[GroupDAO]):
|
||||
if not message.text:
|
||||
await message.answer("❌ Номер группы не может быть пустым")
|
||||
return
|
||||
@@ -63,9 +65,6 @@ async def on_group_number_input(message: Message, _widget: MessageInput, manager
|
||||
await message.answer("❌ Номер группы должен быть четырехзначным (1000-9999)")
|
||||
return
|
||||
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
existing = await group_dao.get_by_number(number)
|
||||
if existing:
|
||||
await message.answer(f"❌ Группа с номером {number} уже существует")
|
||||
@@ -85,10 +84,8 @@ async def on_cancel_add(_callback: CallbackQuery, _button: Button, manager: Dial
|
||||
await manager.switch_to(CreatorGroupsSG.groups_list)
|
||||
|
||||
|
||||
async def get_delete_groups_data(dialog_manager: DialogManager, **_kwargs):
|
||||
container = dialog_manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def get_delete_groups_data(group_dao: FromDishka[GroupDAO], **_kwargs):
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
return {
|
||||
@@ -97,10 +94,8 @@ async def get_delete_groups_data(dialog_manager: DialogManager, **_kwargs):
|
||||
}
|
||||
|
||||
|
||||
async def on_select_group_to_delete(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def on_select_group_to_delete(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str, group_dao: FromDishka[GroupDAO]):
|
||||
group = await group_dao.get_by_id(int(item_id))
|
||||
if not group:
|
||||
await _callback.answer("❌ Группа не найдена", show_alert=True)
|
||||
@@ -119,10 +114,8 @@ async def get_delete_confirm_data(dialog_manager: DialogManager, **_kwargs):
|
||||
}
|
||||
|
||||
|
||||
async def on_confirm_delete(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def on_confirm_delete(_callback: CallbackQuery, _button: Button, manager: DialogManager, group_dao: FromDishka[GroupDAO]):
|
||||
group_id = manager.dialog_data.get("delete_group_id")
|
||||
|
||||
await group_dao.delete(group_id)
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
from aiogram.types import CallbackQuery
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.kbd import Button, Column
|
||||
from aiogram_dialog.widgets.text import Const
|
||||
|
||||
from trudex.application.bot.creator_dialogs.states import CreatorMenuSG, CreatorUsersSG, CreatorTestsSG, CreatorBroadcastSG, CreatorGroupsSG
|
||||
from trudex.application.bot.creator_dialogs.states import (CreatorBroadcastSG,
|
||||
CreatorGroupsSG,
|
||||
CreatorMenuSG,
|
||||
CreatorTestsSG,
|
||||
CreatorUsersSG)
|
||||
|
||||
|
||||
async def on_tests_clicked(_callback: CallbackQuery, _button: Button, manager: DialogManager) -> None:
|
||||
|
||||
@@ -14,6 +14,7 @@ class CreatorUsersSG(StatesGroup):
|
||||
|
||||
class CreatorTestsSG(StatesGroup):
|
||||
tests_list = State()
|
||||
test_detail = State()
|
||||
|
||||
|
||||
class CreatorBroadcastSG(StatesGroup):
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
from aiogram.types import CallbackQuery
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog.widgets.kbd import Button, Column, ScrollingGroup, Select
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.kbd import (Button, Column, Row, ScrollingGroup,
|
||||
Select)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.creator_dialogs.states import CreatorTestsSG, CreatorMenuSG, CreateTestSG
|
||||
from trudex.application.bot.creator_dialogs.states import (CreateTestSG,
|
||||
CreatorMenuSG,
|
||||
CreatorTestsSG)
|
||||
from trudex.infrastructure.database.dao.test import TestDAO
|
||||
from trudex.infrastructure.database.repo.test import TestRepository
|
||||
|
||||
|
||||
@inject
|
||||
@@ -24,7 +28,74 @@ async def get_tests_data(test_dao: FromDishka[TestDAO], **_kwargs):
|
||||
|
||||
async def on_test_selected(_callback: CallbackQuery, _widget: Select, manager: DialogManager, item_id: str):
|
||||
manager.dialog_data["selected_test_id"] = int(item_id)
|
||||
await _callback.answer("Тест выбран")
|
||||
await manager.switch_to(CreatorTestsSG.test_detail)
|
||||
|
||||
|
||||
@inject
|
||||
async def get_test_detail(test_dao: FromDishka[TestDAO], test_repo: FromDishka[TestRepository], dialog_manager: DialogManager, **_kwargs):
|
||||
test_id = dialog_manager.dialog_data.get("selected_test_id")
|
||||
|
||||
if not test_id:
|
||||
return {
|
||||
"test_info": "Тест не найден",
|
||||
"is_active": False,
|
||||
"button_text": "◀️ Назад",
|
||||
}
|
||||
|
||||
test = await test_dao.get_by_id(test_id)
|
||||
questions_count = await test_repo.count_questions_in_test(test_id)
|
||||
|
||||
if not test:
|
||||
return {
|
||||
"test_info": "Тест не найден",
|
||||
"is_active": False,
|
||||
"button_text": "◀️ Назад",
|
||||
}
|
||||
|
||||
status = "🟢 Активен" if test.is_active else "🔴 Деактивирован"
|
||||
password_str = f"🔒 {test.password}" if test.password else "🔓 Без пароля"
|
||||
expires_str = test.expires_at.strftime("%d.%m.%Y %H:%M") if test.expires_at else "♾️ Без срока"
|
||||
group_str = f"🎓 Группа {test.for_group}" if test.for_group else "👥 Для всех"
|
||||
|
||||
test_info = (
|
||||
f"<b>📝 Информация о тесте</b>\n\n"
|
||||
f"<b>Название:</b> {test.title}\n"
|
||||
f"<b>Описание:</b> {test.description or '—'}\n\n"
|
||||
f"<b>Статус:</b> {status}\n"
|
||||
f"<b>Вопросов:</b> {questions_count}\n"
|
||||
f"{password_str}\n"
|
||||
f"{expires_str}\n"
|
||||
f"{group_str}\n\n"
|
||||
f"<b>Создан:</b> {test.created_at.strftime('%d.%m.%Y %H:%M') if test.created_at else '—'}"
|
||||
)
|
||||
|
||||
button_text = "🔴 Деактивировать" if test.is_active else "🟢 Активировать"
|
||||
|
||||
return {
|
||||
"test_info": test_info,
|
||||
"is_active": test.is_active,
|
||||
"button_text": button_text,
|
||||
}
|
||||
|
||||
|
||||
@inject
|
||||
async def on_toggle_active(_callback: CallbackQuery, _button: Button, manager: DialogManager, test_dao: FromDishka[TestDAO]):
|
||||
test_id = manager.dialog_data.get("selected_test_id")
|
||||
if not test_id:
|
||||
await _callback.answer("❌ Тест не найден")
|
||||
return
|
||||
|
||||
test = await test_dao.get_by_id(test_id)
|
||||
|
||||
if test:
|
||||
await test_dao.update(test_id, is_active=not test.is_active)
|
||||
action = "деактивирован" if test.is_active else "активирован"
|
||||
await _callback.answer(f"✅ Тест {action}")
|
||||
await manager.switch_to(CreatorTestsSG.test_detail)
|
||||
|
||||
|
||||
async def on_back_to_list(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
await manager.switch_to(CreatorTestsSG.tests_list)
|
||||
|
||||
|
||||
async def on_add_test_clicked(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
@@ -57,4 +128,17 @@ tests_dialog = Dialog(
|
||||
state=CreatorTestsSG.tests_list,
|
||||
getter=get_tests_data,
|
||||
),
|
||||
Window(
|
||||
Format("{test_info}"),
|
||||
Row(
|
||||
Button(
|
||||
Format("{button_text}"),
|
||||
id="toggle_active",
|
||||
on_click=on_toggle_active
|
||||
),
|
||||
Button(Const("◀️ Назад"), id="back", on_click=on_back_to_list),
|
||||
),
|
||||
state=CreatorTestsSG.test_detail,
|
||||
getter=get_test_detail,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from aiogram_dialog import Dialog, DialogManager, Window, StartMode
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.input import MessageInput
|
||||
from aiogram_dialog.widgets.kbd import Button, Column, Row, ScrollingGroup, Select, SwitchTo
|
||||
from aiogram_dialog.widgets.kbd import (Button, Column, Row, ScrollingGroup,
|
||||
Select, SwitchTo)
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram import CONTAINER_NAME
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.creator_dialogs.states import CreatorUsersSG, CreatorMenuSG
|
||||
from trudex.application.bot.creator_dialogs.states import (CreatorMenuSG,
|
||||
CreatorUsersSG)
|
||||
from trudex.infrastructure.database.dao.user import UserDAO
|
||||
|
||||
|
||||
@@ -81,10 +82,8 @@ async def on_input_mode(_callback: CallbackQuery, _button: Button, manager: Dial
|
||||
await manager.switch_to(CreatorUsersSG.users_input)
|
||||
|
||||
|
||||
async def on_user_input(message: Message, _widget: MessageInput, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
user_dao = await container.get(UserDAO)
|
||||
|
||||
@inject
|
||||
async def on_user_input(message: Message, _widget: MessageInput, manager: DialogManager, user_dao: FromDishka[UserDAO]):
|
||||
text = (message.text or "").strip()
|
||||
|
||||
user = None
|
||||
@@ -107,10 +106,8 @@ async def on_make_admin_clicked(_callback: CallbackQuery, _button: Button, manag
|
||||
await manager.switch_to(CreatorUsersSG.make_admin_confirm)
|
||||
|
||||
|
||||
async def on_confirm_yes(_callback: CallbackQuery, _button: Button, manager: DialogManager):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
user_dao = await container.get(UserDAO)
|
||||
|
||||
@inject
|
||||
async def on_confirm_yes(_callback: CallbackQuery, _button: Button, manager: DialogManager, user_dao: FromDishka[UserDAO]):
|
||||
user_id = manager.dialog_data.get("selected_user_id")
|
||||
if not user_id:
|
||||
await _callback.answer("Ошибка: пользователь не выбран")
|
||||
|
||||
@@ -7,11 +7,11 @@ from dishka.integrations.aiogram import FromDishka
|
||||
|
||||
from trudex.application.bot.admin_dialogs.states import AdminMenuSG
|
||||
from trudex.application.bot.creator_dialogs.states import CreatorMenuSG
|
||||
from trudex.application.bot.user_dialogs.states import UserMenuSG, UserRegistrationSG
|
||||
from trudex.application.bot.user_dialogs.states import (UserMenuSG,
|
||||
UserRegistrationSG)
|
||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||
from trudex.infrastructure.database.dao.user import UserDAO
|
||||
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@ from aiogram.types import CallbackQuery
|
||||
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
|
||||
from aiogram_dialog.widgets.kbd import ScrollingGroup, Select
|
||||
from aiogram_dialog.widgets.text import Const, Format
|
||||
from dishka.integrations.aiogram import CONTAINER_NAME
|
||||
from dishka import FromDishka
|
||||
from dishka.integrations.aiogram_dialog import inject
|
||||
|
||||
from trudex.application.bot.user_dialogs.states import UserMenuSG, UserRegistrationSG
|
||||
from trudex.application.bot.user_dialogs.states import (UserMenuSG,
|
||||
UserRegistrationSG)
|
||||
from trudex.infrastructure.database.dao.group import GroupDAO
|
||||
from trudex.infrastructure.database.dao.user import UserDAO
|
||||
|
||||
|
||||
async def get_groups_for_registration(dialog_manager: DialogManager, **_kwargs):
|
||||
container = dialog_manager.middleware_data[CONTAINER_NAME]
|
||||
group_dao = await container.get(GroupDAO)
|
||||
|
||||
@inject
|
||||
async def get_groups_for_registration(dialog_manager: DialogManager, group_dao: FromDishka[GroupDAO], **_kwargs):
|
||||
groups = await group_dao.get_all()
|
||||
|
||||
return {
|
||||
@@ -20,10 +20,8 @@ async def get_groups_for_registration(dialog_manager: DialogManager, **_kwargs):
|
||||
}
|
||||
|
||||
|
||||
async def on_group_selected(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str):
|
||||
container = manager.middleware_data[CONTAINER_NAME]
|
||||
user_dao = await container.get(UserDAO)
|
||||
|
||||
@inject
|
||||
async def on_group_selected(_callback: CallbackQuery, _widget, manager: DialogManager, item_id: str, user_dao: FromDishka[UserDAO]):
|
||||
user_id = manager.start_data.get("user_id")
|
||||
|
||||
await user_dao.update(user_id=user_id, group=int(item_id))
|
||||
|
||||
Reference in New Issue
Block a user