diff --git a/app/[locale]/login/page.tsx b/app/[locale]/login/page.tsx index 920eee4..67a9a04 100644 --- a/app/[locale]/login/page.tsx +++ b/app/[locale]/login/page.tsx @@ -1,8 +1,10 @@ import type { Metadata } from "next"; +import { Suspense } from "react"; import { setRequestLocale, getTranslations } from "next-intl/server"; import { hasLocale } from "next-intl"; import { notFound } from "next/navigation"; import { SignInButton } from "@/app/components/SignInButton"; +import { LoginErrorNotice } from "@/app/components/LoginErrorNotice"; import { routing } from "@/i18n/routing"; // SEO: 登录页不参与 index(搜索引擎不需要收录登录入口) @@ -30,11 +32,20 @@ export default async function LoginPage({ params }: Props) {

{t("heading")}

{t("subheading")}

+ + +
- {/* Discord 登录暂时下线:后端 provider 已就绪,但新用户"验证邮箱→建号" - 流程(OTP wiring)还没做完,先不对外暴露以免分叉账号。做完后取消注释即可。 */} - {/* */} + {/* Discord 登录灰度中:后端按 Discord id 白名单放行(auth.discord.allowlist), + 名单外的人点了会被回调弹回 /login?error=discord_canary。GA(OTP wiring 完成、 + 清空白名单)后此按钮即对所有人开放。 */} +
diff --git a/app/components/LoginErrorNotice.tsx b/app/components/LoginErrorNotice.tsx new file mode 100644 index 0000000..bc3d3d0 --- /dev/null +++ b/app/components/LoginErrorNotice.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { useSearchParams } from "next/navigation"; + +// 登录页顶端的错误提示。后端 OAuth 回调失败会 302 到 /login?error=xxx。 +// 用 useSearchParams(客户端读 query)而非 server 读 searchParams,避免整页退回 +// 动态渲染(登录页要保持 SSG,见 CLAUDE.md 路由分类约束)。父级用 包裹。 +// 文案由 server 端 getTranslations 取好后作为 prop 传入,省一套 client i18n provider。 +export function LoginErrorNotice({ + messages, +}: { + messages: Record; +}) { + const error = useSearchParams().get("error"); + if (!error) return null; + const msg = messages[error] ?? messages.generic; + return ( +
+ {msg} +
+ ); +} diff --git a/generated/doc-contributors.json b/generated/doc-contributors.json index 822d731..af4a834 100644 --- a/generated/doc-contributors.json +++ b/generated/doc-contributors.json @@ -1,6 +1,6 @@ { "repo": "InvolutionHell/involutionhell", - "generatedAt": "2026-05-24T18:19:10.363Z", + "generatedAt": "2026-07-24T13:55:10.610Z", "docsDir": "content/docs", "totalDocs": 144, "results": [ @@ -2196,9 +2196,9 @@ "githubId": "123258594", "contributions": 2, "lastContributedAt": "2025-09-29T10:32:11.000Z", - "login": "PenghaoJiang", + "login": "OvOhao", "avatarUrl": "https://avatars.githubusercontent.com/u/123258594?v=4", - "htmlUrl": "https://github.com/PenghaoJiang" + "htmlUrl": "https://github.com/OvOhao" }, { "githubId": "41898282", @@ -2816,9 +2816,9 @@ "githubId": "76551253", "contributions": 1, "lastContributedAt": "2025-10-06T00:30:18.000Z", - "login": "840691168", + "login": "YangLiu-Lewis", "avatarUrl": "https://avatars.githubusercontent.com/u/76551253?v=4", - "htmlUrl": "https://github.com/840691168" + "htmlUrl": "https://github.com/YangLiu-Lewis" } ] }, diff --git a/messages/en.json b/messages/en.json index 2d7148b..484d1d1 100644 --- a/messages/en.json +++ b/messages/en.json @@ -70,7 +70,9 @@ "heading": "Sign In", "subheading": "Sign in to access protected pages", "github": "Sign in with GitHub", - "discord": "Sign in with Discord" + "discord": "Sign in with Discord", + "errorDiscordCanary": "Discord sign-in is in limited testing and not open yet — stay tuned!", + "errorGeneric": "Sign-in didn't complete. Please try again." }, "settings": { "theme": { diff --git a/messages/zh.json b/messages/zh.json index 7b935f7..7355d94 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -70,7 +70,9 @@ "heading": "登录", "subheading": "请登录以访问受保护的页面", "github": "用 GitHub 登录", - "discord": "用 Discord 登录" + "discord": "用 Discord 登录", + "errorDiscordCanary": "Discord 登录正在灰度测试中,暂未对外开放,敬请期待~", + "errorGeneric": "登录未完成,请重试。" }, "settings": { "theme": {