From ea6fc84c186f23fa679e760b3be6508c40321058 Mon Sep 17 00:00:00 2001 From: mlogclub Date: Sat, 30 May 2026 20:21:29 +0800 Subject: [PATCH] Refactor code structure for improved readability and maintainability --- web/app/dashboard/login/page.tsx | 69 +------- web/components/login-form.tsx | 190 ++++++++++++++--------- web/messages/en-US.json | 21 +-- web/messages/zh-CN.json | 19 ++- web/public/images/login-illustration.svg | 89 +++++++++++ 5 files changed, 237 insertions(+), 151 deletions(-) create mode 100644 web/public/images/login-illustration.svg diff --git a/web/app/dashboard/login/page.tsx b/web/app/dashboard/login/page.tsx index c38ee7d..2106163 100644 --- a/web/app/dashboard/login/page.tsx +++ b/web/app/dashboard/login/page.tsx @@ -1,72 +1,13 @@ -"use client" - import { LoginForm } from "@/components/login-form" -import { LocaleSwitcher } from "@/components/locale-switcher" -import { useI18n } from "@/i18n/provider" -import { ShieldCheckIcon } from "lucide-react" -import Link from "next/link" import { Suspense } from "react" export default function LoginPage() { - const t = useI18n() - const heroPoints = [ - t("auth.heroPoint1"), - t("auth.heroPoint2"), - t("auth.heroPoint3"), - ] - return ( -
-
-
-
-
-
- - {t("auth.heroBadge")} -
-
-

- {t("auth.heroTitle")} -

-

- {t("auth.heroSubtitle")} -

-
-
-
- {heroPoints.map((text, index) => ( -
-

{text}

-
- ))} -
-
-
-
-
- - {t("app.brand")} - {t("app.brand")} - - -
-
-
- }> - - -
-
+
+
+ }> + +
) diff --git a/web/components/login-form.tsx b/web/components/login-form.tsx index 705f6b1..9b1c0b8 100644 --- a/web/components/login-form.tsx +++ b/web/components/login-form.tsx @@ -10,10 +10,13 @@ import { fetchAuthOptions, loginWithPassword, type AuthOptions } from "@/lib/api import { useI18n } from "@/i18n/provider" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" +import { Card, CardContent } from "@/components/ui/card" import { Field, + FieldDescription, FieldGroup, FieldLabel, + FieldSeparator, } from "@/components/ui/field" import { Input } from "@/components/ui/input" import { KeyRoundIcon } from "lucide-react" @@ -29,7 +32,7 @@ function detectWxWorkEnvironment() { export function LoginForm({ className, ...props -}: React.ComponentProps<"form">) { +}: React.ComponentProps<"div">) { const t = useI18n() const router = useRouter() const searchParams = useSearchParams() @@ -45,6 +48,8 @@ export function LoginForm({ const oidcError = searchParams.get("oidcError") const redirectPath = nextPath && nextPath.startsWith("/") ? nextPath : "/dashboard" + const enabledProviderCount = + Number(authOptions.wxworkEnabled) + Number(authOptions.oidcEnabled) useEffect(() => { if (session) { @@ -110,78 +115,123 @@ export function LoginForm({ } return ( -
- -
- - {t("auth.badge")} - -

{t("auth.welcome")}

-
- - {t("auth.username")} - - - -
- {t("auth.password")} + + + + +
+

{t("auth.welcome")}

+

+ {t("auth.loginDescription", { brand: t("app.brand") })} +

+
+ + {t("auth.username")} + + + +
+ {t("auth.password")} + + {t("auth.forgotPassword")} + +
+ +
+ + + + {enabledProviderCount > 0 ? ( + <> + + {t("auth.continueWith")} + + + {authOptions.wxworkEnabled ? ( + + ) : null} + {authOptions.oidcEnabled ? ( + + ) : null} + + + ) : null} + + {t("auth.noAccount")} {t("auth.signUp")} + +
+ +
+ {/* shadcn login-04 uses a plain img for the decorative side panel. */} + {/* eslint-disable-next-line @next/next/no-img-element */} + {t("auth.imageAlt")}
- - - - - - {authOptions.wxworkEnabled ? ( - - - - ) : null} - {authOptions.oidcEnabled ? ( - - - - ) : null} - - +
+
+ + {t("auth.termsPrefix")} {t("auth.termsOfService")}{" "} + {t("auth.termsJoiner")} {t("auth.privacyPolicy")}. + +
) } diff --git a/web/messages/en-US.json b/web/messages/en-US.json index 50eff03..b8bf27e 100644 --- a/web/messages/en-US.json +++ b/web/messages/en-US.json @@ -100,22 +100,25 @@ "syncingProfile": "Syncing your admin profile and permissions", "loginSuccess": "Signed in. Taking you to the dashboard.", "loginFailed": "Sign-in failed", - "badge": "Shell AI", - "welcome": "Welcome to Shell AI Support", + "welcome": "Welcome back", + "loginDescription": "Login to your {brand} account", "username": "Username", "usernamePlaceholder": "Username or email", "password": "Password", "passwordPlaceholder": "Enter your password", + "forgotPassword": "Forgot your password?", "signingIn": "Signing in...", - "signIn": "Sign in", + "signIn": "Login", + "continueWith": "Or continue with", "wxworkSignIn": "Sign in with WeCom", "oidcSignIn": "Sign in with OIDC", - "heroBadge": "Secure Admin Workspace", - "heroTitle": "Shell AI Support", - "heroSubtitle": "Understand every issue, respond faster, and turn support into accountable outcomes.", - "heroPoint1": "Guide every conversation toward a trackable resolution.", - "heroPoint2": "Keep intake, routing, handoff, and review in one workflow.", - "heroPoint3": "Connect every channel, route intelligently, and help people work with AI.", + "noAccount": "Don't have an account?", + "signUp": "Sign up", + "termsPrefix": "By clicking continue, you agree to our", + "termsOfService": "Terms of Service", + "termsJoiner": "and", + "privacyPolicy": "Privacy Policy", + "imageAlt": "Image", "wxworkMissingTicket": "The WeCom sign-in ticket is missing.", "wxworkFailed": "WeCom sign-in failed.", "wxworkSigningIn": "Signing in with WeCom", diff --git a/web/messages/zh-CN.json b/web/messages/zh-CN.json index 96b2849..2769061 100644 --- a/web/messages/zh-CN.json +++ b/web/messages/zh-CN.json @@ -100,22 +100,25 @@ "syncingProfile": "将自动同步当前管理员信息与权限数据", "loginSuccess": "登录成功,正在进入系统", "loginFailed": "登录失败", - "badge": "贝壳AI", - "welcome": "欢迎使用贝壳 AI 客服平台", + "welcome": "欢迎回来", + "loginDescription": "登录你的 {brand} 账号", "username": "用户名", "usernamePlaceholder": "用户名或邮箱", "password": "密码", "passwordPlaceholder": "请输入密码", + "forgotPassword": "忘记密码?", "signingIn": "登录中...", "signIn": "登录", + "continueWith": "或继续使用", "wxworkSignIn": "企业微信登录", "oidcSignIn": "OIDC 登录", - "heroBadge": "安全管理空间", - "heroTitle": "贝壳AI客服", - "heroSubtitle": "懂问题,更懂用户;快响应,更能落地。", - "heroPoint1": "让每一次咨询,都通向可追踪的结果。", - "heroPoint2": "从接待到转派到复盘,一条链路跑到底。", - "heroPoint3": "多渠道接入,智能分配,人机协同提效。", + "noAccount": "还没有账号?", + "signUp": "注册", + "termsPrefix": "点击继续即表示你同意我们的", + "termsOfService": "服务条款", + "termsJoiner": "和", + "privacyPolicy": "隐私政策", + "imageAlt": "图片", "wxworkMissingTicket": "企业微信登录票据不存在", "wxworkFailed": "企业微信登录失败", "wxworkSigningIn": "企业微信登录中", diff --git a/web/public/images/login-illustration.svg b/web/public/images/login-illustration.svg new file mode 100644 index 0000000..5e1f517 --- /dev/null +++ b/web/public/images/login-illustration.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +