diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AdminLayout.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AdminLayout.razor
index beccc58a..bc7a5fb5 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AdminLayout.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AdminLayout.razor
@@ -153,7 +153,9 @@
@* ═══ MAIN AREA ═══ *@
- @Body
+
+ @Body
+
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
new file mode 100644
index 00000000..b384caaf
--- /dev/null
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopOverview.razor
@@ -0,0 +1,251 @@
+@page "/admin/shop/{ShopId}/overview"
+@layout AdminLayout
+@inherits AdminBase
+@inject PosDataService DataService
+@using WebClientTpos.Client.Services
+
+@*
+ EN: Shop overview — KPIs and info when inside a shop context.
+ Triggers AdminLayout._isShopContext → per-vertical sidebar.
+ VI: Tổng quan cửa hàng — KPI khi đang trong context cửa hàng.
+ Kích hoạt AdminLayout._isShopContext → sidebar theo ngành hàng.
+*@
+
+@(_shop?.Name ?? "Cửa hàng") — GoodGo Admin
+
+@* ═══ TOP BAR ═══ *@
+
+
+ @if (IsLoading)
+ {
+
+
+
Đang tải thông tin cửa hàng...
+
+ }
+ else if (_shop == null)
+ {
+
+ }
+ else
+ {
+ @* ── Store Info Card ── *@
+
+
+
+
+
+
+
@_shop.Name
+
@_shop.Slug • @ShopSidebarConfig.GetVerticalLabel(_shop.Category)
+ @if (!string.IsNullOrEmpty(_shop.Description))
+ {
+
@_shop.Description
+ }
+
+
+ @if (!string.IsNullOrEmpty(_shop.Phone))
+ {
+
+ @_shop.Phone
+
+ }
+ @if (!string.IsNullOrEmpty(_shop.Email))
+ {
+
+ @_shop.Email
+
+ }
+
+
+
+
+ @* ── KPI ROW ── *@
+
+
+
+
--
+
Doanh thu tháng
+
+
+
+
--
+
Đơn hàng tháng
+
+
+
+
--
+
Giá trị TB / đơn
+
+
+
+
+ @* ── BOTTOM: Chart + Right Column ── *@
+
+ @* LEFT: Revenue Chart *@
+
+
+
+
+
+
Chưa có dữ liệu doanh thu
+
Dữ liệu sẽ hiển thị khi có đơn hàng
+
+
+
+
+ @* RIGHT COLUMN *@
+
+
+
+
+
+
Chưa có đơn hàng nào
+
+
+
+
+
+
+
+ Trạng thái
+ @GetStatusLabel(_shop.Status)
+
+
+ Ngành hàng
+ @ShopSidebarConfig.GetVerticalLabel(_shop.Category)
+
+
+ Slug
+ @(_shop.Slug)
+
+
+
+
+
+ }
+
+
+
+@code {
+ [Parameter] public string ShopId { get; set; } = "";
+
+ private PosDataService.ShopInfo? _shop;
+
+ // EN: Cascade layout reference to set shop context for sidebar switching.
+ // VI: Cascade layout để set shop context cho sidebar chuyển đổi.
+ [CascadingParameter] public AdminLayout? Layout { get; set; }
+
+ protected override async Task OnInitializedAsync()
+ {
+ IsLoading = true;
+ try
+ {
+ if (Guid.TryParse(ShopId, out var id))
+ {
+ _shop = await DataService.GetShopByIdAsync(id);
+ if (_shop != null)
+ {
+ Layout?.SetShopContext(ShopId, _shop.Name ?? "Cửa hàng", _shop.Category);
+ }
+ }
+ }
+ catch { _shop = null; }
+ finally { IsLoading = false; }
+ }
+
+ 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 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 GetShopIcon(string? category) => category?.ToLowerInvariant() switch
+ {
+ "foodbeverage" or "café" or "cafe" or "coffee" => "coffee",
+ "restaurant" or "nhà hàng" => "utensils",
+ "entertainment" or "karaoke" => "mic",
+ "beauty" or "spa" => "sparkles",
+ "retail" => "shopping-bag",
+ _ => "store"
+ };
+}
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
new file mode 100644
index 00000000..da1c53ea
--- /dev/null
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopPage.razor
@@ -0,0 +1,213 @@
+@page "/admin/shop/{ShopId}/{Section}"
+@layout AdminLayout
+@inherits AdminBase
+@inject PosDataService DataService
+@using WebClientTpos.Client.Services
+
+@*
+ EN: Catch-all for shop sub-pages (menu, inventory, staff, customers, etc).
+ Each section either shows real content or a "coming soon" placeholder.
+ VI: Catch-all cho các trang con cửa hàng (menu, kho, nhân sự, khách hàng...).
+ Mỗi section hiển thị nội dung thật hoặc placeholder "sắp ra mắt".
+*@
+
+
+
+ @if (IsLoading)
+ {
+
+ }
+ else
+ {
+ @* ── Section-specific content placeholder ── *@
+
+
+
+
+
+
@_sectionTitle
+
+ @_sectionDescription
+
+ @if (_hasQuickStats)
+ {
+
+ @foreach (var stat in _quickStats)
+ {
+
+
@stat.Value
+
@stat.Label
+
+ }
+
+ }
+
+ Tính năng này sẽ được kích hoạt khi có dữ liệu từ hệ thống
+
+
+
+ }
+
+
+@code {
+ [Parameter] public string ShopId { get; set; } = "";
+ [Parameter] public string Section { get; set; } = "";
+ [CascadingParameter] public AdminLayout? Layout { get; set; }
+
+ private string _shopName = "";
+ private string _verticalLabel = "";
+ private string _sectionTitle = "";
+ private string _sectionIcon = "layout-dashboard";
+ private string _sectionDescription = "";
+ private bool _hasQuickStats = false;
+ private List<(string Value, string Label)> _quickStats = new();
+ private List<(string Icon, string Label)> _sectionActions = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+ IsLoading = true;
+ try
+ {
+ if (Guid.TryParse(ShopId, out var id))
+ {
+ var shop = await DataService.GetShopByIdAsync(id);
+ if (shop != null)
+ {
+ _shopName = shop.Name ?? "Cửa hàng";
+ _verticalLabel = ShopSidebarConfig.GetVerticalLabel(shop.Category);
+ Layout?.SetShopContext(ShopId, _shopName, shop.Category);
+ }
+ }
+ ConfigureSection();
+ }
+ catch { }
+ finally { IsLoading = false; }
+ }
+
+ protected override void OnParametersSet()
+ {
+ ConfigureSection();
+ }
+
+ ///