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 5ef833cb..be890238 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 @@ -214,18 +214,37 @@ // ═══ FINANCE ═══ case "finance": -
+
@FormatVND(_orders.Sum(o => o.TotalAmount))Tổng doanh thu
@_orders.CountĐơn hàng
@FormatVND(_orders.Any() ? _orders.Average(o => o.TotalAmount) : 0)TB/đơn
+
@FormatVND(_wallets.Sum(w => w.Balance))Số dư ví
- @if (!_orders.Any()) + @if (_walletTxns.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", $"/pos/{ShopId}/{_posVertical}") +
+

Giao dịch ví gần đây

+
+ + + + + + @foreach (var t in _walletTxns.Take(15)) + { + + + + + + } +
Mô tảSố tiềnNgày
@(t.Description ?? t.ItemName ?? "—")@(t.Amount >= 0 ? "+" : "")@FormatVND(t.Amount)@t.CreatedAt.ToString("dd/MM HH:mm")
+
+
} - else + @if (_orders.Any()) { -
+

Đơn hàng gần đây

@@ -247,6 +266,10 @@ } + else + { + @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/{ShopId}/{_posVertical}") + } break; // ═══ STAFF ═══ @@ -321,7 +344,7 @@ } break; - // ═══ CUSTOMERS ═══ + // ═══ CUSTOMERS + MEMBERSHIP LEVELS ═══ case "customers": @if (!_members.Any()) { @@ -331,8 +354,35 @@ {
@_members.CountTổng khách hàng
+
@_memberLevels.CountCấp bậc
+
@(_members.Any() ? _members.Max(m => m.TotalExpEarned).ToString("N0") : "0")EXP cao nhất
-
+ @if (_memberLevels.Any()) + { +
+

Cấp bậc thành viên

+
+
+ + + + + + @foreach (var lvl in _memberLevels.OrderBy(l => l.Level)) + { + + + + + + + } +
LevelTênEXP cầnThành viên
@lvl.Level@lvl.Name@lvl.MinExp.ToString("N0") — @lvl.MaxExp.ToString("N0")@lvl.MemberCount
+
+
+ } +
+

Danh sách khách hàng

@@ -608,9 +658,44 @@ @RenderEmpty("clipboard-list", "#A855F7", "Quản lý liệu trình", "Theo dõi liệu trình điều trị dài hạn, ảnh before/after, tiến trình") break; - // ═══ PROMOTIONS ═══ + // ═══ PROMOTIONS (real data) ═══ case "promotions": - @RenderEmpty("tag", "#22C55E", "Quản lý khuyến mãi", "Tạo mã giảm giá, combo, chương trình loyalty — Kết nối Promotion Service", "plus-circle", "Tạo khuyến mãi") + @if (!_promotions.Any()) + { + @RenderEmpty("tag", "#22C55E", "Chưa có khuyến mãi", "Tạo mã giảm giá, combo, chương trình loyalty", "plus-circle", "Tạo khuyến mãi") + } + else + { +
+
@_promotions.CountTổng KM
+
@_promotions.Count(p => p.IsActive)Đang hoạt động
+
@_promotions.Sum(p => p.VoucherCount)Voucher
+
@_promotions.Sum(p => p.RedemptionCount)Đã dùng
+
+
+

Danh sách khuyến mãi

+
+
ID
+ + + + + + + @foreach (var p in _promotions) + { + + + + + + + + } +
TênLoạiGiá trịTrạng tháiThời gian
@p.Name@(p.DiscountType ?? "—")@(p.DiscountType == "Percentage" ? $"{p.DiscountValue}%" : FormatVND(p.DiscountValue ?? 0))@(p.IsActive ? "Active" : "Inactive")@(p.StartDate?.ToString("dd/MM/yy") ?? "—") → @(p.EndDate?.ToString("dd/MM/yy") ?? "∞")
+
+
+ } break; // ═══ SETTINGS ═══ @@ -710,6 +795,13 @@ private string? _staffFormMessage; private bool _staffFormSuccess; private Guid? _merchantId; + // New data: wallets, promotions, member levels, schedules, inv txns + private List _wallets = new(); + private List _walletTxns = new(); + private List _promotions = new(); + private List _memberLevels = new(); + private List _staffSchedules = new(); + private List _invTxns = new(); protected override async Task OnInitializedAsync() => await LoadData(); @@ -764,12 +856,16 @@ break; case "finance": _orders = await DataService.GetOrdersAsync(_shopGuid); + _wallets = await DataService.GetWalletsAsync(); + _walletTxns = await DataService.GetWalletTransactionsAsync(); break; case "staff": _staff = await DataService.GetStaffAsync(); + _staffSchedules = await DataService.GetStaffSchedulesAsync(_shopGuid); break; case "customers": _members = await DataService.GetMembersAsync(); + _memberLevels = await DataService.GetMembershipLevelsAsync(); break; case "tables": case "rooms": @@ -787,6 +883,9 @@ _reportOrders = await DataService.GetOrdersAsync(_shopGuid); _reportProducts = await DataService.GetAllProductsAsync(_shopGuid); break; + case "promotions": + _promotions = await DataService.GetPromotionsAsync(); + break; } } catch (Exception ex)