224 lines
6.2 KiB
Python
224 lines
6.2 KiB
Python
from typing import Optional
|
||
|
||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||
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(
|
||
*,
|
||
page: int,
|
||
prev_cb: Optional[str] = None,
|
||
next_cb: Optional[str] = None,
|
||
) -> list[InlineKeyboardButton]:
|
||
row = []
|
||
|
||
if not (prev_cb or next_cb):
|
||
return row
|
||
|
||
if prev_cb:
|
||
row.append(InlineKeyboardButton(text="⬅️", callback_data=prev_cb))
|
||
|
||
row.append(InlineKeyboardButton(text=str(page + 1), callback_data="..."))
|
||
|
||
if next_cb:
|
||
row.append(InlineKeyboardButton(text="➡️", callback_data=next_cb))
|
||
|
||
return row
|
||
|
||
|
||
def cart_btn(cart_items: int) -> InlineKeyboardButton:
|
||
return InlineKeyboardButton(text=f"🛒 Корзина ({cart_items})", callback_data="cart")
|
||
|
||
|
||
def get_back_to_catalogue(
|
||
cat_id: int, *, text: Optional[str] = "⬅️ Назад"
|
||
) -> InlineKeyboardMarkup:
|
||
return InlineKeyboardBuilder(
|
||
[[InlineKeyboardButton(text=text, callback_data=f"cat:{cat_id}")]]
|
||
).as_markup()
|
||
|
||
|
||
def main_menu_kb(cart_items: int) -> InlineKeyboardMarkup:
|
||
return InlineKeyboardBuilder(
|
||
[
|
||
[
|
||
InlineKeyboardButton(text="📦 Каталог", callback_data="cat:root"),
|
||
InlineKeyboardButton(text="🔍", callback_data="find"),
|
||
],
|
||
[cart_btn(cart_items)],
|
||
]
|
||
).as_markup()
|
||
|
||
|
||
def render_category(
|
||
children: list[Category],
|
||
parent_id: Optional[int] = None,
|
||
show_menu: bool = False,
|
||
) -> InlineKeyboardMarkup:
|
||
btns = [
|
||
InlineKeyboardButton(
|
||
text=category.name,
|
||
callback_data=f"cat:{category.id}",
|
||
)
|
||
for category in children
|
||
]
|
||
|
||
nav = []
|
||
|
||
if parent_id is not None:
|
||
nav.append(
|
||
InlineKeyboardButton(text="⬅️ Назад", callback_data=f"cat:{parent_id}")
|
||
)
|
||
|
||
if show_menu:
|
||
nav.append(InlineKeyboardButton(text="⬅️ Назад", callback_data="menu:main"))
|
||
|
||
return InlineKeyboardBuilder(
|
||
[btns[i : i + 2] for i in range(0, len(children), 2)] + [nav],
|
||
).as_markup()
|
||
|
||
|
||
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,
|
||
) -> InlineKeyboardMarkup:
|
||
btns = [
|
||
InlineKeyboardButton(text=product.name, callback_data=f"product:{product.id}")
|
||
for product in products
|
||
]
|
||
|
||
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,
|
||
)
|
||
|
||
return InlineKeyboardBuilder(
|
||
[
|
||
[
|
||
InlineKeyboardButton(
|
||
text="⬅️ Назад",
|
||
callback_data=f"cat:{parent_id}",
|
||
)
|
||
]
|
||
]
|
||
+ [btns[i : i + 2] for i in range(0, len(products), 2)]
|
||
+ [nav]
|
||
).as_markup()
|
||
|
||
|
||
def render_product_interactions(
|
||
*, product_id: int, category_id: int, show_cart: bool = False, cart_amount: int = 0
|
||
) -> InlineKeyboardMarkup:
|
||
btns: list[list[InlineKeyboardButton]] = []
|
||
|
||
if show_cart:
|
||
btns.append(
|
||
[
|
||
InlineKeyboardButton(
|
||
text="➖", callback_data=f"cart_action:remove:{product_id}"
|
||
),
|
||
InlineKeyboardButton(text=f"🛒 {cart_amount}", callback_data="..."),
|
||
InlineKeyboardButton(
|
||
text="➕", callback_data=f"cart_action:add:{product_id}"
|
||
),
|
||
]
|
||
)
|
||
btns.append(
|
||
[
|
||
InlineKeyboardButton(
|
||
text="❌ Удалить из корзины",
|
||
callback_data=f"cart_action:clear:{product_id}",
|
||
)
|
||
]
|
||
)
|
||
|
||
else:
|
||
btns.append(
|
||
[
|
||
InlineKeyboardButton(
|
||
text="🛒 В корзину", callback_data=f"cart_action:add:{product_id}"
|
||
)
|
||
]
|
||
)
|
||
|
||
btns.append([InlineKeyboardButton(text="⬅️", callback_data=f"cat:{category_id}")])
|
||
|
||
return InlineKeyboardBuilder(btns).as_markup()
|
||
|
||
|
||
def render_cart(
|
||
cart_items: list[CartItemDTO],
|
||
*,
|
||
page: int = 0,
|
||
show_prev: Optional[bool] = False,
|
||
show_next: Optional[bool] = False,
|
||
) -> InlineKeyboardMarkup:
|
||
btns = [
|
||
InlineKeyboardButton(
|
||
text=f"🛒 {cart_item.quantity} | {cart_item.name} | {cart_item.total}₽",
|
||
callback_data=f"product:{cart_item.product_id}",
|
||
)
|
||
for cart_item in cart_items
|
||
]
|
||
|
||
nav = pagination_row(
|
||
page=page,
|
||
prev_cb=f"cart:{page - 1}" if show_prev else None,
|
||
next_cb=f"cart:{page + 1}" if show_next else None,
|
||
)
|
||
|
||
return InlineKeyboardBuilder(
|
||
[
|
||
[
|
||
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()
|
||
|
||
|
||
def order_confirmation(order_id: int) -> InlineKeyboardMarkup:
|
||
return InlineKeyboardBuilder(
|
||
[
|
||
[
|
||
InlineKeyboardButton(
|
||
text="🟢 Подтвердить заказ",
|
||
callback_data=f"confirm_order:{order_id}",
|
||
)
|
||
],
|
||
[InlineKeyboardButton(text="❌ Отменить", callback_data="menu:main")],
|
||
]
|
||
).as_markup()
|
||
|
||
|
||
def order_specs_confirmation(order_id: int) -> InlineKeyboardMarkup:
|
||
return InlineKeyboardBuilder(
|
||
[
|
||
[
|
||
InlineKeyboardButton(
|
||
text="🟢 Перейти к оплате",
|
||
callback_data=f"payment:{order_id}",
|
||
)
|
||
],
|
||
[InlineKeyboardButton(text="❌", callback_data="menu:main")],
|
||
]
|
||
).as_markup()
|