2025-12-19 11:19:54 +01:00
|
|
|
|
"""Handlers for managing reminders (view, edit, delete)."""
|
|
|
|
|
|
|
|
|
|
|
|
from aiogram import Router, F
|
|
|
|
|
|
from aiogram.types import Message, CallbackQuery
|
|
|
|
|
|
from aiogram.fsm.context import FSMContext
|
|
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
|
|
|
|
|
|
|
|
from bot.states.reminder_states import EditReminderStates
|
|
|
|
|
|
from bot.keyboards.pagination import get_reminders_list_keyboard, PaginationCallback
|
|
|
|
|
|
from bot.keyboards.reminders import (
|
|
|
|
|
|
get_reminder_details_keyboard,
|
|
|
|
|
|
get_edit_menu_keyboard,
|
|
|
|
|
|
get_interval_selection_keyboard,
|
|
|
|
|
|
get_confirmation_keyboard,
|
|
|
|
|
|
ReminderActionCallback,
|
|
|
|
|
|
ReminderEditCallback,
|
|
|
|
|
|
ReminderIntervalCallback,
|
|
|
|
|
|
ConfirmCallback,
|
|
|
|
|
|
)
|
|
|
|
|
|
from bot.keyboards.main_menu import get_main_menu_keyboard
|
|
|
|
|
|
from bot.services.user_service import UserService
|
|
|
|
|
|
from bot.services.reminders_service import RemindersService
|
|
|
|
|
|
from bot.utils.formatting import format_datetime, format_interval_days
|
|
|
|
|
|
from bot.utils.validators import validate_time_format, validate_days_interval
|
|
|
|
|
|
from bot.logging_config import get_logger
|
|
|
|
|
|
|
|
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
router = Router(name="reminders_manage")
|
|
|
|
|
|
reminders_service = RemindersService()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.message(F.text == "📋 Мои напоминания")
|
|
|
|
|
|
async def show_reminders_list(
|
|
|
|
|
|
message: Message,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Show user's reminders list.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
message: Telegram message
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
user = await UserService.ensure_user_exists(session, message.from_user)
|
|
|
|
|
|
reminders = await reminders_service.get_user_all_reminders(session, user.id)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminders:
|
|
|
|
|
|
await message.answer(
|
|
|
|
|
|
"У тебя пока нет напоминаний.\n\n"
|
|
|
|
|
|
"Нажми «➕ Новое напоминание», чтобы создать первое!",
|
|
|
|
|
|
reply_markup=get_main_menu_keyboard(),
|
|
|
|
|
|
)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
await message.answer(
|
|
|
|
|
|
f"📋 Твои напоминания ({len(reminders)}):",
|
|
|
|
|
|
reply_markup=get_reminders_list_keyboard(reminders, page=0),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(PaginationCallback.filter(F.action.in_(["prev", "next"])))
|
|
|
|
|
|
async def paginate_reminders(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: PaginationCallback,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Handle pagination for reminders list.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
user = await UserService.ensure_user_exists(session, callback.from_user)
|
|
|
|
|
|
reminders = await reminders_service.get_user_all_reminders(session, user.id)
|
|
|
|
|
|
|
|
|
|
|
|
await callback.message.edit_reply_markup(
|
|
|
|
|
|
reply_markup=get_reminders_list_keyboard(reminders, page=callback_data.page)
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(PaginationCallback.filter(F.action == "select"))
|
|
|
|
|
|
async def show_reminder_details(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: PaginationCallback,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Show reminder details.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
reminder = await reminders_service.get_reminder(session, callback_data.reminder_id)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminder:
|
|
|
|
|
|
await callback.answer("Напоминание не найдено", show_alert=True)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
status = "Активно ✅" if reminder.is_active else "На паузе ⏸"
|
|
|
|
|
|
last_done = (
|
|
|
|
|
|
format_datetime(reminder.last_done_at)
|
|
|
|
|
|
if reminder.last_done_at
|
|
|
|
|
|
else "Ещё не выполнялось"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
details_text = (
|
|
|
|
|
|
f"📝 <b>Напоминание #{reminder.id}</b>\n\n"
|
|
|
|
|
|
f"<b>Текст:</b> {reminder.text}\n\n"
|
|
|
|
|
|
f"<b>Периодичность:</b> {format_interval_days(reminder.days_interval)}\n"
|
|
|
|
|
|
f"<b>Время:</b> {reminder.time_of_day.strftime('%H:%M')}\n"
|
|
|
|
|
|
f"<b>Статус:</b> {status}\n\n"
|
|
|
|
|
|
f"<b>Следующее напоминание:</b> {format_datetime(reminder.next_run_at)}\n"
|
|
|
|
|
|
f"<b>Последнее выполнение:</b> {last_done}\n"
|
|
|
|
|
|
f"<b>Выполнено раз:</b> {reminder.total_done_count}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
details_text,
|
|
|
|
|
|
reply_markup=get_reminder_details_keyboard(reminder.id, reminder.is_active),
|
|
|
|
|
|
parse_mode="HTML",
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-12-19 12:09:04 +01:00
|
|
|
|
@router.callback_query(ReminderActionCallback.filter(F.action == "back_to_list"))
|
|
|
|
|
|
async def back_to_reminders_list(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Return to reminders list from details view.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
user = await UserService.ensure_user_exists(session, callback.from_user)
|
|
|
|
|
|
reminders = await reminders_service.get_user_all_reminders(session, user.id)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminders:
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
"У тебя пока нет напоминаний.\n\n"
|
|
|
|
|
|
"Нажми «➕ Новое напоминание», чтобы создать первое!"
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
f"📋 Твои напоминания ({len(reminders)}):",
|
|
|
|
|
|
reply_markup=get_reminders_list_keyboard(reminders, page=0),
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-12-19 11:19:54 +01:00
|
|
|
|
# ==================== Edit Reminder Flow ====================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(ReminderActionCallback.filter(F.action == "edit"))
|
|
|
|
|
|
async def start_edit_reminder(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: ReminderActionCallback,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Start editing reminder.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
"""
|
|
|
|
|
|
await state.update_data(reminder_id=callback_data.reminder_id)
|
|
|
|
|
|
await state.set_state(EditReminderStates.selecting_field)
|
|
|
|
|
|
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
"Что изменить?",
|
|
|
|
|
|
reply_markup=get_edit_menu_keyboard(callback_data.reminder_id),
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(
|
|
|
|
|
|
EditReminderStates.selecting_field,
|
|
|
|
|
|
ReminderEditCallback.filter(F.action == "back")
|
|
|
|
|
|
)
|
|
|
|
|
|
async def cancel_edit(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: ReminderEditCallback,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Cancel editing and return to reminder details.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
|
|
|
|
|
|
# Show reminder details again
|
|
|
|
|
|
reminder = await reminders_service.get_reminder(session, callback_data.reminder_id)
|
|
|
|
|
|
if not reminder:
|
|
|
|
|
|
await callback.answer("Напоминание не найдено", show_alert=True)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
status = "Активно ✅" if reminder.is_active else "На паузе ⏸"
|
|
|
|
|
|
last_done = (
|
|
|
|
|
|
format_datetime(reminder.last_done_at)
|
|
|
|
|
|
if reminder.last_done_at
|
|
|
|
|
|
else "Ещё не выполнялось"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
details_text = (
|
|
|
|
|
|
f"📝 <b>Напоминание #{reminder.id}</b>\n\n"
|
|
|
|
|
|
f"<b>Текст:</b> {reminder.text}\n\n"
|
|
|
|
|
|
f"<b>Периодичность:</b> {format_interval_days(reminder.days_interval)}\n"
|
|
|
|
|
|
f"<b>Время:</b> {reminder.time_of_day.strftime('%H:%M')}\n"
|
|
|
|
|
|
f"<b>Статус:</b> {status}\n\n"
|
|
|
|
|
|
f"<b>Следующее напоминание:</b> {format_datetime(reminder.next_run_at)}\n"
|
|
|
|
|
|
f"<b>Последнее выполнение:</b> {last_done}"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
details_text,
|
|
|
|
|
|
reply_markup=get_reminder_details_keyboard(reminder.id, reminder.is_active),
|
|
|
|
|
|
parse_mode="HTML",
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(
|
|
|
|
|
|
EditReminderStates.selecting_field,
|
|
|
|
|
|
ReminderEditCallback.filter(F.action == "text")
|
|
|
|
|
|
)
|
|
|
|
|
|
async def edit_text_start(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: ReminderEditCallback,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Start editing reminder text.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
"""
|
|
|
|
|
|
await state.set_state(EditReminderStates.editing_text)
|
|
|
|
|
|
await callback.message.edit_text("Введи новый текст напоминания:")
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.message(EditReminderStates.editing_text)
|
|
|
|
|
|
async def edit_text_process(
|
|
|
|
|
|
message: Message,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Process new reminder text.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
message: Telegram message
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
text = message.text.strip()
|
|
|
|
|
|
|
|
|
|
|
|
if not text or len(text) > 1000:
|
|
|
|
|
|
await message.answer("Текст должен быть от 1 до 1000 символов. Попробуй ещё раз:")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
data = await state.get_data()
|
|
|
|
|
|
reminder_id = data["reminder_id"]
|
|
|
|
|
|
|
|
|
|
|
|
reminder = await reminders_service.update_reminder_text(session, reminder_id, text)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminder:
|
|
|
|
|
|
await message.answer("Напоминание не найдено")
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
await message.answer(
|
|
|
|
|
|
f"✅ Текст обновлён!\n\nНовый текст: {text}",
|
|
|
|
|
|
reply_markup=get_main_menu_keyboard(),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(
|
|
|
|
|
|
EditReminderStates.selecting_field,
|
|
|
|
|
|
ReminderEditCallback.filter(F.action == "interval")
|
|
|
|
|
|
)
|
|
|
|
|
|
async def edit_interval_start(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: ReminderEditCallback,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Start editing reminder interval.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
"""
|
|
|
|
|
|
await state.set_state(EditReminderStates.editing_interval)
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
"Выбери новый период или введи количество дней:",
|
|
|
|
|
|
reply_markup=get_interval_selection_keyboard(),
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(
|
|
|
|
|
|
EditReminderStates.editing_interval,
|
|
|
|
|
|
ReminderIntervalCallback.filter()
|
|
|
|
|
|
)
|
|
|
|
|
|
async def edit_interval_button(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: ReminderIntervalCallback,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Process interval selection via button.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
if callback_data.days == 0:
|
|
|
|
|
|
await callback.message.edit_text("Введи количество дней (целое положительное число):")
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
data = await state.get_data()
|
|
|
|
|
|
reminder_id = data["reminder_id"]
|
|
|
|
|
|
|
|
|
|
|
|
reminder = await reminders_service.update_reminder_interval(
|
|
|
|
|
|
session, reminder_id, callback_data.days
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminder:
|
|
|
|
|
|
await callback.answer("Напоминание не найдено", show_alert=True)
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
f"✅ Периодичность обновлена!\n\nТеперь: {format_interval_days(callback_data.days)}"
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.message.answer(
|
|
|
|
|
|
"Выбери действие из меню:",
|
|
|
|
|
|
reply_markup=get_main_menu_keyboard(),
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer("Обновлено!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.message(EditReminderStates.editing_interval)
|
|
|
|
|
|
async def edit_interval_text(
|
|
|
|
|
|
message: Message,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Process interval input as text.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
message: Telegram message
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
days = validate_days_interval(message.text)
|
|
|
|
|
|
|
|
|
|
|
|
if days is None:
|
|
|
|
|
|
await message.answer("Некорректное значение. Введи целое положительное число дней:")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
data = await state.get_data()
|
|
|
|
|
|
reminder_id = data["reminder_id"]
|
|
|
|
|
|
|
|
|
|
|
|
reminder = await reminders_service.update_reminder_interval(session, reminder_id, days)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminder:
|
|
|
|
|
|
await message.answer("Напоминание не найдено")
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
await message.answer(
|
|
|
|
|
|
f"✅ Периодичность обновлена!\n\nТеперь: {format_interval_days(days)}",
|
|
|
|
|
|
reply_markup=get_main_menu_keyboard(),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.callback_query(
|
|
|
|
|
|
EditReminderStates.selecting_field,
|
|
|
|
|
|
ReminderEditCallback.filter(F.action == "time")
|
|
|
|
|
|
)
|
|
|
|
|
|
async def edit_time_start(
|
|
|
|
|
|
callback: CallbackQuery,
|
|
|
|
|
|
callback_data: ReminderEditCallback,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Start editing reminder time.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
callback: Callback query
|
|
|
|
|
|
callback_data: Parsed callback data
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
"""
|
|
|
|
|
|
await state.set_state(EditReminderStates.editing_time)
|
|
|
|
|
|
await callback.message.edit_text(
|
|
|
|
|
|
"Введи новое время в формате ЧЧ:ММ (например, 09:00):"
|
|
|
|
|
|
)
|
|
|
|
|
|
await callback.answer()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.message(EditReminderStates.editing_time)
|
|
|
|
|
|
async def edit_time_process(
|
|
|
|
|
|
message: Message,
|
|
|
|
|
|
state: FSMContext,
|
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
|
) -> None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Process new reminder time.
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
message: Telegram message
|
|
|
|
|
|
state: FSM state context
|
|
|
|
|
|
session: Database session
|
|
|
|
|
|
"""
|
|
|
|
|
|
time_of_day = validate_time_format(message.text)
|
|
|
|
|
|
|
|
|
|
|
|
if time_of_day is None:
|
|
|
|
|
|
await message.answer(
|
|
|
|
|
|
"Некорректный формат времени. Используй формат ЧЧ:ММ (например, 09:00):"
|
|
|
|
|
|
)
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
data = await state.get_data()
|
|
|
|
|
|
reminder_id = data["reminder_id"]
|
|
|
|
|
|
|
|
|
|
|
|
reminder = await reminders_service.update_reminder_time(session, reminder_id, time_of_day)
|
|
|
|
|
|
|
|
|
|
|
|
if not reminder:
|
|
|
|
|
|
await message.answer("Напоминание не найдено")
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
await state.clear()
|
|
|
|
|
|
await message.answer(
|
|
|
|
|
|
f"✅ Время обновлено!\n\nНовое время: {time_of_day.strftime('%H:%M')}",
|
|
|
|
|
|
reply_markup=get_main_menu_keyboard(),
|
|
|
|
|
|
)
|