product management, unification of kb and so on.

This commit is contained in:
2026-02-24 20:47:52 +07:00
parent 36ffca460f
commit 035170e46f
23 changed files with 470 additions and 130 deletions

View File

@@ -1,4 +1,4 @@
from typing import Optional
from typing import Optional, Callable
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
@@ -6,10 +6,6 @@ from aiogram.utils.keyboard import InlineKeyboardBuilder
from db.models import Category, Product
from dto.cart import CartItemDTO
return_menu = InlineKeyboardBuilder(
[[InlineKeyboardButton(text="⬅️ В меню", callback_data="menu:main")]]
).as_markup()
def pagination_row(
*,
@@ -61,11 +57,13 @@ def render_category(
children: list[Category],
parent_id: Optional[int] = None,
show_menu: bool = False,
*,
category_cb_factory: Callable[[Category], str],
) -> InlineKeyboardMarkup:
btns = [
InlineKeyboardButton(
text=category.name,
callback_data=f"cat:{category.id}",
callback_data=category_cb_factory(category),
)
for category in children
]
@@ -88,35 +86,37 @@ def render_category(
def render_products(
products: list[Product],
*,
parent_id: int,
cat_id: int,
page: int = 0,
show_prev: Optional[bool] = False,
show_next: Optional[bool] = False,
product_cb_factory: Callable[[Product], str],
back_cb: Optional[str] = None,
prev_cb: Optional[str] = None,
next_cb: Optional[str] = None,
columns: int = 2,
) -> InlineKeyboardMarkup:
btns = [
InlineKeyboardButton(text=product.name, callback_data=f"product:{product.id}")
for product in products
]
builder = InlineKeyboardBuilder()
nav = pagination_row(
page=page,
prev_cb=f"products:{cat_id}:{page - 1}" if show_prev else None,
next_cb=f"products:{cat_id}:{page + 1}" if show_next else None,
)
if back_cb:
builder.row(InlineKeyboardButton(text="⬅️ Назад", callback_data=back_cb))
return InlineKeyboardBuilder(
[
[
InlineKeyboardButton(
text="⬅️ Назад",
callback_data=f"cat:{parent_id}",
)
]
for i in range(0, len(products), columns):
row = [
InlineKeyboardButton(
text=p.name,
callback_data=product_cb_factory(p),
)
for p in products[i : i + columns]
]
+ [btns[i : i + 2] for i in range(0, len(products), 2)]
+ [nav]
).as_markup()
builder.row(*row)
nav_buttons = []
if prev_cb:
nav_buttons.append(InlineKeyboardButton(text="◀️", callback_data=prev_cb))
if next_cb:
nav_buttons.append(InlineKeyboardButton(text="▶️", callback_data=next_cb))
if nav_buttons:
builder.row(*nav_buttons)
return builder.as_markup()
def render_product_interactions(
@@ -165,6 +165,7 @@ def render_cart(
page: int = 0,
show_prev: Optional[bool] = False,
show_next: Optional[bool] = False,
show_purchase: Optional[bool] = False,
) -> InlineKeyboardMarkup:
btns = [
InlineKeyboardButton(
@@ -180,19 +181,25 @@ def render_cart(
next_cb=f"cart:{page + 1}" if show_next else None,
)
return InlineKeyboardBuilder(
markup: list[list[InlineKeyboardButton]] = (
[
[
InlineKeyboardButton(
text="⬅️ Назад",
callback_data="menu:main",
)
]
],
]
+ [btns[i : i + 2] for i in range(0, len(cart_items), 2)]
+ [nav]
+ [[InlineKeyboardButton(text="🔷 Оформить заказ", callback_data="checkout")]]
).as_markup()
)
if show_purchase:
markup.append(
[InlineKeyboardButton(text="🔷 Оформить заказ", callback_data="checkout")]
)
return InlineKeyboardBuilder(markup).as_markup()
def order_confirmation(order_id: int) -> InlineKeyboardMarkup: