From 9714e9d37b10eb6192264b2a496f0024cd9e0a9f Mon Sep 17 00:00:00 2001 From: sysadmin Date: Thu, 28 Aug 2025 12:18:45 +0100 Subject: [PATCH] "Complete-product-UX-improvements-with-navigation-and-category-enhancements" --- LittleShop/littleshop.db-wal | Bin 1050632 -> 1314312 bytes TeleBot/TeleBot/Handlers/CallbackHandler.cs | 46 +++++++++++++++++++- TeleBot/TeleBot/UI/MenuBuilder.cs | 44 ++++++++++++++++++- TeleBot/TeleBot/UI/MessageFormatter.cs | 14 +----- 4 files changed, 89 insertions(+), 15 deletions(-) diff --git a/LittleShop/littleshop.db-wal b/LittleShop/littleshop.db-wal index fb66879d06e8a8763ed6d58e02f303f1005e2369..7ff98dac31faeca3cfb4fa7de28a024aa60be4af 100644 GIT binary patch delta 8260 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 delta 41 wcmeB}6VNfip`nGbg{g(Pg{6hHg{_6Xg` c.Id == categoryId); var products = await _shopService.GetProductsAsync(categoryId, 1); + // Edit the original message to show category header (bigger, more prominent) + var headerText = $"šŸ›ļø **{category?.Name ?? "Unknown Category"} PRODUCTS**\n\nšŸ“‹ Browse individual products below:"; + await bot.EditMessageTextAsync( message.Chat.Id, message.MessageId, - MessageFormatter.FormatProductList(products, category?.Name), + headerText, parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, - replyMarkup: MenuBuilder.ProductListMenu(products, categoryId, 1) + replyMarkup: MenuBuilder.CategoryNavigationMenu(categoryId) ); + + // Send individual product bubbles + if (products.Items.Any()) + { + foreach (var product in products.Items) + { + await bot.SendTextMessageAsync( + message.Chat.Id, + MessageFormatter.FormatSingleProduct(product), + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.SingleProductMenu(product.Id) + ); + } + + // Send navigation message after all products + await bot.SendTextMessageAsync( + message.Chat.Id, + "šŸ”½ *Navigation*", + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.ProductNavigationMenu(categoryId) + ); + } + else + { + await bot.SendTextMessageAsync( + message.Chat.Id, + "No products available in this category.", + replyMarkup: MenuBuilder.BackToCategoriesMenu() + ); + } + session.State = SessionState.ViewingProducts; } @@ -244,6 +278,14 @@ namespace TeleBot.Handlers replyMarkup: MenuBuilder.SingleProductMenu(product.Id) ); } + + // Send navigation message after all products + await bot.SendTextMessageAsync( + message.Chat.Id, + "šŸ”½ *Navigation*", + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.ProductNavigationMenu(categoryId) + ); } else { diff --git a/TeleBot/TeleBot/UI/MenuBuilder.cs b/TeleBot/TeleBot/UI/MenuBuilder.cs index 9594d08..d950c8e 100644 --- a/TeleBot/TeleBot/UI/MenuBuilder.cs +++ b/TeleBot/TeleBot/UI/MenuBuilder.cs @@ -28,9 +28,11 @@ namespace TeleBot.UI foreach (var category in categories) { + // Add description to category button text + var categoryText = GetCategoryDisplayText(category.Name, category.Description); buttons.Add(new[] { InlineKeyboardButton.WithCallbackData( - $"šŸ“ {category.Name}", + categoryText, $"category:{category.Id}" ) }); @@ -352,5 +354,45 @@ namespace TeleBot.UI } }); } + + public static InlineKeyboardMarkup ProductNavigationMenu(Guid? categoryId) + { + return new InlineKeyboardMarkup(new[] + { + new[] { + InlineKeyboardButton.WithCallbackData("ā¬…ļø Back to Categories", "browse"), + InlineKeyboardButton.WithCallbackData("šŸ›’ View Cart", "cart") + }, + new[] { + InlineKeyboardButton.WithCallbackData("šŸ  Main Menu", "menu") + } + }); + } + + private static string GetCategoryDisplayText(string categoryName, string? description) + { + var emoji = categoryName.ToLower() switch + { + var name when name.Contains("electronics") => "šŸ“±", + var name when name.Contains("clothing") || name.Contains("fashion") => "šŸ‘•", + var name when name.Contains("books") || name.Contains("book") => "šŸ“š", + var name when name.Contains("home") || name.Contains("house") => "šŸ ", + var name when name.Contains("sports") || name.Contains("fitness") => "⚽", + var name when name.Contains("beauty") || name.Contains("cosmetics") => "šŸ’„", + var name when name.Contains("food") || name.Contains("grocery") => "šŸŽ", + _ => "šŸ“¦" + }; + + if (!string.IsNullOrEmpty(description)) + { + // Truncate description for button + var shortDesc = description.Length > 40 + ? description.Substring(0, 37) + "..." + : description; + return $"{emoji} {categoryName}\n{shortDesc}"; + } + + return $"{emoji} {categoryName}"; + } } } \ No newline at end of file diff --git a/TeleBot/TeleBot/UI/MessageFormatter.cs b/TeleBot/TeleBot/UI/MessageFormatter.cs index 125a95f..59c0016 100644 --- a/TeleBot/TeleBot/UI/MessageFormatter.cs +++ b/TeleBot/TeleBot/UI/MessageFormatter.cs @@ -30,18 +30,8 @@ namespace TeleBot.UI public static string FormatCategories(List categories) { var sb = new StringBuilder(); - sb.AppendLine("šŸ“ *Product Categories*\n"); - - foreach (var category in categories) - { - sb.AppendLine($"• *{category.Name}*"); - if (!string.IsNullOrEmpty(category.Description)) - { - sb.AppendLine($" _{category.Description}_"); - } - } - - sb.AppendLine("\nSelect a category to browse products:"); + sb.AppendLine("šŸ›ļø **PRODUCT CATEGORIES**\n"); + sb.AppendLine("šŸ”½ Choose a category to start shopping:"); return sb.ToString(); }