From af0461f2333e18429535ca6d13e55e53084a17ec Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Mon, 23 Mar 2026 09:50:13 +0700 Subject: [PATCH] fix(frontend): resolve 4 P2 architecture issues (Wave 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FRONT-I-01: Extract Auth components to Razor Class Library packages/blazor-ui/ - Created GoodGo.BlazorUi RCL (net10.0, MudBlazor 8.15) at packages/blazor-ui/ - Moved AuthButton, AuthCard, AuthInput, OtpInput, BrandPanel, SocialLogin, LanguageSwitcher - Referenced RCL from WebClientTpos.Client via ProjectReference - Added GoodGo.BlazorUi.Components.Auth/Common namespaces to _Imports.razor FRONT-I-02: Add ARIA/accessibility attributes (WCAG 2.1 AA) - AuthButton: aria-label, aria-busy, aria-disabled, aria-hidden on decorative icons - OtpInput: role=group, aria-label per digit, autocomplete=one-time-code - PosLayout: aria-expanded + aria-controls on sidebar/order toggles, aria-label on all icon buttons FRONT-I-03: Implement Style Dictionary design token pipeline - Created packages/design-tokens/ with token JSON (color, spacing, typography, border) - Style Dictionary config outputs: CSS custom properties → wwwroot/css/tokens.generated.css - Second output: C# constants → packages/blazor-ui/DesignTokens/DesignTokens.g.cs - Added tokens:build script to root package.json - Added tokens.generated.css link to index.html (before app.css for cascade correctness) FRONT-I-04: Replace eval() in OtpInput with safe JS interop - Created wwwroot/js/otp-input.js with window.focusOtpInput(index) helper - Replaced JS.InvokeVoidAsync("eval", ...) with JS.InvokeVoidAsync("focusOtpInput", index) - Eliminates CSP-violating eval(), improves security and debuggability Co-Authored-By: Paperclip --- .../Layout/PosLayout.razor | 34 ++++-- .../WebClientTpos.Client.csproj | 5 + .../src/WebClientTpos.Client/_Imports.razor | 2 + .../WebClientTpos.Client/wwwroot/index.html | 12 ++ .../wwwroot/js/otp-input.js | 18 +++ package.json | 1 + .../Components/Auth/AuthButton.razor | 15 ++- .../blazor-ui}/Components/Auth/AuthCard.razor | 0 .../Components/Auth/AuthInput.razor | 0 .../Components/Auth/BrandPanel.razor | 0 .../blazor-ui}/Components/Auth/OtpInput.razor | 16 ++- .../Components/Auth/SocialLogin.razor | 0 .../Components/Common}/LanguageSwitcher.razor | 0 packages/blazor-ui/GoodGo.BlazorUi.csproj | 26 +++++ packages/blazor-ui/_Imports.razor | 10 ++ packages/design-tokens/package.json | 14 +++ .../design-tokens/style-dictionary.config.mjs | 109 ++++++++++++++++++ packages/design-tokens/tokens/border.json | 10 ++ packages/design-tokens/tokens/color.json | 72 ++++++++++++ packages/design-tokens/tokens/spacing.json | 16 +++ packages/design-tokens/tokens/typography.json | 8 ++ 21 files changed, 350 insertions(+), 18 deletions(-) create mode 100644 apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/js/otp-input.js rename {apps/web-client-tpos-net/src/WebClientTpos.Client => packages/blazor-ui}/Components/Auth/AuthButton.razor (76%) rename {apps/web-client-tpos-net/src/WebClientTpos.Client => packages/blazor-ui}/Components/Auth/AuthCard.razor (100%) rename {apps/web-client-tpos-net/src/WebClientTpos.Client => packages/blazor-ui}/Components/Auth/AuthInput.razor (100%) rename {apps/web-client-tpos-net/src/WebClientTpos.Client => packages/blazor-ui}/Components/Auth/BrandPanel.razor (100%) rename {apps/web-client-tpos-net/src/WebClientTpos.Client => packages/blazor-ui}/Components/Auth/OtpInput.razor (82%) rename {apps/web-client-tpos-net/src/WebClientTpos.Client => packages/blazor-ui}/Components/Auth/SocialLogin.razor (100%) rename {apps/web-client-tpos-net/src/WebClientTpos.Client/Components => packages/blazor-ui/Components/Common}/LanguageSwitcher.razor (100%) create mode 100644 packages/blazor-ui/GoodGo.BlazorUi.csproj create mode 100644 packages/blazor-ui/_Imports.razor create mode 100644 packages/design-tokens/package.json create mode 100644 packages/design-tokens/style-dictionary.config.mjs create mode 100644 packages/design-tokens/tokens/border.json create mode 100644 packages/design-tokens/tokens/color.json create mode 100644 packages/design-tokens/tokens/spacing.json create mode 100644 packages/design-tokens/tokens/typography.json 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 4a2a3e42..4724c467 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 @@ -23,8 +23,12 @@
@* EN: Hamburger menu — visible on tablet/mobile only / VI: Menu hamburger — chi hien thi tren tablet/mobile *@ - @StoreName @@ -37,15 +41,19 @@ @_currentTime @* EN: Order panel toggle — visible on tablet/mobile when order panel is hidden VI: Nút mở panel đơn hàng — hiện trên tablet/mobile khi panel đơn hàng ẩn *@ - -
@@ -60,11 +68,13 @@ @* EN: Sidebar navigation — collapsible on tablet/mobile VI: Sidebar điều hướng — thu gọn trên tablet/mobile *@ -