Merge pull request 'fix(auth): 独立登录注册页面并弱化主题切换' (#39) from codex/auth-page-fix into main
creative workspace CI and deployment / verify-and-deploy (push) Failing after 9m31s

Reviewed-on: #39
This commit was merged in pull request #39.
This commit is contained in:
2026-11-01 13:16:22 +00:00
6 changed files with 38 additions and 5 deletions
@@ -48,9 +48,11 @@ export const useGuidanceAccount = () => useContext(AccountContext);
export default function GuidanceShell({
children,
title = "探索文档",
standalone = false,
}: {
children: ReactNode;
title?: string;
standalone?: boolean;
}) {
const router = useRouter();
const dialog = useRef<HTMLDialogElement>(null);
@@ -187,6 +189,19 @@ export default function GuidanceShell({
</>
);
}
if (standalone) return (
<AccountContext.Provider value={{ user, loading, error, refresh }}>
<div className={s.accountPage}>
<Head><title>{`${title} · 啡跃`}</title></Head>
<a className={s.skipLink} href="#account-content">跳到正文</a>
<header className={s.accountHeader}>
<Link href="/" aria-label="啡跃首页"><Brand /></Link>
<div><Link href="/">返回首页</Link><ThemeToggle /></div>
</header>
<main id="account-content">{children}</main>
</div>
</AccountContext.Provider>
);
return (
<AccountContext.Provider value={{ user, loading, error, refresh }}>
<div className={s.site}>
@@ -3,5 +3,5 @@ export function ThemeToggle() {
const [dark, setDark] = useState(false);
const [ready, setReady] = useState(false);
useEffect(() => { const sync = () => setDark(document.documentElement.dataset.mode === 'dark'); sync(); setReady(true); window.addEventListener('endoleap-theme', sync); return () => window.removeEventListener('endoleap-theme', sync); }, []);
return <button type="button" data-theme-ready={ready} className="endoleap-theme-toggle" aria-label="切换明暗主题" title={dark ? '切换浅色模式' : '切换深色模式'} onClick={() => { const mode = document.documentElement.dataset.mode === 'dark' ? 'light' : 'dark'; const scope = document.documentElement.dataset.theme?.startsWith('canvas-') ? 'canvas' : 'home'; document.documentElement.dataset.mode = mode; document.documentElement.dataset.theme = `${scope}-${mode}`; try { localStorage.setItem('endoleap.theme', mode); } catch {} window.dispatchEvent(new Event('endoleap-theme')); }}>◐<span>{dark ? '浅色' : '深色'}</span></button>;
return <button type="button" data-theme-ready={ready} className="endoleap-theme-toggle" aria-label="切换明暗主题" title={dark ? '切换浅色模式' : '切换深色模式'} onClick={() => { const mode = document.documentElement.dataset.mode === 'dark' ? 'light' : 'dark'; const scope = document.documentElement.dataset.theme?.startsWith('canvas-') ? 'canvas' : 'home'; document.documentElement.dataset.mode = mode; document.documentElement.dataset.theme = `${scope}-${mode}`; try { localStorage.setItem('endoleap.theme', mode); } catch {} window.dispatchEvent(new Event('endoleap-theme')); }}><span aria-hidden="true">◐</span></button>;
}
+1 -1
View File
@@ -37,7 +37,7 @@ function localNext(value: string | string[] | undefined) {
}
export default function AccountPage() {
return (
<GuidanceShell title="邮箱账户">
<GuidanceShell title="登录与注册" standalone>
<AccountContent />
</GuidanceShell>
);
+2 -2
View File
@@ -8,11 +8,11 @@ body{margin:0}
[data-theme$="-dark"] .endoleap-mark-dark{display:block!important}
.endoleap-wordmark{display:flex!important;flex-direction:column;font-size:17px!important;color:var(--foreground-strong)!important;letter-spacing:.02em!important;margin:0!important;gap:3px}
.endoleap-wordmark small{display:block;font-size:9px;font-weight:500;letter-spacing:.08em;color:var(--muted-foreground)}
button.endoleap-theme-toggle{display:inline-flex;align-items:center;justify-content:center;gap:5px;border:1px solid var(--border);background:var(--surface);color:var(--foreground);border-radius:8px;padding:7px 9px;font-size:12px;line-height:1.2;flex-shrink:0;cursor:pointer}
button.endoleap-theme-toggle{display:inline-flex;align-items:center;justify-content:center;gap:5px;border:0;background:transparent;color:var(--muted-foreground);border-radius:8px;padding:8px;width:32px;height:32px;font-size:16px;line-height:1.2;flex-shrink:0;cursor:pointer}
button.endoleap-theme-toggle:hover{background:var(--row-hover)}
:where(a,button,input,textarea,select):focus-visible{outline:2px solid var(--ring);outline-offset:3px}
::selection{background:var(--selection);color:var(--foreground)}
@media(max-width:600px){.endoleap-theme-toggle span{display:none}.endoleap-brand{gap:5px}.endoleap-brand .endoleap-mark{width:26px;height:26px}.endoleap-wordmark{font-size:14px!important}}
@media(max-width:600px){.endoleap-theme-toggle span{display:inline}.endoleap-brand{gap:5px}.endoleap-brand .endoleap-mark{width:26px;height:26px}.endoleap-wordmark{font-size:14px!important}}
button:disabled{cursor:default}
input,textarea,select{accent-color:var(--primary)}
@@ -2380,3 +2380,14 @@
.primaryButton,.primaryButton:hover{color:var(--primary-foreground);background:var(--primary)}
.primaryButton:hover{background:var(--primary-hover)}
.primaryButton:disabled{background:var(--disabled-background);color:var(--disabled-foreground)}
/* Authentication has its own public page, without workspace navigation. */
.accountPage { min-height: 100vh; background: var(--background); color: var(--foreground); }
.accountHeader { max-width: 1200px; margin: 0 auto; padding: 24px 32px; display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.accountHeader a { color: var(--muted-foreground); text-decoration: none; }
.accountHeader > div { display: flex; align-items: center; gap: 20px; font-size: 13px; }
.accountPage > main { max-width: 1120px; margin: 0 auto; padding: 48px 32px 72px; }
@media (max-width: 650px) {
.accountHeader { padding: 20px; }
.accountPage > main { padding: 20px 20px 48px; }
}
@@ -102,7 +102,11 @@ export async function verifyGuidanceWorkspaceUI(base: string, browser: Browser)
try {
const navigation = await (reload ? page.reload({waitUntil:"commit"}) : page.goto(url,{waitUntil:"commit"}));
assert.ok(navigation?.ok(), "Navigation returns a successful document");
await page.getByText(signedIn ? "editor@example.com" : "登录你的账户",{exact:true}).first().waitFor({state:"attached"});
if (new URL(url).pathname === "/account") {
await page.getByRole("heading", { name: signedIn ? "你的账户" : "欢迎回来", exact: true }).waitFor();
} else {
await page.getByText(signedIn ? "editor@example.com" : "登录你的账户",{exact:true}).first().waitFor({state:"attached"});
}
assert.ok(sessionReplies > previousSessionReplies, "The new document requests its account fixture and renders the resulting account state");
} catch (error) {
const probeStarted=Date.now();
@@ -155,6 +159,9 @@ export async function verifyGuidanceWorkspaceUI(base: string, browser: Browser)
fullPage: true,
});
await navigate(base + "/account");
assert.equal(await page.getByRole("complementary").count(), 0, "Account page has no workspace sidebar");
assert.equal(await page.getByRole("link", { name: "创建文档", exact: true }).count(), 0);
await page.getByRole("link", { name: "返回首页", exact: true }).waitFor();
await page.getByRole("button", { name: "创建账户", exact: true }).click();
await page.getByRole("heading", { name: "创建你的账户" }).waitFor();
await page