diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-18 15:49:44 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-18 15:49:44 +0800 |
| commit | a7aab01f051487327e5ce52b6a8905208c546e8c (patch) | |
| tree | 630a624523bc15d1a9f59ab20693385eaf55befb /frontend/src/pages/AuthPages.svelte | |
| parent | 375584174fb7191a57c5423fea45924ad6d812d5 (diff) | |
| download | strategy-lab-a7aab01f051487327e5ce52b6a8905208c546e8c.tar.gz | |
[变更性质] feat(frontend)
[新增功能] 12 页面组件全量 shadcn:Card/Button/Table/Tabs/Select/Alert;375 底部 Tab Bar 改用 Tabs 组件实现
[实现方案] 页面级手写 class 全部移除(.btn/.banner/table.data/.badge/.tabs/.metric-row/.m-tile/.hint 等改为 shadcn + tailwind 工具类);Modal/DatasetWizard/DatasetCard/DiffView/CodeEditor/Status/Layout 同步
[影响范围] src/pages/*.svelte、src/components/*.svelte
Diffstat (limited to 'frontend/src/pages/AuthPages.svelte')
| -rw-r--r-- | frontend/src/pages/AuthPages.svelte | 154 |
1 files changed, 63 insertions, 91 deletions
diff --git a/frontend/src/pages/AuthPages.svelte b/frontend/src/pages/AuthPages.svelte index 88ca07a..da5d54c 100644 --- a/frontend/src/pages/AuthPages.svelte +++ b/frontend/src/pages/AuthPages.svelte @@ -92,114 +92,86 @@ } </script> -<section class="auth-wrap"> - <Card.Root class="auth-card" role="main"> - <div class="auth-brand"> - <span class="mark" aria-hidden="true"></span> - <h1>策研 <span class="sub">Strategy Lab</span></h1> - <p class="hint">内部策略研究平台 · 仅限受邀成员</p> +<section class="min-h-screen flex items-center justify-center p-6 min-w-0"> + <Card.Root class="w-[min(400px,100%)] p-8 max-[768px]:p-7" role="main"> + <div class="mb-4"> + <span class="inline-block w-8 h-8 rounded-lg bg-primary mb-2" aria-hidden="true"></span> + <h1 class="text-xl font-semibold mb-1">策研 <span class="text-muted-foreground/70 font-medium text-[0.8rem]">Strategy Lab</span></h1> + <p class="text-sm text-muted-foreground max-w-[26em]">内部策略研究平台 · 仅限受邀成员</p> </div> {#if mode === 'register'} <form onsubmit={register}> - <div> - <Label for="inv">邀请令牌</Label> - <Input id="inv" bind:value={inviteToken} required autocomplete="off" /> - <p class="hint">单次有效,来自管理员邀请</p> - </div> - <div> - <Label for="nm">姓名</Label> - <Input id="nm" bind:value={name} required autocomplete="name" /> - </div> - <div> - <Label for="em">邮箱</Label> - <Input id="em" type="email" bind:value={email} required autocomplete="email" /> - </div> - <div> - <Label for="pw">密码</Label> - <Input id="pw" type="password" bind:value={password} required autocomplete="new-password" minlength={8} /> - <div class="hint">至少 8 位</div> + <div class="flex flex-col gap-4"> + <div> + <Label for="inv">邀请令牌</Label> + <Input id="inv" bind:value={inviteToken} required autocomplete="off" /> + <p class="text-sm text-muted-foreground mt-1">单次有效,来自管理员邀请</p> + </div> + <div> + <Label for="nm">姓名</Label> + <Input id="nm" bind:value={name} required autocomplete="name" /> + </div> + <div> + <Label for="em">邮箱</Label> + <Input id="em" type="email" bind:value={email} required autocomplete="email" /> + </div> + <div> + <Label for="pw">密码</Label> + <Input id="pw" type="password" bind:value={password} required autocomplete="new-password" minlength={8} /> + <p class="text-sm text-muted-foreground mt-1">至少 8 位</p> + </div> + {#if resultError}<Alert variant="destructive">{resultError}</Alert>{/if} + <Button type="submit" disabled={busy}>{busy ? '创建中…' : '开通账户'}</Button> + <p class="text-sm text-muted-foreground">已有账户? <a class="hover:underline" href="#/login">登录</a></p> </div> - {#if resultError}<Alert variant="destructive" class="bg-[var(--danger-soft)] border-[#f2c7c7]">{resultError}</Alert>{/if} - <Button type="submit" disabled={busy}>{busy ? '创建中…' : '开通账户'}</Button> - <p class="hint">已有账户? <a href="#/login">登录</a></p> </form> {:else if mode === 'reset'} {#if done} - <Alert class="bg-[var(--brand-soft)] border-[#bfe9db]">{done}</Alert> - <p><a href="#/login">前往登录</a></p> + <Alert>{done}</Alert> + <p class="mt-2"><a class="hover:underline" href="#/login">前往登录</a></p> {:else} <form onsubmit={reset}> - <div> - <Label for="rt">重置令牌</Label> - <Input id="rt" bind:value={resetToken} autocomplete="off" /> - <p class="hint">由管理员线下发放的恢复链接自动填入;不支持邮箱自动发送</p> + <div class="flex flex-col gap-4"> + <div> + <Label for="rt">重置令牌</Label> + <Input id="rt" bind:value={resetToken} autocomplete="off" /> + <p class="text-sm text-muted-foreground mt-1">由管理员线下发放的恢复链接自动填入;不支持邮箱自动发送</p> + </div> + <div> + <Label for="np">新密码</Label> + <Input id="np" type="password" bind:value={newPassword} required autocomplete="new-password" minlength={8} /> + </div> + <div> + <Label for="np2">再输入一次新密码</Label> + <Input id="np2" type="password" bind:value={pw2} required autocomplete="new-password" minlength={8} /> + </div> + {#if resultError}<Alert variant="destructive">{resultError}</Alert>{/if} + <Button type="submit" disabled={busy}>{busy ? '重置中…' : '重置密码'}</Button> + <p class="text-sm text-muted-foreground">想起密码了? <a class="hover:underline" href="#/login">直接登录</a></p> </div> - <div> - <Label for="np">新密码</Label> - <Input id="np" type="password" bind:value={newPassword} required autocomplete="new-password" minlength={8} /> - </div> - <div> - <Label for="np2">再输入一次新密码</Label> - <Input id="np2" type="password" bind:value={pw2} required autocomplete="new-password" minlength={8} /> - </div> - {#if resultError}<Alert variant="destructive" class="bg-[var(--danger-soft)] border-[#f2c7c7]">{resultError}</Alert>{/if} - <Button type="submit" disabled={busy}>{busy ? '重置中…' : '重置密码'}</Button> - <p class="hint">想起密码了? <a href="#/login">直接登录</a></p> </form> {/if} {:else} <form onsubmit={login}> - <div> - <Label for="le">邮箱</Label> - <Input id="le" type="email" bind:value={email} required autocomplete="email" /> - </div> - <div> - <Label for="lp">密码</Label> - <Input id="lp" type="password" bind:value={password} required autocomplete="current-password" /> + <div class="flex flex-col gap-4"> + <div> + <Label for="le">邮箱</Label> + <Input id="le" type="email" bind:value={email} required autocomplete="email" /> + </div> + <div> + <Label for="lp">密码</Label> + <Input id="lp" type="password" bind:value={password} required autocomplete="current-password" /> + </div> + {#if resultError}<Alert variant="destructive">{resultError}</Alert>{/if} + <Button type="submit" disabled={busy}>{busy ? '登录中…' : '登录'}</Button> + <p class="text-sm text-muted-foreground"> + 开通新账户需要管理员邀请: <a class="hover:underline" href="#/register">用邀请令牌注册</a> + {#if route.query.get('invite')}<span>(邀请令牌已自动填入)</span>{/if} + </p> + <p class="text-sm text-muted-foreground">忘记密码?请联系管理员获取 <a class="hover:underline" href="#/reset">恢复链接</a></p> </div> - {#if resultError}<Alert variant="destructive" class="bg-[var(--danger-soft)] border-[#f2c7c7]">{resultError}</Alert>{/if} - <Button type="submit" disabled={busy}>{busy ? '登录中…' : '登录'}</Button> - <p class="hint"> - 开通新账户需要管理员邀请: <a href="#/register">用邀请令牌注册</a> - {#if route.query.get('invite')}<span>(邀请令牌已自动填入)</span>{/if} - </p> - <p class="hint">忘记密码?请联系管理员获取 <a href="#/reset">恢复链接</a></p> </form> {/if} </Card.Root> </section> - -<style> - .auth-wrap { - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - padding: 1.5rem; - /* grid place-items center sizes the implicit track to the card's fixed - width so max-width:100% never engaged (375px probe: 47px doc overflow); - flex + min() keeps the resolved card width inside the padded viewport */ - min-width: 0; - background: - radial-gradient(700px 350px at 85% -60px, rgba(13, 148, 136, 0.08), transparent), - var(--bg); - } - :global(.auth-card) { width: min(400px, 100%); padding: 2rem 1.75rem 1.8rem; } - /* round2 登录页留白重排:标题区与表单拉开,卡片下缘留呼吸感 */ - @media (min-width: 768px) { - :global(.auth-card) { padding: 2.4rem 2.2rem 2.1rem; } - } - .auth-brand { margin-bottom: 1.35rem; } - .auth-brand h1 { margin-bottom: 0.3rem; } - .auth-brand p { max-width: 26em; } - .mark { - display: inline-block; - width: 34px; - height: 34px; - border-radius: 9px; - background: var(--teal-strong); - margin-bottom: 0.6rem; - } - .sub { color: var(--text-3); font-weight: 500; font-size: 0.8rem; } -</style> |
