diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/AdminSettings.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/AdminSettings.razor
index 5ba2261f..20b44918 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/AdminSettings.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/AdminSettings.razor
@@ -80,11 +80,12 @@
@foreach (var svc in _services)
{
+
+
@svc.Name
Online
-
@svc
}
@@ -202,7 +203,22 @@
private string _tab = "general";
private int _shopCount = 0;
- private readonly string[] _services = { "API Gateway", "IAM Service", "Merchant Service", "Catalog Service", "Order Service" };
+ // EN: Service list matching actual deployed Docker containers
+ // VI: Danh sách dịch vụ khớp với Docker containers thực tế
+ private readonly (string Name, string Icon)[] _services = new[]
+ {
+ ("IAM Service", "shield"),
+ ("Merchant Service", "store"),
+ ("Catalog Service", "package"),
+ ("Order Service", "shopping-bag"),
+ ("Inventory Service", "warehouse"),
+ ("Wallet Service", "wallet"),
+ ("Membership Service", "users"),
+ ("Promotion Service", "tag"),
+ ("Booking Service", "calendar"),
+ ("F&B Engine", "utensils"),
+ ("Storage Service", "hard-drive"),
+ };
protected override async Task OnInitializedAsync()
{
@@ -211,7 +227,11 @@
var shops = await DataService.GetShopsAsync();
_shopCount = shops.Count;
}
- catch { _shopCount = 0; }
+ catch (Exception ex)
+ {
+ _shopCount = 0;
+ Console.Error.WriteLine($"[AdminSettings] Error loading shop count: {ex.Message}");
+ }
}
private record NotifSetting(string Label, string Desc, bool Enabled);
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopOverview.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopOverview.razor
index 4cb82650..6f698324 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopOverview.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopOverview.razor
@@ -161,10 +161,33 @@
Đơn gần nhất
-
-
-
Chưa có đơn hàng nào
-
+
+ @if (_orders.Any())
+ {
+
+ @foreach (var o in _orders.Take(5))
+ {
+
+
+ @o.Id.ToString()[..8]
+ @o.CreatedAt.ToString("dd/MM HH:mm")
+
+
+ @(o.Status ?? "—")
+ @FormatVND(o.TotalAmount)
+
+
+ }
+
+ }
+ else
+ {
+
+
+
Chưa có đơn hàng nào
+
+ }
+
@@ -235,21 +258,8 @@
private static string FormatVND(decimal val) => val.ToString("N0") + " ₫";
- private static string GetStatusBadgeClass(string? status) => status?.ToLowerInvariant() switch
- {
- "published" or "active" => "online",
- "draft" or "setup" => "setup",
- "inactive" or "paused" => "paused",
- _ => "setup"
- };
+ private static string GetStatusBadgeClass(string? status) => ShopVerticalHelper.GetStatusBadgeClass(status);
- private static string GetStatusLabel(string? status) => status?.ToLowerInvariant() switch
- {
- "published" or "active" => "Đang mở",
- "draft" or "setup" => "Thiết lập",
- "inactive" or "paused" => "Tạm dừng",
- "closed" => "Đã đóng",
- _ => status ?? "—"
- };
+ private static string GetStatusLabel(string? status) => ShopVerticalHelper.GetStatusLabel(status);
}
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor
index e2ea8f0e..82c37915 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor
@@ -54,7 +54,7 @@
case "products":
@if (!_products.Any())
{
- @RenderEmpty("coffee", "#F59E0B", "Chưa có sản phẩm", "Thêm sản phẩm để bắt đầu bán hàng", "plus-circle", "Thêm sản phẩm")
+ @RenderEmpty("coffee", "#F59E0B", "Chưa có sản phẩm", "Thêm sản phẩm để bắt đầu bán hàng", "plus-circle", "Thêm sản phẩm", $"/admin/shop/{ShopId}/menu")
}
else
{
@@ -78,7 +78,7 @@
case "inventory":
@if (!_inventory.Any())
{
- @RenderEmpty("warehouse", "#3B82F6", "Chưa có tồn kho", "Tồn kho sẽ hiển thị khi có sản phẩm", "package", "Thêm sản phẩm trước")
+ @RenderEmpty("warehouse", "#3B82F6", "Chưa có tồn kho", "Tồn kho sẽ hiển thị khi có sản phẩm", "package", "Thêm sản phẩm trước", $"/admin/shop/{ShopId}/menu")
}
else
{
@@ -117,7 +117,7 @@
@if (!_orders.Any())
{
- @RenderEmpty("bar-chart-3", "#22C55E", "Chưa có dữ liệu tài chính", "Dữ liệu sẽ tự động cập nhật khi có đơn hàng", "monitor", "Mở POS bán hàng")
+ @RenderEmpty("bar-chart-3", "#22C55E", "Chưa có dữ liệu tài chính", "Dữ liệu sẽ tự động cập nhật khi có đơn hàng", "monitor", "Mở POS bán hàng", "/pos")
}
else
{
@@ -149,7 +149,7 @@
case "staff":
@if (!_staff.Any())
{
- @RenderEmpty("users", "#8B5CF6", "Chưa có nhân viên", "Thêm nhân viên để quản lý cửa hàng", "user-plus", "Thêm nhân viên")
+ @RenderEmpty("users", "#8B5CF6", "Chưa có nhân viên", "Thêm nhân viên để quản lý cửa hàng", "user-plus", "Thêm nhân viên", $"/admin/shop/{ShopId}/staff")
}
else
{
@@ -184,7 +184,7 @@
case "customers":
@if (!_members.Any())
{
- @RenderEmpty("heart", "#EF4444", "Chưa có khách hàng", "Khách hàng sẽ hiển thị khi có giao dịch", "monitor", "Mở POS bán hàng")
+ @RenderEmpty("heart", "#EF4444", "Chưa có khách hàng", "Khách hàng sẽ hiển thị khi có giao dịch", "monitor", "Mở POS bán hàng", "/pos")
}
else
{
@@ -339,8 +339,8 @@
private static string FormatVND(decimal val) => val.ToString("N0") + " ₫";
- // EN: Reusable empty state renderer with optional CTA / VI: Renderer trạng thái trống tái sử dụng với CTA tùy chọn
- private RenderFragment RenderEmpty(string icon, string color, string title, string desc, string? ctaIcon = null, string? ctaLabel = null) => __builder =>
+ // EN: Reusable empty state renderer with dynamic CTA href / VI: Renderer trạng thái trống với CTA href động
+ private RenderFragment RenderEmpty(string icon, string color, string title, string desc, string? ctaIcon = null, string? ctaLabel = null, string? ctaHref = null) => __builder =>
{
@@ -350,7 +350,7 @@
@desc
@if (ctaIcon != null && ctaLabel != null)
{
-
+
@ctaLabel
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Store/StoreList.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Store/StoreList.razor
index f062506b..d7153e58 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Store/StoreList.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Store/StoreList.razor
@@ -37,22 +37,38 @@
@* ═══ STORE LIST ═══ *@
- @if (IsLoading)
+ @if (!string.IsNullOrEmpty(_errorMessage))
+ {
+
+
+
+
+
+
Lỗi tải dữ liệu
+
@_errorMessage
+
+
+
+ }
+ else if (IsLoading)
{
@@ -96,43 +112,44 @@
{
@foreach (var shop in FilteredShops)
{
- var isPaused = IsPaused(shop.Status);
+ var isPaused = ShopVerticalHelper.IsPaused(shop.Status);
+ var stats = GetStatsForShop(shop.Id);
NavigateTo($"shop/{shop.Id}/overview"))">
-
-
+
+
@shop.Name
-
+
- @GetStatusLabel(shop.Status)
+ @ShopVerticalHelper.GetStatusLabel(shop.Status)
-
@(shop.Category ?? "—") • @(shop.Slug)
+
@ShopVerticalHelper.GetLabel(shop.Category) • @(shop.Slug)
-
--
+
@FormatRevenue(stats.Revenue)
Doanh thu
-
--
+
@stats.OrderCount
Đơn hàng
-
--
+
@stats.StaffCount
Nhân viên
-
--
+
@stats.ProductCount
Sản phẩm
- @if (IsSetup(shop.Status))
+ @if (ShopVerticalHelper.IsSetup(shop.Status))
{