This commit is contained in:
@@ -1,10 +1,26 @@
|
||||
namespace MidrandBookshop.Components.Pages;
|
||||
using LiteCharms.Features.Hasher;
|
||||
using LiteCharms.Features.MidrandBooks.Customers;
|
||||
using LiteCharms.Features.MidrandBooks.Customers.Models;
|
||||
using LiteCharms.Features.MidrandBooks.Orders;
|
||||
using LiteCharms.Features.MidrandBooks.Payments;
|
||||
using LiteCharms.Features.MidrandBooks.Products;
|
||||
|
||||
namespace MidrandBookshop.Components.Pages;
|
||||
|
||||
public partial class Account : ComponentBase
|
||||
{
|
||||
[Inject] private AuthenticationStateProvider AuthStateProvider { get; set; } = default!;
|
||||
[Inject] private CustomerService CustomerService { get; set; } = default!;
|
||||
[Inject] private OrderService OrderService { get; set; } = default!;
|
||||
[Inject] private PaymentService PaymentService { get; set; } = default!;
|
||||
[Inject] private ProductService ProductService { get; set; } = default!;
|
||||
[Inject] private HashService HashService { get; set; } = default!;
|
||||
[Inject] private CancellationToken CancellationToken { get; set; } = default!;
|
||||
[Inject] private IToastService ToasterService { get; set; } = default!;
|
||||
|
||||
private ClaimsPrincipal? User { get; set; }
|
||||
private Customer? customer;
|
||||
|
||||
private bool showAddForm = false;
|
||||
private AddressItem? editingAddress = null;
|
||||
private string newAddressName = "";
|
||||
@@ -13,17 +29,7 @@ public partial class Account : ComponentBase
|
||||
private string newPostalCode = "";
|
||||
private bool isBilling, isShipping;
|
||||
|
||||
private List<OrderItem> orderHistory = new()
|
||||
{
|
||||
// 1. Delivered + Paid (Green Mapping Rules)
|
||||
new OrderItem { OrderId = "#MB-2026-8712", ProductId = "mastering-css-isolation", ProductTitle = "Mastering CSS Isolation in Modern .NET Web Applications Architecture", OrderDate = new DateTime(2026, 4, 14), ShippingAddressName = "Midrand Warehouse", Status = "Delivered", PaymentStatus = "Paid", Total = 890.00 },
|
||||
|
||||
// 2. Shipped + Paid (Amber Logistics + Green Payment Rules)
|
||||
new OrderItem { OrderId = "#MB-2026-9481", ProductId = "introduction-to-blazor", ProductTitle = "Introduction to Blazor WebAssembly Framework Development", OrderDate = new DateTime(2026, 5, 20), ShippingAddressName = "Home Address", Status = "Shipped", PaymentStatus = "Paid", Total = 720.00 },
|
||||
|
||||
// 3. Unshipped + Abandoned/Unpaid (Muted Grey / Soft Red Rules — Hides Invoice Button)
|
||||
new OrderItem { OrderId = "#MB-2026-1034", ProductId = "csharp-functional-paradigms", ProductTitle = "Advanced Functional Architecture & Monadic Paradigms in Modern C#", OrderDate = new DateTime(2026, 6, 11), ShippingAddressName = "Home Address", Status = "Unshipped", PaymentStatus = "Unpaid", Total = 650.00 }
|
||||
};
|
||||
private List<OrderItem> orderHistory = [];
|
||||
|
||||
private List<AddressItem> savedAddresses = new()
|
||||
{
|
||||
@@ -35,64 +41,138 @@ public partial class Account : ComponentBase
|
||||
{
|
||||
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
||||
User = authState?.User;
|
||||
|
||||
var customerFetch = await CustomerService.GetCustomerAsync(User?.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)!.Value!, CancellationToken);
|
||||
|
||||
if (customerFetch.IsSuccess)
|
||||
customer = customerFetch.Value;
|
||||
|
||||
await LoadOrdersAsync();
|
||||
}
|
||||
|
||||
private async Task LoadOrdersAsync()
|
||||
{
|
||||
if (customer is null)
|
||||
{
|
||||
ToasterService.ShowError("There was a problem loading your details, please contact the administrator");
|
||||
return;
|
||||
}
|
||||
|
||||
var ordersFetch = await OrderService.GetOrdersByCustomerAsync(customer.Id, CancellationToken);
|
||||
|
||||
if (ordersFetch.IsFailed)
|
||||
{
|
||||
ToasterService.ShowWarning("No orders were found");
|
||||
return;
|
||||
}
|
||||
|
||||
orderHistory.Clear();
|
||||
|
||||
foreach (var order in ordersFetch.Value)
|
||||
{
|
||||
var paymentFetch = await PaymentService.GetOrderPaymentAsync(order.Id, CancellationToken);
|
||||
|
||||
var orderEntry = new OrderItem
|
||||
{
|
||||
OrderDate = order.CreatedAt,
|
||||
OrderId = HashService.HashEncodeLongId(order.Id).Value,
|
||||
Status = order.Status.ToString(),
|
||||
PaymentStatus = paymentFetch.IsSuccess ? paymentFetch.Value.Status.ToString() : "NotPaid",
|
||||
ShippingStatus = "Processing",
|
||||
ShippingAddressName = "TBA",
|
||||
Total = order.Total,
|
||||
InvoiceUrl = order.InvoiceUrl!,
|
||||
};
|
||||
|
||||
var orderItemsFetch = await OrderService.GetOrderItemsAsync(order.Id, CancellationToken);
|
||||
if (orderItemsFetch.IsFailed) continue;
|
||||
|
||||
foreach (var item in orderItemsFetch.Value)
|
||||
{
|
||||
var productPriceFetch = await ProductService.GetProductPriceAsync(item.ProductPriceId, CancellationToken);
|
||||
if (productPriceFetch.IsFailed) continue;
|
||||
|
||||
var productFetch = await ProductService.GetProductAsync(productPriceFetch.Value.ProductId, CancellationToken);
|
||||
|
||||
var itemEntry = new PurchasedBook
|
||||
{
|
||||
Quantity = item.Quantity,
|
||||
PriceUnitPrice = productPriceFetch.Value.Amount,
|
||||
CoverImageUrl = productFetch.Value.ImageUrl!,
|
||||
Title = productFetch.Value.Name!,
|
||||
};
|
||||
orderEntry.PurchasedBooks.Add(itemEntry);
|
||||
}
|
||||
orderHistory.Add(orderEntry);
|
||||
}
|
||||
}
|
||||
|
||||
private void DownloadInvoice(string orderId)
|
||||
{
|
||||
Navigation.NavigateTo($"/api/invoices/download/{orderId.Replace("#", "")}", forceLoad: true);
|
||||
var order = orderHistory.FirstOrDefault(o => o.OrderId == orderId)!;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(order.InvoiceUrl))
|
||||
ToasterService.ShowWarning("Your invoice is currently not availabe for viewing");
|
||||
else
|
||||
Navigation.NavigateTo(orderHistory.FirstOrDefault(o => o.OrderId == orderId)!.InvoiceUrl, forceLoad: true);
|
||||
}
|
||||
|
||||
private string GetStatusClass(string status) => status?.ToLower() switch
|
||||
// Badge Style 1: Core Order Lifecycle Status Mapping
|
||||
private string GetOrderStatusClass(string? status)
|
||||
{
|
||||
"delivered" => "status-delivered", // Green
|
||||
"shipped" => "status-shipped", // Amber
|
||||
_ => "status-processing" // Muted Architectural Dark Grey
|
||||
};
|
||||
|
||||
private string GetPaymentStatusClass(string paymentStatus) => paymentStatus?.ToLower() switch
|
||||
{
|
||||
"paid" => "pay-paid", // Green
|
||||
"refunded" => "pay-refunded", // Grey
|
||||
_ => "pay-pending" // Red Alert Tone
|
||||
};
|
||||
|
||||
private void EditAddress(AddressItem addr)
|
||||
{
|
||||
editingAddress = addr;
|
||||
showAddForm = false;
|
||||
newAddressName = addr.Name;
|
||||
newStreetAddress = addr.Street;
|
||||
newCity = addr.City;
|
||||
newPostalCode = addr.PostalCode;
|
||||
isBilling = addr.IsBilling;
|
||||
isShipping = addr.IsShipping;
|
||||
return status?.ToLower() switch
|
||||
{
|
||||
"completed" => "order-completed",
|
||||
"processing" => "order-processing",
|
||||
"cancelled" => "order-cancelled",
|
||||
_ => "order-hold"
|
||||
};
|
||||
}
|
||||
|
||||
private void CancelAddressActions()
|
||||
// Badge Style 2: Financial Payment Status Mapping
|
||||
private string GetPaymentStatusClass(string? status)
|
||||
{
|
||||
showAddForm = false;
|
||||
editingAddress = null;
|
||||
ClearFormFields();
|
||||
return status?.ToLower() switch
|
||||
{
|
||||
"paid" => "pay-paid",
|
||||
"refunded" => "pay-refunded",
|
||||
_ => "pay-pending"
|
||||
};
|
||||
}
|
||||
|
||||
private void ClearFormFields()
|
||||
// Badge Style 3: Logistics Shipment Status Mapping
|
||||
private string GetShippingStatusClass(string? status)
|
||||
{
|
||||
newAddressName = "";
|
||||
newStreetAddress = "";
|
||||
newCity = "";
|
||||
newPostalCode = "";
|
||||
isBilling = false;
|
||||
isShipping = false;
|
||||
return status?.ToLower() switch
|
||||
{
|
||||
"delivered" => "status-delivered",
|
||||
"shipped" => "status-shipped",
|
||||
_ => "status-processing"
|
||||
};
|
||||
}
|
||||
|
||||
// Implemented to resolve UI registration click events
|
||||
private void SaveAddress()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(newAddressName) || string.IsNullOrWhiteSpace(newStreetAddress)) return;
|
||||
if (string.IsNullOrWhiteSpace(newAddressName) || string.IsNullOrWhiteSpace(newStreetAddress))
|
||||
{
|
||||
ToasterService.ShowWarning("Please fill in the required fields.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (editingAddress == null)
|
||||
if (editingAddress != null)
|
||||
{
|
||||
editingAddress.Name = newAddressName;
|
||||
editingAddress.Street = newStreetAddress;
|
||||
editingAddress.City = newCity;
|
||||
editingAddress.PostalCode = newPostalCode;
|
||||
editingAddress.IsBilling = isBilling;
|
||||
editingAddress.IsShipping = isShipping;
|
||||
}
|
||||
else
|
||||
{
|
||||
var nextId = savedAddresses.Any() ? savedAddresses.Max(a => a.Id) + 1 : 1;
|
||||
var newAddr = new AddressItem
|
||||
savedAddresses.Add(new AddressItem
|
||||
{
|
||||
Id = nextId,
|
||||
Name = newAddressName,
|
||||
@@ -102,26 +182,39 @@ public partial class Account : ComponentBase
|
||||
IsBilling = isBilling,
|
||||
IsShipping = isShipping,
|
||||
IsPrimary = !savedAddresses.Any()
|
||||
};
|
||||
savedAddresses.Add(newAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
var target = savedAddresses.FirstOrDefault(a => a.Id == editingAddress.Id);
|
||||
if (target != null)
|
||||
{
|
||||
target.Name = newAddressName;
|
||||
target.Street = newStreetAddress;
|
||||
target.City = newCity;
|
||||
target.PostalCode = newPostalCode;
|
||||
target.IsBilling = isBilling;
|
||||
target.IsShipping = isShipping;
|
||||
}
|
||||
editingAddress = null;
|
||||
});
|
||||
}
|
||||
|
||||
CancelAddressActions();
|
||||
}
|
||||
|
||||
private void CancelAddressActions()
|
||||
{
|
||||
showAddForm = false;
|
||||
editingAddress = null;
|
||||
ResetFormFields();
|
||||
}
|
||||
|
||||
private void ResetFormFields()
|
||||
{
|
||||
newAddressName = "";
|
||||
newStreetAddress = "";
|
||||
newCity = "";
|
||||
newPostalCode = "";
|
||||
isBilling = false;
|
||||
isShipping = false;
|
||||
}
|
||||
|
||||
private void EditAddress(AddressItem addr)
|
||||
{
|
||||
editingAddress = addr;
|
||||
newAddressName = addr.Name;
|
||||
newStreetAddress = addr.Street;
|
||||
newCity = addr.City;
|
||||
newPostalCode = addr.PostalCode;
|
||||
isBilling = addr.IsBilling;
|
||||
isShipping = addr.IsShipping;
|
||||
showAddForm = false;
|
||||
ClearFormFields();
|
||||
}
|
||||
|
||||
private void DeleteAddress(AddressItem addr)
|
||||
@@ -161,12 +254,21 @@ public partial class Account : ComponentBase
|
||||
public class OrderItem
|
||||
{
|
||||
public string OrderId { get; set; } = "";
|
||||
public string ProductId { get; set; } = "";
|
||||
public string ProductTitle { get; set; } = "";
|
||||
public DateTime OrderDate { get; set; }
|
||||
public string ShippingAddressName { get; set; } = "";
|
||||
public string Status { get; set; } = "";
|
||||
public string PaymentStatus { get; set; } = "Pending";
|
||||
public double Total { get; set; }
|
||||
public string PaymentStatus { get; set; } = "";
|
||||
public string ShippingStatus { get; set; } = "";
|
||||
public string InvoiceUrl { get; set; } = "";
|
||||
public decimal Total { get; set; }
|
||||
public List<PurchasedBook> PurchasedBooks { get; set; } = new();
|
||||
}
|
||||
|
||||
public class PurchasedBook
|
||||
{
|
||||
public string Title { get; set; } = "";
|
||||
public string CoverImageUrl { get; set; } = "";
|
||||
public int Quantity { get; set; }
|
||||
public decimal PriceUnitPrice { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user