feat(multi-vertical): P2 — resources real data, treatments enhanced, inv txns
- Resources: real table from booking_service (stats + capacity + status) - Treatments: enhanced UI with Before/After, tái khám, hồ sơ y tế chips - Inventory: transactions loading wired to GetInventoryTransactionsAsync - PosDataService: added GetResourcesAsync for booking resources - LoadData: resources, inventory txns cases added
This commit is contained in:
@@ -650,12 +650,60 @@
|
||||
|
||||
// ═══ RESOURCES (Spa/Beauty — phòng, giường, thiết bị) ═══
|
||||
case "resources":
|
||||
@RenderEmpty("door-open", "#EC4899", "Quản lý tài nguyên", "Phòng, giường, thiết bị — Kết nối với Booking Service", "plus-circle", "Thêm tài nguyên")
|
||||
@if (!_resources.Any())
|
||||
{
|
||||
@RenderEmpty("door-open", "#EC4899", "Chưa có tài nguyên", "Cấu hình phòng, giường, thiết bị cho cửa hàng", "plus-circle", "Thêm tài nguyên")
|
||||
}
|
||||
else
|
||||
{
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:16px;">
|
||||
<div class="admin-stat-card"><div class="admin-stat-card__icon" style="background:rgba(236,72,153,0.1);"><i data-lucide="door-open" style="color:#EC4899;"></i></div><div class="admin-stat-card__content"><span class="admin-stat-card__value">@_resources.Count</span><span class="admin-stat-card__label">Tổng tài nguyên</span></div></div>
|
||||
<div class="admin-stat-card"><div class="admin-stat-card__icon" style="background:rgba(34,197,94,0.1);"><i data-lucide="check-circle" style="color:#22C55E;"></i></div><div class="admin-stat-card__content"><span class="admin-stat-card__value">@_resources.Count(r => r.IsActive)</span><span class="admin-stat-card__label">Đang hoạt động</span></div></div>
|
||||
<div class="admin-stat-card"><div class="admin-stat-card__icon" style="background:rgba(59,130,246,0.1);"><i data-lucide="users" style="color:#3B82F6;"></i></div><div class="admin-stat-card__content"><span class="admin-stat-card__value">@_resources.Sum(r => r.Capacity)</span><span class="admin-stat-card__label">Tổng sức chứa</span></div></div>
|
||||
</div>
|
||||
<div class="admin-panel" style="margin-top:16px;">
|
||||
<div class="admin-panel__header"><h3 class="admin-panel__title">Danh sách tài nguyên</h3></div>
|
||||
<div class="admin-panel__body" style="padding:0;">
|
||||
<table class="admin-table" style="width:100%;"><thead><tr>
|
||||
<th style="padding:12px 16px;text-align:left;font-size:12px;text-transform:uppercase;color:var(--admin-text-tertiary);">Tên</th>
|
||||
<th style="padding:12px 16px;text-align:center;font-size:12px;text-transform:uppercase;color:var(--admin-text-tertiary);">Loại</th>
|
||||
<th style="padding:12px 16px;text-align:right;font-size:12px;text-transform:uppercase;color:var(--admin-text-tertiary);">Sức chứa</th>
|
||||
<th style="padding:12px 16px;text-align:center;font-size:12px;text-transform:uppercase;color:var(--admin-text-tertiary);">Trạng thái</th>
|
||||
</tr></thead><tbody>
|
||||
@foreach (var r in _resources)
|
||||
{
|
||||
<tr style="border-top:1px solid var(--admin-border-subtle);">
|
||||
<td style="padding:12px 16px;font-weight:600;">@r.Name</td>
|
||||
<td style="padding:12px 16px;text-align:center;font-size:12px;color:var(--admin-text-tertiary);">@(r.ResourceType ?? "—")</td>
|
||||
<td style="padding:12px 16px;text-align:right;font-weight:600;color:var(--admin-orange-primary);">@r.Capacity</td>
|
||||
<td style="padding:12px 16px;text-align:center;"><span class="admin-status-badge @(r.IsActive ? "admin-status-badge--online" : "admin-status-badge--offline")" style="font-size:11px;padding:2px 10px;"><span class="admin-status-badge__dot" style="width:5px;height:5px;"></span>@(r.IsActive ? "Active" : "Inactive")</span></td>
|
||||
</tr>
|
||||
}
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
break;
|
||||
|
||||
// ═══ TREATMENTS (Beauty — Liệu trình) ═══
|
||||
case "treatments":
|
||||
@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")
|
||||
<div class="admin-panel">
|
||||
<div class="admin-panel__header" style="display:flex;justify-content:space-between;align-items:center;">
|
||||
<h3 class="admin-panel__title">Liệu trình điều trị</h3>
|
||||
</div>
|
||||
<div class="admin-panel__body" style="text-align:center;padding:40px 20px;">
|
||||
<div style="width:64px;height:64px;border-radius:20px;background:rgba(168,85,247,0.1);display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
|
||||
<i data-lucide="clipboard-list" style="width:28px;height:28px;color:#A855F7;"></i>
|
||||
</div>
|
||||
<h3 style="font-size:18px;font-weight:700;margin:0 0 8px;">Quản lý liệu trình dài hạn</h3>
|
||||
<p style="font-size:14px;color:var(--admin-text-tertiary);margin:0 0 8px;max-width:400px;margin-left:auto;margin-right:auto;">Theo dõi tiến trình điều trị nhiều buổi, ảnh before/after, lịch tái khám sau phẫu thuật.</p>
|
||||
<div style="display:flex;gap:12px;justify-content:center;margin-top:16px;">
|
||||
<span style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--admin-text-tertiary);"><i data-lucide="camera" style="width:14px;height:14px;"></i> Ảnh Before/After</span>
|
||||
<span style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--admin-text-tertiary);"><i data-lucide="calendar-check" style="width:14px;height:14px;"></i> Lịch tái khám</span>
|
||||
<span style="display:flex;align-items:center;gap:6px;font-size:12px;color:var(--admin-text-tertiary);"><i data-lucide="file-text" style="width:14px;height:14px;"></i> Hồ sơ y tế</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
break;
|
||||
|
||||
// ═══ PROMOTIONS (real data) ═══
|
||||
@@ -802,6 +850,7 @@
|
||||
private List<PosDataService.LevelDefinitionInfo> _memberLevels = new();
|
||||
private List<PosDataService.ScheduleInfo> _staffSchedules = new();
|
||||
private List<PosDataService.InventoryTxnInfo> _invTxns = new();
|
||||
private List<PosDataService.ResourceInfo> _resources = new();
|
||||
|
||||
protected override async Task OnInitializedAsync() => await LoadData();
|
||||
|
||||
@@ -853,6 +902,7 @@
|
||||
break;
|
||||
case "inventory":
|
||||
_inventory = await DataService.GetInventoryAsync(_shopGuid);
|
||||
_invTxns = await DataService.GetInventoryTransactionsAsync(_shopGuid);
|
||||
break;
|
||||
case "finance":
|
||||
_orders = await DataService.GetOrdersAsync(_shopGuid);
|
||||
@@ -876,6 +926,10 @@
|
||||
if (_shopGuid.HasValue)
|
||||
_appointments = await DataService.GetAppointmentsAsync(_shopGuid.Value);
|
||||
break;
|
||||
case "resources":
|
||||
if (_shopGuid.HasValue)
|
||||
_resources = await DataService.GetResourcesAsync(_shopGuid.Value);
|
||||
break;
|
||||
case "services":
|
||||
_products = await DataService.GetAllProductsAsync(_shopGuid);
|
||||
break;
|
||||
|
||||
@@ -212,4 +212,11 @@ public class PosDataService
|
||||
|
||||
public async Task<List<ShopStatsInfo>> GetShopStatsAsync()
|
||||
{ AttachToken(); return await _http.GetFromJsonAsync<List<ShopStatsInfo>>("api/bff/shops/stats", _jsonOptions) ?? new(); }
|
||||
|
||||
// ═══ BOOKING RESOURCES ═══
|
||||
|
||||
public record ResourceInfo(Guid Id, string Name, string? ResourceType, int Capacity, bool IsActive);
|
||||
|
||||
public async Task<List<ResourceInfo>> GetResourcesAsync(Guid shopId)
|
||||
{ AttachToken(); return await _http.GetFromJsonAsync<List<ResourceInfo>>($"api/bff/shops/{shopId}/resources", _jsonOptions) ?? new(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user