From ab8e0a65d75ef2630de82fe2277ff5cf14728a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:16:23 +0200 Subject: [PATCH 1/9] Update header branding and navigation links in MainLayout --- src/webapp/Components/Layout/MainLayout.razor | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/webapp/Components/Layout/MainLayout.razor b/src/webapp/Components/Layout/MainLayout.razor index 2b6545f..8696946 100644 --- a/src/webapp/Components/Layout/MainLayout.razor +++ b/src/webapp/Components/Layout/MainLayout.razor @@ -5,8 +5,8 @@
- -

Fashion Store Assistant

+ +

My Company Copilot

From 97b6eb5b23a0ab4b3caa8e49005e1933c9329bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:16:35 +0200 Subject: [PATCH 2/9] Remove Cart.razor component and associated logic --- src/webapp/Components/Pages/Cart.razor | 585 ------------------------- 1 file changed, 585 deletions(-) delete mode 100644 src/webapp/Components/Pages/Cart.razor diff --git a/src/webapp/Components/Pages/Cart.razor b/src/webapp/Components/Pages/Cart.razor deleted file mode 100644 index 8a00e57..0000000 --- a/src/webapp/Components/Pages/Cart.razor +++ /dev/null @@ -1,585 +0,0 @@ -@page "/cart" -@layout MainLayout -@using dotnetfashionassistant.Models -@using dotnetfashionassistant.Components.Layout -@using dotnetfashionassistant.Services -@inject HttpClient Http -@inject IHttpClientFactory HttpClientFactory -@inject NavigationManager NavigationManager -@inject IJSRuntime JSRuntime -@inject CartUpdateService CartUpdateService -@rendermode InteractiveServer - -Shopping Cart - -
-
-

Your Shopping Cart

-
- - @if (isLoading) - { -
-
- Loading... -
-

Loading your cart...

-
- } - else if (cartItems.Count == 0) - { -
-
- -
-

Your cart is empty

-

Looks like you haven't added any items to your cart yet.

- -
- } - else - { -
-
- @foreach (var item in cartItems) - { -
-
- @item.ProductName -
-

@item.ProductName

-
- Size: @item.Size - Price: $@item.Price.ToString("0.00") -
-
-
- - - -
-
-
-
- -
-
- } -
- -
-
- Items (@cartItems.Sum(i => i.Quantity)): - $@CalculateSubtotal().ToString("0.00") -
-
- Order Total: - $@CalculateSubtotal().ToString("0.00") -
-
- -
- - - -
-
-
- } -
- - - -@code { - private List cartItems = new List(); - private decimal totalCost = 0; - private bool isLoading = true; - private HttpClient client = null!; protected override async Task OnInitializedAsync() - { - client = HttpClientFactory.CreateClient("LocalApi"); - await LoadCart(); - - // Start polling for cart updates - StartCartPolling(); - } - - private System.Threading.Timer? _pollingTimer; - - private async Task LoadCart() - { - isLoading = true; - try - { - var cartSummary = await client.GetFromJsonAsync("api/Cart"); - if (cartSummary != null) - { - cartItems = cartSummary.Items; - totalCost = cartSummary.TotalCost; - } - else - { - cartItems = new List(); - totalCost = 0; - } - } - catch (Exception ex) - { - Console.WriteLine($"Error loading cart: {ex.Message}"); - cartItems = new List(); - totalCost = 0; - } - isLoading = false; - } private string GetProductImageUrl(int productId) - { - // Map product IDs to specific image files that match the product descriptions - switch (productId) - { - case 3: - return "/images/products/navy-blazer.jpeg"; // Navy Single-Breasted Slim Fit Formal Blazer - case 111: - return "/images/products/white-navy-shirt.jpeg"; // White & Navy Blue Slim Fit Printed Casual Shirt - case 116: - return "/images/products/red-checked-shirt.jpeg"; // Red Slim Fit Checked Casual Shirt - case 10: - return "/images/products/denim-jacket.jpeg"; // Navy Blue Washed Denim Jacket - default: - // Fallback to a placeholder if the product ID is not recognized - return $"https://picsum.photos/seed/{productId}/400/228"; - } - }private decimal CalculateSubtotal() - { - return cartItems.Sum(item => item.Quantity * item.Price); - } private async Task IncreaseQuantity(CartItem item) - { - isLoading = true; - try - { - var request = new { Quantity = item.Quantity + 1 }; - var response = await client.PutAsJsonAsync($"api/Cart/{item.ProductId}/size/{item.Size}", request); - - if (response.IsSuccessStatusCode) - { - var cartSummary = await response.Content.ReadFromJsonAsync(); - if (cartSummary != null) - { - cartItems = cartSummary.Items; - totalCost = cartSummary.TotalCost; - - // Update cart counter immediately - await UpdateCartCounterDisplay(); - // Notify other components about cart update - CartUpdateService.NotifyCartUpdated(); - } - } - else - { - var errorMessage = await response.Content.ReadAsStringAsync(); - Console.WriteLine($"Error: {errorMessage}"); - } - } - catch (Exception ex) - { - Console.WriteLine($"Error updating quantity: {ex.Message}"); - } - isLoading = false; - } private async Task DecreaseQuantity(CartItem item) - { - if (item.Quantity <= 1) return; - - isLoading = true; - try - { - var request = new { Quantity = item.Quantity - 1 }; - var response = await client.PutAsJsonAsync($"api/Cart/{item.ProductId}/size/{item.Size}", request); - - if (response.IsSuccessStatusCode) - { - var cartSummary = await response.Content.ReadFromJsonAsync(); - if (cartSummary != null) - { - cartItems = cartSummary.Items; - totalCost = cartSummary.TotalCost; - - // Update cart counter immediately - await UpdateCartCounterDisplay(); - // Notify other components about cart update - CartUpdateService.NotifyCartUpdated(); - } - } - } - catch (Exception ex) - { - Console.WriteLine($"Error updating quantity: {ex.Message}"); - } - isLoading = false; - } private async Task RemoveItem(CartItem item) - { - isLoading = true; - try - { - var response = await client.DeleteAsync($"api/Cart/{item.ProductId}/size/{item.Size}"); - if (response.IsSuccessStatusCode) - { - var cartSummary = await response.Content.ReadFromJsonAsync(); - if (cartSummary != null) - { - cartItems = cartSummary.Items; - totalCost = cartSummary.TotalCost; - - // Update cart counter immediately - await UpdateCartCounterDisplay(); - // Notify other components about cart update - CartUpdateService.NotifyCartUpdated(); - } - } - } - catch (Exception ex) - { - Console.WriteLine($"Error removing item: {ex.Message}"); - } - isLoading = false; - } private async Task ClearCart() - { - isLoading = true; - try - { - var response = await client.DeleteAsync("api/Cart"); - if (response.IsSuccessStatusCode) - { - var cartSummary = await response.Content.ReadFromJsonAsync(); - if (cartSummary != null) - { - cartItems = cartSummary.Items; - totalCost = cartSummary.TotalCost; - } - else - { - cartItems.Clear(); - totalCost = 0; - } - - // Update cart counter immediately (will be 0 since cart is cleared) - await UpdateCartCounterDisplay(); - // Notify other components about cart update - CartUpdateService.NotifyCartUpdated(); - } - } - catch (Exception ex) - { - Console.WriteLine($"Error clearing cart: {ex.Message}"); - } - isLoading = false; - } - - private void NavigateToInventory() - { - NavigationManager.NavigateTo("/inventory"); - } - private void Checkout() - { - // In a real application, this would navigate to a checkout page - // For now, just show an alert - JSRuntime.InvokeVoidAsync("alert", "Checkout functionality is not implemented in this demo."); - } - - // Method to start polling for cart updates - private void StartCartPolling() - { - // Poll every 3 seconds for cart updates - _pollingTimer = new System.Threading.Timer(async _ => - { - await CheckForCartUpdates(); - }, null, TimeSpan.Zero, TimeSpan.FromSeconds(3)); - } - - private async Task CheckForCartUpdates() - { - try - { - var cartSummary = await client.GetFromJsonAsync("api/Cart"); - if (cartSummary != null) - { - // Check if there are any differences between the current cart and the new cart - bool hasChanged = false; - - // Check if item count changed - if (cartSummary.Items.Count != cartItems.Count) - { - hasChanged = true; - } - else - { - // Check for changes in quantity or price of items - foreach (var newItem in cartSummary.Items) - { - var existingItem = cartItems.FirstOrDefault(i => - i.ProductId == newItem.ProductId && i.Size == newItem.Size); - - if (existingItem == null || existingItem.Quantity != newItem.Quantity || existingItem.Price != newItem.Price) - { - hasChanged = true; - break; - } - } - } - - // If cart has changed, update UI and notify components - if (hasChanged) - { - await InvokeAsync(async () => - { - cartItems = cartSummary.Items; - totalCost = cartSummary.TotalCost; - - // Update cart counter immediately - await UpdateCartCounterDisplay(); - // Notify other components about cart update - CartUpdateService.NotifyCartUpdated(); - - StateHasChanged(); - }); - } - } - } - catch (Exception ex) - { - Console.WriteLine($"Error checking for cart updates: {ex.Message}"); - } - } - - // IDisposable implementation to clean up the timer - public void Dispose() - { - _pollingTimer?.Dispose(); - } - - // Method to update the cart counter immediately using JavaScript - private async Task UpdateCartCounterDisplay() - { - try - { - // Calculate the total quantity of items in the cart - int totalQuantity = cartItems?.Sum(item => item.Quantity) ?? 0; - - // Use JavaScript interop to update the cart badge in real-time - await JSRuntime.InvokeVoidAsync("updateCartBadge", totalQuantity); - } - catch - { - // Silently fail if we can't update the counter - } - } -} From 187112a7d517277f4fa9cb61325a75b08d262443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:16:42 +0200 Subject: [PATCH 3/9] Refactor greeting message in chat interface for brevity --- src/webapp/Components/Pages/Home.razor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/webapp/Components/Pages/Home.razor b/src/webapp/Components/Pages/Home.razor index c69b564..9e0fa71 100644 --- a/src/webapp/Components/Pages/Home.razor +++ b/src/webapp/Components/Pages/Home.razor @@ -30,7 +30,7 @@ {
-

Hello! I'm your AI shopping assistant. How can I help you with your fashion needs today?

+

Hello! I'm your AI assistant. How can I help you today?

} @@ -285,7 +285,7 @@ { chatHistory.Add(new ChatMessage { - Content = "Hello! I'm your AI shopping assistant. How can I help you with your fashion needs today?", + Content = "Hello! I'm your AI assistant. How can I help you today?", IsUser = false, Timestamp = DateTime.Now }); @@ -306,7 +306,7 @@ chatHistory.Clear(); chatHistory.Add(new ChatMessage { - Content = "Hello! I'm your AI shopping assistant. How can I help you with your fashion needs today?", + Content = "Hello! I'm your AI assistant. How can I help you today?", IsUser = false, Timestamp = DateTime.Now }); @@ -331,7 +331,7 @@ // Add a welcome message chatHistory.Add(new ChatMessage { - Content = "Hello! I'm your AI shopping assistant. How can I help you with your fashion needs today?", + Content = "Hello! I'm your AI assistant. How can I help you today?", IsUser = false, Timestamp = DateTime.Now }); From a50193e2529f9007e4509cafa467304afb7f1c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:16:48 +0200 Subject: [PATCH 4/9] Remove Inventory.razor component and associated logic --- src/webapp/Components/Pages/Inventory.razor | 491 -------------------- 1 file changed, 491 deletions(-) delete mode 100644 src/webapp/Components/Pages/Inventory.razor diff --git a/src/webapp/Components/Pages/Inventory.razor b/src/webapp/Components/Pages/Inventory.razor deleted file mode 100644 index 76ed345..0000000 --- a/src/webapp/Components/Pages/Inventory.razor +++ /dev/null @@ -1,491 +0,0 @@ -@page "/inventory" -@layout MainLayout -@using dotnetfashionassistant.Models -@using dotnetfashionassistant.Components.Layout -@using dotnetfashionassistant.Services -@inject IHttpClientFactory HttpClientFactory -@inject NavigationManager NavigationManager -@inject IJSRuntime JSRuntime -@inject CartUpdateService CartUpdateService -@rendermode InteractiveServer - -Fashion Store Inventory - -@if (showSuccessToast) -{ -
- -
-} - -
-
-

Fashion Store

-

Browse our latest collection of premium fashion items

- - @if (errorMessage != null) - { - - }
- -
- @foreach (var item in inventory) - { -
-
- @item.ProductName -
-

@item.ProductName

-
$@item.Price.ToString("0.00")
-
- Available Sizes: -
- @foreach (var size in InventoryService.GetSizes()) - { - @if (item.SizeInventory[size] > 0) - { - - @size (@item.SizeInventory[size]) - - } - else - { - @size (0) - } - } -
-
- -
- @{ - var availableSizes = GetAvailableSizes(item); - var hasSizes = availableSizes.Count > 0; - } -
- -
- -
-
- - - -
-
- - -
-
-
- } -
-
- - - -@code { - private List inventory = null!; - private Dictionary selectedSizes = new Dictionary(); - private Dictionary quantities = new Dictionary(); - private bool showSuccessToast = false; - private string? errorMessage = null; - private HttpClient client = null!; - private string lastAddedItem = ""; - - protected override void OnInitialized() - { - inventory = InventoryService.GetInventory(); - client = HttpClientFactory.CreateClient("LocalApi"); - - // Initialize size selections and quantities - foreach (var item in inventory) - { - selectedSizes[item.ProductId] = ""; - quantities[item.ProductId] = 1; - } - } - - private string GetStockLevelClass(int count) - { - if (count == 0) - return "out-of-stock"; - if (count < 6) - return "bg-danger"; - if (count <= 15) - return "bg-warning"; - return "bg-success"; - } - - private List GetAvailableSizes(InventoryItem item) - { - return item.SizeInventory - .Where(s => s.Value > 0) - .Select(s => s.Key) - .ToList(); - } - - private bool CanAddToCart(InventoryItem item) - { - if (!selectedSizes.TryGetValue(item.ProductId, out var selectedSize)) - return false; - - if (string.IsNullOrEmpty(selectedSize) || - !item.SizeInventory.TryGetValue(selectedSize, out var stock)) - return false; - - int qty = GetQuantity(item.ProductId); - return stock >= qty; - } - - private int GetQuantity(int productId) - { - if (quantities.TryGetValue(productId, out int qty)) - return qty; - - quantities[productId] = 1; - return 1; - } - - private void IncreaseQuantity(int productId) - { - int currentQty = GetQuantity(productId); - if (currentQty < 99) // Set a reasonable upper limit - { - quantities[productId] = currentQty + 1; - } - } - - private void DecreaseQuantity(int productId) - { - int currentQty = GetQuantity(productId); - if (currentQty > 1) - { - quantities[productId] = currentQty - 1; - } - } - - private void UpdateQuantity(int productId, int quantity) - { - // Ensure quantity is within valid range - if (quantity < 1) - quantity = 1; - if (quantity > 99) - quantity = 99; - - quantities[productId] = quantity; - } - private string GetProductImageUrl(int productId) - { - // Map product IDs to specific image files that match the product descriptions - switch (productId) - { - case 3: - return "/images/products/navy-blazer.jpeg"; // Navy Single-Breasted Slim Fit Formal Blazer - case 111: - return "/images/products/white-navy-shirt.jpeg"; // White & Navy Blue Slim Fit Printed Casual Shirt - case 116: - return "/images/products/red-checked-shirt.jpeg"; // Red Slim Fit Checked Casual Shirt - case 10: - return "/images/products/denim-jacket.jpeg"; // Navy Blue Washed Denim Jacket - default: - // Fallback to a placeholder if the product ID is not recognized - return $"https://picsum.photos/seed/{productId}/400/228"; - } - } - - private async Task AddToCart(InventoryItem item) - { - errorMessage = null; - if (!selectedSizes.TryGetValue(item.ProductId, out var size) || string.IsNullOrEmpty(size)) - { - errorMessage = "Please select a size first"; - return; - } - - int quantity = GetQuantity(item.ProductId); - - // Check if enough stock is available - if (!item.SizeInventory.TryGetValue(size, out int stock) || stock < quantity) - { - errorMessage = $"Not enough stock. Only {stock} items available"; - return; - } - - try - { - var request = new - { - ProductId = item.ProductId, - Size = size, - Quantity = quantity - }; - - var response = await client.PostAsJsonAsync("api/Cart/add", request); - - if (response.IsSuccessStatusCode) - { - // Set the details of the last added item for the toast notification - lastAddedItem = $"{quantity} x {item.ProductName} (Size: {size})"; - showSuccessToast = true; - - // Reset quantity to 1 after successful add - quantities[item.ProductId] = 1; - - // Update cart counter immediately using JavaScript interop - await UpdateCartCounterDisplay(response); - } - else - { - var error = await response.Content.ReadAsStringAsync(); - errorMessage = $"Failed to add item to cart: {error}"; - } - } - catch (Exception ex) - { - errorMessage = $"An error occurred: {ex.Message}"; - } - } - private async Task UpdateCartCounterDisplay(HttpResponseMessage response) - { - try - { - // Get the updated cart summary from the API response - var cartSummary = await response.Content.ReadFromJsonAsync(); - - // Calculate the new cart count - int newCount = cartSummary?.Items?.Sum(item => item.Quantity) ?? 0; - - // Use JavaScript interop to update the cart badge in real-time - await JSRuntime.InvokeVoidAsync("updateCartBadge", newCount); - - // Notify other components (like MainLayout) about cart update - CartUpdateService.NotifyCartUpdated(); - } - catch (Exception ex) - { - Console.WriteLine($"Error updating cart counter: {ex.Message}"); - // Silently fail if we can't update the counter - } - } -} From 6b7a5965d3a7de8148b9e2411583496666ac7d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:16:53 +0200 Subject: [PATCH 5/9] Remove CartController and associated logic --- src/webapp/Controllers/CartController.cs | 151 ----------------------- 1 file changed, 151 deletions(-) delete mode 100644 src/webapp/Controllers/CartController.cs diff --git a/src/webapp/Controllers/CartController.cs b/src/webapp/Controllers/CartController.cs deleted file mode 100644 index 2497ab8..0000000 --- a/src/webapp/Controllers/CartController.cs +++ /dev/null @@ -1,151 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using dotnetfashionassistant.Models; -using System.Collections.Generic; -using System.Linq; - -namespace dotnetfashionassistant.Controllers -{ - [ApiController] - [Route("api/[controller]")] - [Produces("application/json")] - public class CartController : ControllerBase - { /// - /// Gets all items in the shopping cart along with the total cost - /// - /// A cart summary containing items and total cost - [HttpGet] - [ProducesResponseType(typeof(CartSummary), 200)] - public ActionResult GetCart() - { - return Ok(CartService.GetCartSummary()); - } /// - /// Adds an item to the shopping cart - /// - /// The item to add to the cart - /// The updated cart summary with total cost - [HttpPost("add")] - [ProducesResponseType(typeof(CartSummary), 200)] - [ProducesResponseType(400)] - public ActionResult AddToCart(AddToCartRequest request) - { - // Validate request - if (request.Quantity <= 0) - { - return BadRequest("Quantity must be greater than zero"); - } - - // Check if the product exists and is in stock - var product = InventoryService.GetInventory().FirstOrDefault(i => i.ProductId == request.ProductId); - if (product == null) - { - return BadRequest("Product not found"); - } - - if (!product.SizeInventory.TryGetValue(request.Size, out int stock)) - { - return BadRequest($"Size {request.Size} not available for this product"); - } - - if (stock < request.Quantity) - { - return BadRequest($"Not enough stock. Only {stock} items available"); - } // Add to cart - CartService.AddToCart(request.ProductId, product.ProductName, request.Size, request.Quantity, product.Price); - - return Ok(CartService.GetCartSummary()); - } /// - /// Updates the quantity of an item in the cart - /// - /// The product ID - /// The product size - /// The update quantity request - /// The updated cart summary with total cost - [HttpPut("{productId}/size/{size}")] - [ProducesResponseType(typeof(CartSummary), 200)] - [ProducesResponseType(400)] - [ProducesResponseType(404)] - public ActionResult UpdateCartItemQuantity(int productId, string size, UpdateQuantityRequest request) - { - // Check if trying to update to a positive quantity - if (request.Quantity > 0) - { - // Check if the product exists and has enough stock - var product = InventoryService.GetInventory().FirstOrDefault(i => i.ProductId == productId); - if (product == null) - { - return BadRequest("Product not found"); - } - - if (!product.SizeInventory.TryGetValue(size, out int stock)) - { - return BadRequest($"Size {size} not available for this product"); - } - - if (stock < request.Quantity) - { - return BadRequest($"Not enough stock. Only {stock} items available"); - } - } // Update the cart - bool success = CartService.UpdateCartItemQuantity(productId, size, request.Quantity); - if (!success) - { - return NotFound("Item not found in cart"); - } - - return Ok(CartService.GetCartSummary()); - } /// - /// Removes an item from the cart - /// - /// The product ID - /// The product size - /// The updated cart summary with total cost - [HttpDelete("{productId}/size/{size}")] - [ProducesResponseType(typeof(CartSummary), 200)] - [ProducesResponseType(404)] - public ActionResult RemoveFromCart(int productId, string size) - { bool success = CartService.RemoveFromCart(productId, size); - if (!success) - { - return NotFound("Item not found in cart"); - } - - return Ok(CartService.GetCartSummary()); - } /// - /// Clears all items from the cart - /// - /// Empty cart summary with zero total cost - [HttpDelete] - [ProducesResponseType(typeof(CartSummary), 200)] - public ActionResult ClearCart() - { - CartService.ClearCart(); - return Ok(CartService.GetCartSummary()); - } - } - - public class AddToCartRequest - { - /// - /// The product ID to add to the cart - /// - public int ProductId { get; set; } - - /// - /// The size of the product (e.g., XS, S, M, L, XL, XXL, XXXL) - /// - public required string Size { get; set; } - - /// - /// The quantity to add - /// - public int Quantity { get; set; } - } - - public class UpdateQuantityRequest - { - /// - /// The new quantity for the cart item - /// - public int Quantity { get; set; } - } -} From 527743c4774d38788b7bf61a44b2764d6cc5ea42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:17:00 +0200 Subject: [PATCH 6/9] Remove InventoryController and associated logic --- src/webapp/Controllers/InventoryController.cs | 111 ------------------ 1 file changed, 111 deletions(-) delete mode 100644 src/webapp/Controllers/InventoryController.cs diff --git a/src/webapp/Controllers/InventoryController.cs b/src/webapp/Controllers/InventoryController.cs deleted file mode 100644 index 3f642c1..0000000 --- a/src/webapp/Controllers/InventoryController.cs +++ /dev/null @@ -1,111 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using dotnetfashionassistant.Models; -using System.Collections.Generic; -using System.Linq; - -namespace dotnetfashionassistant.Controllers -{ - [ApiController] - [Route("api/[controller]")] - [Produces("application/json")] - public class InventoryController : ControllerBase - { - /// - /// Gets all inventory items - /// - /// A list of all inventory items with their sizes and quantities - [HttpGet] - [ProducesResponseType(typeof(IEnumerable), 200)] - public ActionResult> GetInventory() - { - return Ok(InventoryService.GetInventory()); - } - - /// - /// Gets a specific inventory item by product ID - /// - /// The product ID to look up - /// The inventory item matching the specified ID - [HttpGet("{id}")] - [ProducesResponseType(typeof(InventoryItem), 200)] - [ProducesResponseType(404)] - public ActionResult GetInventoryItem(int id) - { - var item = InventoryService.GetInventory().FirstOrDefault(i => i.ProductId == id); - - if (item == null) - { - return NotFound(); - } - - return Ok(item); - } - - /// - /// Gets inventory count for a specific product and size - /// - /// The product ID - /// The size to check (e.g., XS, S, M, L, XL, XXL, XXXL) - /// The inventory count for the specified product and size - [HttpGet("{id}/size/{size}")] - [ProducesResponseType(typeof(SizeInventoryResponse), 200)] - [ProducesResponseType(404)] - public ActionResult GetSizeInventory(int id, string size) - { - var item = InventoryService.GetInventory().FirstOrDefault(i => i.ProductId == id); - - if (item == null) - { - return NotFound("Product not found"); - } - - if (!item.SizeInventory.TryGetValue(size.ToUpper(), out var count)) - { - return NotFound($"Size {size} not found for product {id}"); - } - - return Ok(new SizeInventoryResponse - { - ProductId = id, - ProductName = item.ProductName, - Size = size.ToUpper(), - Count = count - }); - } - - /// - /// Gets all available sizes - /// - /// A list of available sizes - [HttpGet("sizes")] - [ProducesResponseType(typeof(IEnumerable), 200)] - public ActionResult> GetSizes() - { - return Ok(InventoryService.GetSizes()); - } - } /// - /// Represents the response for a size inventory query - /// - public class SizeInventoryResponse - { - /// - /// The product ID - /// - public int ProductId { get; set; } - - /// - /// The product name - /// - public required string ProductName { get; set; } - - /// - /// The size being queried (e.g., XS, S, M, L, XL, XXL, XXXL) - /// - public required string Size { get; set; } - - /// - /// The inventory count for the specified product and size - /// - public int Count { get; set; } - } -} From ab0dcba0a91b97afa9e00b6d1ba4436b559f2ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:17:13 +0200 Subject: [PATCH 7/9] Remove Inventory model and associated logic --- src/webapp/Models/Inventory.cs | 108 --------------------------------- 1 file changed, 108 deletions(-) delete mode 100644 src/webapp/Models/Inventory.cs diff --git a/src/webapp/Models/Inventory.cs b/src/webapp/Models/Inventory.cs deleted file mode 100644 index df99034..0000000 --- a/src/webapp/Models/Inventory.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.Collections.Generic; - -namespace dotnetfashionassistant.Models -{ public class InventoryItem - { - public int ProductId { get; set; } - public required string ProductName { get; set; } - public Dictionary SizeInventory { get; set; } - public decimal Price { get; set; } - - public InventoryItem() - { - SizeInventory = new Dictionary(); - Price = 29.99m; // Default price if not specified - } - } - - public static class InventoryService - { - private static readonly List Sizes = new List { "XS", "S", "M", "L", "XL", "XXL", "XXXL" }; - - public static List GetInventory() - { - // Create dummy inventory data - var inventory = new List(); - // Navy Formal Blazer - var blazer = new InventoryItem - { - ProductId = 3, - ProductName = "Navy Single-Breasted Slim Fit Formal Blazer", - Price = 89.99m, - SizeInventory = new Dictionary - { - { "XS", 0 }, - { "S", 0 }, - { "M", 0 }, - { "L", 0 }, - { "XL", 0 }, - { "XXL", 0 }, - { "XXXL", 0 } - } - }; - // White & Navy Blue Shirt - var whiteNavyShirt = new InventoryItem - { - ProductId = 111, - ProductName = "White & Navy Blue Slim Fit Printed Casual Shirt", - Price = 34.99m, - SizeInventory = new Dictionary - { - { "XS", 8 }, - { "S", 15 }, - { "M", 0 }, - { "L", 18 }, - { "XL", 12 }, - { "XXL", 0 }, - { "XXXL", 4 } - } - }; - // Red Checked Shirt - var redShirt = new InventoryItem - { - ProductId = 116, - ProductName = "Red Slim Fit Checked Casual Shirt", - Price = 39.99m, - SizeInventory = new Dictionary - { - { "XS", 10 }, - { "S", 18 }, - { "M", 22 }, - { "L", 16 }, - { "XL", 14 }, - { "XXL", 7 }, - { "XXXL", 5 } - } - }; - // Navy Blue Denim Jacket - var denimJacket = new InventoryItem - { - ProductId = 10, - ProductName = "Navy Blue Washed Denim Jacket", - Price = 59.99m, - SizeInventory = new Dictionary - { - { "XS", 6 }, - { "S", 14 }, - { "M", 19 }, - { "L", 17 }, - { "XL", 11 }, - { "XXL", 9 }, - { "XXXL", 4 } - } - }; - - inventory.Add(blazer); - inventory.Add(whiteNavyShirt); - inventory.Add(redShirt); - inventory.Add(denimJacket); - - return inventory; - } - - public static List GetSizes() - { - return Sizes; - } - } -} From 7c77f65bb0e33e83bf9726a60ec87fc09c6f21df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:17:30 +0200 Subject: [PATCH 8/9] Remove ShoppingCart model and associated logic --- src/webapp/Models/ShoppingCart.cs | 118 ------------------------------ 1 file changed, 118 deletions(-) delete mode 100644 src/webapp/Models/ShoppingCart.cs diff --git a/src/webapp/Models/ShoppingCart.cs b/src/webapp/Models/ShoppingCart.cs deleted file mode 100644 index 4823aa4..0000000 --- a/src/webapp/Models/ShoppingCart.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace dotnetfashionassistant.Models -{ - public class CartSummary - { - public List Items { get; set; } = new(); - public decimal TotalCost { get; set; } - } - - public class CartItem - { - public int ProductId { get; set; } - public required string ProductName { get; set; } - public required string Size { get; set; } - public int Quantity { get; set; } - public decimal Price { get; set; } - } public static class CartService - { - // In-memory cart storage - in a real application, this would use session state or a database - private static readonly List Cart = new(); - - /// - /// Gets all items currently in the cart - /// - public static List GetCart() - { - return Cart; - } - - /// - /// Gets the cart summary including items and total cost - /// - /// A CartSummary containing items and total cost - public static CartSummary GetCartSummary() - { - decimal totalCost = Cart.Sum(item => item.Quantity * item.Price); - - return new CartSummary - { - Items = Cart, - TotalCost = totalCost - }; - }/// - /// Adds an item to the cart or increases quantity if it already exists - /// - public static void AddToCart(int productId, string productName, string size, int quantity, decimal price) - { - // Check if the item already exists in the cart with the same product ID and size - var existingItem = Cart.FirstOrDefault(item => item.ProductId == productId && item.Size == size); - - if (existingItem != null) - { - // If item exists, just update the quantity - existingItem.Quantity += quantity; - } - else - { - // Add new item to the cart - Cart.Add(new CartItem - { - ProductId = productId, - ProductName = productName, - Size = size, - Quantity = quantity, - Price = price - }); - } - } - - /// - /// Updates the quantity of an item in the cart - /// - public static bool UpdateCartItemQuantity(int productId, string size, int quantity) - { - var existingItem = Cart.FirstOrDefault(item => item.ProductId == productId && item.Size == size); - - if (existingItem == null) - { - return false; - } - - if (quantity <= 0) - { - // If quantity is zero or negative, remove the item - return RemoveFromCart(productId, size); - } - - existingItem.Quantity = quantity; - return true; - } - - /// - /// Removes an item from the cart - /// - public static bool RemoveFromCart(int productId, string size) - { - var existingItem = Cart.FirstOrDefault(item => item.ProductId == productId && item.Size == size); - - if (existingItem == null) - { - return false; - } - - Cart.Remove(existingItem); - return true; - } - - /// - /// Clears all items from the cart - /// - public static void ClearCart() - { - Cart.Clear(); - } - } -} From 1c8bf7917ddcde8846f2707f4b1b6ba44d77d36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duygu=20Do=C4=9Fan?= Date: Thu, 24 Jul 2025 11:17:35 +0200 Subject: [PATCH 9/9] Add obungilogo.png image asset --- src/webapp/wwwroot/images/obungilogo.png | Bin 0 -> 6444 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/webapp/wwwroot/images/obungilogo.png diff --git a/src/webapp/wwwroot/images/obungilogo.png b/src/webapp/wwwroot/images/obungilogo.png new file mode 100644 index 0000000000000000000000000000000000000000..659f74e3b580bca1f1b65661d47756ab2b9d5187 GIT binary patch literal 6444 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 Odfe%CaWdar0sI%)3O#uM literal 0 HcmV?d00001