From 89bd8232a8395faf53715ceae547aa4392796b1c Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Wed, 4 Mar 2026 11:35:41 +0700 Subject: [PATCH] feat: Implement Blazor lifecycle improvements, enhance navigation with browser history, and update EF Core entity configurations for backing fields --- .../Pages/Pos/Cafe/CafeDesktop.razor | 4 +- .../Pages/Pos/Cafe/CafeMobile.razor | 12 +++-- .../Pages/Pos/Cafe/CafeTablet.razor | 12 +++-- .../Pos/Cafe/Workflow/MenuManagement.razor | 2 + .../Pages/Pos/Karaoke/KaraokeDesktop.razor | 2 + .../Pages/Pos/Karaoke/KaraokeMobile.razor | 2 + .../Pages/Pos/Karaoke/KaraokeTablet.razor | 2 + .../Pages/Pos/Karaoke/Workflow/OrderFnb.razor | 2 + .../Pages/Pos/Karaoke/Workflow/RoomMap.razor | 2 + .../Pos/Karaoke/Workflow/RoomSelect.razor | 2 + .../Pos/Karaoke/Workflow/RoomSession.razor | 2 + .../Pos/Karaoke/Workflow/ServiceDisplay.razor | 2 + .../Pos/Restaurant/RestaurantDesktop.razor | 2 + .../Pos/Restaurant/RestaurantMobile.razor | 2 + .../Pos/Restaurant/RestaurantTablet.razor | 2 + .../Restaurant/Workflow/KitchenDisplay.razor | 2 + .../Restaurant/Workflow/OrderHistory.razor | 2 + .../Workflow/RestaurantMenuManagement.razor | 2 + .../Pos/Restaurant/Workflow/TableMap.razor | 2 + .../Restaurant/Workflow/TableMergeSplit.razor | 2 + .../Pos/Restaurant/Workflow/TableSelect.razor | 2 + .../Pos/Restaurant/Workflow/WaiterPad.razor | 2 + .../Pages/Pos/Retail/RetailDesktop.razor | 4 +- .../Pages/Pos/Retail/RetailMobile.razor | 4 +- .../Pages/Pos/Retail/RetailTablet.razor | 4 +- .../Pos/Retail/Workflow/ProductSearch.razor | 2 + .../Pos/Shared/Dialogs/OrderCancel.razor | 9 ++-- .../Pages/Pos/Shared/Dialogs/OrderEdit.razor | 7 +-- .../Pages/Pos/Shared/Dialogs/PriceCheck.razor | 5 +- .../Pages/Pos/Shared/Dialogs/SplitBill.razor | 7 +-- .../Pages/Pos/Shared/Dialogs/StockIn.razor | 7 +-- .../Pages/Pos/Shared/Dialogs/StockOut.razor | 7 +-- .../Pos/Shared/Dialogs/StockTransfer.razor | 7 +-- .../Pages/Pos/Shared/Dialogs/VoidRefund.razor | 9 ++-- .../Pos/Shared/Operations/ClockInOut.razor | 19 ++++++-- .../Pos/Shared/Operations/PendingOrders.razor | 3 +- .../Pos/Shared/Operations/QuickSale.razor | 8 ++-- .../Shared/Operations/ShiftManagement.razor | 3 +- .../Pos/Shared/Payment/MethodSelect.razor | 3 +- .../Pos/Shared/Payment/PaymentSuccess.razor | 3 +- .../Pages/Pos/Shared/Payment/QrPayment.razor | 40 ++++++++++++++-- .../Pages/Pos/Shared/Payment/Receipt.razor | 19 ++++---- .../Pages/Pos/Spa/SpaDesktop.razor | 2 + .../Pages/Pos/Spa/SpaMobile.razor | 2 + .../Pages/Pos/Spa/SpaTablet.razor | 2 + .../Pos/Spa/Workflow/AppointmentBook.razor | 2 + .../Pos/Spa/Workflow/ServicePackage.razor | 2 + .../Controllers/OrderController.cs | 2 +- .../AppointmentEntityTypeConfiguration.cs | 47 +++++++++---------- .../ResourceEntityTypeConfiguration.cs | 29 +++++------- .../StaffScheduleEntityTypeConfiguration.cs | 27 +++++------ .../Controllers/CategoriesController.cs | 21 +++++++++ .../Controllers/ProductsController.cs | 27 +++++++++++ .../TableEntityTypeConfiguration.cs | 39 ++++++++------- .../Application/DTOs/OrderDtos.cs | 23 ++++----- .../Application/Queries/GetOrderStatsQuery.cs | 4 +- .../Queries/GetPosDashboardQuery.cs | 8 ++-- 57 files changed, 317 insertions(+), 156 deletions(-) diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeDesktop.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeDesktop.razor index c25f9fea..0fe33a2a 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeDesktop.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeDesktop.razor @@ -466,9 +466,7 @@ protected override async Task OnInitializedAsync() { - // EN: Restore auth session from localStorage so API calls have JWT token - // VI: Khôi phục session auth từ localStorage để API calls có JWT token - await AuthService.TryRestoreSessionAsync(); + await base.OnInitializedAsync(); try { diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeMobile.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeMobile.razor index c2aeec2d..126580a8 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeMobile.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeMobile.razor @@ -129,6 +129,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var productsTask = DataService.GetProductsAsync(ShopId); @@ -139,6 +141,7 @@ var apiCategories = await categoriesTask; _products = apiProducts.Select(p => new Product( + p.Id, p.Name, p.Price, p.Category ?? "Khác" @@ -165,9 +168,9 @@ private void AddToCart(Product product) { - var existing = _cartItems.FirstOrDefault(i => i.Name == product.Name); + var existing = _cartItems.FirstOrDefault(i => i.ProductId == product.Id); if (existing != null) existing.Qty++; - else _cartItems.Add(new CartItem(product.Name, product.Price)); + else _cartItems.Add(new CartItem(product.Id, product.Name, product.Price)); } private void ChangeQty(CartItem item, int delta) @@ -178,9 +181,10 @@ private void Checkout() => NavigateTo("cafe/order-customize"); - private record Product(string Name, decimal Price, string Category); - private class CartItem(string name, decimal price) + private record Product(Guid Id, string Name, decimal Price, string Category); + private class CartItem(Guid productId, string name, decimal price) { + public Guid ProductId { get; set; } = productId; public string Name { get; set; } = name; public decimal Price { get; set; } = price; public int Qty { get; set; } = 1; diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeTablet.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeTablet.razor index 4833afbe..5d580985 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeTablet.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/CafeTablet.razor @@ -108,6 +108,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var productsTask = DataService.GetProductsAsync(ShopId); @@ -118,6 +120,7 @@ var apiCategories = await categoriesTask; _products = apiProducts.Select(p => new Product( + p.Id, p.Name, p.Price, p.Category ?? "Khác" @@ -144,9 +147,9 @@ private void AddToCart(Product product) { - var existing = _cartItems.FirstOrDefault(i => i.Name == product.Name); + var existing = _cartItems.FirstOrDefault(i => i.ProductId == product.Id); if (existing != null) existing.Qty++; - else _cartItems.Add(new CartItem(product.Name, product.Price)); + else _cartItems.Add(new CartItem(product.Id, product.Name, product.Price)); } private void ChangeQty(CartItem item, int delta) @@ -157,9 +160,10 @@ private void Checkout() => NavigateTo("cafe/order-customize"); - private record Product(string Name, decimal Price, string Category); - private class CartItem(string name, decimal price) + private record Product(Guid Id, string Name, decimal Price, string Category); + private class CartItem(Guid productId, string name, decimal price) { + public Guid ProductId { get; set; } = productId; public string Name { get; set; } = name; public decimal Price { get; set; } = price; public int Qty { get; set; } = 1; diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/Workflow/MenuManagement.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/Workflow/MenuManagement.razor index df24858f..3e177214 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/Workflow/MenuManagement.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Cafe/Workflow/MenuManagement.razor @@ -128,6 +128,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var productsTask = DataService.GetProductsAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeDesktop.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeDesktop.razor index 4d4ef3a0..19613efb 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeDesktop.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeDesktop.razor @@ -177,6 +177,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var tables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeMobile.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeMobile.razor index 51cd6d04..ab2c03eb 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeMobile.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeMobile.razor @@ -115,6 +115,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var tables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeTablet.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeTablet.razor index aff83a10..6f8c5c9d 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeTablet.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/KaraokeTablet.razor @@ -164,6 +164,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var tables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/OrderFnb.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/OrderFnb.razor index 88899b29..75cb0a7a 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/OrderFnb.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/OrderFnb.razor @@ -133,6 +133,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var productsTask = DataService.GetProductsAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomMap.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomMap.razor index 74468cc2..9f1dcdd3 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomMap.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomMap.razor @@ -124,6 +124,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var tables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSelect.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSelect.razor index 4191949a..2b682eed 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSelect.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSelect.razor @@ -185,6 +185,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var tables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSession.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSession.razor index 269b0a66..6b750043 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSession.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/RoomSession.razor @@ -175,6 +175,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var products = await DataService.GetProductsAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/ServiceDisplay.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/ServiceDisplay.razor index a948cf4e..74850661 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/ServiceDisplay.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Karaoke/Workflow/ServiceDisplay.razor @@ -166,6 +166,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var tables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantDesktop.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantDesktop.razor index 7e221b72..53c3021a 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantDesktop.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantDesktop.razor @@ -129,6 +129,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiTables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantMobile.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantMobile.razor index b1f455e4..31953449 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantMobile.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantMobile.razor @@ -109,6 +109,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiTables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantTablet.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantTablet.razor index 901bc17d..ecc762a9 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantTablet.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/RestaurantTablet.razor @@ -128,6 +128,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiTables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/KitchenDisplay.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/KitchenDisplay.razor index ab2049b0..e2b50cdc 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/KitchenDisplay.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/KitchenDisplay.razor @@ -133,6 +133,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { // EN: Preload tables for reference — kitchen_tickets API not yet available diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/OrderHistory.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/OrderHistory.razor index 271ceec0..e98e078c 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/OrderHistory.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/OrderHistory.razor @@ -142,6 +142,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { // EN: Preload tables for reference — orders API not yet available diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/RestaurantMenuManagement.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/RestaurantMenuManagement.razor index dee3824a..2675a583 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/RestaurantMenuManagement.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/RestaurantMenuManagement.razor @@ -138,6 +138,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var products = await DataService.GetProductsAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMap.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMap.razor index 2f6a70c1..038ff3e2 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMap.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMap.razor @@ -105,6 +105,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiTables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMergeSplit.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMergeSplit.razor index 8ad6828a..1c6fd01a 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMergeSplit.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableMergeSplit.razor @@ -186,6 +186,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiTables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableSelect.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableSelect.razor index ab4d6bb2..279cd832 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableSelect.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/TableSelect.razor @@ -151,6 +151,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiTables = await DataService.GetTablesAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/WaiterPad.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/WaiterPad.razor index 70a37fd1..70b720c6 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/WaiterPad.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Restaurant/Workflow/WaiterPad.razor @@ -121,6 +121,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var products = await DataService.GetProductsAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailDesktop.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailDesktop.razor index 549cf79d..d6dd62f9 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailDesktop.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailDesktop.razor @@ -134,6 +134,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiProducts = await DataService.GetProductsAsync(ShopId); @@ -179,7 +181,7 @@ _barcodeInput = ""; } - private void Checkout() { } + private void Checkout() => NavigateTo("payment-method-select"); private static string GetCategoryIcon(string category) => category switch { diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailMobile.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailMobile.razor index 95ff6af2..d3efb4a0 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailMobile.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailMobile.razor @@ -138,6 +138,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiProducts = await DataService.GetProductsAsync(ShopId); @@ -176,7 +178,7 @@ if (item.Qty <= 0) _cartItems.Remove(item); } - private void Checkout() { } + private void Checkout() => NavigateTo("payment-method-select"); private static string GetCategoryIcon(string category) => category switch { diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailTablet.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailTablet.razor index 7e218a39..af23a8be 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailTablet.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/RetailTablet.razor @@ -132,6 +132,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiProducts = await DataService.GetProductsAsync(ShopId); @@ -170,7 +172,7 @@ if (item.Qty <= 0) _cartItems.Remove(item); } - private void Checkout() { } + private void Checkout() => NavigateTo("payment-method-select"); private static string GetCategoryIcon(string category) => category switch { diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/Workflow/ProductSearch.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/Workflow/ProductSearch.razor index 804491e2..7bed2813 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/Workflow/ProductSearch.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Retail/Workflow/ProductSearch.razor @@ -141,6 +141,8 @@ protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + try { var apiProducts = await DataService.GetProductsAsync(ShopId); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderCancel.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderCancel.razor index bb6f11bb..95502707 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderCancel.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderCancel.razor @@ -6,6 +6,7 @@ @layout PosLayout @inherits PosBase @using WebClientTpos.Client.Services +@inject IJSRuntime JS
Đơn #DH2024-0589
@@ -91,7 +92,7 @@
@@ -132,9 +133,9 @@ new("Nước mía", 20_000, 3), }; - private void CancelOrder() + private async Task CancelOrder() { - NavigateTo(""); + await JS.InvokeVoidAsync("history.back"); } private record CancelItem(string Name, decimal Price, int Qty); diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderEdit.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderEdit.razor index a9f1c992..2a2fc91a 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderEdit.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/OrderEdit.razor @@ -6,6 +6,7 @@ @layout PosLayout @inherits PosBase @using WebClientTpos.Client.Services +@inject IJSRuntime JS
Bàn 5 · 15:20 · Đang phục vụ
@@ -137,7 +138,7 @@
@@ -125,7 +126,7 @@
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/SplitBill.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/SplitBill.razor index d621e6cf..820af16a 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/SplitBill.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Dialogs/SplitBill.razor @@ -6,6 +6,7 @@ @layout PosLayout @inherits PosBase @using WebClientTpos.Client.Services +@inject IJSRuntime JS
Tổng: @FormatPrice(_billTotal) · Bàn 3 · 6 khách
@@ -174,7 +175,7 @@
@@ -138,7 +139,7 @@
@@ -118,7 +119,7 @@
@@ -139,7 +140,7 @@
@@ -147,7 +148,7 @@
Chấm công @@ -32,7 +34,7 @@
-
@_staffName
+
@StaffName
@_staffRole
_clockEntries = new() @@ -105,11 +107,22 @@ new("13:30", "in"), }; + protected override void OnInitialized() + { + _clockTimer = new Timer(_ => + { + _currentTime = DateTime.Now; + InvokeAsync(StateHasChanged); + }, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); + } + private void ToggleClock() { _isClockedIn = !_isClockedIn; _clockEntries.Add(new(DateTime.Now.ToString("HH:mm"), _isClockedIn ? "in" : "out")); } + public void Dispose() => _clockTimer?.Dispose(); + private record ClockEntry(string Time, string Type); } diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/PendingOrders.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/PendingOrders.razor index 2a37c615..2601eb49 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/PendingOrders.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/PendingOrders.razor @@ -7,11 +7,12 @@ @inherits PosBase @using WebClientTpos.Client.Services @inject PosDataService DataService +@inject IJSRuntime JS
@* ═══ HEADER ═══ *@
- Đơn hàng đang chờ diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/QuickSale.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/QuickSale.razor index c7dda4c4..c994e581 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/QuickSale.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Pos/Shared/Operations/QuickSale.razor @@ -6,11 +6,12 @@ @layout PosLayout @inherits PosBase @using WebClientTpos.Client.Services +@inject IJSRuntime JS
@* ═══ HEADER ═══ *@
- Bán nhanh @@ -23,7 +24,7 @@
Số tiền
- @FormatPrice(decimal.Parse(_amountStr == "" ? "0" : _amountStr)) + @FormatPrice(ParsedAmount)
@@ -101,7 +102,7 @@