From 33e0bab4f7343adeff108bf291a0eac3b9bfb6e7 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Sun, 1 Mar 2026 05:58:58 +0700 Subject: [PATCH] refactor(web-client-tpos): centralize theme, fix layout bugs, cleanup dead code --- .../src/WebClientTpos.Client/AppTheme.cs | 57 ++++++++ .../Layout/AdminLayout.razor | 25 ++-- .../Layout/AuthLayout.razor | 28 +--- .../Layout/MarketingLayout.razor | 26 ++-- .../Layout/PosLayout.razor | 19 +-- .../Pages/Auth/Login.razor.bak | 136 ------------------ .../wwwroot/css/admin.css | 49 +++++++ 7 files changed, 131 insertions(+), 209 deletions(-) create mode 100644 apps/web-client-tpos-net/src/WebClientTpos.Client/AppTheme.cs delete mode 100644 apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Auth/Login.razor.bak diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/AppTheme.cs b/apps/web-client-tpos-net/src/WebClientTpos.Client/AppTheme.cs new file mode 100644 index 00000000..bb9874ca --- /dev/null +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/AppTheme.cs @@ -0,0 +1,57 @@ +// EN: Centralized MudBlazor theme definitions for all layouts. +// VI: Định nghĩa MudBlazor theme tập trung cho tất cả layouts. + +using MudBlazor; + +namespace WebClientTpos.Client; + +/// +/// EN: Centralized theme configuration — used by all layouts (Admin, Auth, POS, Marketing). +/// VI: Cấu hình theme tập trung — sử dụng bởi tất cả layouts (Admin, Auth, POS, Marketing). +/// +public static class AppTheme +{ + /// + /// EN: Default dark theme — aPOS brand orange (#FF5C00) on dark background. + /// VI: Theme tối mặc định — thương hiệu aPOS cam (#FF5C00) trên nền tối. + /// Used by: AdminLayout, AuthLayout, PosLayout + /// + public static MudTheme DefaultDark { get; } = new() + { + PaletteDark = new PaletteDark() + { + Primary = "#FF5C00", + PrimaryContrastText = "#FFFFFF", + AppbarBackground = "#1A1A1D", + AppbarText = "#FFFFFF", + Background = "#0A0A0B", + Surface = "#1A1A1D", + TextPrimary = "#FFFFFF", + TextSecondary = "#ADADB0", + ActionDefault = "#FFFFFF", + LinesDefault = "#1F1F23" + } + }; + + /// + /// EN: Marketing dark theme — yellow accent (#FACC15) for tMarketing module. + /// VI: Theme tối Marketing — điểm nhấn vàng (#FACC15) cho module tMarketing. + /// Used by: MarketingLayout + /// + public static MudTheme MarketingDark { get; } = new() + { + PaletteDark = new PaletteDark() + { + Primary = "#FACC15", + PrimaryContrastText = "#18181B", + AppbarBackground = "#0F0F10", + AppbarText = "#FAFAFA", + Background = "#18181B", + Surface = "#0F0F10", + TextPrimary = "#FAFAFA", + TextSecondary = "#71717A", + ActionDefault = "#FAFAFA", + LinesDefault = "#27272A" + } + }; +} 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 a1ea7e3e..d6de8040 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 @@ -14,7 +14,7 @@ @inject Microsoft.Extensions.Localization.IStringLocalizer L @using WebClientTpos.Client.Services - + @@ -135,6 +135,13 @@ @* ═══ MAIN AREA ═══ *@
+ @* Mobile-only hamburger toggle *@ +
+ + GoodGo Admin +
@@ -263,22 +270,6 @@ NavigationManager.NavigateTo("/auth/login", forceLoad: true); } - private MudTheme _theme = new() - { - PaletteDark = new PaletteDark() - { - Primary = "#FF5C00", - PrimaryContrastText = "#FFFFFF", - AppbarBackground = "#1A1A1D", - AppbarText = "#FFFFFF", - Background = "#0A0A0B", - Surface = "#1A1A1D", - TextPrimary = "#FFFFFF", - TextSecondary = "#ADADB0", - ActionDefault = "#FFFFFF", - LinesDefault = "#1F1F23" - } - }; public void Dispose() { diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AuthLayout.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AuthLayout.razor index 77fac367..c0c9a3c7 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AuthLayout.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/AuthLayout.razor @@ -1,7 +1,8 @@ @inherits LayoutComponentBase @inject IJSRuntime JS +@inject Microsoft.Extensions.Localization.IStringLocalizer L - + @@ -10,10 +11,10 @@ @@ -29,21 +30,4 @@ { try { await JS.InvokeVoidAsync("lucide.createIcons"); } catch { } } - - private MudTheme _theme = new() - { - PaletteDark = new PaletteDark() - { - Primary = "#FF5C00", - PrimaryContrastText = "#FFFFFF", - AppbarBackground = "rgba(10,10,11,0.85)", - AppbarText = "#FFFFFF", - Background = "#0A0A0B", - Surface = "#111113", - TextPrimary = "#FFFFFF", - TextSecondary = "#ADADB0", - ActionDefault = "#FFFFFF", - LinesDefault = "#1F1F23" - } - }; } diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/MarketingLayout.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/MarketingLayout.razor index d2e99073..90175c29 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/MarketingLayout.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/MarketingLayout.razor @@ -6,8 +6,10 @@ @inherits LayoutComponentBase @inject NavigationManager NavigationManager @inject IJSRuntime JS +@inject WebClientTpos.Client.Services.AuthService AuthSvc +@using WebClientTpos.Client.Services - + @@ -125,22 +127,12 @@ private void ToggleSidebar() => _sidebarOpen = !_sidebarOpen; private void CloseSidebar() => _sidebarOpen = false; private void ToggleSearch() => _searchOpen = !_searchOpen; - private void Logout() => NavigationManager.NavigateTo("/login"); - private MudTheme _theme = new() + // EN: Properly clear auth state on logout instead of just navigating + // VI: Xóa auth state đúng cách khi đăng xuất thay vì chỉ điều hướng + private async Task Logout() { - PaletteDark = new PaletteDark() - { - Primary = "#FACC15", - PrimaryContrastText = "#18181B", - AppbarBackground = "#0F0F10", - AppbarText = "#FAFAFA", - Background = "#18181B", - Surface = "#0F0F10", - TextPrimary = "#FAFAFA", - TextSecondary = "#71717A", - ActionDefault = "#FAFAFA", - LinesDefault = "#27272A" - } - }; + await AuthSvc.LogoutAsync(); + NavigationManager.NavigateTo("/auth/login", forceLoad: true); + } } diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/PosLayout.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/PosLayout.razor index 655deef0..c2540bde 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/PosLayout.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Layout/PosLayout.razor @@ -8,7 +8,7 @@ @inject NavigationManager NavigationManager @inject WebClientTpos.Client.Services.PosDataService DataService - + @@ -65,21 +65,6 @@ private void GoToAdmin() => NavigationManager.NavigateTo("/admin"); - private MudTheme _theme = new() - { - PaletteDark = new PaletteDark() - { - Primary = "#FF5C00", - PrimaryContrastText = "#FFFFFF", - AppbarBackground = "#1A1A1D", - AppbarText = "#FFFFFF", - Background = "#0A0A0B", - Surface = "#1A1A1D", - TextPrimary = "#FFFFFF", - TextSecondary = "#ADADB0", - ActionDefault = "#FFFFFF", - LinesDefault = "#1F1F23" - } - }; } + diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Auth/Login.razor.bak b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Auth/Login.razor.bak deleted file mode 100644 index 924e25b5..00000000 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Auth/Login.razor.bak +++ /dev/null @@ -1,136 +0,0 @@ -@page "/login" -@using WebClientTpos.Shared.DTOs -@using WebClientTpos.Shared -@inject HttpClient Http -@inject NavigationManager Navigation -@inject IStringLocalizer L - -@* - EN: Login page with email/password authentication. - VI: Trang đăng nhập với xác thực email/mật khẩu. -*@ - -@L["Auth_Login_Title"] - -
-
-

@L["Auth_Login_Title"]

-

@L["Auth_Login_Subtitle"]

- - - - -
- - - -
- -
- - - -
- -
-
- - -
- - @L["Auth_Login_ForgotPassword"] -
- - -
- - @if (!string.IsNullOrEmpty(message)) - { -
- @message -
- } - - -
-
- -@code { - private LoginDto loginModel = new(); - private bool isSubmitting = false; - private string message = ""; - private bool success = false; - - /// - /// EN: Handle login form submission. - /// VI: Xử lý submit form đăng nhập. - /// - private async Task HandleLogin() - { - isSubmitting = true; - message = ""; - - try - { - var response = await Http.PostAsJsonAsync("api/auth/login", loginModel); - - if (response.IsSuccessStatusCode) - { - var result = await response.Content.ReadFromJsonAsync>(); - if (result?.Success == true && result.Data != null) - { - success = true; - message = string.Format(L["Auth_Login_Success"], result.Data.DisplayName); - - // EN: Redirect to home after 1 second - // VI: Chuyển hướng về trang chủ sau 1 giây - await Task.Delay(1000); - Navigation.NavigateTo("/"); - } - else - { - success = false; - message = L["Auth_Login_Error"]; - } - } - else - { - success = false; - message = L["Auth_Login_Error"]; - } - } - catch (Exception ex) - { - success = false; - message = $"{L["Common_Error"]}: {ex.Message}"; - } - finally - { - isSubmitting = false; - } - } -} diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/admin.css b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/admin.css index 7e3a0393..c4e66de4 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/admin.css +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/admin.css @@ -1518,4 +1518,53 @@ select.admin-form-input { .admin-status-badge--offline .admin-status-badge__dot { background-color: var(--admin-danger); +} + +/* ═════════════════════════════════════════════════════════════════════════ + 17. MOBILE BAR (hamburger toggle header — visible ≤ 1024px only) + ═════════════════════════════════════════════════════════════════════════ */ + +/* EN: Hidden on desktop / VI: Ẩn trên desktop */ +.admin-mobile-bar { + display: none; + align-items: center; + gap: 12px; + padding: 12px 20px; + background-color: var(--admin-bg-elevated); + border-bottom: 1px solid var(--admin-border-subtle); +} + +.admin-mobile-toggle { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: var(--admin-radius-md); + background: transparent; + border: 1px solid var(--admin-border-default); + color: var(--admin-text-primary); + cursor: pointer; + transition: background 0.2s ease; +} + +.admin-mobile-toggle:hover { + background-color: var(--admin-bg-interactive); +} + +.admin-mobile-toggle i { + width: 20px; + height: 20px; +} + +.admin-mobile-bar__title { + font-size: 16px; + font-weight: 700; + color: var(--admin-text-primary); +} + +@media (max-width: 1024px) { + .admin-mobile-bar { + display: flex; + } } \ No newline at end of file