from __future__ import annotations from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup from app.categories import EXPENSE_CATEGORIES, category_label from app.domain import BudgetCategory MONTH_TOTAL = "📅 Итог за месяц" ALL_TOTAL = "💰 Итог общий" ANALYTICS = "📊 Аналитика" RECENT = "🧾 Последние записи" FAMILY = "👨‍👩‍👧 Семья" DEBT = "💳 Общий долг" CATEGORIES = "🗂 Категории" HELP = "❓ Помощь" def main_keyboard() -> ReplyKeyboardMarkup: return ReplyKeyboardMarkup( keyboard=[ [KeyboardButton(text=MONTH_TOTAL), KeyboardButton(text=ALL_TOTAL)], [KeyboardButton(text=ANALYTICS), KeyboardButton(text=RECENT)], [KeyboardButton(text=FAMILY), KeyboardButton(text=DEBT)], [KeyboardButton(text=CATEGORIES), KeyboardButton(text=HELP)], ], resize_keyboard=True, input_field_placeholder="Например: 467 ярче", is_persistent=True, ) def family_setup_keyboard() -> InlineKeyboardMarkup: return InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="Создать общий бюджет", callback_data="family:create")], [InlineKeyboardButton(text="Ввести код супруга", callback_data="family:join")], ] ) def family_approval_keyboard(candidate_user_id: int) -> InlineKeyboardMarkup: return InlineKeyboardMarkup( inline_keyboard=[ [ InlineKeyboardButton( text="✅ Подтвердить", callback_data=f"family:approve:{candidate_user_id}", ), InlineKeyboardButton( text="🚫 Отклонить", callback_data=f"family:reject:{candidate_user_id}", ), ] ] ) def debt_keyboard(can_edit: bool) -> InlineKeyboardMarkup | None: if not can_edit: return None return InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="✏️ Указать текущий долг", callback_data="debt:set")] ] ) def category_tree_keyboard( transaction_id: int, categories: list[BudgetCategory] ) -> InlineKeyboardMarkup: rows: list[list[InlineKeyboardButton]] = [] for category in categories: if category.parent_name: text = f"↳ {category.icon} {category.name}" else: text = f"{category.icon} {category.name}" rows.append( [ InlineKeyboardButton( text=text, callback_data=f"bcat:{transaction_id}:{category.id}", ) ] ) rows.append([InlineKeyboardButton(text="Отмена", callback_data=f"cancel:{transaction_id}")]) return InlineKeyboardMarkup(inline_keyboard=rows) def category_management_keyboard() -> InlineKeyboardMarkup: return InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="➕ Добавить категорию", callback_data="catmanage:add-main")], [InlineKeyboardButton(text="↳ Добавить подкатегорию", callback_data="catmanage:add-sub")], ] ) def category_kind_keyboard() -> InlineKeyboardMarkup: return InlineKeyboardMarkup( inline_keyboard=[ [ InlineKeyboardButton(text="↘️ Расход", callback_data="catmanage:kind:expense"), InlineKeyboardButton(text="↗️ Доход", callback_data="catmanage:kind:income"), ], [InlineKeyboardButton(text="Отмена", callback_data="catmanage:cancel")], ] ) def parent_category_keyboard(categories: list[BudgetCategory]) -> InlineKeyboardMarkup: parents = [category for category in categories if category.parent_id is None] return InlineKeyboardMarkup( inline_keyboard=[ [ InlineKeyboardButton( text=f"{category.icon} {category.name}", callback_data=f"catmanage:parent:{category.id}", ) ] for category in parents ] + [[InlineKeyboardButton(text="Отмена", callback_data="catmanage:cancel")]] ) def transaction_actions(transaction_id: int, *, is_expense: bool) -> InlineKeyboardMarkup: # In a family budget, selecting a category may also change the operation type. # Keep this action available for both current expenses and current incomes. buttons: list[InlineKeyboardButton] = [ InlineKeyboardButton(text="Изменить категорию", callback_data=f"choose:{transaction_id}") ] buttons.append(InlineKeyboardButton(text="Удалить", callback_data=f"delete:{transaction_id}")) return InlineKeyboardMarkup(inline_keyboard=[buttons]) def category_keyboard(transaction_id: int) -> InlineKeyboardMarkup: rows = [] categories = list(EXPENSE_CATEGORIES) for index in range(0, len(categories), 2): rows.append( [ InlineKeyboardButton( text=category_label(category), callback_data=f"category:{transaction_id}:{category.value}", ) for category in categories[index : index + 2] ] ) rows.append([InlineKeyboardButton(text="Отмена", callback_data=f"cancel:{transaction_id}")]) return InlineKeyboardMarkup(inline_keyboard=rows) def analytics_period_keyboard(active: str = "month") -> InlineKeyboardMarkup: month_label = "✓ Этот месяц" if active == "month" else "Этот месяц" all_label = "✓ Всё время" if active == "all" else "Всё время" return InlineKeyboardMarkup( inline_keyboard=[ [ InlineKeyboardButton(text=month_label, callback_data="analytics:month"), InlineKeyboardButton(text=all_label, callback_data="analytics:all"), ] ] )