From f353f8843e8ac1b7350abbfa610a54368b0f94fb Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Sun, 1 Mar 2026 06:02:20 +0700 Subject: [PATCH] feat(web-client-tpos): redesign Home/NotFound pages, localize Dashboard --- .../Pages/Admin/Dashboard.razor | 37 ++- .../src/WebClientTpos.Client/Pages/Home.razor | 73 +++- .../WebClientTpos.Client/Pages/NotFound.razor | 29 +- .../WebClientTpos.Client/wwwroot/css/app.css | 313 ++++++++++++++++++ .../wwwroot/locales/en-US.json | 25 +- .../wwwroot/locales/vi-VN.json | 25 +- 6 files changed, 471 insertions(+), 31 deletions(-) diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Dashboard.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Dashboard.razor index 87305a67..f1aba2b8 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Dashboard.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Dashboard.razor @@ -2,6 +2,7 @@ @layout AdminLayout @inherits AdminBase @inject PosDataService DataService +@inject Microsoft.Extensions.Localization.IStringLocalizer L @using WebClientTpos.Client.Services @* @@ -14,20 +15,20 @@ @* ═══ TOP BAR ═══ *@
-

Dashboard

-

Tổng quan kinh doanh • @GetTodayFormatted()

+

@L["Dashboard_Title"]

+

@L["Dashboard_Subtitle"] • @GetTodayFormatted()

@@ -45,7 +46,7 @@
@_shops.Count
-
Cửa hàng
+
@L["Dashboard_KPI_Stores"]
@* KPI 2: Đang hoạt động *@ @@ -56,7 +57,7 @@
@_shops.Count(s => s.Status == "active")
-
Đang hoạt động
+
@L["Dashboard_KPI_Active"]
@* KPI 3: Đang thiết lập *@ @@ -67,7 +68,7 @@
@_shops.Count(s => s.Status != "active")
-
Đang thiết lập
+
@L["Dashboard_KPI_Setup"]
@* KPI 4: Ngành hàng *@ @@ -78,7 +79,7 @@
@_shops.Select(s => s.Category).Distinct().Count()
-
Ngành hàng
+
@L["Dashboard_KPI_Verticals"]
@@ -94,7 +95,7 @@ @if (_shops.Count > 0) { - Quản lý tất cả → + @L["Dashboard_ManageAll"] → }
@@ -102,11 +103,11 @@ {
-

Welcome! Tạo cửa hàng đầu tiên

-

Bắt đầu bằng việc tạo cửa hàng để quản lý kinh doanh của bạn.

+

@L["Dashboard_WelcomeTitle"]

+

@L["Dashboard_WelcomeSubtitle"]

- Tạo cửa hàng ngay + @L["Dashboard_CreateStoreNow"]
} @@ -127,7 +128,7 @@
- @(shop.Status == "active" ? "Đang mở" : "Thiết lập") + @(shop.Status == "active" ? L["Dashboard_Status_Open"] : L["Dashboard_Status_Setup"])
@@ -143,23 +144,23 @@

- Thao tác nhanh + @L["Dashboard_QuickActions"]

@@ -170,7 +171,7 @@

- Trạng thái hệ thống + @L["Dashboard_SystemStatus"]

diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Home.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Home.razor index 8a1529df..8dbb0ce5 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Home.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Home.razor @@ -1,14 +1,71 @@ +@* + EN: Home page — branded landing with hero CTA and quick navigation. + VI: Trang chủ — landing page với hero CTA và điều hướng nhanh. +*@ @page "/home" @page "/" +@layout MainLayout +@inject NavigationManager NavigationManager +@inject Microsoft.Extensions.Localization.IStringLocalizer L -GoodGo POS +@L["AppName"] — @L["HeroHeadline"] -
-

GoodGo POS

-

Hệ thống quản lý POS đa ngành

-

Café · Nhà hàng · Karaoke · Spa · Bán lẻ

-
- Dùng thử miễn phí - Đăng nhập +
+
@L["HeroBadge"]
+

@L["HeroHeadline"]

+

@L["HeroSubtext"]

+ + + @* Trust Badges *@ +
+ @L["Trust_Label"] +
+ @L["Trust_Stat1"] + + @L["Trust_Stat2"] +
+ +@* Verticals Showcase *@ + + +@code { + protected override void OnInitialized() + { + // EN: Redirect authenticated users to Admin dashboard + // VI: Chuyển hướng người dùng đã xác thực đến Admin dashboard + } +} diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/NotFound.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/NotFound.razor index 917ada1d..cfc538fd 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/NotFound.razor +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/NotFound.razor @@ -1,5 +1,28 @@ -@page "/not-found" +@* + EN: 404 Not Found page — branded error page with navigation options. + VI: Trang 404 — trang lỗi thương hiệu với các tùy chọn điều hướng. +*@ +@page "/not-found" @layout MainLayout +@inject Microsoft.Extensions.Localization.IStringLocalizer L -

Not Found

-

Sorry, the content you are looking for does not exist.

\ No newline at end of file +404 — @L["AppName"] + +
+
+ +
+
404
+

@L["NotFound_Title"]

+

@L["NotFound_Subtitle"]

+ +
\ No newline at end of file diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/app.css b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/app.css index 2764a4fe..a3570aaf 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/app.css +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/css/app.css @@ -1668,4 +1668,317 @@ a { padding-left: var(--space-4); padding-right: var(--space-4); } +} + +/* ═════════════════════════════════════════════════════════════════════════ + HOME PAGE — Hero, Trust, Verticals + ═════════════════════════════════════════════════════════════════════════ */ +.home-hero { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + min-height: 70vh; + padding: var(--space-16) var(--space-6) var(--space-12); +} + +.home-hero__badge { + display: inline-flex; + align-items: center; + gap: var(--space-2); + background: var(--accent-glow); + border: 1px solid rgba(255, 92, 0, 0.25); + color: var(--accent-light); + padding: var(--space-2) var(--space-5); + border-radius: 999px; + font-size: 0.8125rem; + font-weight: 600; + margin-bottom: var(--space-8); + letter-spacing: 0.03em; + animation: fadeInUp 0.6s ease-out; +} + +.home-hero__title { + font-size: 3.5rem; + font-weight: 800; + line-height: 1.08; + margin-bottom: var(--space-6); + letter-spacing: -0.03em; + background: linear-gradient(180deg, #FFFFFF 30%, #ADADB0 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + max-width: 800px; + animation: fadeInUp 0.6s ease-out 0.1s both; +} + +.home-hero__subtitle { + font-size: 1.125rem; + color: var(--text-secondary); + max-width: 640px; + margin: 0 auto var(--space-10); + line-height: 1.7; + animation: fadeInUp 0.6s ease-out 0.2s both; +} + +.home-hero__actions { + display: flex; + gap: var(--space-4); + justify-content: center; + flex-wrap: wrap; + margin-bottom: var(--space-12); + animation: fadeInUp 0.6s ease-out 0.3s both; +} + +.home-hero__btn { + display: inline-flex; + align-items: center; + gap: var(--space-2); + padding: var(--space-4) var(--space-8); + border-radius: var(--border-radius-xl); + font-weight: 700; + font-size: 1rem; + text-decoration: none; + transition: all 0.25s ease; +} + +.home-hero__btn i { + width: 18px; + height: 18px; +} + +.home-hero__btn--primary { + background: var(--brand-gradient); + color: #FFFFFF; + box-shadow: 0 4px 24px var(--accent-glow-strong); +} + +.home-hero__btn--primary:hover { + transform: translateY(-2px); + box-shadow: 0 8px 32px var(--accent-glow-strong); +} + +.home-hero__btn--secondary { + background: transparent; + color: var(--text-primary); + border: 1px solid var(--border-default); +} + +.home-hero__btn--secondary:hover { + background: rgba(255, 255, 255, 0.05); + border-color: var(--border-strong); +} + +/* Trust badges */ +.home-trust { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-3); + animation: fadeInUp 0.6s ease-out 0.4s both; +} + +.home-trust__label { + font-size: 0.8125rem; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--text-tertiary); +} + +.home-trust__stats { + display: flex; + align-items: center; + gap: var(--space-4); +} + +.home-trust__stat { + font-size: 0.875rem; + font-weight: 600; + color: var(--text-secondary); +} + +.home-trust__divider { + color: var(--text-disabled); +} + +/* Verticals showcase */ +.home-verticals { + padding: var(--space-12) var(--space-6) var(--space-16); + max-width: 900px; + margin: 0 auto; +} + +.home-verticals__grid { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: var(--space-4); +} + +.home-vertical-card { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-3); + padding: var(--space-6) var(--space-4); + background: var(--bg-surface); + border: 1px solid var(--border-subtle); + border-radius: var(--border-radius-xl); + text-decoration: none; + color: var(--text-secondary); + font-size: 0.8125rem; + font-weight: 600; + transition: all 0.25s ease; +} + +.home-vertical-card i { + width: 28px; + height: 28px; + color: var(--accent-primary); +} + +.home-vertical-card:hover { + border-color: var(--accent-primary); + background: var(--accent-glow); + color: var(--text-primary); + transform: translateY(-2px); +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@media (max-width: 768px) { + .home-hero__title { + font-size: 2.25rem; + } + + .home-verticals__grid { + grid-template-columns: repeat(3, 1fr); + } +} + +@media (max-width: 480px) { + .home-verticals__grid { + grid-template-columns: repeat(2, 1fr); + } + + .home-hero__actions { + flex-direction: column; + width: 100%; + max-width: 320px; + } + + .home-hero__btn { + width: 100%; + justify-content: center; + } +} + +/* ═════════════════════════════════════════════════════════════════════════ + NOT FOUND (404) PAGE + ═════════════════════════════════════════════════════════════════════════ */ +.notfound-page { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + min-height: 70vh; + padding: var(--space-16) var(--space-6); +} + +.notfound-page__icon { + width: 80px; + height: 80px; + border-radius: var(--border-radius-2xl); + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: var(--space-6); +} + +.notfound-page__icon i { + width: 36px; + height: 36px; + color: var(--accent-primary); +} + +.notfound-page__code { + font-size: 5rem; + font-weight: 800; + background: linear-gradient(180deg, var(--accent-primary) 0%, var(--accent-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + line-height: 1; + margin-bottom: var(--space-4); +} + +.notfound-page__title { + font-size: 1.5rem; + font-weight: 700; + margin-bottom: var(--space-3); +} + +.notfound-page__subtitle { + font-size: 1rem; + color: var(--text-secondary); + margin-bottom: var(--space-8); + max-width: 400px; +} + +.notfound-page__actions { + display: flex; + gap: var(--space-4); + flex-wrap: wrap; + justify-content: center; +} + +.notfound-page__btn { + display: inline-flex; + align-items: center; + gap: var(--space-2); + padding: var(--space-3) var(--space-6); + border-radius: var(--border-radius-lg); + font-weight: 600; + font-size: 0.9375rem; + text-decoration: none; + transition: all 0.25s ease; +} + +.notfound-page__btn i { + width: 16px; + height: 16px; +} + +.notfound-page__btn--primary { + background: var(--accent-primary); + color: #FFFFFF; +} + +.notfound-page__btn--primary:hover { + background: var(--action-primary-bg-hover); + transform: translateY(-1px); + box-shadow: 0 4px 20px var(--accent-glow-strong); +} + +.notfound-page__btn--secondary { + background: transparent; + color: var(--text-primary); + border: 1px solid var(--border-default); +} + +.notfound-page__btn--secondary:hover { + background: rgba(255, 255, 255, 0.05); + border-color: var(--border-strong); } \ No newline at end of file diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/en-US.json b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/en-US.json index 93e3b11a..3f183f40 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/en-US.json +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/en-US.json @@ -399,5 +399,28 @@ "Status_Active": "Open", "Status_Setup": "Setting up", "Status_Paused": "Paused", - "Status_Closed": "Closed" + "Status_Closed": "Closed", + "NotFound_Title": "Page not found", + "NotFound_Subtitle": "The page you're looking for doesn't exist or has been moved.", + "NotFound_GoHome": "Go to Home", + "Dashboard_Title": "Dashboard", + "Dashboard_Subtitle": "Business Overview", + "Dashboard_Search": "Search...", + "Dashboard_CreateStore": "Create Store", + "Dashboard_KPI_Stores": "Stores", + "Dashboard_KPI_Active": "Active", + "Dashboard_KPI_Setup": "Setting up", + "Dashboard_KPI_Verticals": "Verticals", + "Dashboard_YourStores": "Your Stores", + "Dashboard_ManageAll": "Manage All", + "Dashboard_WelcomeTitle": "Welcome! Create your first store", + "Dashboard_WelcomeSubtitle": "Get started by creating a store to manage your business.", + "Dashboard_CreateStoreNow": "Create Store Now", + "Dashboard_QuickActions": "Quick Actions", + "Dashboard_QA_CreateStore": "Create new store", + "Dashboard_QA_SystemSettings": "System Settings", + "Dashboard_QA_Permissions": "Permissions", + "Dashboard_SystemStatus": "System Status", + "Dashboard_Status_Open": "Open", + "Dashboard_Status_Setup": "Setting up" } \ No newline at end of file diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/vi-VN.json b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/vi-VN.json index f7b942df..24c344ce 100644 --- a/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/vi-VN.json +++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/wwwroot/locales/vi-VN.json @@ -399,5 +399,28 @@ "Status_Active": "Đang mở", "Status_Setup": "Thiết lập", "Status_Paused": "Tạm dừng", - "Status_Closed": "Đã đóng" + "Status_Closed": "Đã đóng", + "NotFound_Title": "Không tìm thấy trang", + "NotFound_Subtitle": "Trang bạn tìm kiếm không tồn tại hoặc đã được di chuyển.", + "NotFound_GoHome": "Về trang chủ", + "Dashboard_Title": "Dashboard", + "Dashboard_Subtitle": "Tổng quan kinh doanh", + "Dashboard_Search": "Tìm kiếm...", + "Dashboard_CreateStore": "Tạo cửa hàng", + "Dashboard_KPI_Stores": "Cửa hàng", + "Dashboard_KPI_Active": "Đang hoạt động", + "Dashboard_KPI_Setup": "Đang thiết lập", + "Dashboard_KPI_Verticals": "Ngành hàng", + "Dashboard_YourStores": "Cửa hàng của bạn", + "Dashboard_ManageAll": "Quản lý tất cả", + "Dashboard_WelcomeTitle": "Welcome! Tạo cửa hàng đầu tiên", + "Dashboard_WelcomeSubtitle": "Bắt đầu bằng việc tạo cửa hàng để quản lý kinh doanh của bạn.", + "Dashboard_CreateStoreNow": "Tạo cửa hàng ngay", + "Dashboard_QuickActions": "Thao tác nhanh", + "Dashboard_QA_CreateStore": "Tạo cửa hàng mới", + "Dashboard_QA_SystemSettings": "Cài đặt hệ thống", + "Dashboard_QA_Permissions": "Phân quyền", + "Dashboard_SystemStatus": "Trạng thái hệ thống", + "Dashboard_Status_Open": "Đang mở", + "Dashboard_Status_Setup": "Thiết lập" } \ No newline at end of file