diff --git a/telegram_bot_project/bot/buttons.py b/telegram_bot_project/bot/buttons.py index 6691d96..09756b4 100644 --- a/telegram_bot_project/bot/buttons.py +++ b/telegram_bot_project/bot/buttons.py @@ -41,11 +41,13 @@ def idea_reply_keyboard() -> ReplyKeyboardMarkup: idea_reply_keyboard = ReplyKeyboardMarkup(keyboard=[], resize_keyboard=True, row_width=2) button_menu = KeyboardButton(text=MENU_BUTTON) + button_update = KeyboardButton(text=UPDATE_IDEA_BUTTON) button_delete = KeyboardButton(text=DEL_IDEA_BUTTON) button_add = KeyboardButton(text=BUTTON_IDEA) button_all_ideas = KeyboardButton(text=ALL_IDEAS) idea_reply_keyboard.keyboard.append([button_delete, button_add]) - idea_reply_keyboard.keyboard.append([button_menu, button_all_ideas]) + idea_reply_keyboard.keyboard.append([button_update, button_all_ideas]) + idea_reply_keyboard.keyboard.append([button_menu]) return idea_reply_keyboard \ No newline at end of file diff --git a/telegram_bot_project/bot/commands.py b/telegram_bot_project/bot/commands.py index b5c0186..71a33b7 100644 --- a/telegram_bot_project/bot/commands.py +++ b/telegram_bot_project/bot/commands.py @@ -105,3 +105,16 @@ async def delete_idea_command(message: types.Message, state: FSMContext): else: await message.answer(MESSAGES[language]['DELETE_IDEA']) await state.set_state(DialogStates.delete_idea) + +# Update Idea Handler +async def update_idea_command(message: types.Message, state: FSMContext): + user_id: int = message.from_user.id + user_find: Any = await UserService.get_user_by_id(user_id) + language: str = await UserService.get_user_language(user_id) + + if not user_find: + await message.answer(MESSAGES['ENGLISH']['AUTHORIZATION_PROBLEM']) + else: + await message.answer(MESSAGES[language]['UPDATE_IDEA']) + await state.set_state(DialogStates.update_idea) + diff --git a/telegram_bot_project/bot/handlers.py b/telegram_bot_project/bot/handlers.py index 0eeeb61..a8529e3 100644 --- a/telegram_bot_project/bot/handlers.py +++ b/telegram_bot_project/bot/handlers.py @@ -5,6 +5,7 @@ from messages import MESSAGES from service.idea import IdeaService from service.user import UserService +from states import DialogStates async def process_idea_save(message: Message, state: FSMContext) -> None: user_id = message.from_user.id @@ -19,7 +20,7 @@ async def process_idea_save(message: Message, state: FSMContext) -> None: exist = await IdeaService.get_by_idea_name(idea) if exist: await message.answer( - MESSAGES[language].get('IDEA_EXIST', "⚠️ This idea already exists."), + MESSAGES[language]['IDEA_EXIST'], reply_markup=menu_reply_keyboard() ) return @@ -41,10 +42,8 @@ async def process_idea_save(message: Message, state: FSMContext) -> None: except Exception as e: print(f"[ERROR] Saving idea failed: {e}") await message.answer( - MESSAGES[language].get( - 'ERROR_SAVING_IDEA', - "⚠️ Error saving the idea. Please try again later." - ) + MESSAGES[language]['ERROR_SAVING_IDEA'], + reply_markup=idea_reply_keyboard() ) async def process_idea_delete(message: Message, state: FSMContext) -> None: @@ -78,4 +77,72 @@ async def process_idea_delete(message: Message, state: FSMContext) -> None: await IdeaService.delete_user_idea(real_id) await message.answer(MESSAGES[language]['IDEA_DELETED'].format(user_number, idea_to_delete['idea_name']), reply_markup=idea_reply_keyboard()) - await state.clear() \ No newline at end of file + await state.clear() + + +async def process_idea_update(message: Message, state: FSMContext) -> None: + user_id = message.from_user.id + user_find = await UserService.get_user_by_id(user_id) + if not user_find or not user_find.get("id"): + await message.answer(MESSAGES["ENGLISH"]["AUTHORIZATION_PROBLEM"]) + return + + language = await UserService.get_user_language(user_id) or "ENGLISH" + ideas = await IdeaService.get_all_ideas_by_user_id(user_id) + + print(f"--[DEBUG] User {user_id} ideas: {ideas}") + + try: + user_number = int(message.text.strip()) + except ValueError: + await message.answer( + MESSAGES[language]["NOT_VALID_IDEA_NUM"], + reply_markup=idea_reply_keyboard() + ) + return + + index = user_number - 1 + if not (0 <= index < len(ideas)): + await message.answer( + MESSAGES[language]["INVALID_IDEA_NUM"], + reply_markup=idea_reply_keyboard() + ) + return + + idea_to_update = ideas[index] + real_id = idea_to_update["id"] + + print(f"--[DEBUG] Selected idea with id {real_id} for update by user {user_id}") + + await state.update_data(idea_id=real_id, idea_number=user_number) + await state.set_state(DialogStates.waiting_for_update_text) + + await message.answer( + MESSAGES[language]["ASK_NEW_IDEA_TEXT"].format(user_number, idea_to_update["idea_name"]), + reply_markup=idea_reply_keyboard() + ) + +async def process_save_updated_idea_text(message: Message, state: FSMContext): + data = await state.get_data() + idea_id = data.get("idea_id") + idea_number = data.get("idea_number") + + language = await UserService.get_user_language(message.from_user.id) or "ENGLISH" + + new_text = message.text.strip() + idea_exists = await IdeaService.get_by_idea_name(new_text) + + if idea_exists: + await message.answer( + MESSAGES[language]["IDEA_EXIST"], + reply_markup=menu_reply_keyboard() + ) + else: + await IdeaService.update_user_idea(idea_id, new_text) + + await message.answer( + MESSAGES[language]["IDEA_UPDATED"].format(idea_number), + reply_markup=idea_reply_keyboard() + ) + + await state.clear() diff --git a/telegram_bot_project/main.py b/telegram_bot_project/main.py index a1b8047..270a415 100644 --- a/telegram_bot_project/main.py +++ b/telegram_bot_project/main.py @@ -1,12 +1,11 @@ import asyncio from aiogram import Dispatcher, Bot, F from aiogram.filters import Command -from aiogram.fsm.context import FSMContext from aiogram.fsm.storage.memory import MemoryStorage -from aiogram.types import Message, CallbackQuery +from aiogram.types import CallbackQuery from config import TOKEN from bot.commands import * -from bot.handlers import process_idea_save, process_idea_delete +from bot.handlers import * from bot.callbacks import start_callback_language, callback_idea_process from messages import * from states import DialogStates @@ -46,6 +45,10 @@ async def ideas(message: Message): async def delete_idea(message: Message, state: FSMContext): await delete_idea_command(message, state) +@dp.message(lambda m: m.text == UPDATE_IDEA_BUTTON) +async def update_idea(message: Message, state: FSMContext): + await update_idea_command(message, state) + @dp.message(Command("task")) async def task(message: Message): pass @@ -59,13 +62,18 @@ async def callback_idea(callback_query: CallbackQuery, state: FSMContext): await callback_idea_process(callback_query, state) @dp.message() -async def process_idea_fallback(message: Message, state: FSMContext): +async def process_fallback(message: Message, state: FSMContext): current_state = await state.get_state() print(f"[DEBUG] Current state: {current_state}") if current_state == DialogStates.waiting_for_idea.state: await process_idea_save(message, state) elif current_state == DialogStates.delete_idea.state: await process_idea_delete(message, state) + elif current_state == DialogStates.update_idea.state: + await process_idea_update(message, state) + elif current_state == DialogStates.waiting_for_update_text: + await process_save_updated_idea_text(message, state) + # Main Function async def main(): bot = Bot(token=TOKEN) diff --git a/telegram_bot_project/messages.py b/telegram_bot_project/messages.py index ab84940..7076fb9 100644 --- a/telegram_bot_project/messages.py +++ b/telegram_bot_project/messages.py @@ -19,11 +19,15 @@ "IDEA_PROBLEM": "⚠️ Виникла проблема із збереженням ідеї. Спробуйте ще раз.", "IDEAS_SHOW": "💡 Усі ваші ідеї: ", "IDEA_EXISTS": "⚠️ Ця ідея вже існує.", + "ERROR_SAVING_IDEA": "⚠️ Проблема із збереженням ідеї. Спробуйте ще раз.", "NO_IDEAS": "📝 Ви ще не маєте ідей.", "DELETE_IDEA": "ℹ️ Вкажіть номер ідеї, яку хочете видалити", + "UPDATE_IDEA": "ℹ️ Вкажіть номер ідеї, яку хочете обновити", "NOT_VALID_IDEA_NUM": "❌ Будь ласка, введіть дійсний номер.", "INVALID_IDEA_NUM": "❌ Неправильний номер. Спробуйте ще раз.", "IDEA_DELETED": "🗑️ Ідею №{} '{}' було видалено.", + "ASK_NEW_IDEA_TEXT": "✏️ Введіть новий текст для ідеї №{} '{}'.", + "IDEA_UPDATED": "✅ Ідею №{} успішно оновлено.", "LANGUAGE_ASK": ( "🌐 **Оберіть мову інтерфейсу:**\n" "Натисніть кнопку нижче, щоб продовжити:" @@ -55,11 +59,15 @@ "IDEA_PROBLEM": "⚠️ There was an issue saving your idea. Please try again.", "IDEAS_SHOW": "💡 Here are your ideas: ", "IDEA_EXISTS": "⚠️ This idea already exists", + "ERROR_SAVING_IDEA": "⚠️ Error saving the idea. Please try again later.", "DELETE_IDEA": "ℹ️ Enter the idea number you want to delete", + "UPDATE_IDEA": "ℹ️ Enter the idea number you want to update", "NOT_VALID_IDEA_NUM": "❌ Please enter a valid number.", "INVALID_IDEA_NUM": "❌ Invalid number. Please try again.", "NO_IDEAS": "📝 You don't have any ideas yet. Be the first to save one!", "IDEA_DELETED": "🗑️ Idea #{} '{}' has been deleted.", + "ASK_NEW_IDEA_TEXT": "✏️ Please enter the new text for idea #{} '{}'.", + "IDEA_UPDATED": "✅ Idea №{} updated successfully.", "LANGUAGE_ASK": ( "🌐 **Please choose your interface language:**\n" "Tap a button below to continue:" @@ -75,15 +83,16 @@ } } -BUTTON_ADD_TASK: str = "➕ New Task" +BUTTON_ADD_TASK: str = "📝 Create Task" BUTTON_IDEA: str = "💡 Save Idea" BUTTON_MYDAY: str = "📅 My Day" BUTTON_SETTINGS: str = "⚙️ Settings" BUTTON_HELP: str = "❓ Help" BUTTON_UA_LANG: str = "🌻 Українська" BUTTON_EN_LANG: str = "🇬🇧 English" -DEL_BUTTON: str = "🗑️ Delete Idea" -DEL_IDEA_BUTTON: str = "🗑️ Delete" -SAVE_BUTTON: str = "💾 Save" -MENU_BUTTON: str = "📂 Menu" -ALL_IDEAS: str = "📝 All Ideas" +DEL_BUTTON: str = "🗑️ Remove Idea" +DEL_IDEA_BUTTON: str = "🗑️ Delete Idea" +SAVE_BUTTON: str = "✅ Save" +MENU_BUTTON: str = "📂 Main Menu" +UPDATE_IDEA_BUTTON: str = "✏️ Update Idea" +ALL_IDEAS: str = "📋 View All Ideas" diff --git a/telegram_bot_project/states.py b/telegram_bot_project/states.py index 4183416..8839600 100644 --- a/telegram_bot_project/states.py +++ b/telegram_bot_project/states.py @@ -3,4 +3,6 @@ class DialogStates(StatesGroup): waiting_for_idea = State() confirm_idea = State() - delete_idea = State() \ No newline at end of file + delete_idea = State() + update_idea = State() + waiting_for_update_text = State() \ No newline at end of file