create event

This commit is contained in:
2025-10-03 14:09:43 +03:00
parent 2056558ea8
commit 7734adda8b
18 changed files with 399 additions and 88 deletions

View File

@@ -1,6 +1,7 @@
from aiogram import Router
from .events.dialogs import events_dialog
from .new_event.dialogs import new_event_dialog
from .profile.dialogs import profile_dialog
from .start.dialogs import start_dialog
@@ -8,3 +9,4 @@ dialogs_router = Router(name="dialogs")
dialogs_router.include_router(start_dialog)
dialogs_router.include_router(events_dialog)
dialogs_router.include_router(profile_dialog)
dialogs_router.include_router(new_event_dialog)

View File

@@ -1,39 +1,34 @@
from aiogram_dialog import Dialog, Window
from aiogram_dialog.widgets.kbd import Back, Cancel, Column, Select
from aiogram_dialog.widgets.text import Const, Format
from aiogram_dialog.widgets.text import Const, Format, Jinja
from .getters import events_getter
from app.bot.dialogs.templates import event_template
from .getters import event_getter, events_list_getter
from .handlers import on_event_selected
from .states import EventsSG
async def on_event_selected(
c,
widget: Select,
manager,
item_id: str,
):
manager.dialog_data["selected_event"] = item_id
await manager.next()
events_dialog = Dialog(
Window(
Const("События"),
Column(
Cancel(Const("Назад")),
Select(
Format("{item}"),
Format("{item[title]}"),
id="categ",
item_id_getter=lambda x: x,
item_id_getter=lambda x: x["id"],
items="events",
on_click=on_event_selected,
),
),
getter=events_getter,
getter=events_list_getter,
state=EventsSG.events_list,
),
Window(
Format("{dialog_data[selected_event]}"),
Jinja(event_template),
Back(Const("Назад")),
getter=event_getter,
parse_mode="HTML",
state=EventsSG.event,
),
)

View File

@@ -1,6 +1,22 @@
from aiogram.types import User
from aiogram_dialog import DialogManager
from app.infrastructure.database.crud import get_event_by_id, get_events_list
async def events_getter(dialog_manager: DialogManager, event_from_user: User, **kwargs) -> dict[str, str]:
return {"events": ["ev1", "ev2", "ev3"]}
async def events_list_getter(
dialog_manager: DialogManager, event_from_user: User, **kwargs
) -> dict[str, str]:
events = await get_events_list(dialog_manager.middleware_data["session"])
return {"events": [{"title": event.title, "id": event.id} for event in events]}
async def event_getter(
dialog_manager: DialogManager, **kwargs
) -> dict[str, str]:
return {
"event_obj": await get_event_by_id(
dialog_manager.middleware_data["session"],
int(dialog_manager.dialog_data["selected_event"]),
)
}

View File

@@ -0,0 +1,13 @@
from aiogram.types import CallbackQuery
from aiogram_dialog import DialogManager
from aiogram_dialog.widgets.kbd import Select
async def on_event_selected(
callback: CallbackQuery,
widget: Select,
manager: DialogManager,
item_id: str,
):
manager.dialog_data["selected_event"] = item_id
await manager.next()

View File

@@ -0,0 +1,52 @@
from aiogram_dialog import Dialog, Window
from aiogram_dialog.widgets.input import TextInput
from aiogram_dialog.widgets.kbd import Back, Button, Calendar, Cancel
from aiogram_dialog.widgets.text import Const, Jinja
from app.bot.dialogs.templates import event_template
from .getters import event_data_getter
from .handlers import (
confirm_creation,
input_description,
input_end_date,
input_start_date,
input_title,
)
from .states import NewEventSG
new_event_dialog = Dialog(
Window(
Const("Введите название:"),
TextInput(id="title", on_success=input_title),
Cancel(Const("❌ Отмена")),
state=NewEventSG.input_title,
),
Window(
Const("Введите описание:"),
TextInput(id="description", on_success=input_description),
Back(Const("◀️ Назад")),
state=NewEventSG.input_description,
),
Window(
Const("Выберите дату начала:"),
Calendar(id="start_date", on_click=input_start_date),
Back(Const("◀️ Назад")),
state=NewEventSG.input_start_date,
),
Window(
Const("Выберите дату окончания:"),
Calendar(id="end_date", on_click=input_end_date),
Back(Const("◀️ Назад")),
state=NewEventSG.input_end_date,
),
Window(
Jinja(event_template),
Back(Const("◀️ Назад")),
Cancel(Const("❌ Отмена")),
Button(Const("✅ Создать"), id="cancel", on_click=confirm_creation),
state=NewEventSG.confirm_creation,
getter=event_data_getter,
parse_mode="HTML",
),
)

View File

@@ -0,0 +1,8 @@
from aiogram.types import User
from aiogram_dialog import DialogManager
async def event_data_getter(
dialog_manager: DialogManager, event_from_user: User, **kwargs
):
return {"event_obj": dialog_manager.dialog_data["event_obj"]}

View File

@@ -0,0 +1,61 @@
from datetime import date
from aiogram.types import CallbackQuery
from aiogram_dialog import DialogManager
from aiogram_dialog.widgets.input import ManagedTextInput
from aiogram_dialog.widgets.kbd import Button, Calendar
from app.infrastructure.database.crud import create_event
async def input_title(
callback: CallbackQuery,
widget: ManagedTextInput,
manager: DialogManager,
text: date,
):
if "event_obj" not in manager.dialog_data:
manager.dialog_data["event_obj"] = {}
manager.dialog_data["event_obj"]["title"] = text
await manager.next()
async def input_description(
callback: CallbackQuery,
widget: ManagedTextInput,
manager: DialogManager,
text: date,
):
manager.dialog_data["event_obj"]["description"] = text
await manager.next()
async def input_start_date(
callback: CallbackQuery,
widget: Calendar,
manager: DialogManager,
selected_date: date,
):
manager.dialog_data["event_obj"]["start_date"] = selected_date
await manager.next()
async def input_end_date(
callback: CallbackQuery,
widget: Calendar,
manager: DialogManager,
selected_date: date,
):
manager.dialog_data["event_obj"]["end_date"] = selected_date
await manager.next()
async def confirm_creation(
callback: CallbackQuery,
button: Button,
manager: DialogManager,
):
await create_event(
manager.middleware_data["session"], **manager.dialog_data["event_obj"]
)
await manager.done()

View File

@@ -0,0 +1,9 @@
from aiogram.fsm.state import State, StatesGroup
class NewEventSG(StatesGroup):
input_title = State()
input_description = State()
input_start_date = State()
input_end_date = State()
confirm_creation = State()

View File

@@ -1,11 +1,11 @@
from aiogram_dialog import Dialog, Window
from aiogram_dialog.widgets.input import TextInput
from aiogram_dialog.widgets.kbd import Cancel, SwitchTo
from aiogram_dialog.widgets.text import Const, Format
from aiogram_dialog.widgets.text import Const, Jinja
from app.bot.dialogs.templates import profile_template
from app.bot.dialogs.widgets.getters import user_getter
from .getters import phone_getter
from .handlers import (
name_type_factory,
on_error,
@@ -17,9 +17,7 @@ from .states import ProfileSG
profile_dialog = Dialog(
Window(
Const("*Профиль*\n"),
Format("*Имя*: {user.fullname}"),
Format("*Телефон*: {phone}"),
Jinja(profile_template),
SwitchTo(
Const("✏️ изменить имя"),
id="change_name",
@@ -31,8 +29,9 @@ profile_dialog = Dialog(
state=ProfileSG.change_phone,
),
Cancel(Const("◀️ назад")),
getter=user_getter,
parse_mode="HTML",
state=ProfileSG.profile,
getter=[user_getter, phone_getter],
),
Window(
Const("Введите имя"),
@@ -55,5 +54,6 @@ profile_dialog = Dialog(
on_error=on_error,
),
state=ProfileSG.change_phone,
parse_mode="Markdown",
),
)

View File

@@ -16,7 +16,7 @@ def name_type_factory(text: str):
def phone_type_factory(text: str):
if len(re.findall("\d", text)) < 11:
raise ValueError("Телефон должен быть в формате \+79991112233")
raise ValueError("Телефон должен быть в формате +79991112233")
return text
async def on_error(

View File

@@ -3,6 +3,7 @@ from aiogram_dialog.widgets.kbd import Button, Start
from aiogram_dialog.widgets.text import Const, Format
from app.bot.dialogs.flows.events.dialogs import EventsSG
from app.bot.dialogs.flows.new_event.dialogs import NewEventSG
from app.bot.dialogs.flows.profile.dialogs import ProfileSG
from app.bot.dialogs.widgets.getters import is_admin_getter, user_getter
@@ -12,7 +13,12 @@ start_dialog = Dialog(
Window(
Format("Привет, {user.fullname}"),
Start(Const("📃 события"), id="events", state=EventsSG.events_list),
Button(Const("✏️ создать событие"), id="create_event", when="is_admin"),
Start(
Const("✏️ создать событие"),
id="create_event",
state=NewEventSG.input_title,
when="is_admin",
),
Start(Const("👤 профиль"), id="profile", state=ProfileSG.profile),
getter=[user_getter, is_admin_getter],
state=StartSG.start,